A snapshot is a labeled summary of the world at a tick. Take two and diff them to see what
changed between them — the lightweight counterpart to a full fork.
Start a local server first — see the Quickstart. All commands target
http://localhost:3917; every POST sends Content-Type: application/json.
1. Snapshot, change, snapshot
# Build a small world (these return entity ids 1, 2, 3 — id 3 is the team-2 entity),
# then label the starting point.
curl -s -X POST http://localhost:3917/spawn -H 'Content-Type: application/json' -d '{"health":100,"team":1}'
curl -s -X POST http://localhost:3917/spawn -H 'Content-Type: application/json' -d '{"health":100,"team":1}'
curl -s -X POST http://localhost:3917/spawn -H 'Content-Type: application/json' -d '{"health":60,"team":2}'
curl -s -X POST http://localhost:3917/snapshot \
-H 'Content-Type: application/json' -d '{"label":"before"}'
# {
# "ok": true,
# "snapshot": {
# "label": "before", "tick": 0, "entity_count": 4,
# "summary": {
# "teams": [ { "team": 1, "entity_count": 2, "heroes_alive": 0, "towers_alive": 0, "score": 0 },
# { "team": 2, "entity_count": 1, "heroes_alive": 0, "towers_alive": 0, "score": 0 } ],
# "game_phase": "none", "match_time": 0.0, "total_dead": 0, "entity_counts_by_role": {}
# },
# "assertion_results": []
# }
# }
# entity_count is 4 — the three spawns plus the internal bookkeeping entity (id 0).
# Make a real change — remove the team-2 entity (id 3; needs id AND generation).
curl -s -X POST http://localhost:3917/despawn \
-H 'Content-Type: application/json' -d '{"entity_id":3,"entity_generation":0}'
# { "ok": true }
curl -s -X POST http://localhost:3917/snapshot \
-H 'Content-Type: application/json' -d '{"label":"after"}'
# Same shape; entity_count is now 3 (team 2 is gone).
/despawn needs both entity_id and entity_generation — use the values returned by
the /spawn that created the entity.
2. Diff the two snapshots
curl -s "http://localhost:3917/snapshot/diff?from=before&to=after"
# {
# "ok": true, "from": "before", "to": "after",
# "entity_delta": -1, "from_entities": 4, "to_entities": 3,
# "phase_changed": false, "from_phase": "none", "to_phase": "none",
# "role_changes": [], "assertion_changes": []
# }
The diff reads off the change at a glance: one entity removed (entity_delta: -1), no game-phase
change. Quote the URL so your shell does not eat the &.
A snapshot diff compares game-state summaries — entity counts, game phase, role counts,
and assertion results — not raw per-entity transforms. role_changes is empty here because
plain spawns carry no role; the entity delta is the signal. For full per-entity divergence,
use a fork and compare two observe dumps.
3. List and inspect
# All snapshots (labels + counts).
curl -s http://localhost:3917/snapshot/list
# { "ok": true, "count": 2, "snapshots": [ { "label": "before", "tick": 0, "entity_count": 4 }, { "label": "after", "tick": 0, "entity_count": 3 } ] }
# The most recent snapshot in full.
curl -s http://localhost:3917/snapshot/latest
A snapshot’s tick field tracks game-match time, so it reads 0 until a match is created
with POST /game/create. The labels and counts are what you diff against.