Files
mmo/plan.md
Marek Lenczewski f1d34ebf1d update
2026-04-04 00:00:15 +02:00

333 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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)
---