replay

Replay

Record broadcasts server-side (archive) + play a .cdrp recording back through the live client dispatch with play/pause/speed/seek.

Category Meta Seams 2 Unity types 2
Server
services.AddCrossplayReplayArchive();
Unity package
com.crossplay.replay
Depends on
core

Seams you implement 1

Crossplay calls these; your game supplies them. Each ships an inert or permissive default, so register yours before services.AddCrossplayReplayArchive(); and it wins.

IReplaySpectatorHost game SPI

Where a ReplayRecorder spectates from: it seats the recorder as an invisible, receive-only session in a zone, so the recorder is handed exactly the frames a watching client would get. Why this is a seam. Replay's core job is the archive and client playback, which need no world. Only RECORDING a zone needs a broadcast source, so that half lives outside the piece: the Hosting composition answers this seam from World spectating (WorldReplaySpectatorHost) when World is installed, and a game without World can seat the recorder in whatever broadcasts it has. Replay itself references no spatial piece — the same shape as Voice's IVoiceProximityAudience.

  • void Enter(ISession spectator, string zone, float x, float z)

    Seats spectator in zone around (x, z), receive-only.

  • void Leave(ISession spectator)

    Removes spectator; nothing more is delivered to it.

Providers you can swap 1

Infrastructure seams. Crossplay ships a working implementation of each — replacing one changes where data lives or how it moves, never a game rule.

IReplayArchive provider

Durable storage for recordings: upload a blob under a game key, list what exists, fetch it back, delete it. Blobs are OPAQUE here — .cdrp broadcast recordings and lockstep input streams both ride the same shelf (the Kind tag tells them apart).

  • bool Delete(string id)

    Removes a recording.

  • IReadOnlyList<ReplayInfo> List(string key = null)

    Metadata for every archived recording (optionally only one key's), newest first.

  • string Save(string key, string kind, byte[] blob, long createdMs)

    Stores a recording blob under a game key.

  • bool TryLoad(string id, out byte[] blob)

    Fetches a stored blob.

Unity seams you implement 1

The client half's sockets. Bind your implementation in the client context and Crossplay's client calls it — this is where your models, animators, UI and controls plug in.

IReplayPlayer unity SPI

Replay playback control: load a .cdrp recording and play it back through the live client dispatch. The game binds its own scrubber UI to these members. Absent if the piece isn't installed.

  • bool IsLoaded
  • bool IsPlaying
  • float Speed

    Playback speed (1 = real time). Persists across a Load.

  • double PositionSeconds
  • double DurationSeconds
  • float Progress

    0..1 through the recording.

  • event Action Finished

    Raised once when playback reaches the end.

  • void Load(byte[] cdrp)

    Loads a .cdrp blob (parsed via ReplayData), paused at the start.

  • void Play()
  • void Pause()
  • void Seek(double seconds)

    Jumps the cursor to a time in seconds (clamped to 0..duration).

UI views you can replace 1

Each ships a working uGUI panel you can drag into a scene. Substitute your own view to keep the logic and change the look — the presenter never knows.

ICrossplayReplayView

Narrow contract the presenter drives. UI-only: render calls in, user intents out.