How it works

The toroidal 256×160 world, deterministic replay from keyframes and sparse edits, the 4096-generation history window, why Life cannot be reverse-simulated, how pluggable rules and account-free multiplayer both work.

The world

The shipped world is a 256×160 grid, running standard B3/S23, with toroidal wrap: the top edge connects to the bottom, the left to the right, so every cell has exactly 8 neighbours with no special-cased edges. A glider that exits the right side re-enters on the left and keeps going. This also means a snapshot of the world is always the same fixed size — a 256×160 buffer, one byte per cell — which is what makes keyframes cheap and two branches diffable cell-for-cell without any alignment logic.

Deterministic replay, not stored snapshots

The history ribbon does not store a full snapshot of every generation — that would be enormous. Instead it stores a keyframe (a full snapshot) every 64 generations, plus the sparse list of edits you made at each generation in between. Scrubbing to any generation restores the nearest keyframe at or before it and replays forward deterministically, reapplying your edits at the exact generations you made them. Because the rule is exact and edits are absolute (a cell is set alive or dead, never merely "toggled"), replaying the same history twice — even out of order — produces bit-identical results every time. That's what lets scrubbing feel instantaneous while still being the real recorded history rather than an approximation of it.

Only the most recent 4096 generations are kept in memory at once; older keyframes and edits are dropped as new history accumulates. That's a deliberate budget — enough history to dwarf what the Time Sculpture can show in one view (256 slices), while keeping a browser tab comfortable. Scrubbing past the retained window surfaces a message rather than failing silently.

Why you can't just run the rule backward

It would be convenient if rewinding meant literally reversing the B3/S23 rule — running it backward instead of forward. That doesn't work, because Conway's Game of Life is not reversible. The rule is many-to-one: multiple different past generations can produce the exact same next generation (a dying cell with 0, 1, 4, 5, 6, 7 or 8 neighbours all just die — the rule doesn't record which), so going from a single present state back to "the" previous state is ambiguous in general, and for most patterns there simply is no valid predecessor at all. This is a structural fact about the rule, true for any implementation, not a limitation specific to AFTERLIFE.

That's the actual reason the ribbon works the way it does: rather than trying to compute the past from the present, AFTERLIFE keeps a real record of the past (keyframes plus edits, as above) and replays it forward on demand. Scrubbing "backward" is really just asking for an earlier point in a forward-only recording — the only approach that's actually correct for a rule that can't be run in reverse.

Edits commit at a generation boundary

A single pointer drag while drawing accumulates into one batch of cell changes; nothing is recorded until you release, at which point the whole batch is committed as one edit at the current generation, applied at the very start of that generation, before the step that produces the next one. One gesture equals one undoable, replayable unit. Committing an edit at a generation before the present normally truncates that branch's future — unless you ask to branch instead, which is the entire mechanism behind "alternate futures."

Rules are pluggable, but never mid-history

B3/S23 isn't hardwired into the step loop — the engine holds an 18-entry lookup table (one entry per "was this cell alive, and how many live neighbours does it have" combination) and looks the next state up directly, so any Life-like B/S rule runs through the exact same code path. Conway's own rule keeps a separate, hand-written fast path that the engine switches to automatically whenever the active rule happens to canonicalise to exactly B3/S23, which is why supporting other rules didn't come at the expense of Conway's own performance (measured: well under 1% difference).

What the lookup table can't do is retroactively apply to history that's already been recorded. A saved edit and a keyframe both describe what changed, not what rule produced the change — so switching rules always starts a brand-new world (playback stops, the board clears, history resets) rather than reinterpreting old history under a rule that never actually ran it.

Multiplayer without a server

Because a world is already "a seed plus a sparse, timestamped edit log," sharing one is mostly a networking problem, not a simulation one: instead of ever sending the grid itself, every peer sends the same tiny edits everyone already knows how to replay. Each edit is time-stamped to land about a second in the future relative to the sender's own clock — for every peer, including the sender — so nobody's own edits ever apply "instantly" while everyone else's arrive late; that symmetry is what keeps every peer's recorded history identical. If two edits ever land on the same generation, every peer sorts them by the same rule (which peer, then which of that peer's own edits), so there's never a need to ask a server who goes first. The simulation simply won't advance past a generation whose inputs might still be outstanding, and every so often peers compare a cheap checksum of their own worlds so a genuine disagreement is loud and recoverable rather than a silent, slowly-diverging bug.