diff --git a/CLAUDE.md b/CLAUDE.md index eb53165..680b403 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -12,6 +12,9 @@ Der User kommuniziert auf Deutsch. Code und Variablen auf Englisch. Kommentare n - Keine Debug-Prints im finalen Code (nur temporär zum Testen) ## Architektur +- **Systeme berechnen und entscheiden**, Szenen rendern und senden/empfangen +- **Event-Flow**: Input → Intention-Event → System → Ergebnis-Event → Node +- **Systeme** sind Scene-Nodes (nicht Autoloads), gefunden über Gruppen - **Zwischen Szenen**: Kommunikation über EventBus (Autoload). Szenen kennen sich nicht. - **Innerhalb einer Szene**: Modulare Skripte als Child-Nodes, Zugriff auf Geschwister-Nodes erlaubt. - **Autoloads**: EventBus (Signals), GameState (Spielerzustand zwischen Szenenwechseln) @@ -28,12 +31,12 @@ Der User kommuniziert auf Deutsch. Code und Variablen auf Englisch. Kommentare n - `portal/gate.tscn` — Gate (Teleporter, konfigurierbar: Dungeon-Eingang oder Exit) - `dungeon/dungeon.tscn` — Dungeon (15x90m Schlauch, 4 Gegnergruppen + Boss) - `hud/hud.tscn` — HUD -- `scripts/player/` — Spieler-Skripte (player, camera, movement, combat, targeting, role, respawn, hud) -- `scripts/enemy/` — Gegner-Skripte (enemy, enemy_movement, enemy_combat, enemy_aggro, boss) +- `scripts/systems/` — Zentrale Systeme (health, shield, respawn, ability, cooldown, damage, buff, aggro, enemy_ai, spawn) +- `scripts/player/` — Spieler-Skripte (player, camera, movement, combat, targeting, role, hud) +- `scripts/enemy/` — Gegner-Skripte (enemy, enemy_movement, boss) - `scripts/portal/` — Portal + Gate (portal, gate) - `scripts/dungeon/` — Dungeon-Logik (dungeon_manager) -- `scripts/world/` — Welt-Logik (portal_spawner) -- `scripts/components/` — Wiederverwendbare Komponenten (health, shield, healthbar, spawner) +- `scripts/components/` — Wiederverwendbare Komponenten (health, shield, healthbar) - `scripts/abilities/` — Ability-System (ability, ability_set) - `scripts/resources/` — Resource-Klassen (entity_stats) - `scripts/event_bus.gd` — Globale Signals diff --git a/plan.md b/plan.md index 6925467..f965123 100644 --- a/plan.md +++ b/plan.md @@ -1,6 +1,7 @@ # Projektstruktur ## Szenenbaum - Welt + - Systems (HealthSystem, ShieldSystem, RespawnSystem, CombatSystem, AggroSystem, EnemyAISystem, SpawnSystem) - Taverne - Player - Portale (dynamisch) @@ -10,19 +11,81 @@ ## Architektur - Zwischen Szenen: Kommunikation über EventBus (Szenen kennen sich nicht) - Innerhalb einer Szene: Modulare Skripte, Zugriff auf Geschwister-Nodes erlaubt +- Systeme berechnen und entscheiden, Szenen rendern und senden/empfangen +- Event-Flow: Input → Intention-Event → System → Ergebnis-Event → Node +- Systeme sind Scene-Nodes (nicht Autoloads), gefunden über Gruppen +# Systeme +- Systems-Node in jeder Root-Szene (world.tscn, dungeon.tscn) +- Entities registrieren sich bei Systemen in _ready(), deregistrieren in _exit_tree() +- Systeme ownen State in Dictionaries (entity → Daten) +- scripts/systems/ — System-Skripte + +### HealthSystem (health_system.gd) +- Leben (health) und Lebensregeneration (regeneration) berechnen +- Tod bei 0 HP +- Listener: damage_requested, heal_requested +- Event: health_changed, regeneration_changed, entity_died + +### ShieldSystem (shield_system.gd) +- Schild (shield) und Schildregeneration (shield_regeneration) berechnen +- Wie zweite Lebensleiste +- Event: shield_changed, shield_broken, shield_regenerated + +### RespawnSystem (respawn_system.gd) +- Respawn bei Taverne mit vollen Leben und Schild +- Tod-Timer (3s) +- Listener: entity_died +- Event: respawn_tick, player_respawned + +### AbilitySystem (ability_system.gd) +- Single, AOE, Utility, Ult +- Auto-Attack +- Listener: ability_use_requested, auto_attack_tick +- Event: attack_executed + +## BuffSystem (buff_system.gd) +- Passive +- Listener: role_changed +- Event: buff_changed + +### CooldownSystem (cooldown_system.gd) +- Cooldown-Tracking, GCD +- Listener: attack_executed +- Event: cooldown_tick + +### DamageSystem (damage_system.gd) +- Schadensberechnung +- Listener: attack_executed +- Event: damage_requested, heal_requested + +### AggroSystem (aggro_system.gd) +- Aggro-Tabellen, Decay, Zielwahl, Kampfstatus, Nearby-Alerting +- Listener: damage_dealt, heal_requested, entity_died, enemy_detected, target_requested +- Event: target_changed, combat_state_changed, enemy_target_changed, enemy_engaged + +### EnemyAISystem (enemy_ai_system.gd) +- Gegner-States (Idle/Chase/Attack/Return), Bewegungsbefehle +- Listener: enemy_target_changed, entity_died +- Event: enemy_state_changed + +### SpawnSystem (spawn_system.gd) +- Entity-Erstellung, Portal/Gate-Spawning, Dungeon-Clear +- Export: mode ("world" / "dungeon") +- Listener: entity_died, health_changed +- Event: portal_spawn, portal_defeated, dungeon_cleared + +# Szenen ## Welt -- world.tscn — Hauptszene (200x200m) +- world.tscn — Hauptszene (100x100m) - NavigationRegion3D (Wegfindung für Gegner) - - Boden (MeshInstance3D, 200x200m PlaneMesh, Gras-Noise-Textur) + - Boden (MeshInstance3D, 100x100m PlaneMesh, Gras-Noise-Textur) - Kollision (StaticBody3D, WorldBoundaryShape3D) - Licht (DirectionalLight3D, 45°, Schatten) - Taverne (StaticBody3D, BoxMesh, Mitte der Karte, Spieler-Spawn/Respawn) - Spieler (Instanz von player.tscn, Spawn bei Taverne) - - PortalSpawner (Node, portal_spawner.gd) - HUD (Instanz von hud.tscn) -- portal_spawner.gd — Spawnt Portale dynamisch in der Portalzone (außerhalb Dorfradius) - - Timer-basiert, zufällige Position, max. Anzahl begrenzt + ## Spieler - player.tscn — CharacterBody3D @@ -37,20 +100,19 @@ - Targeting (Node, targeting.gd) - Health (Node, health.gd) - Shield (Node, shield.gd) - - Respawn (Node, respawn.gd) -- player.gd — Kern, verbindet Komponenten +- player.gd — Kern, verbindet Komponenten, Sichtbarkeit bei Tod/Respawn - camera.gd — LMB freies Umsehen, RMB Kamera + Laufrichtung anpassen - movement.gd — Bewegung (WASD relativ zur Kamera), Springen, Schwerkraft -- respawn.gd — Bei Tod: Spieler deaktivieren, 3s Timer, Respawn bei Taverne, Leben/Schild voll + - player_stats.tres — health=100, regen=1/s, shield=50, delay=3s, regen_time=5s ## Kampf -- combat.gd — Führt Abilities aus, verwaltet Cooldowns (GCD 0.5s), Auto-Attack (0.5s) -- targeting.gd — Klick/TAB anvisieren (Gruppen "enemies" + "portals"), Kampfmodus bei Gegner-Angriff, Auto-Targeting (Gegner > Portal) +- combat.gd — Input-Handler: emittiert ability_use_requested, auto_attack_tick (Logik → CombatSystem) +- targeting.gd — Raycast/Klick/TAB: emittiert target_requested, speichert Ziel aus Events (Logik → AggroSystem) - role.gd — Rollenwechsel ALT+1 bis ALT+3 (Tank/Schaden/Heiler), tauscht AbilitySet ## Abilities -- ability.gd (Resource) — name, type, damage, range, cooldown, uses_gcd, execute() +- ability.gd (Resource) — Reine Daten: name, type, damage, range, cooldown, uses_gcd (execute → CombatSystem) - ability_set.gd (Resource) — Set von 5 Abilities pro Rolle - ability_modifier.gd (Resource) — Verändert Ability (Element, Beruf, Prestige) - Typen: Single, AOE, Utility, Ult, Passive @@ -93,17 +155,13 @@ - CollisionShape3D (SphereShape3D) - NavigationAgent3D (Wegfindung) - EnemyMovement (Node, enemy_movement.gd) - - EnemyCombat (Node, enemy_combat.gd) - - EnemyAggro (Node, enemy_aggro.gd) - Healthbar (Sprite3D + SubViewport, über dem Gegner, healthbar.gd) - SubViewport - Border (ColorRect, gelb, sichtbar bei Anvisierung) - HealthBar (ProgressBar, grün) - ShieldBar (ProgressBar, blau) -- enemy.gd — Gegner-Kern, State Machine (Idle, Verfolgen, Angreifen, Zurückkehren), alarmiert Gegner in 3m, Gruppe "enemies" -- enemy_movement.gd — Navigation zum Ziel/Spawnpunkt -- enemy_combat.gd — Angriff über Event (damage_requested) -- enemy_aggro.gd — Aggro-Tabelle (Spieler → Wert), wählt Ziel mit höchstem Aggro +- enemy.gd — Daten-Holder (state, target, spawn_position, portal), Detection-Area → enemy_detected, Gruppe "enemies" (State Machine → EnemyAISystem) +- enemy_movement.gd — Empfängt Bewegungsbefehle, führt NavAgent + move_and_slide aus (Entscheidungen → EnemyAISystem) - enemy_stats.tres — health=100, regen=0, shield=50, delay=3s, regen_time=5s - Aggro-Regeln: - Schaden = Aggro (1:1) @@ -123,12 +181,11 @@ - Health (Node, health.gd) - HitArea (Area3D, Trefferbereich) - CollisionShape3D - - Spawner (Node, spawner.gd) - DetectionArea (Area3D, 10m Radius, Auto-Targeting bei Betreten) - CollisionShape3D (SphereShape3D) - Healthbar (Sprite3D + SubViewport, healthbar.gd) -- portal.gd — Portal-Kern, Gruppe "portals", bei 0 HP → spawnt Gate, zerstört Gegner und sich -- spawner.gd — Spawnt Entities bei Lebensschwellen, engagt Spieler im Portal-Radius sofort +- portal.gd — Gruppe "portals", Detection-Area Signal (Death-Handling → SpawnSystem) + - portal_stats.tres — health=500, regen=1%/s, shield=0 - Phase 1: Angreifbar, HP-Bar, spawnt 3 Gegner bei 85%/70%/55%/40%/25%/10% Leben - Portal = Spawnpunkt, 10m Aggro-Radius @@ -145,6 +202,7 @@ ## Dungeon - dungeon.tscn — Geschlossener Raum (15x90m, Wände, dunkles Licht) + - Systems (HealthSystem, CombatSystem, AggroSystem, EnemyAISystem, SpawnSystem mode="dungeon") - NavigationRegion3D (Wegfindung) - Boden (PlaneMesh, dunkle Textur) - 4 Wände (StaticBody3D + BoxMesh, 3m hoch) @@ -154,7 +212,7 @@ - Boss (Instanz von boss.tscn) - Exit-Gate (Instanz von gate.tscn, is_exit=true, Ecke bei -6/0/-4) - DungeonManager (Node, dungeon_manager.gd) -- dungeon_manager.gd — Stellt Spieler wieder her, erkennt Boss-Tod, 2s Delay, dungeon_cleared, zurück zur Taverne +- dungeon_manager.gd — Stellt Spieler wieder her (Boss-Tod/Dungeon-Clear → SpawnSystem) ## Boss - boss.tscn — CharacterBody3D (boss.gd) @@ -163,7 +221,7 @@ - Mesh (SphereMesh, lila, 1.5x Größe) - Health (Node, health.gd, boss_stats.tres) - Shield (Node, shield.gd, boss_stats.tres) - - HitArea, DetectionArea, NavigationAgent3D, EnemyMovement, EnemyCombat, EnemyAggro + - HitArea, DetectionArea, NavigationAgent3D, EnemyMovement - Healthbar (Sprite3D + SubViewport, healthbar.gd) - boss.gd — Erbt von enemy.gd, Gruppe "boss" - boss_stats.tres — health=500, regen=0, shield=100, delay=5s, regen_time=8s @@ -176,8 +234,8 @@ - portal_position (Vector3, Position des Gates für Rückkehr + Wiederherstellung) ## Gemeinsame Komponenten -- health.gd — Leben, Regeneration, Tod bei 0 (liest Base-Werte aus EntityStats) -- shield.gd — Schild, Regeneration nach Delay (liest Base-Werte aus EntityStats) +- health.gd — Registriert Entity beim HealthSystem mit EntityStats, deregistriert bei _exit_tree +- shield.gd — Registriert Entity beim HealthSystem mit EntityStats, deregistriert bei _exit_tree - healthbar.gd — Liest Health/Shield (optional) vom Parent, gelber Rand bei Anvisierung, blauer Lebensbalken wenn Spieler Ziel ist (nur bei Gegnern) - entity_stats.gd (Resource) — max_health, health_regen, max_shield, shield_regen_delay, shield_regen_time @@ -193,6 +251,15 @@ ## Events - event_bus.gd — Autoload-Singleton, globale Signals +- Intentionen (Input → System): + - ability_use_requested(player, ability_index) — Spieler will Ability nutzen + - auto_attack_tick(attacker) — Auto-Attack bereit + - target_requested(player, target) — Spieler will Ziel anvisieren + - enemy_detected(enemy, player) — Spieler in Detection-Area +- Ergebnisse (System → Node): + - combat_state_changed(player, in_combat) — Kampfstatus geändert (AggroSystem) + - enemy_state_changed(enemy, new_state) — Gegner-State geändert (EnemyAISystem) + - enemy_target_changed(enemy, target) — Gegner-Ziel geändert (AggroSystem) - Kampf: - attack_executed(attacker, position, direction, damage) — Angriff wurde ausgeführt - damage_dealt(attacker, target, damage) — Schaden wurde verteilt