spatial_delta
Get only what changed since the last baseline snapshot.
spatial_delta is the efficient alternative to repeated spatial_snapshot calls. Instead of returning all tracked nodes, it returns only nodes whose tracked properties changed since the stored baseline. In a scene where most nodes are stationary, this can be 10-50x smaller than a full snapshot.
When to use it
- Polling for changes: "What moved since my last check?"
- After a game event: "What changed after the enemy spawned?"
- Watch polling: Reading accumulated changes since the baseline
- Verifying a fix: "Did the teleport land the player where I expected?"
Do not use spatial_delta as your first call in a session — use spatial_snapshot first to get oriented and establish the baseline. Delta computes changes relative to that stored baseline.
How the baseline works
When you call spatial_snapshot, the server stores the response as the baseline. Every subsequent spatial_delta call computes what changed since that baseline. There is no since_frame parameter — the baseline is set automatically by the most recent snapshot.
To update the baseline, call spatial_snapshot again. This is the normal pattern for watch loops:
spatial_snapshot → baseline established
... game runs ...
spatial_delta → what changed since snapshot?
spatial_snapshot → new baseline established
... game runs ...
spatial_delta → what changed since second snapshot?Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
class_filter | string[] | optional | Filter by node class. |
groups | string[] | optional | Filter by group membership. |
perspective | any"camera" | "node" | "point" | optional | Perspective to use for the snapshot. Default: camera. |
radius | number | optional default: 50 | Max distance from perspective. Default: 50.0. |
token_budget | number | optional | Soft token budget override. |
Response format
{
"frame": 284,
"baseline_frame": 120,
"elapsed_ms": 2733,
"changed_node_count": 2,
"nodes": {
"Player": {
"class": "CharacterBody3D",
"global_position": [3.1, 0.0, -2.3],
"velocity": [2.0, 0.0, 0.0],
"on_floor": true
},
"Enemy_0": {
"class": "CharacterBody3D",
"global_position": [-1.5, 0.0, 4.2],
"velocity": [1.2, 0.0, 0.5]
}
}
}| Field | Description |
|---|---|
frame | The current frame when the delta was computed |
baseline_frame | The frame from the most recent spatial_snapshot |
elapsed_ms | Milliseconds between baseline_frame and frame |
changed_node_count | Number of nodes with changes |
nodes | Map of node name → changed properties only |
Only changed properties are included in each node entry. If the player's position changed but velocity did not, only global_position appears in the player's entry.
Example conversation
Using delta in a watch loop
The typical watch pattern is:
- Call
spatial_snapshotto get the current state and establish the baseline - Optionally call
spatial_watchon nodes of interest - Periodically call
spatial_deltato check changes since the baseline - Call
spatial_snapshotagain when you want a new baseline
spatial_snapshot → baseline
... game runs ...
spatial_delta → player moved, enemy_0 moved
spatial_snapshot → new baseline
... game runs ...
spatial_delta → enemy_0 changed velocityEach delta response is small because it only includes actual changes.
Tips
Start with spatial_snapshot, then use deltas. Snapshot establishes the baseline that delta compares against. Without a prior snapshot, there is no baseline.
Call spatial_snapshot to reset the baseline. If you want to start tracking from a fresh state (for example, after making a change with spatial_action), call spatial_snapshot again to update the baseline.
Use class_filter to focus on relevant nodes. If you are debugging enemies, filter to CharacterBody3D to avoid including unrelated node changes in your delta.
Delta responses include only changed properties. If the player's position changed but rotation didn't, you only see global_position in the response. This is intentional — it keeps responses small and makes changes obvious.