Skip to content

Replay und Leaderboards

Aktiver Ist-Zustand

Lokale Dungeon-Runs besitzen einen Combat-Recorder ohne stilles Verwerfen. LocalCombatReplayRecorder speichert Events bis zu den gemeinsamen Hard-Limits in ReplayLimits und finalisiert daraus eine stabile Replay-ID.

Limit Wert
Events 65 536
Checkpoints 65 536
Unkomprimiertes Payload 64 MiB
Komprimiertes Payload 32 MiB
Chunks (max) 128
Checkpoint-Sampling alle 3 Physics-Frames (~20 Hz bei 60 Hz), Soft-Budget drosselt bei großen Runs

Policy-/Loadout-Hashes liegen nur auf dem Replay-Envelope, nicht mehr pro Event. Defaults (0/false/leer) werden beim Serialisieren weggelassen. Client und Nakama müssen dieselben Limits verwenden.

Deterministische Aufnahme (Schema v2)

Ab Payload-Schema 2 (ReplayPayload.PlaybackSchemaVersion) enthält ein Replay:

  • Simulation-Ticks (Physics-Frames) statt Wall-Clock;
  • periodische ReplayCheckpoint-Samples inkl. Position, PlayerYaw, Health/Ammo/Waffe/Room;
  • weapon_fire mit Shot-Seed in PolicyHash (shotseed:{ulong});
  • optional PowerUpSelections im Payload.

ReplayPlaybackCapability prüft Schema ≥ 2, mindestens zwei Checkpoints und ein run_started-Event. Ältere Replays ohne Samples sind nicht playback-fähig.

Replay Viewer (Variant A)

Playback lebt unter Features/Replay/ und mischt sich nicht mit Live-DungeonRun3DController-Gameplay:

  1. Leaderboard AnsehenGameFlowService.GoToReplayAsyncReplayViewerScene
  2. ReplayLoader lädt lokal (LocalReplayStore) oder remote (rpc_get_leaderboard_replay)
  3. Dungeon wird nur über bestehende Generatoren aus dem Seed rekonstruiert
  4. ReplayPlayerPuppet interpoliert Checkpoints; Weapon-Events sind Präsentation (VFX/SFX)
  5. Enemy-Puppets starten aus Objective-Initialspawns; Mid-Fight-Adds/Wellen kommen aus enemy_spawned (inkl. Definition-ID). Boss-Flächen/Minen aus arena_hazard_spawned
  6. ReplaySession steuert Zeit/Speed (0.5/1/2/4), Pause, Ende; Seek ist vorbereitet, aber noch nicht unterstützt
  7. Kamera: IReplayCameraMode / Player-Follow (Free/Cinematic später)

Eingaben: replay_toggle_pause, replay_stop, replay_speed_down, replay_speed_up.

Leaderboard Watch (2A)

Leaderboard-Einträge tragen replayId. rpc_get_leaderboard_replay liefert fremde Complete + leaderboard-eligible Replays (Server liest Storage als Owner). Fehlt Replay oder Capability → klare Fehlermeldung, kein Watch.

Erfasste Ereignisse umfassen weiterhin Weapon Fire/Reload/Switch, Treffer, Kills, Encounter-/Enemy-Events (enemy_spawned mit Definition), Boss-Arena-/Ground-Hazards (arena_hazard_spawned), Objectives und Drop-/Power-up-Pfad.

Periodische Checkpoints (inkl. Enemy-Poses) werden nahe dem Soft-Budget (~85 % unkomprimiert) gestoppt, damit Finalize noch gelingt. Combat-Events werden nicht verworfen. Scheitert Finalize trotzdem am Hard-Limit, zeigt der Client weiterhin das Run-Ergebnis (ohne Replay-ID) statt „Completion failed“.

RunResult.ReplayId verknüpft das Ergebnis mit dem lokalen Replay Store.

Backend

Nakama validiert Replay-Größe und Eventanzahl gegen dieselben Zahlen wie ReplayLimits. Nach Limit-Änderungen muss das Nakama-Modul neu gebaut und deployed werden. Migration 003_leaderboard_replay_id.sql ergänzt replay_id auf leaderboard_run_entries.

Bekannte Limits / später

  • Seek mit vollem World-Rewind
  • Free-/Cinematic-Kamera
  • Streaming statt ganzem Payload im RAM
  • Alte Schema-v1-Replays visual abspielen (nicht geplant — Capability-Gate)

Erweiterung und Tests

Neue Events erhalten eine stabile Eventtyp-ID und werden am fachlichen Ergebnisereignis aufgezeichnet. Anleitung: Replay-Event ergänzen.

Zu testen: Capability-Gate, Session Speed/Pause/End, Loader-Fehler, Chunk-Reassembly, Hashstabilität. Manuell: lange Runs, Speed-Wechsel, Leaderboard-Watch.

Verwandt: Dungeon-Runs, Run Authority, Nakama, Serverautorisierter Combat.