conduit-rewind
conduit-rewind is the engine’s time machine. Since 0.26.0 a paused level is fully held (entities, blocks, fluids, block entities, every player interaction), chests and signs rewind with their contents, a game’s own attribute modifiers rewind with the player, and a GameHost game gets all of it from .rewind(cfg). A host arms a recording on a running match, then at any point can pause it, scrub back to any earlier moment, and resume live play from there. The world, players, blocks, entities and scores all snap back together. It is a real do-over, mid-match, on a server that is not supposed to be able to do that.
The core invariant
Section titled “The core invariant”It restores state. It never replays behaviour.
Minecraft is not deterministic, so nothing is ever re-simulated forward. The recording is only ever read backwards to reconstruct a past moment, and play after a rewind is ordinary live gameplay continuing fresh from the restored state.
That single decision is what makes a full-fidelity time machine tractable at all, and it is the thing to keep in mind whenever you are wondering what rewind can and cannot do. It is helped enormously by Conduit games running in small per-match void instance dimensions: the recorder only ever snapshots one bounded level, not a whole open world.
What actually rewinds
Section titled “What actually rewinds”| Subsystem | How it is captured | How it is restored |
|---|---|---|
| Players | Per-tick PlayerPose (position, rotation, health, food, gamemode, xp, effects) plus coarser inventory keyframes | SafeTeleport, with every mutation applied in the post-arrival callback |
| Blocks | A LevelChunk.setBlockState mixin journals (pos, old, new) | A minimal undo/redo diff walked back from the live head |
| Entities | Spawn/remove ledger, spawn NBT, transform samples, state keyframes | Despawn the extras, recreate the removed ones from NBT, reposition the rest |
| Game state | The SnapshotSlice SPI, change-deduped | Each slice’s own restore() |
That last row is the one that matters when you are building a game. Blocks and bodies come back for free; your match state only comes back if you tell the engine how, which is a snapshot slice.
When to depend on this
Section titled “When to depend on this”- You want hosts to be able to undo a bad round, a griefed build, or a botched clutch without restarting the match.
- You are filming, and you want retakes of a moment that has already happened.
- You want a durable record of a match at the end of it.
Two things every game on rewind must do
Section titled “Two things every game on rewind must do”Both are small, both are easy to forget, and skipping either produces a game that looks like it half-rewound:
- Gate your round loop on the freeze. The engine freezes vanilla ticking and locks players, but it cannot stop your mod’s own tick logic. One
iffixes it. - Register a snapshot slice for any state you keep outside the world, such as scores, phase, or timers. Otherwise the world travels back in time and your scoreboard does not.
- Rewind reference is the complete surface: the frame-index model, rolling-floor eviction, every command, the full API and events.
- Recording and playback covers arming, pausing, scrubbing, committing, and the command surface.
- Cooperative pause is the one-line gate your round loop needs.
- Snapshot slices make your own game state rewind with the world.
- Configuration covers the memory window, keyframe interval, and sampling knobs.
API surface
Section titled “API surface”me.zlex.conduit.rewind RewindRecorder, RewindController, Recording, RewindConfig, SnapshotSlice, Marker, TickRangeme.zlex.conduit.rewind.block BlockJournal, BlockEditme.zlex.conduit.rewind.entity EntityLedger, EntityTrack, EntitySample, EntityNbtme.zlex.conduit.rewind.player PlayerCapture, PlayerRestoreme.zlex.conduit.rewind.snapshot PlayerPose, InventorySnapshot, EffectSnapshotme.zlex.conduit.rewind.timeline Timeline, Frameme.zlex.conduit.rewind.store RewindStore, RecordingManifestme.zlex.conduit.rewind.event GamePausedEvent, GameResumedEvent, RecordingStartedEvent, RecordingStoppedEvent, RewindBeganEvent, RewindCommittedEventme.zlex.conduit.rewind.ui RewindPanel, RewindHud, PausedOverlayMaven coordinate: me.zlex:conduit-rewind:<engine_version>. Depends on conduit-core, conduit-render, conduit-world and conduit-fx.
Cost when idle
Section titled “Cost when idle”Both mixins (RewindBlockWriteMixin on block writes, RewindEntityTickMixin on entity ticking) gate on a single volatile read in the common case where nothing is recording and nothing is frozen. A server with rewind installed but unused pays effectively nothing.
Honest scope
Section titled “Honest scope”- In-session live rewind is complete and shipping: arm, pause, scrub, commit, resume.
- Memory coverage is full up to
rewind_memory_cap_mb. Past that ceiling the oldest per-tick history is evicted and the rewindable floor advances. This is logged; it is never silently truncated. - A replay is read-only. A saved recording can be reopened and scrubbed, but not resumed as live play: see Saved tapes and replays.