Skip to main content
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.