
Description
Debug continuous behavior in WebXR scenes — physics, animations, collisions, game loops, or any real-time interaction that happens too fast for an agent to observe. Uses ECS pause/step/snapshot/diff to freeze time and inspect state frame by frame.
SKILL.md
Debug Continuous Behavior
Real-time behavior (physics, animations, collisions, game loops) happens too fast for an agent to observe directly. By the time you take a screenshot, the action is over. This skill uses ECS time-control tools to freeze, step, and diff state frame by frame.
User request is in $ARGUMENTS.
Core Workflow
Every debugging session follows this pattern:
- Set up the scenario (position objects, aim controllers, etc.)
ecs_pause— freeze ECS updates right before the interesting momentecs_snapshot({ "label": "before" })— capture state before the action- Trigger the action (release grip, apply force, start animation, etc.)
ecs_step(count, delta)— advance a few frames at fixed timestepbrowser_screenshot— visually verify what happenedecs_snapshot({ "label": "after" })— capture state after steppingecs_diff({ "from": "before", "to": "after" })— see exactly what changed- Repeat steps 5-8, stepping further until the behavior completes
ecs_resume— return to normal execution when done
The key insight: pause BEFORE triggering the action, not after. If you pause after, you've already missed the first frames.
Tool Reference
| Tool | Purpose |
|---|---|
ecs_pause | Freeze all ECS system updates. Render loop continues — screenshots still work. |
ecs_step({"count":N,"delta":SECONDS}) | Advance N frames with fixed timestep (seconds). Must pause first. |
ecs_resume | Resume normal execution. First frame uses capped delta to avoid physics explosions. |
ecs_snapshot({"label":"..."}) | Capture full ECS state. Stores up to 2 snapshots. |
ecs_diff({"from":"...","to":"..."}) | Compare two snapshots. Shows added/removed entities and field-level value changes. |
ecs_toggle_system({"name":"...","paused":true}) | Pause/resume a single system. Use ecs_list_systems to discover names. |
browser_screenshot | Visual verification — works while paused since the render loop continues. |
Stepping Guidelines
deltais in seconds. Common values:0.016(60fps),0.0139(72fps/Quest refresh rate).- Start small — step 1-3 frames first to catch the initial moment, then step more.
- Don't overshoot — stepping 100 frames at once defeats the purpose. Step in batches of 5-20.
Patterns
Short domain-specific tips. Apply the core workflow above, plus these hints.
Physics (falling, bouncing, collisions)
- Pause BEFORE releasing the object or applying force.
- Step 1-3 frames at
delta: 0.016to catch initial acceleration. - In diffs, check
PhysicsBody._linearVelocityandPhysicsBody._angularVelocityto see motion direction and speed. - Check
Transform.positionto track movement. - If an object falls through a surface: verify the surface entity has both
PhysicsBody(Static) andPhysicsShape(TriMesh for complex geometry). - Use
ecs_query_entityto inspectPhysicsShapeandPhysicsBodyon both the falling object and the surface.
Grab and Throw
- Pause while the object is still held (trigger/grip engaged).
- Release the input (set button value to 0) while paused.
- Step frame by frame to observe the release velocity.
- In diffs,
PhysicsBody._linearVelocityshows the throw direction and speed. - If the object doesn't move after release: check that it has
PhysicsBodywithstate: Dynamic.
Animations and Transitions
- Step 1 frame at a time with
deltamatching your target framerate. - Compare
Transform.position,Transform.orientation, andTransform.scaleacross snapshots to track interpolation. - Use screenshots between steps to observe visual progression.
Collision Detection
- Pause just before two objects meet.
- Step 1 frame at a time.
- Watch for
PhysicsBody._linearVelocitysign changes (indicates bounce/impact). - Watch for
PhysicsBody._angularVelocityspikes (indicates tumbling from impact). - If objects pass through each other: check
PhysicsShapeexists on both entities, and verify shape types are appropriate (useTriMeshfor complex static geometry).
System Isolation
- Use
ecs_list_systemsto see all systems and their priorities. - Use
ecs_toggle_system({ "name": "SystemName", "paused": true })to pause a suspect system while others run. - Step forward and observe — if the bug disappears, that system is the cause.
- Remember to unpause the system when done.
Notes
- Snapshots overwrite — only 2 are stored. Label them clearly ("before"/"after") and diff before taking new ones.
- Resume is safe — the first frame after resume uses a capped delta to prevent physics explosions from accumulated time.
- Render loop continues while paused — screenshots always work, and the XR session stays alive.
- Stepping requires pause —
ecs_stepwill fail if you haven't calledecs_pausefirst.
More skills from the immersive-web-sdk repository
View all 7 skillsiwsdk-depth-occlusion
implement depth sensing and occlusion in IWSDK
Jul 21ARIWSDKVRWebXRiwsdk-grab
grab and move objects in WebXR scenes
Apr 6ARImmersiveInteractionVR +1iwsdk-physics
implement physics in IWSDK projects
Jul 21ImmersiveInteractionIWSDKPhysics +1iwsdk-planner
plan IWSDK projects and architecture
Jul 21ArchitectureImmersiveIWSDKStrategy +1iwsdk-ray
implement ray-based interactions in WebXR
Apr 6ARImmersiveInteractionVR +1iwsdk-ui
develop IWSDK PanelUI components
Apr 6FrontendImmersiveIWSDKUI Components +1
More from Meta Open Source
View publisherrelay-best-practices
write idiomatic Relay code
relay
Apr 22EngineeringFrontendGraphQLReact +1relay-performance
optimize Relay application performance
relay
Jun 10FrontendGraphQLPerformanceReact +1add-shape-types-to-torch-model
annotate PyTorch models with tensor shapes
pyrefly
Jul 18Data ModelingDeep LearningPythonPyTorchcamera-streaming
configure camera streaming and photo capture
meta-wearables-dat-ios
May 15CameraHardwareiOSVideodat-conventions
develop iOS applications with DAT SDK
meta-wearables-dat-ios
May 15iOSMobileSDKSwiftdebugging
debug wearable device software
meta-wearables-dat-ios
May 15DebuggingEngineeringiOS