Files
mmo/plan.md
Marek Le 971ffc8da2 update
2026-04-01 05:02:03 +02:00

12 KiB

Projektstruktur

Szenenbaum

  • Welt
    • Systems (HealthSystem, ShieldSystem, RespawnSystem, CombatSystem, AggroSystem, EnemyAISystem, SpawnSystem)
    • Taverne
    • Player
    • Portale (dynamisch)
      • Gegner
    • HUD

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 (100x100m)
    • NavigationRegion3D (Wegfindung für Gegner)
      • 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)
    • HUD (Instanz von hud.tscn)

Spieler

  • player.tscn — CharacterBody3D

    • Gruppe (player)
    • Kollision (CapsuleShape3D, 1.8m x 0.3m)
    • Mesh (CapsuleMesh)
    • CameraPivot (Node3D, Kopfhöhe, camera.gd)
      • Camera3D (hinter/über Spieler)w
    • Movement (Node, movement.gd)
    • Combat (Node, combat.gd)
    • Role (Node, role.gd)
    • Targeting (Node, targeting.gd)
    • Health (Node, health.gd)
    • Shield (Node, shield.gd)
  • 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

  • player_stats.tres — health=100, regen=1/s, shield=50, delay=3s, regen_time=5s

Kampf

  • 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) — 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
  • Auto-Attack: Automatisch bei anvisiertem Gegner im Kampf
  • 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: Kein Autotarget, Anvisierter Spieler wird geheilt, ist keiner anvisiert dann Selfheal
    • 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)
  • Jede Rolle hat ein eigenes AbilitySet
  • Beim Rollenwechsel wird das AbilitySet getauscht
  • Elemente und Modifikatoren verändern Abilities nachträglich

Gegner

  • enemy.tscn — CharacterBody3D
    • Gruppe (enemies)
    • Kollision (CapsuleShape3D)
    • Mesh (SphereMesh, Platzhalter)
    • Health (Node, health.gd)
    • Shield (Node, shield.gd)
    • HitArea (Area3D, Trefferbereich des Gegners)
      • CollisionShape3D (CapsuleShape3D)
    • DetectionArea (Area3D, Erkennungsradius)
      • CollisionShape3D (SphereShape3D)
    • NavigationAgent3D (Wegfindung)
    • EnemyMovement (Node, enemy_movement.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 — 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)
    • Heilung = Aggro (0.5x)
    • Tank = Aggro-Multiplikator (2x)
    • Aggro verfällt -1/s
    • Spieler im Portal-Radius: Aggro bleibt bei mindestens 1
    • Außerhalb 10m Portal-Radius: Aggro verfällt 1% * 2 je s (1%, 2%, 4%, 8%, ...)
    • Ohne Aggro: Gegner kehrt zum Portal zurück, regeneriert 10% Leben/s bis 100%, dann 1%/s
    • Bei Spieler-Tod → Aggro auf 0

Portal

  • portal.tscn — StaticBody3D

    • Gruppe (portals)
    • Kollision (CylinderShape3D)
    • Mesh (CylinderMesh, blau)
    • Health (Node, health.gd)
    • HitArea (Area3D, Trefferbereich)
      • CollisionShape3D
    • DetectionArea (Area3D, 10m Radius, Auto-Targeting bei Betreten)
      • CollisionShape3D (SphereShape3D)
    • Healthbar (Sprite3D + SubViewport, healthbar.gd)
  • 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

Gate

  • gate.tscn — StaticBody3D (keine Kollision)
    • Mesh (CylinderMesh, grün, leuchtend)
    • GateArea (Area3D, 3m Radius, Spieler-Erkennung)
      • CollisionShape3D (SphereShape3D)
  • gate.gd — Konfigurierbar: target_scene, is_exit
    • Eingangs-Gate: Prüft nach 0.5s ob Spieler bereits in GateArea steht, speichert Portal-Position
    • Exit-Gate: 1s Aktivierungsdelay (verhindert Re-Triggern bei Spawn)
    • Beide Gates bestehen solange Boss lebt, verschwinden bei dungeon_cleared

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)
    • Spieler (Instanz von player.tscn, Position 0/1/-5)
    • HUD (Instanz von hud.tscn)
    • Gegnergruppen bei (15x15, 15x30, 15x45, 15x60), je 4 Gegner
    • 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 (Boss-Tod/Dungeon-Clear → SpawnSystem)

Boss

  • boss.tscn — CharacterBody3D (boss.gd)
    • Gruppe (enemies, boss)
    • Kollision (CapsuleShape3D, größer als Enemy)
    • 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
    • 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

GameState

  • game_state.gd — Autoload, speichert Spielerzustand zwischen Szenenwechseln
    • save_player(player), restore_player(player), clear_player(), clear()
    • returning_from_dungeon — Spieler kommt aus Dungeon, spawnt bei Gate-Position
    • dungeon_cleared — Boss tot, Gates werden entfernt, Spieler spawnt bei Taverne
    • portal_position (Vector3, Position des Gates für Rückkehr + Wiederherstellung)

Gemeinsame Komponenten

  • 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

HUD

  • hud.tscn — CanvasLayer (hud.gd)
    • HealthBar (ProgressBar, links oben, Label "50/100")
    • ShieldBar (ProgressBar, links oben, unter HealthBar, Label "25/50")
    • RespawnTimer (Label, mitte, Countdown bei Tod)
    • AbilityBar (HBoxContainer, mitte unten)
      • RoleIcon (Label, T=Tank, D=Schaden, H=Heiler)
      • Abilities (Label, Fähigkeiten 1-4, Passive P)
  • hud.gd — Reagiert auf Events, aktualisiert HealthBar/ShieldBar/AbilityBar/RespawnTimer

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
    • damage_requested(attacker, target, amount) — Schaden zwischen Szenen anfordern
  • Entity:
    • entity_died(entity) — Entity ist gestorben
    • health_changed(entity, current, max) — Leben hat sich verändert
    • shield_changed(entity, current, max) — Schild hat sich verändert
    • shield_broken(entity) — Schild ist auf 0 gefallen
    • shield_regenerated(entity) — Schild ist wieder voll
  • Spieler:
    • target_changed(player, target) — Spieler hat neues Ziel anvisiert
    • player_respawned(player) — Spieler ist respawnt
    • role_changed(player, role_type) — Spieler hat Rolle gewechselt
    • respawn_tick(timer) — Respawn-Countdown Update
    • cooldown_tick(cooldowns, max_cooldowns, gcd_timer) — Cooldown-Update für HUD
  • Gegner:
    • enemy_engaged(enemy, target) — Gegner hat Spieler anvisiert
  • Portal:
    • portal_spawn(portal, enemies) — Portal hat Gegner gespawnt
    • portal_defeated(portal) — Portal besiegt, wird Gate
  • Dungeon:
    • dungeon_cleared() — Boss tot, Dungeon gesäubert