mcpbeat

Xb Simulator

google/xb-simulator

>- Develop and test XR Blocks apps on the desktop without a headset using the built-in simulator — a simulated user, hands, depth, and planes rendered in a normal browser, with control modes for moving the user, posing hands, or driving controllers. Use when running/iterating locally, reproducing XR interactions on desktop, posing hands for gesture work, or adding the optional 2D simulator settings UI. Covers the `?formFactor=desktop` autostart, `options.simulator.*`, `xb.SimulatorMode`, the `SimulatorAddons` 2D UI import, and the `onSimulatorStarted()` hook.

1k tokens
context cost
the whole folder, loaded on every use
1
files
instructions only
0
copies elsewhere
how many repositories repackaged it
455
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/google/xrblocks --skill xb-simulator

The instruction itself

8 sections, as written by the author

xb-simulator: desktop XR simulator

The simulator runs the same app in a normal browser so you can iterate without a device. It is

on by default (options.enableSimulator).

Run / autostart

npm run dev    # serves http://127.0.0.1:8080
  • Click Enter Simulator on the XR button, or
  • append ?formFactor=desktop to the URL to autostart the simulator, or
  • set it in code:
const options = new xb.Options();
options.formFactor = 'desktop'; // autostart simulator
// or expose a button: options.xrButton.showEnterSimulatorButton = true;

Optional 2D desktop UI

Import the simulator addon to get on-screen settings/instruction panels (hand-pose picker,

gamepad settings, mic button, etc.) on desktop:

import 'xrblocks/addons/simulator/SimulatorAddons.js';

Control modes

options.simulator.defaultMode = xb.SimulatorMode.POSE; // pose hands (great for gestures/hands)

SimulatorMode.POSE lets you pose virtual hands; other modes move the user or drive

controllers — see src/simulator/SimulatorOptions.ts

and src/simulator/controlModes/.

Reach limits

You can limit how far each virtual hand controller can travel from the user's shoulder origin (in meters) and restrict their movement to an angular cone (in radians) facing forward from the camera:

options.simulator.reachDistance.enabled = true;
options.simulator.reachDistance.radius = 0.75; // meters from shoulder origin
options.simulator.leftHandOrigin = {x: -0.2, y: -0.2, z: 0};
options.simulator.rightHandOrigin = {x: 0.2, y: -0.2, z: 0};

options.simulator.reachAngle.enabled = true;
options.simulator.reachAngle.angle = Math.PI; // radians (default Math.PI is a front hemisphere)

Physical simulated hands are opt-in and require Rapier:

options.simulator.handPhysics.enabled = true;

Disable all simulator-owned physics while leaving regular app physics available with:

options.simulator.physics.enabled = false;

The top-level hand origins are shared by reach limits and hand physics. When hand physics

is enabled, they act as invisible shoulder-to-palm tethers so fixed geometry cannot leave

a hand trapped on the far side of a wall. Dynamic objects remain pushable by the hands.

Scene manifests and physical-world objects

Simulator environments use one strict JSON manifest:

options.simulator.environments = [
  {name: 'Evaluation Room', manifestPath: './evaluation-room.json'},
];

The manifest can contain scenePath or videoPath, scenePlanesPath,

navMeshPath, a root position/quaternion/scale, and an objects array.

Object entries support assetPath, optional transform arrays,

physics: false | 'fixed' | 'dynamic', and detectObject plus label. All paths

may be manifest-relative, root-relative, or absolute CDN URLs.

At runtime, use the plural API:

await xb.core.simulator.objects.addObjects([
  {
    assetPath: './chair.glb',
    physics: 'fixed',
    detectObject: true,
    label: 'chair',
  },
]);
xb.core.simulator.objects.get();
xb.core.simulator.objects.removeObjects(['simulator-object-1']);

Set options.world.objects.simulatorOverride = true after enabling object

detection to make the normal world.objects.runDetection() API use simulator

frustum and visibility checks on desktop. Real XR sessions continue to use the

configured detector backend.

Lifecycle

onSimulatorStarted() fires when the simulator boots — a common pattern is to mirror your XR

startup:

onSimulatorStarted() { this.onXRSessionStarted(); }

Notes

  • The simulator provides simulated depth and planes, so xb-depth and

xb-world features work on desktop.

  • demos/sim_hand_poses is a focused example of posing hands in the simulator.
  • options.enableSimulator = false (or formFactor: 'xr') disables it for device-only builds.

How to use it

Copy the folder

Take google/xb-simulator from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.