# Projektstruktur ## Ordnerstruktur Drei Grundordner nach Verantwortung. Resources liegen bei ihren Skripten. ``` scenes/ — Darstellung + Input effect_icon_factory.gd — Shared Utility (statisch, Effekt-Icon-Erstellung) healthbar.gd — Health-Anzeige + Viewport-Setup healthbar_shield.gd — Shield-Anzeige healthbar_status.gd — Target-Border + Aggro-Farbwechsel healthbar_effects.gd — Effekt-Icons auf Healthbar player/ — Spieler + player_stats role/ — Rollenwechsel + Ability/AbilitySet-Klassen damage/ — set.tres + abilities/ tank/ — set.tres + abilities/ healer/ — set.tres + abilities/ enemy/ — Gegner + enemy_stats boss/ — Boss + boss_stats portal/ — Portal + Gate + portal_stats dungeon/ — Dungeon + dungeon_manager hud/ — HUD (4 Skripte: vitals, respawn, abilities, effects) world/ — Hauptszene + portal_spawner systems/ — Spiellogik aggro/ — AggroSystem (system, tracker, decay, events) + aggro_config effect.gd — Effect Resource (Buff/Debuff/Aura Daten) 11× *_system.gd — health, shield, ability, auto_attack, cooldown, enemy_ai, respawn, spawn, effect, element, buff_calc aura_system.gd — Aura-Propagierung (Child von EffectSystem) autoloads/ — Globaler Zustand event_bus.gd game_state.gd stats/ — stats.gd + base_stats.gd ``` ## Szenenbaum - Welt - Systems (12 Systeme als Child-Nodes) - Taverne - Player - Portale (dynamisch) - Gegner - HUD ## Architektur - Resources (stats/, roles/) — Datenmodelle + Basiswerte, werden später zu Go-Structs + DB - Autoload (Stats) — Laufzeit-Datenhaltung, wird später zu Server-API-Client - Systeme — Spiellogik, lesen/schreiben über Stats - Szenen — Views, rendern + Input, kein Gameplay-State - EventBus — Signale zwischen Szenen und Systemen - Flow: Szene → Input → EventBus → System → Stats → EventBus → Szene - Szenen kennen sich nicht - Innerhalb einer Szene: direkter Zugriff auf Geschwister erlaubt # Autoload ## EventBus (autoload/event_bus.gd) - Intentionen (Input → System): - ability_use_requested(player, ability_index) - enemy_detected(enemy, player) - Kampf: - attack_executed(attacker, position, direction, damage) - damage_dealt(attacker, target, damage) - damage_requested(attacker, target, amount) - heal_requested(healer, target, amount) - Entity: - entity_died(entity) - health_changed(entity, current, max) - shield_changed(entity, current, max) - shield_broken(entity) - shield_regenerated(entity) - Spieler: - target_changed(player, target) - player_respawned(player) - role_changed(player, role_type) - respawn_tick(timer) - cooldown_tick(cooldowns, max_cooldowns, gcd_timer) - Buff: - buff_changed(entity, stat, value) - Gegner: - enemy_engaged(enemy, target) - Portal: - portal_spawn(portal, enemies) - portal_defeated(portal) - Dungeon: - dungeon_cleared() - Effects: - effect_requested(target, effect, source) - effect_applied(target, effect) - effect_expired(target, effect) - Elements: - element_damage_dealt(attacker, target, amount, element) - element_applied(target, element) - element_reaction(target, element_a, element_b, reaction_name) ## Stats (autoload/stats.gd) - Speichert aktuelle Attribute aller Entities - Basiswerte aus BaseStats Resource - player_cache für Szenenwechsel ## GameState (autoload/game_state.gd) - Speichert Rolle + Position zwischen Szenenwechseln # Resources ## resources/stats/ ### BaseStats (base_stats.gd) - max_health, health_regen, max_shield, shield_regen_delay, shield_regen_time ### PlayerStats (player_stats.gd, extends BaseStats) - speed, jump_velocity, target_range, combat_timeout, respawn_time, gcd_time, aa_cooldown ### EnemyStats (enemy_stats.gd, extends BaseStats) - speed, attack_range, attack_cooldown, attack_damage, regen_fast, regen_slow, aggro_decay, portal_radius, alert_radius ### BossStats (boss_stats.gd, extends EnemyStats) ### PortalStats (portal_stats.gd, extends BaseStats) - spawn_count, thresholds ## resources/roles/ ### Ability (ability.gd) - ability_name, type, damage, ability_range, cooldown, uses_gcd, aoe_radius, icon, is_heal, passive_stat, element - Typen: Single, AOE, Utility, Ult, Passive ### AbilitySet (ability_set.gd) - abilities (Array[Ability]), aa_damage, aa_range, aa_is_heal ### AbilityModifier (geplant, Zukunft) - Verändert Ability (Beruf, Prestige) ### Rollen-Ordner (damage/, tank/, healer/) - set.tres — AbilitySet der Rolle - abilities/ — 5 Ability .tres pro Rolle (single, aoe, utility, ult, passive) # Systeme (systems/) - In jeder Root-Szene instanziert (world.tscn, dungeon.tscn) - Entities registrieren/deregistrieren sich bei Stats - Systeme lesen/schreiben über Stats ### HealthSystem (health_system.gd) - Leben und Lebensregeneration berechnen, Tod bei 0 HP - Listener: damage_requested, heal_requested - Event: health_changed, entity_died ### ShieldSystem (shield_system.gd) - Schild und Schildregeneration berechnen - absorb(entity, amount) → remaining damage - Event: shield_changed, shield_broken, shield_regenerated ### RespawnSystem (respawn_system.gd) - Respawn bei Taverne mit vollen Leben und Schild - Listener: entity_died - Event: respawn_tick, player_respawned ### AbilitySystem (ability_system.gd) - Ability-Ausführung (Single, AOE, Utility, Ult) - Listener: ability_use_requested - Event: attack_executed, damage_requested, heal_requested ### AutoAttackSystem (auto_attack_system.gd) - Auto-Attack-Logik, läuft jeden Frame in _process - Liest CombatState.in_combat + Targeting.current_target - Event: damage_requested, heal_requested ### EffectSystem (effect_system.gd) - Verwaltet Buffs, Debuffs und Auras auf Entities - Effect Resource (effect.gd): effect_name, type (BUFF/DEBUFF/AURA), stat, value, duration, is_multiplier, aura_radius, tick_interval, element - State: active_effects Dictionary[Node, Array[Dict]] (effect, source, remaining, tick_timer) - Kein Stacking: gleicher effect_name auf Entity → wird refreshed statt gestackt - Passive-Abilities werden als AURA-Effekte erstellt (role_changed → permanente Auras) - _process: Dauer ticken, abgelaufene entfernen, DoT/HoT-Ticks - Listener: role_changed, entity_died, effect_requested - Event: effect_applied, effect_expired - Children: - AuraSystem (aura_system.gd) — Aura-Propagierung im Radius, Buff-Refresh - BuffCalcSystem (buff_calc_system.gd) — Multiplier aggregieren → Stats + Shield updaten - Event: buff_changed, shield_changed ### ElementSystem (element_system.gd) - Verwaltet Element-Zustände auf Entities und löst Elementareffekte aus - Element Enum: NONE, FIRE (erweiterbar) - State: applied_elements Dictionary[Node, int] - Nur Entities in Gruppen "enemies" oder "portals" erhalten Elemente - Bei Element-Schaden: Element auf Ziel anwenden, passenden Effekt erstellen - Feuer: DoT (3 Schaden/Tick, 2s Interval, 6s Dauer) - Bei zwei verschiedenen Elementen: Reaktion auslösen (Zukunft) - Listener: element_damage_dealt, entity_died, effect_expired - Event: element_applied, element_reaction ### CooldownSystem (cooldown_system.gd) - Cooldown-Tracking, GCD, AA-Timer per Entity - register/deregister per Entity, direkte Funktionsaufrufe vom AbilitySystem - Event: cooldown_tick ### AggroSystem (systems/aggro/) - Systemweite Werte in AggroConfig Resource (resources/stats/aggro_config.tres) - aggro_system.gd — Parent, Config halten, Children verdrahten - aggro_tracker.gd — Aggro-Tabellen, Players-in-Range, Zielwahl, Radius-Helper - aggro_decay.gd — Combat-Timer, Decay-Berechnung, Spread, Alert - aggro_events.gd — Signal-Handler (damage_dealt, heal_requested, entity_died, enemy_detected, enemy_lost) - Event: enemy_engaged ### EnemyAISystem (enemy_ai_system.gd) - ATTACK-State: Range-Check, Timer, Schaden - Iteriert Enemies in _physics_process - Event: damage_requested ### SpawnSystem (spawn_system.gd) - Portal-HP-Schwellen-Spawning - Listener: health_changed, entity_died - Event: portal_spawn # Szenen - Szenen sind Views — rendern, Input senden, Events empfangen - Kein Gameplay-State in Szenen (liegt in Stats Autoload) - Entities registrieren sich bei Stats in _ready(), deregistrieren in _exit_tree() - Stats cached Spieler-Werte automatisch bei Szenenwechsel (player_cache) ## Welt (world/) - world.tscn — Hauptszene (100x100m) - Systems (alle 11 Systeme als Child-Nodes) - NavigationRegion3D - Boden (MeshInstance3D, 100x100m PlaneMesh) - Kollision (StaticBody3D, WorldBoundaryShape3D) - Licht (DirectionalLight3D, 45°, Schatten) - Taverne (StaticBody3D, BoxMesh, Mitte der Karte) - Spieler (Instanz von player.tscn) - HUD (Instanz von hud.tscn) - PortalSpawner (Node, portal_spawner.gd) ## Spieler (player/) - player.tscn — CharacterBody3D - Gruppe (player) - Kollision (CapsuleShape3D, 1.8m x 0.3m) - Mesh (CapsuleMesh) - CameraPivot (Node3D, camera.gd) - Camera3D - Movement (Node, movement.gd) — WASD + Springen, liest Werte von Stats - Combat (Node, combat.gd) — Input-Handler, emittiert ability_use_requested - CombatState (Node, combat_state.gd) — in_combat-Tracking, Combat-Timer - Role (Node, role.gd) — Rollenwechsel ALT+1/2/3, emittiert role_changed (auch bei _ready) - Targeting (Node, targeting.gd) — Klick/TAB/Auto-Target, emittiert target_changed - player.gd — Registriert bei Stats mit PlayerStats Resource, Sichtbarkeit bei Tod/Respawn - camera.gd — LMB freies Umsehen, RMB Kamera + Laufrichtung ## Gegner (enemy/) - enemy.tscn — CharacterBody3D - Gruppe (enemies) - Kollision (CapsuleShape3D) - Mesh (SphereMesh) - HitArea (Area3D) - DetectionArea (Area3D, emittiert enemy_detected) - NavigationAgent3D - EnemyMovement (Node, enemy_movement.gd) — Empfängt Bewegungsbefehle - Healthbar (Sprite3D + SubViewport, healthbar.gd) — Health-Anzeige - HealthbarShield (Node, healthbar_shield.gd) — Shield-Anzeige - HealthbarStatus (Node, healthbar_status.gd) — Target-Border + Aggro-Farbe - HealthbarEffects (Node, healthbar_effects.gd) — Effekt-Icons - enemy.gd — Registriert bei Stats mit EnemyStats Resource, Detection-Area Signal - Aggro-Regeln (Werte in AggroConfig Resource): - Aufbau: - Schaden = Aggro (1:1), Tank 2x Multiplikator - Heilung = 0.5x Aggro auf alle Gegner die Heiler kennen - Aggro-Spread: 50% des Aggro an Gegner im alert_radius (10m) - Detection-Area (10m): +1 Aggro, Alert an Nachbarn im alert_radius - Kampfstatus: - Spieler in DetectionArea → immer im Kampf (kein Decay) - Spieler verlässt DetectionArea → 5s Combat-Timeout, dann Decay - Schaden verursachen setzt Combat-Timer zurück - Abbau (nach Combat-Timeout): - Basis: -aggro_decay/s (default 1.0) - Exponentieller Decay basierend auf Zeit seit Kampfende (1%·2^sekunden) - Ohne Aggro: Gegner kehrt zum Portal zurück, regeneriert - Bei Spieler-Tod → Aggro auf 0 ## Boss (enemy/) - boss.tscn — wie enemy.tscn aber größer (Mesh lila, 1.5x) - Gruppe (enemies, boss) - boss.gd — Erbt von enemy.gd, registriert bei Stats mit BossStats Resource ## Portal (portal/) - portal.tscn — StaticBody3D - Gruppe (portals) - Kollision (CylinderShape3D) - Mesh (CylinderMesh, blau) - HitArea (Area3D) - DetectionArea (Area3D, Auto-Targeting bei Betreten) - Healthbar (Sprite3D + SubViewport, healthbar.gd) - HealthbarShield (Node, healthbar_shield.gd) - HealthbarStatus (Node, healthbar_status.gd) - HealthbarEffects (Node, healthbar_effects.gd) - portal.gd — Registriert bei Stats mit PortalStats Resource - Spawnt Gegner bei HP-Schwellen (→ SpawnSystem) ## Gate (portal/) - gate.tscn — StaticBody3D (keine Kollision) - Mesh (CylinderMesh, grün, leuchtend) - GateArea (Area3D, 3m Radius) - gate.gd — Konfigurierbar: target_scene, is_exit - Beide Gates bestehen solange Boss lebt, verschwinden bei dungeon_cleared ## Dungeon (dungeon/) - dungeon.tscn — Geschlossener Raum (15x90m, Wände, dunkles Licht) - Systems (alle 12 Systeme, temporär bis Welt parallel läuft) - NavigationRegion3D - Boden, 4 Wände (StaticBody3D + BoxMesh, 3m hoch) - Spieler (Instanz von player.tscn) - HUD (Instanz von hud.tscn) - Gegnergruppen (4x4 Gegner) - Boss (Instanz von boss.tscn) - Exit-Gate (Instanz von gate.tscn, is_exit=true) - DungeonManager (Node, dungeon_manager.gd) - Eigene Systems bis Welt parallel läuft (geplant: Reparenting) ## HUD (hud/) - hud.tscn — CanvasLayer (kein Root-Skript) - HealthBar (ProgressBar, Label) - ShieldBar (ProgressBar, Label) - RespawnTimer (Label, Countdown bei Tod) - AbilityBar (HBoxContainer, RoleIcon + Abilities 1-4 + Passive) - HudVitals (Node, hud_vitals.gd) — HP/Shield-Bars - HudRespawn (Node, hud_respawn.gd) — Respawn-Timer - HudAbilities (Node, hud_abilities.gd) — Ability-Bar + Cooldowns + Rollen-Icon - HudEffects (Node, hud_effects.gd) — Effekt-Icons (nutzt EffectIconFactory) # Abilities (Werte) - Schadens-Klasse: - AA: 10 Schaden, 10m - 1 Single: 30 Schaden, 20m Range, 2s CD, GCD - 2 AOE: 20 Schaden, 5m Range, 3s CD, GCD - 3 Utility: Schild sofort auf 100%, 5s CD, kein GCD - 4 Ult: 5x Single (50 Schaden) + 2x AOE 3m (20 Schaden), 20m Range, 15s CD, GCD - 5 Passive: 50% mehr Schaden Aura, 50m (permanent aktiv, kein CD) - Tank-Klasse: - AA: 5 Schaden, 3m - 1 Single: 15 Schaden, 3m Range, 2s CD, GCD - 2 AOE: 10 Schaden, 10m Range, 3s CD, GCD - 3 Utility: Schild sofort auf 100%, 5s CD, kein GCD - 4 Ult: Schild 300%, 20s CD, GCD - 5 Passive: 50% mehr Schild Aura, 50m (permanent aktiv, kein CD) - Heiler-Klasse: - AA: 1 Heilung, 20m - 1 Single: 15 Heilung, 20m Range, 2s CD, GCD - 2 AOE: 10 Heilung, 20m Range, 3s CD, GCD - 3 Utility: Schild sofort auf 100%, 5s CD, kein GCD - 4 Ult: 25 Heal Single + 10 AOE Heal 3m radius, 20m Range, 15s CD, GCD - 5 Passive: 50% mehr Heal Aura, 50m (permanent aktiv, kein CD) ---