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.Developer→combat-arcade-v2SeedKind.Dailymit Prefixarcade-daily-test:→combat-arcade-v2- sonst →
combat-classic-v2 - Legacy-String
combat-arcade-v1mappt auf Arcade-v2 - explizit:
DungeonRunConfig.CombatBalanceVersion
Beim Run-Start schreibt RunDefinition den Snapshot fest (CombatBalance / CombatBalanceVersion).
Neues Profil erstellen
- Snapshot in
CombatBalanceCatalogergänzen oderCombatBalanceProfileim Editor duplizieren. BalanceVersioneindeutig setzen (z. B.combat-arcade-v3).- Tests für Resolve/Leaderboard-Komposition erweitern.
- 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-WaveInterWavePauseSeconds/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 ausDefaultEnemyCatalog.tresplus Shared-Defaults. - Power-ups kommen aus
BalancingPowerUpCatalog;BalancingDebugHudund Floating Damage Numbers zeigen Laufzeitwerte. - Änderungen an Sandbox-Regeln mit
BalancingSandboxTests.csprüfen und anschließend die Scene manuell starten.
Leaderboards
- Classic: Leaderboard-
BalanceVersion= Weapon-Balance (unverändert) - Arcade:
weapon-balance-…|combat-arcade-v2nur aufRunResult.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
Im Hub einen Developer-Run starten oder einen Daily-Seed mit Prefix arcade-daily-test: wählen / konfigurieren. Produktiv-Daily ohne Prefix bleibt Classic.