Skip to content

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.

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.

SubsystemHow it is capturedHow it is restored
PlayersPer-tick PlayerPose (position, rotation, health, food, gamemode, xp, effects) plus coarser inventory keyframesSafeTeleport, with every mutation applied in the post-arrival callback
BlocksA LevelChunk.setBlockState mixin journals (pos, old, new)A minimal undo/redo diff walked back from the live head
EntitiesSpawn/remove ledger, spawn NBT, transform samples, state keyframesDespawn the extras, recreate the removed ones from NBT, reposition the rest
Game stateThe SnapshotSlice SPI, change-dedupedEach 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.

  • 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.

Both are small, both are easy to forget, and skipping either produces a game that looks like it half-rewound:

  1. 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 if fixes it.
  2. 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.
me.zlex.conduit.rewind RewindRecorder, RewindController, Recording,
RewindConfig, SnapshotSlice, Marker, TickRange
me.zlex.conduit.rewind.block BlockJournal, BlockEdit
me.zlex.conduit.rewind.entity EntityLedger, EntityTrack, EntitySample, EntityNbt
me.zlex.conduit.rewind.player PlayerCapture, PlayerRestore
me.zlex.conduit.rewind.snapshot PlayerPose, InventorySnapshot, EffectSnapshot
me.zlex.conduit.rewind.timeline Timeline, Frame
me.zlex.conduit.rewind.store RewindStore, RecordingManifest
me.zlex.conduit.rewind.event GamePausedEvent, GameResumedEvent,
RecordingStartedEvent, RecordingStoppedEvent,
RewindBeganEvent, RewindCommittedEvent
me.zlex.conduit.rewind.ui RewindPanel, RewindHud, PausedOverlay

Maven coordinate: me.zlex:conduit-rewind:<engine_version>. Depends on conduit-core, conduit-render, conduit-world and conduit-fx.

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.

  • 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.