agentleFS
GoogleKnown publishergoogle/three-live/skills/three-live-authoring/SKILL.md

three-live-authoring

Skill198 starsChanged 5 days agoApache-2.0View on GitHub

Builds interactive 3D viewers, procedural Three.js scenes, AR product configurators, and 6DoF WebXR, Android XR, and iOS/visionOS spatial computing apps using <three-live> and <xr-live>. Use when creating or editing <three-live> or <xr-live> HTML elements, writing <script type="text/three"> procedural scenes, configuring userData.xr spatial traits or userData.interactivity behavior graphs, building <div slot="spatial"> 3D HTML cards, or integrating native Android (Filament / Jetpack XR SceneCore) and iOS/visionOS (RealityKit) spatial views.

The file

We split this skill into the rules it gives an agent

5 rules. About 0 are common, 1 is distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Use <xr-live> (xr-live-full.min.js): when you need:

    line 33
  2. Very specific:

    Add xr-live-sim.min.js (included in xr-live-full.min.js): when the scene is an interactive simulation: a game, training drill, or …

    line 54
  3. Very specific:

    Do not import * as THREE from 'three', do not create a new THREE.WebGLRenderer(), and do not call document.body.appendChild(...) inside …

    line 71
  4. Distinctive:

    Read these reference files when you need detailed schemas, copy-pasteable recipes, or debugging steps:

    line 127
  5. Very specific:

    Always verify authored .js, .html, or .glb scenes headlessly using three-live-cli:

    line 152

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Authoring 3D & Spatial Apps with <three-live> and <xr-live>

<three-live> and <xr-live> compile declarative HTML and sandboxed Three.js scripts (<script type="text/three">) into WebGL2/WebXR on the web, Google Filament & Jetpack XR SceneCore on Android, and Apple RealityKit & Quick Look on iOS/visionOS.

1. Choose the Right Component & Bundle

  • Use <three-live> (three-live.min.js or three-live-full.min.js) when you need:
    • A 3D .glb / .usdz model viewer (<model-viewer> drop-in replacement) with built-in EXT_meshopt_compression decoding and KHR_materials_variants (variant-name)
    • A procedural Three.js scene (including 2D Shape/ExtrudeGeometry, THREE.CSG Booleans, 3D TextGeometry, and THREE.InstancedMesh GPU instancing) with orbit controls and 1-tap mobile AR handoff (ar)
    • PBR Next materials (clearcoat, transmission, dispersion, iridescence, sheen, volume), 5 filmic/commerce tone-mapping modes (tone-mapping="neutral|aces|agx|reinhard|none"), HDR emissive bloom, silhouette outline, .hdr environment lighting, ground contact shadows, skeletal animations & 2-bone/FABRIK ik, or 2D screen-space hotspots (slot="hotspot-*")
  • Use <xr-live> (xr-live-full.min.js) when you need:
    • 6DoF WebXR (xr-mode="ar" / "vr" / "auto") or desktop 6DoF simulation (xr-simulator="living-room")
    • Declarative spatial manipulation traits (grab, scale, billboard, follow, anchor, physics, orbit, handles, dimensions, snapTo, snapSocket, gaze, explode, navigable, sync, bloom, outline, ik, text, splat, audioEmitter)
    • True 3D raycastable HTML/CSS spatial cards (<div slot="spatial">)
    • Real-world depth occlusion & heightfield physics (xr-depth="occlusion-physics"), 25-joint hand gesture recognition (xr-hands="gestures"), spatial 3D painting (spatial-paint), depth-colliding particles (particles), 3D Gaussian Splats with 3D covariance & SH degree 1–3 (splatUrl / splat), world plane/reticle understanding (world-understanding), multimodal Gemini Live (connectGeminiLive() / holdToAsk), 3D CAD dimension callouts & tape measure (spatial-measure), magnetic socket/grid snapping (magnetic-snap), hands-free eye/head gaze dwell (gaze-dwell), multi-part exploded views & section clipping (explode / section-plane), #xr-state & XRAnchor persistence (persistent-anchors), parabolic XR locomotion (locomotion), or multi-user co-presence & WebRTC voice signaling (shared-room + shared-room-voice; your app owns the RTCPeerConnection).
  • Add xr-live-sim.min.js (included in xr-live-full.min.js) when the scene is an interactive simulation: a game, training drill, or safety walkthrough with a controllable character (character), steering agents (agent), integrity and hits (integrity, hit-zones), trigger zones (zone), spawners (spawner), objectives and scoring (objective, scenario-timer, target-score, attempts), or procedural audio cues (audioCues, synth-audio). Use neutral names: integrity (not health), group (not team).

2. Critical Rules That Prevent Broken Scenes

  1. Include allow-client-scripts whenever using inline <script type="text/three"> or executeScript():
    • <three-live> and <xr-live> reject inline client scripts unless allow-client-scripts is present on the host element.
    • Server-hosted scripts loaded via script-src="/path/to/scene.js" do not require allow-client-scripts.
  2. Use the pre-defined THREE and scene globals inside <script type="text/three">:
    • Do not import * as THREE from 'three', do not create a new THREE.WebGLRenderer(), and do not call document.body.appendChild(...) inside <script type="text/three">. The script runs inside an isolated Web Worker (or Rust Boa sandbox) with zero DOM access and populates the global scene directly (scene.add(mesh)).
  3. Never use GLTFLoader or TextureLoader inside <script type="text/three">:
    • Network APIs (fetch, XMLHttpRequest) are revoked inside the procedural sandbox. Load .glb assets declaratively via <three-live src="model.glb"> or <xr-anchor src="model.glb">.
  4. Prefer mesh.userData.xr = { ... } over legacy userData.xrTraits:
    • The structured userData.xr object supports all core and extended spatial traits and exports cleanly to .glb (extras.xr + ANDROID_xr_scenecore) and .usdz (customData.xr).
  5. Always name interactive meshes (mesh.name = '...'):
    • meshclick events, selected-mesh, userData.xr.orbit.target, userData.interactivity target references, holdToAsk prompts, and WebMCP place_xr_object_at_gaze all identify nodes by mesh.name.

3. Canonical userData.xr Trait Quick Reference

Attach userData.xr to any THREE.Mesh or THREE.Group inside <script type="text/three">:

Trait KeyAccepted ValuesBehavior
grab'1-hand' | '2-hand' | trueEnables 6DoF pinch / controller trigger grabbing (true defaults to '2-hand').
scale{ min?: number, max?: number } | trueTwo-hand pinch-to-scale clamped to [min, max] (default 0.05–5.0).
billboard'capsule' | 'cylindrical' | 'spherical' | trueFaces the active viewer camera ('capsule' / 'cylindrical' yaw-only; 'spherical' full 3D).
follow'head' | 'hand-left' | 'hand-right' or { mode, lazy, distance, deadzoneDeg, stiffness, height, faceUser, snapOnStart }String values use eager spring follow; object values activate lazy follow with angular deadzone + critically damped spring.
anchor'floor' | 'wall' | 'ceiling' | 'table' | 'horizontal' | 'vertical' or { target?, id?, persist? }Snaps node to detected real-world planes or simulated surfaces; persist: true saves user-moved transforms across reloads and #xr-state URLs.
physics / rigidBody'dynamic' | 'static' | 'kinematic' | true or { body?, shape?: 'auto' | 'box' | 'sphere' | 'cylinder', mass?, restitution?, friction?, linearDamping?, angularDamping?, gravityScale?, velocity?, angularVelocity?, lockRotation? }Steps 60 Hz deterministic Sequential Impulse rigid-body physics (gravity, restitution bounce, friction, stacking, sleeping, character push, projectile knockback, and depth heightfield collisions); emits xrcollision and xrsleep.
orbit{ target: [x,y,z] | 'nodeName', radius, speed, height, phase, faceCenter }Orbits around a 3D point or named target mesh at speed rad/s.
handles{ rotateAxis?: 'y' | 'none', minScale?: number, maxScale?: number } | trueSpawns 4 top-corner uniform-scale handles and a bottom pedestal yaw-rotation bar; emits xr-handles-change.
dimensions{ unit?: 'auto' | 'm' | 'cm' | 'mm' | 'in' | 'ft-in', axes?: Array<'x' | 'y' | 'z'>, color?: string, showOnSelect?: boolean } | trueRenders live W × H × D bounding-box dimension guide bars and 3D vector-glyph labels (spatial-measure).
snapTo{ grid?: number | [x,y,z], angleDeg?: number, surface?: 'none' | 'floor' | 'wall' | 'ceiling' | 'any', socketTag?: string, radius?: number } | trueSnaps grabbed meshes to matching snapSocket anchors (1.25× breakaway hysteresis), grids, surfaces, and yaw angles (magnetic-snap).
snapSocketstring or { tag: string, radius?: number, alignRotation?: boolean, highlightColor?: string }Marks a node as a magnetic snap target socket with a pulsing proximity ring (magnetic-snap).
gaze{ dwellMs?: number, action?: 'select' | 'ask', repeat?: boolean } | trueOpts mesh into hands-free eye/head gaze dwell (250..10000ms, default 1200ms), routing to meshclick or gemini-live (gaze-dwell).
explode{ direction?: [x,y,z], distance?: number, layer?: number, leaderLine?: boolean } | booleanConfigures per-part explosion vector, distance, staggered layer (1..10), and dashed leader lines (exploded-view); false pins base parts.
navigableboolean | 'walkable' | 'blocked'Marks floor/deck meshes as valid ('walkable') or blocked landing surfaces for parabolic XR teleportation (spatial-locomotion).
syncbooleanControls whether user manipulations sync across peers in shared-room (defaults to true on grabbable nodes).
particles{ preset: 'rain' | 'snow' | 'sparks' | 'confetti', count?: number, area?: [x,y,z], speed?: number }Emits up to 2,000 depth-colliding particles inside area.
holdToAsk{ prompt?: string, holdMs?: number } | truePress-and-hold on the mesh starts speech recognition and queries Gemini Live; emits xr-hold-to-ask.
worldUnderstanding{ planes?: boolean, meshes?: boolean, reticle?: boolean, objects?: boolean }Enables WebXR plane/mesh detection and gaze surface reticle (__xr_reticle__).
splatUrl'https://.../scene.splat' or '.spz'Streams and depth-sorts 3D Gaussian Splats (.splat or Niantic .spz v2/v3 with 3D covariance + SH degree 1–3).
splat{ url: string, shDegree?: 0 | 1 | 2 | 3, maxSplats?: number }Structured 3D Gaussian Splat trait controlling Spherical Harmonics degree (0..3) and splat cap.
bloom{ strength?: number, threshold?: number, radius?: number } | boolean | numberEnables HDR emissive bloom on the scene/node (strength in [0, 5], threshold in [0, 2], radius in [0, 1]).
outline{ color?: string, thickness?: number } | boolean | stringRenders an inverted-hull or screen-space silhouette outline (thickness in [0.002, 0.25]) around the node.
ik{ root: string, mid?: string, effector: string, target: string | [x, y, z], pole?: string | [x, y, z], solver?: 'two-bone' | 'fabrik', iterations?: number, tolerance?: number, weight?: number }Solves analytical 2-bone (root → mid → effector) or FABRIK inverse kinematics toward target (and optional pole, alias poleTarget).
lodboolean | number[] | { distances?: number[], ratios?: number[], levels?: Array<{ distance: number, ratio?: number, node?: string }>, cullDistance?: number, hysteresis?: number }Distance-based Level-of-Detail switching with hysteresis, far-distance culling, and automatic vertex-clustering decimation (also new THREE.LOD()).
text{ text: string, size?: number, depth?: number, bevelEnabled?: boolean, bevelThickness?: number, bevelSize?: number }Extruded 3D vector text metadata exported to glTF extras.xr.text and USDZ customData.xr.
audioEmitter / audio'hum' | 'reactor' | 'wind' | 'beacon' | 'geiger' | 'chimeLoop' | 'machinery' | 'water' or 'https://.../sound.mp3' or { preset?, src?, volume?, loop?, autoplay?, playOnSelect?, distanceModel?, refDistance?, maxDistance?, rolloffFactor?, coneInnerAngle?, coneOuterAngle?, coneOuterGain?, pitchHz? }Attaches a 3D positional and directional spatial audio emitter (spatial-audio), exporting KHR_audio_emitter and USDZ SpatialAudio.
charactertrue | 'third-person' | 'first-person' | 'top-down' | 'fixed' or { speed, jumpVelocity, radius, height, cameraMode, clips }(xr-live-sim) Keyboard, gamepad, or touch-joystick character that slides along collidable nodes.
agent'patrol' | 'chase' | 'flee' | 'follow' | 'wander' or { mode, target, speed, sightRadius, waypoints }(xr-live-sim) Steering agent; target: 'user' means the character, else the viewer.
integritynumber or { max, group, showBar, scoreValue, contactAmount, hideOnDepleted }(xr-live-sim) Takes hits from other groups; emits xrhit and xrdepleted.
zone'box' | 'sphere' or { shape, size, radius, watchGroups, color }(xr-live-sim) Emits xrzoneenter / xrzoneexit for characters, agents, and integrity nodes.
spawner'TemplateName' or { template, intervalSec, maxActive, totalCount, spawnRadius }(xr-live-sim) Clones a hidden template node; emits xrspawn.
objective'pickup' | 'checkpoint' | 'key' | 'time-bonus' | 'restore' or { type, amount, order, required, radius, respawnSec }(xr-live-sim) Completed by proximity to the character, or by tap without one; order > 0 enforces sequence.
audioCues{ onTap?, onObjective?, onHit?, onDepleted?, onZoneEnter?, onZoneExit?, onSpawn?, onJump?, onLand? } (cue names such as 'confirm', 'alarm')(xr-live-sim) Procedural cues with synth-audio; separate from the file-based audio trait.
collidabletrue(xr-live-sim) Wall or floor for characters and agents.
pointerEvents'none'Excludes the mesh from raycast picking so rays pass through to objects behind it.

4. Progressive Disclosure References

Read these reference files when you need detailed schemas, copy-pasteable recipes, or debugging steps:

  • references/xr-traits-and-plugins.md: Complete attribute tables, clamping ranges, DOM events, userData.interactivity (KHR_interactivity) actions, all 15 spatial plugin controllers, the 6 xr-live-sim simulation plugins, Gemini Live API, and WebMCP tool schemas.
  • references/recipes.md: 10 production-ready, copy-pasteable code templates (E-commerce configurator, Physics ballpit & spatial HTML UI, manipulation handles & lazy HUD, Gemini Live + World Understanding, Spatial Paint + Particles + Gaussian Splats, Native Android/iOS integration, CAD Exploded View + Measure + Gaze Dwell, Magnetic Snapping + Persistent #xr-state + Locomotion, Multi-User shared-room Co-Presence, and an xr-live-sim training drill).
  • references/debugging-and-csp.md: Diagnosing blank scenes, inspecting THREE.getAuthorWarnings(), running closed-loop three-live-cli validate --json / render --view=quad / sim --json checks (TL100–TL402), configuring Worker/iframe sandboxes & connect-src wss: under strict CSP / Trusted Types, and verifying bundle budgets.

5. Closed-Loop CLI Verification (three-live-cli)

Always verify authored .js, .html, or .glb scenes headlessly using three-live-cli:

  1. Validate & Spatial Lint: three-live-cli validate scene.js --json — fix all TL100–TL402 errors and spatial warnings (inFrustum, screenCoveragePct, grounded, broken target references) before rendering.
  2. Render 4-Up Quad Contact Sheet: three-live-cli render scene.js -o preview.png --view=quad --grid --annotations — inspect perspective camera framing (CAMERA), front/right elevation (FRONT, RIGHT), and top-down layout (TOP) with 1 m gridlines and AABB labels.
  3. Simulate Interactivity & Temporal Motion: three-live-cli render scene.js -o anim.png --frames=4 --duration=2.0 --trigger-select=<node> or three-live-cli sim scene.js --duration=5.0 --actions='[...]' --json.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.