Skip to content

Combat-Balance und Arcade-Profil

Status: aktiv für Developer-Seeds und lokalen Arcade-Daily-Testseed

Zweck

Holodeck Arena zielt auf einen schnellen Top-down-Action-Shooter. Combat-Werte liegen nicht mehr verstreut in Gegner-/Encounter-Skripten, sondern in einem versionierten Balance-Profil.

Wo liegt das Profil?

Ebene Pfad
Domain-Snapshot (Godot-frei) src/HolodeckArena.Shared/Gameplay/Combat/CombatBalanceSnapshot.cs
Catalog src/HolodeckArena.Shared/Gameplay/Combat/CombatBalanceCatalog.cs
Editor-Resource src/HolodeckArena.Game3D/Features/Combat/Balance/CombatBalanceProfile.cs
Arcade-Asset src/HolodeckArena.Game3D/Resources/Combat/CombatArcadeV1.tres
Encounter-Director src/HolodeckArena.Shared/Gameplay/Combat/RoomEncounterDirector.cs
Enemy Packs src/HolodeckArena.Game3D/Features/Dungeons/Enemies/
Aggression-Rewards src/HolodeckArena.Shared/Gameplay/Combat/AggressionRewardTracker.cs

Profil auswählen

CombatBalanceCatalog.Resolve(DungeonRunConfig):

  • SeedKind.Developercombat-arcade-v2
  • SeedKind.Daily mit Prefix arcade-daily-test:combat-arcade-v2
  • sonst → combat-classic-v2
  • Legacy-String combat-arcade-v1 mappt auf Arcade-v2
  • explizit: DungeonRunConfig.CombatBalanceVersion

Beim Run-Start schreibt RunDefinition den Snapshot fest (CombatBalance / CombatBalanceVersion).

Neues Profil erstellen

  1. Snapshot in CombatBalanceCatalog ergänzen oder CombatBalanceProfile im Editor duplizieren.
  2. BalanceVersion eindeutig setzen (z. B. combat-arcade-v3).
  3. Tests für Resolve/Leaderboard-Komposition erweitern.
  4. Bei kompetitiven Änderungen immer neue Version – nie stille Overrides auf bestehende Leaderboard-Keys.

Gegnerzahl / Schaden / Leben

  • Spawn-Count: EnemyDensityCalculator (Floor, RoomIndex, Size, Difficulty, Budget) × EnemyCountMultiplier
  • Runtime-Caps: MaximumActiveEnemies / MaximumActiveRangedEnemies
  • Hybrid-Wellen: Intra-Wave ReinforcementThreshold + Inter-Wave InterWavePauseSeconds / WaveOpenLivingRatio
  • Stats: DungeonEnemyCatalog.Resolve(..., balance) wendet Health-/Damage-Multiplikatoren an (Small zusätzlich reduziert)

Rüstung und Drops

  • Schaden trifft zuerst Rüstung, Overflow HP (HealthState + ArmorDamageResolver)
  • Keine Auto-Regen; Rückgewinnung über Armor-Pickups und Aggression-Kills
  • Wave-Clear-Chancen im Balance-Profil; Elite garantiert ≥1 Drop
  • Kein Magnet-Pickup: Drops bleiben liegen und werden nur bei Kontakt eingesammelt (BodyEntered / PickupRadius)

Spawn-Budgets

Pro Raum erzeugt RoomEncounterRuntime3D eine Queue aus der Objective-Liste (inkl. WaveIndex). Director tickt simulationzeitbasiert, telegraphiert Spawns und hält Caps ein.

Balance-Tests beobachten

Debug-Overlay (DEBUG-Builds, deaktivierbar): aktive Gegner, Ranged, Queue, Budget, HP/Armor, KPM, Idle, Seed, BalanceVersion.

Zusätzlich: Time-to-Kill kleiner Gegner, Druck ohne Bullet-Sponge, Armor-Gain bei Aggression.

Balancing-Sandbox

res://Features/Balancing/BalancingSandboxScene.tscn lässt sich im Godot-Editor per F6 ohne Dungeon-, Matchmaking- oder Completion-Flow starten. Die Scene bleibt in der Gruppe standalone_tool_scene, damit AppBootstrap nicht zum Main Menu umleitet.

  • F1 oder die blaue Config-Zone öffnet das pausierende BalancingConfigMenu.
  • Waffen kommen aus WeaponDefinitionFactory, Gegner aus DefaultEnemyCatalog.tres plus Shared-Defaults.
  • Power-ups kommen aus BalancingPowerUpCatalog; BalancingDebugHud und Floating Damage Numbers zeigen Laufzeitwerte.
  • Änderungen an Sandbox-Regeln mit BalancingSandboxTests.cs prüfen und anschließend die Scene manuell starten.

Leaderboards

  • Classic: Leaderboard-BalanceVersion = Weapon-Balance (unverändert)
  • Arcade: weapon-balance-…|combat-arcade-v2 nur auf RunResult.LeaderboardBalanceVersion

Replay-/Session-balanceVersion bleibt immer OnlineRunVersions.Balance (weapon-balance-2026-07), sonst lehnt Nakama mit VERSION_MISMATCH ab. Combat-Profil wird separat als Replay-Event combat_balance_locked und auf dem RunResult geführt.

Damit mischen lokale Arcade-Tests keine produktiven Daily-Boards, ohne die Online-Session-Validierung zu brechen.

Dash

Kein Dash implementiert (Architektur-/Authority-Risiko). Mobility kommt über PlayerMoveSpeedMultiplier. Dash bleibt optionaler Folgepunkt.

Lokaler Arcade-Daily-Test

godot --path src/HolodeckArena.Game3D -- --env=local --client-profile=client_a

Im Hub einen Developer-Run starten oder einen Daily-Seed mit Prefix arcade-daily-test: wählen / konfigurieren. Produktiv-Daily ohne Prefix bleibt Classic.