Delta-log save for deterministic procedural worlds
When the world is deterministically generated from a spec, a save is {version, spec, edits[]} — never a geometry snapshot. Load = validate → regenerate → replay edits. Same format works for save, co-op edit sync, and late-join replay.
When the world is deterministically generated from a spec, a save is
{version, spec, edits[]} — the generator inputs plus an ORDERED log of
user edits — never a geometry/grid snapshot. Load = validate → regenerate from
spec → replay edits in order. Proven with a round-trip suite: grid hash
byte-identical across save→different-world→load, and pixel-identical
screenshots.
Companion pieces: saveload-without-drift, /guides/runtime-terrain-meshing (grid as truth), /guides/networking-methods (spec replication + late join).
Record at the single mutation choke point
Every edit path — UI and editor tools — funnels through ONE method. Store the POST-clamp/normalized params so replay re-clamping is a no-op and file validation is a plain range check. If two code paths can mutate the world, you don't have a log — you have a race.
Validate EVERYTHING before touching the live world
Schema version equality, spec normalization, then every edit (known op, finite floats, in-range radius, in-bounds cells) — fail on the FIRST bad edit with its index; a partially-valid log is a rejected load. A save that can't be validated is a world-destroyer.
Serialize enums as stable ints
Enum NAMES aren't a guaranteed Json round-trip in this engine; validate with
Enum.IsDefined on load. Keep the record's fields append-only — same contract
discipline as the spec itself.
Suppress recording during replay
A flag reset in finally, and restore the log AFTER replay so re-saving
round-trips. Forgetting the suppress flag double-writes every stroke on load.
Measure replay before building compaction
Replay cost is settle + dirty-remesh per stroke. Real authoring sessions are often sub-second. Bake-to-snapshot is a future optimization, not a v1 feature — don't invent compaction until measurement says you need it.
Why it beats snapshots
Tiny on disk, versionable, and the SAME format works as:
- Save/load for single-player sessions.
- Live co-op edit wire protocol (post frozen-world MVP).
- Late-joiner replay stream — joiner regenerates from spec, then applies the edit log.
One format, three jobs. Pair with the content-hash handshake from /guides/networking-methods Part A so a desynced replay fails loud instead of walking a wrong world.