Ghost Racer Demo
Overview
The Ghost Racer sample showcases how Crystal Save's Time Machine integrates with racing-style gameplay so players can compete against their past performances. By combining Crystal Save persistence with Time Crystal's Time Machine recordings, the demo enables a race to resume mid-progress, automatically captures new ghost laps, and keeps every previous ghost available so you can race against an unlimited field of personal bests.
Heads up: Shipping a production-ready racer will still require Unity experience and custom coding to adapt the patterns shown here.
Core Architecture
IRaceControllerStateProvider
IRaceControllerStateProvider is the abstraction layer that exposes race progress as serialized bytes. Any race implementation that wants to participate in RememberMe persistence must implement this interface so that RememberRaceController can save and restore state without coupling to specific gameplay code.
RaceController

RaceController drives the Ghost Racer loop: it manages laps, checkpoint validation, race timing, audio hooks, and the Unity events the UI listens to. Because it implements IRaceControllerStateProvider, it can serialize the live race snapshot (lap counts, checkpoint progress, lap time history, best lap) with MemoryPack and restore those values later, rearming player control if a session resumes mid-race.
RememberRaceController bridge

RememberRaceController is a thin SaveableComponent that delegates directly to the IRaceControllerStateProvider. It retrieves the interface during Awake, writes serialized race data when Crystal Save saves, and feeds the bytes back into the race controller on load. This decoupling lets you swap in any race system as long as it implements the interface.
RaceUI
RaceUI binds the gameplay loop to on-screen widgets. It subscribes to RaceController events, drives buttons that start, reset, or repeat the race, toggles ghost visibility, updates ghost counts, and surfaces lap/best/total time readouts. When the race ends it requests a ghost recording so the new lap joins the roster automatically.
GhostRecorder

GhostRecorder is the bridge between Crystal Save's persistent state and Time Machine's replay branches. It starts and stops recordings on the player vehicle, clears the "Original" branch so each lap starts from time 0, and instantiates coloured ghost vehicles for playback. It also exposes helpers to show/hide ghosts, restart all replays, and mirror animator settings from the player vehicle so each ghost retains personality.
VehicleGhostController
The VehicleGhostController implements IGhostPlaybackController for cars. When a ghost spawns, it disables player input on the clone and leaves room for you to bolt on any vehicle-specific tweaks (camera, particles, audio). Cleanup simply logs the destruction event.
Crystal Save's Time Crystal Integration
The Crystal Save settings window ships with a Ghost Racing preset that configures Time Crystal's Time Machine for race replays. That preset enables continuous time so recordings across attempts stay in a single timeline, but the demo deliberately overrides that mode at runtime so every lap starts at timestamp zero—essential for aligning ghosts on the start grid. The editor warns about this in the preset description and encourages code overrides when needed.
Because Time Crystal's Time Machine stores history as branches, GhostRecorder clears the original branch between laps and can spawn as many ghost branches as memory allows. Each ghost vehicle references a dedicated GhostPlayer that can play back independently, letting the demo pit the active lap against every previous attempt simultaneously.
Typical Flow
Start race –
RaceController.StartRaceresets checkpoints, lap counters, and events whileGhostRecorderbegins a fresh Time Machine capture if auto-start is enabled.Run laps – Checkpoint triggers advance lap progress and fire UI events; Time Machine keeps recording positional snapshots the whole time.
Finish – When the race completes,
RaceUIasksGhostRecorderto stop recording, mint a new ghost, optionally persist it, then immediately resume recording for the next attempt.Persist or reload – RememberMe serializes race progress through the interface, restoring laps, checkpoint index, best times, and checkpoint state so players can relaunch straight into the action.
Related Games & Mechanics
Ghost replays are a staple in time-trial games, and this demo mirrors features seen in:
Mario Kart series – Time Trial mode lets racers compete against staff ghosts and their own best laps.
TrackMania – Every run spawns a ghost so players constantly compare lines and refine technique.
Forza Motorsport / Horizon – Drivatar ghosts and rivals system emulate opponent behaviour based on recorded laps.
F-Zero GX – Story and time attack challenges often pit you against personal ghost data for mastery.
Mirror's Edge Time Trials – Parkour ghosts teach optimal routes and provide split feedback.
These titles pair fast resets with immediate ghost feedback, the same philosophy embodied by the Ghost Racer scripts.
Extending the Demo
To use these patterns in your own project you will need to:
Provide a race controller that implements
IRaceControllerStateProviderand exposes serialization-friendly state.Configure RememberMe's Time Machine preset (usually Ghost Racing) and adjust runtime overrides—particularly continuous time—so they match your recording strategy.
Supply
SaveablePrefabdefinitions for the player vehicle and ensure aTimeMachineRecordersits on the prefab hierarchy.Customize ghost visuals and gameplay restrictions (camera, physics, effects) through
VehicleGhostControlleror your ownIGhostPlaybackControllerimplementation.Expand persistence if you want to store ghost archives beyond the session—
GhostRecorderintentionally marks serialization TODOs so you can bolt on save slots or leaderboards.
Remember that this repository gives you a teaching tool, not a drop-in racing game. Expect to adapt the code, integrate it with your own vehicle physics, and potentially modify the Time Machine pipeline to suit your production goals.
Last updated