Skip to main content
Version: 5.x
Supported on
Snapchat

Turn Based Replay

The Turn Based Replay component enables recording and replaying gameplay in turn-based lenses. It captures player actions, object movements, animations, and any time-based data with precise synchronization and smooth interpolation, allowing players to see exactly what their opponent did during their turn.

Overview

The Turn Based Replay component provides:

  • Complete recording system: Capture any type of data over time during gameplay
  • Smooth playback: Replay recorded actions with interpolation between data points
  • Flexible configuration: Record transforms, text, enabled states, or custom variables
  • Independent tracks: Configure multiple replayable items with different update frequencies
  • Event-driven: Subscribe to recording and playback lifecycle events
  • Persistent storage: Automatically save and load replay data between turns

Turn Based Replay is perfect for:

  • Showing opponent's previous turn in strategy games
  • Replaying puzzle solutions
  • Creating highlight reels of gameplay
  • Ghost racing in competitive games

Adding the Component

  1. In the Assets panel, click Asset Library
  2. Search for "Turn Based Replay"
  3. Click Import to add it to your project (this also installs Turn Based component)
  4. In the Objects panel, select a scene object (or create a new one)
  5. In the Inspector panel, click Add Component > Custom Components > Turn Based Replay
  6. Set the Turn Based input to your Turn Based component in the scene

The Turn Based Replay component requires the Turn Based component to be present in your scene. This is automatically added when you import Turn Based Replay.

Configuration

Replayable Items

Configure what data to record and replay in the Replayable Items section. Each item represents a different type of data captured over time:

Transform Data

Records position, rotation, and/or scale of scene objects.

  • Position: Capture object movement (vec3)
  • Rotation: Capture object rotation (quat)
  • Scale: Capture object scaling (vec3)
  • Update Frequency: Minimum time between recordings (seconds)

Text Content

Records text displayed in Text or Text3D components.

  • Text Component: Reference to Text/Text3D component
  • Update Frequency: How often to check for text changes

Object Enabled State

Records when SceneObjects or Components are enabled/disabled.

  • Target: SceneObject or Component to track
  • Update Frequency: How often to check state

Custom Variables

Records custom values using getter/setter functions.

  • Getter: Function returning current value
  • Setter: Function applying value during playback
  • Type: number, string, vec2, vec3, vec4, quat, boolean
  • Interpolation: Optional smooth transitions between values

Use the Turn Based Replay Object helper component (included in the package) for streamlined setup of individual objects. It simplifies configuration for common use cases.

Event Triggers

Configure when to start, pause, resume, and stop recording/playback:

Recording Triggers:

  • Turn Based Component events (onTurnStart, onTurnEnd)
  • Behavior system triggers
  • Interaction Component events (tap, swipe)
  • Custom script calls via API

Playback Triggers:

  • Turn Based Component events
  • Automatic playback at turn start
  • Manual control via scripting API

Event Responses

Add responses to recording and playback events:

Recording Events:

  • onRecordingStarted - When recording begins
  • onRecordingPaused - When recording pauses
  • onRecordingResumed - When recording resumes
  • onRecordingCancelled - When recording is cancelled
  • onDataSaved - When data is saved to storage

Playback Events:

  • onPlaybackReady - When playback data is loaded
  • onPlaybackStarted - When playback begins
  • onPlaybackFinished - When playback completes
  • onPlaybackPaused - When playback pauses

Response Types:

  • Trigger Behavior scripts
  • Enable/disable scene objects
  • Call methods on other components

Advanced Settings

Data Storage:

  • Storage Key Prefix: Custom prefix for Turn Based storage keys
  • Data Source: Where to load replay data from (default: Turn Based storage)
  • Auto-save: Automatically save recorded data (recommended: enabled)

Leave advanced settings at default values unless you have specific requirements for custom storage or data sources.

Scripting API

Properties

PropertyTypeDescription
isPlayingbooleanTrue when playback is running (not paused, not stopped).
playbackTimenumberCurrent playback time position in seconds.
playbackSpeednumberPlayback speed multiplier. 1.0 = normal speed, 2.0 = double speed, 0.5 = half speed.
hasPlaybackStartedbooleanTrue if playback was started, even if currently paused/stopped. False if never started or was reset.
isRecordingbooleanTrue when recording is in progress.

Recording Methods

MethodDescription
startRecording(): voidStart recording new data. Clears any existing unsaved recording. Cannot start while playback is active.
pauseRecording(): voidPause recording but keep recorded data. Can be resumed later to continue the same session.
resumeRecording(): voidResume recording from paused state. Continues in the same session. Cannot resume while playback is active.
pauseRecordingAndSave(): voidPause recording and save all pending data. Convenient combination of pause + save.
getCurrentRecordingTime(): numberGet the current recording time in seconds.
setRecordingTime(targetTime: number): voidSet the current recording time for all tracks. Used to synchronize with external time systems.
saveAllPendingData(): voidForce immediate save of any unsaved recorded data.
cancelRecording(): voidCancel current recording session. Discards unsaved data but keeps previously saved data.
clearAllSavedData(): voidClear all saved data from persistent storage. Does not affect current recording.
clearCurrentRecording(): voidClear current recording session data only. Does not affect saved data.
clearAllData(): voidClear both current recording and all saved data. Complete reset.
cancelRecordingAndClearSaved(): voidCancel recording and clear all saved data. Combination method.

Playback Methods

MethodDescription
isPlaybackFinished(): booleanCheck if playback reached the end of all recorded data.
isPlaybackReady(): booleanCheck if playback data is loaded and ready to start.
waitForPlaybackReady(): Promise<void>Wait for playback to be ready. Returns a promise that resolves when ready.
startPlayback(): voidStart playback from the beginning. Resets if already playing. Throws error if not ready. Cannot start while recording.
startPlaybackWhenReady(): voidStart playback when ready, waiting if needed. Safer alternative to startPlayback().
pausePlayback(): voidPause playback at current position. Can be resumed from same position.
resumePlayback(): voidResume playback from current position. Cannot resume while recording.
resetPlayback(): voidReset playback to initial state. Stops and resets time to 0, keeps loaded data.
jumpToTime(targetTime: number): voidJump to specific time in playback. Updates all tracks to interpolated values at that time.
jumpToEnd(): voidJump to the end of playback and pause. Sets all tracks to final recorded values.
setPlaybackSpeed(speed: number): voidSet playback speed multiplier. Values > 1 speed up, < 1 slow down.
getCurrentPlaybackTime(): numberGet the current playback time in seconds.

Setup Methods

MethodDescription
waitForSetupComplete(): Promise<void>Wait for all configurations to be ready. Returns promise that resolves when setup is complete.
isSetupReady(): booleanCheck if setup is ready for recording and playback.
addConfig(config: ReplayableItemConfig<any, any>): voidAdd a single replayable item configuration programmatically.
addConfigs(configs: ReplayableItemConfig<any, any>[]): voidAdd multiple replayable item configurations programmatically.

ReplayableItemConfig Interface

The ReplayableItemConfig interface is used to configure what data should be recorded and how it should be played back.

PropertyTypeDescription
trackIdstringUnique identifier for this track.
getter() => TEngineFunction to get the current state value during recording.
setter(value: TEngine) => voidFunction to set the state value during playback.
updateFrequencynumberMinimum time to wait before recording new data (in seconds).
diffCheck(a: TEngine, b: TEngine) => booleanFunction to check if two values are different.
converterToStorage(value: TEngine) => TStorageOptional function to convert values for storage.
converterFromStorage(value: TStorage) => TEngineOptional function to convert values from storage.
interpolation(start: TEngine, end: TEngine, t: number) => TEngineOptional function for smooth interpolation between values.

TEngine is the type of the value represented in the engine (e.g., number, vec3, string).

TStorage is the type of the value when stored (e.g., number, string, number[]). It should be a primitive value that can be automatically serialized in JSON format. It can be the same as TEngine if no conversion is needed.

Events

Playback Events

EventTypeDescription
onPlaybackReadyEvent<void>Triggered when playback is ready to start after data loads.
onPlaybackStartedEvent<void>Triggered when playback begins, including after resets.
onPlaybackFinishedEvent<void>Triggered when playback reaches the end and stops.
onPlaybackPausedEvent<void>Triggered when playback is paused or interrupted.

Recording Events

EventTypeDescription
onRecordingStartedEvent<void>Triggered when recording begins successfully.
onRecordingPausedEvent<void>Triggered when recording is paused (data retained).
onRecordingResumedEvent<void>Triggered when recording resumes from paused state.
onRecordingCancelledEvent<void>Triggered when recording is cancelled (unsaved data discarded).
onDataSavedEvent<string>Triggered when data is saved, with track name as parameter.

Usage Example

This example replays the previous turn's recording at the start of each new turn, then starts recording the new turn.

import { TurnBasedReplay } from 'Turn Based Replay.lsc/Turn Based Replay';
import { TurnBased } from 'Turn Based.lsc/Turn Based/Turn Based';

@component
export class ReplayExample extends BaseScriptComponent {
@input turnBasedReplay: TurnBasedReplay;
@input turnBased: TurnBased;

onAwake() {
this.createEvent('OnStartEvent').bind(() => {
this.turnBased.onTurnStart.add((eventData) => {
// If first turn, start turn gameplay right away
if (eventData.turnCount == 0) {
this.startTurnGameplay();
} else {
// Otherwise, start playback of the last turn's recording
this.startPlayback(() => this.startTurnGameplay());
}
});
});
}

private startPlayback(onComplete: () => void) {
// First, subscribe to playback finished event to be notified when playback is done
this.turnBasedReplay.onPlaybackFinished.addOnce(onComplete);
// Start playback
this.turnBasedReplay.startPlaybackWhenReady();
}

private startTurnGameplay() {
// Start recording the turn
this.turnBasedReplay.startRecording();

// Do your game stuff here, and call onTurnOver() when the turn is over :)
}

private onTurnOver() {
// When turn ends, pause the recording
this.turnBasedReplay.pauseRecording();

// And if autosave is disabled, save the recording manually:
// this.turnBasedReplay.saveAllPendingData();
}
}

Restrictions

  • Mutual Exclusivity: A Turn Based Replay component cannot record while playback is active, or start playback while recording is active. However, multiple components can work independently.
  • No Object Creation/Deletion: Recording does not support creating or deleting objects dynamically. All objects must exist before recording starts. Use the "Object Enabled State" replayable item to show/hide objects instead.
  • Scene Persistence: Objects shouldn't be deleted during recording or playback, or unexpected behavior may occur.

Best Practices

  1. First Turn Handling: Always check if it's the first turn before attempting playback, as there's no previous recording to replay.

  2. Auto-save Enabled: Keep auto-save enabled (default) to ensure data is saved as it's recorded. This prevents data loss if recording is interrupted.

  3. Update Frequency: Set appropriate update frequencies for each replayable item:

    • Transforms: 0.016-0.033s (60-30 FPS) for smooth movement
    • Text: 0.1s or higher (text doesn't change frequently)
    • Enabled state: 0.05s for responsive on/off changes
  4. Interpolation: Use interpolation for smooth playback of transforms (position, rotation, scale) and numeric values.

  5. Skip Option: Always provide a skip button for players who want to start their turn immediately.

  6. Loading States: Show loading UI while waiting for playback to be ready (waitForPlaybackReady()).

  7. Clear Feedback: Use visual indicators to show when recording is active vs. when playback is running.

Was this page helpful?
Yes
No