Skip to content

spatial_snapshot

Get an instant picture of every tracked node in the running game.

spatial_snapshot is the entry point for most Spectator sessions. It returns positions, velocities, and key properties for all nodes the collector is tracking, subject to your token budget.

When to use it

  • Starting a new investigation: "What is the current state of my scene?"
  • After a major game event: "What are the positions now that the enemy has spawned?"
  • Confirming a fix: "Does the player spawn at the right position now?"
  • Orientation: Before using more targeted tools, snapshot gives context.

Do not use spatial_snapshot repeatedly to detect changes — use spatial_delta instead. Snapshots include all tracked nodes even if nothing changed; deltas only include what changed.

Parameters

ParameterTypeRequiredDescription
class_filterstring[] optional Filter by node class.
detailstring
"summary" | "standard" | "full"
optional
default: "standard"
Detail tier: summary (~200 tokens, clusters only), standard (~400-800 tokens, per-entity), full (~1000+ tokens, transforms/physics/children). Default: standard.
expandstring optional Expand a cluster from a previous summary response.
focal_nodestring optional Node path, required when perspective is "node".
focal_pointnumber[] optional World position [x, y, z], required when perspective is "point".
groupsstring[] optional Filter by group membership.
include_offscreenboolean optional
default: false
Include nodes outside camera frustum. Default: false.
perspectiveany
"camera" | "node" | "point"
optional Where to look from: camera (active camera, default), node (requires focal_node), point (requires focal_point).
radiusnumber optional
default: 50
Max distance from perspective to include. Default: 50.0.
token_budgetnumber optional Soft token budget override.

detail values

"summary" — Position and velocity only (approximately 80-120 tokens per node):

json
{
  "class": "CharacterBody3D",
  "global_position": [2.3, 0.0, -1.7],
  "velocity": [0.0, -2.4, 0.0]
}

"full" — All tracked properties (approximately 300-500 tokens per node):

json
{
  "class": "CharacterBody3D",
  "global_position": [2.3, 0.0, -1.7],
  "rotation_deg": [0.0, 45.2, 0.0],
  "velocity": [0.0, -2.4, 0.0],
  "scale": [1.0, 1.0, 1.0],
  "visible": true,
  "collision_layer": 1,
  "collision_mask": 3,
  "on_floor": false,
  "on_wall": false
}

"standard" — Position, velocity, rotation, scale, and common flags (approximately 150-250 tokens per node).

focal_node

When set, the focal node is always included in the response (even if it would be cut by the budget), and nearby nodes are prioritized over distant nodes. Useful when debugging a specific character or object in a large scene.

json
{
  "detail": "summary",
  "focal_node": "World/Player",
  "token_budget": 1000
}

Filtering by type

json
{
  "detail": "full",
  "class_filter": ["CharacterBody3D", "RigidBody3D"],
  "token_budget": 3000
}

This returns only physics bodies, ignoring cameras, lights, UI nodes, etc.

Response format

json
{
  "frame": 412,
  "timestamp_ms": 6867,
  "node_count": 47,
  "included_nodes": 12,
  "truncated": false,
  "nodes": {
    "Player": {
      "class": "CharacterBody3D",
      "path": "World/Player",
      "global_position": [2.3, 0.0, -1.7],
      "velocity": [0.0, 0.0, 0.0]
    },
    "Enemy_0": {
      "class": "CharacterBody3D",
      "path": "World/Enemies/Enemy_0",
      "global_position": [-3.1, 0.0, 4.2],
      "velocity": [0.8, 0.0, 0.0]
    },
    "Camera3D": {
      "class": "Camera3D",
      "path": "World/Player/Camera3D",
      "global_position": [2.3, 1.8, 0.3]
    }
  }
}
FieldDescription
framePhysics frame number when data was collected
timestamp_msMilliseconds since game start
node_countTotal tracked nodes in the scene
included_nodesNodes included in this response
truncatedtrue if budget was reached before including all nodes
nodesMap of node name → node data

Node data fields

FieldDescription
classGodot class name
pathFull scene tree path from root
global_position[x, y, z] in world space
velocity[x, y, z] units/second (for physics bodies)
rotation_deg[x, y, z] rotation in degrees (for full detail)
scale[x, y, z] scale (for full detail)
visibleBoolean visibility (for full detail)
collision_layerBitmask integer (for physics nodes, full detail)
collision_maskBitmask integer (for physics nodes, full detail)
on_floortrue if CharacterBody3D is on a floor surface
on_walltrue if CharacterBody3D is on a wall surface

Example conversation

The game is running. What does my scene look like right now?
Let me take a spatial snapshot to see the current state.
I can see 8 nodes in your scene. The Player (CharacterBody3D) is at [2.3, 0.0, -1.7] with zero velocity — standing still. There are 3 enemies: Enemy_0 at [-3.1, 0.0, 4.2] moving at 0.8 units/sec along X, Enemy_1 at [5.0, 0.0, 1.1] stationary, Enemy_2 at [0.0, 0.0, -8.3] stationary. The Camera3D follows the player at [2.3, 1.8, 0.3]. There are also 3 StaticBody3D platforms and a SpotLight3D.
Focus on the player and anything nearby.
Player details: on_floor=true, collision_layer=1, collision_mask=3, velocity=[0,0,0]. Enemy_0 is the closest at 5.7 units — also on layer 1. Enemy_1 is 2.9 units to the right. Both enemies are in motion toward the player.

Tips

Use focal_node in large scenes. Without it, the budget may be exhausted by nodes you do not care about (terrain, lights, UI containers). Setting focal_node: "Player" ensures the player and nearby objects are always in the response.

Combine with class_filter for targeted investigations. If you are debugging pathfinding, filter to NavigationAgent3D and CharacterBody3D. If you are debugging physics, filter to physics body types.

One snapshot per investigation start. Do not call snapshot in a loop. Call it once, orient the agent, then use spatial_delta, spatial_inspect, or spatial_query for subsequent questions.

Check truncated. If truncated: true, the budget was hit. Either increase token_budget, add a class_filter to reduce scope, or use spatial_query to search a smaller area.

Open source under the MIT License.