311 lines
13 KiB
Markdown
311 lines
13 KiB
Markdown
# Projektstruktur
|
||
|
||
## Ordnerstruktur
|
||
Drei Grundordner nach Verantwortung. Resources liegen bei ihren Skripten.
|
||
```
|
||
scenes/ — Darstellung + Input
|
||
healthbar.gd — Shared Component
|
||
player/ — Spieler + player_stats
|
||
role/ — Rollenwechsel + Ability/AbilitySet-Klassen
|
||
damage/ — set.tres + abilities/
|
||
tank/ — set.tres + abilities/
|
||
healer/ — set.tres + abilities/
|
||
enemy/ — Gegner + Boss + enemy_stats + boss_stats
|
||
portal/ — Portal + Gate + portal_stats
|
||
dungeon/ — Dungeon + dungeon_manager
|
||
hud/ — HUD
|
||
world/ — Hauptszene + portal_spawner
|
||
systems/ — Spiellogik
|
||
aggro/ — AggroSystem (system, tracker, decay, events) + aggro_config
|
||
effect.gd — Effect Resource (Buff/Debuff/Aura Daten)
|
||
10× *_system.gd — health, shield, damage, ability, cooldown, enemy_ai, respawn, spawn, effect, element
|
||
autoloads/ — Globaler Zustand
|
||
event_bus.gd
|
||
game_state.gd
|
||
stats/ — stats.gd + base_stats.gd
|
||
```
|
||
|
||
## Szenenbaum
|
||
- Welt
|
||
- Systems (11 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) + Auto-Attack in _process
|
||
- Listener: ability_use_requested
|
||
- Event: attack_executed, 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)
|
||
- Aura-Propagierung: Auras mit aura_radius > 0 geben allen Spielern im Radius einen temporären Buff (0.5s, refreshed jedes Frame). Verlässt man den Radius → Buff sofort weg
|
||
- _process: Dauer ticken, abgelaufene entfernen, DoT/HoT-Ticks, Aura-Propagierung
|
||
- _recalc_stat_buffs: Multiplier-Effekte aggregieren → buff_damage/heal/shield in Stats
|
||
- Listener: role_changed, entity_died, effect_requested
|
||
- Event: buff_changed, shield_changed, effect_applied, effect_expired
|
||
### 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
|
||
### DamageSystem (damage_system.gd)
|
||
- Reserviert für spätere Schadensberechnung (aktuell leer)
|
||
### 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
|
||
- Role (Node, role.gd) — Rollenwechsel ALT+1/2/3, emittiert role_changed (auch bei _ready)
|
||
- Targeting (Node, targeting.gd) — Klick/TAB, emittiert target_requested
|
||
- 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) — liest HP/Shield von Stats, zeigt 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)
|
||
- 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 11 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
|
||
- HealthBar (ProgressBar, Label)
|
||
- ShieldBar (ProgressBar, Label)
|
||
- EffectContainer (HBoxContainer, programmatisch, unter ShieldBar)
|
||
- RespawnTimer (Label, Countdown bei Tod)
|
||
- AbilityBar (HBoxContainer, RoleIcon + Abilities 1-4 + Passive)
|
||
- hud.gd — Reagiert auf Events, liest Werte von Stats, zeigt Effekt-Icons
|
||
|
||
# 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)
|