mcpField
X
xrift-world

xrift-world

github.com/webxr-jpDevelopment173 installsUpdated 5d ago
Repository

About xrift-world

xrift-world is a development guide for creating and modifying WebXR worlds on XRift. It gives React Three Fiber developers platform-specific implementation rules, device-support requirements, configuration guidance, and code references.

Key features

  1. 01XRift API and type references
  2. 02Asset loading and directory rules
  3. 03PC and mobile support guidance
  4. 043D interaction and UI patterns
  5. 05Physics and camera configuration

Use cases

  1. 01Creating an XRift WebXR world
  2. 02Adapting interactions for mobile and VR
  3. 03Configuring world physics and camera

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/webxr-jp/xrift-skills --skill xrift-world

After installing, type/xrift-worldin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
api-reference.md
code-templates.md
type-definitions.md

Details

From the project README

XRift World Development Guide

A guide for creating and modifying WebXR worlds for the XRift platform.

References

  • API Reference - Full specification of all hooks, components, and constants in @xrift/world-components
  • Code Templates - Implementation patterns for GLB models, textures, Skybox, interactions, and more
  • Type Definitions - Type definitions for User, PlayerMovement, VRTrackingData, TeleportDestination, WorldInfo, InstanceInfo, ConfirmOptions, Tag, VideoState, LogEntry, PhysicsConfig, CameraConfig, VoiceVolumeOverrideContextValue

Critical Rules (Must Follow)

  1. Always use baseUrl from useXRift() when loading assets
  2. Place asset files in the public/ directory
  3. baseUrl includes a trailing /, so join with ${baseUrl}path (${baseUrl}/path is WRONG)
// Correct
const { baseUrl } = useXRift()
const model = useGLTF(`${baseUrl}robot.glb`)

// Wrong
const model = useGLTF('/robot.glb')           // Absolute path - NG
const model = useGLTF(`${baseUrl}/robot.glb`) // Extra / - NG

Device Support (Must Follow)

Visitors join the same instance from PC, mobile (smartphones and tablets), and VR headsets. A world must work on at least both PC and mobile. Support VR as far as possible.

DeviceSupportControls
PCRequiredMouse + keyboard, center crosshair + click
MobileRequiredTouch, virtual joystick
VRBest effortControllers, ray + trigger

The dev server (npm run dev) only exercises PC controls, so these mistakes go unnoticed:

  1. Do not build features on custom keyboard shortcuts (window.addEventListener('keydown')). Mobile and VR have no keyboard, so those features become unusable. Keys such as W/A/S/D, Space, Q/E, G, H, and Esc are also taken by the platform.
    • Buttons and switches: wrap them in Interactable (click on PC, touch on mobile, controller in VR)
    • Vehicles: use onControlInput on Seat / Vehicle (keyboard, virtual joystick, and thumbsticks arrive in the same form)
    • Text entry: TextInput. Confirmation: useConfirm
    • A shortcut is acceptable only as a PC convenience for an action that is also reachable through Interactable
  2. Do not build HUDs or UI with DOM elements. DOM overlays break on small or rotated mobile screens and overlap the platform's virtual joystick and buttons. In VR only the 3D scene is rendered, so DOM UI is not shown at all.
    • Place UI as objects in 3D space: Text from @react-three/drei, panels and menus with @react-three/uikit
    • Load useDefaultFont for Japanese text, wrap in BillboardY to face the player, wrap in Interactable to make it clickable
  3. Do not make progress depend on Grabbable alone. Grabbing currently works only on PC (pointer lock + crosshair).

Project Overview

  • Purpose: WebXR worlds for the XRift platform
  • Tech Stack: React Three Fiber + Rapier physics engine + Module Federation
  • How It Works: Uploaded to CDN, dynamically loaded by the frontend

Project Structure

xrift-world-template/
├── public/              # Asset files (place directly, no subdirectories needed)
│   ├── model.glb
│   ├── texture.jpg
│   └── skybox.jpg
├── src/
│   ├── components/      # 3D components
│   ├── World.tsx        # Main world component
│   ├── dev.tsx          # Development entry point
│   ├── index.tsx        # Production export
│   └── constants.ts     # Constants
├── .triplex/            # Triplex (3D editor) config
├── xrift.json           # XRift CLI config
├── vite.config.ts       # Build config (Module Federation)
└── package.json

xrift.json Configuration

physics (Physics Settings)
FieldTypeDefaultDescription
gravitynumber9.81Gravity strength (positive value; Earth=9.81, Moon=1.62, Jupiter=24.79)
allowInfiniteJumpbooleantrueWhether to allow infinite jumping
{
  "physics": {
    "gravity": 9.81,
    "allowInfiniteJump": true
  }
}

Examples:

  • Obstacle course world: "allowInfiniteJump": false to add fall risk
  • Low gravity world: "gravity": 1.62 (Moon gravity) for floaty movement
  • High gravity world: "gravity": 24.79 (Jupiter gravity) for heavy movement
camera (Camera Settings)
FieldTypeDescription
nearnumberNear clip distance (hides objects closer than this distance)
farnumberFar clip distance (hides objects farther than this distance)
{
  "camera": {
    "near": 0.1,
    "far": 1000
  }
}

Examples:

  • Vast world: "far": 5000 to render distant objects
  • Precise world: "near": 0.01 for higher near-range rendering precision
outputBufferType (Output Buffer Type)

Specifies the output buffer type for WebGLRenderer. Affects post-processing and HDR rendering precision.

ValueDescription
UnsignedByteType8-bit integer (default, standard rendering)
HalfFloatType16-bit float (HDR and post-processing)
FloatType32-bit float (highest precision, higher GPU cost)
{
  "outputBufferType": "HalfFloatType"
}
items (Items Placed From the Start)

IDs of user-created items placed in the world with <Item itemId>. Only the IDs listed here are loaded in production (preloaded on entry; visitors resolve bundle URLs from this list). You can only declare items you created or added to your library (acquire on the marketplace). Up to 50.

{
  "items": [
    "2a69ded4-d913-4359-8c1f-eac83a982b0c"
  ]
}

Local development: add xriftDev() from @xrift/sdk/vite to vite.config.ts and run xrift login; DevEnvironment then loads the same bundles as production through the dev server proxy (/__xrift). To develop an item and a world together, pass local components via <DevEnvironment items={{ [itemId]: Component }}>.

permissions (Permission Settings)

Declares permissions required by the world. Declared permissions are shown to users as an approval screen when entering an instance.

FieldTypeDescription
allowedDomainsstring[]External domains the world communicates with
allowedCodeRulesstring[]Code security rules to relax
{
  "permissions": {
    "allowedDomains": ["api.example.com", "cdn.example.com"],
    "allowedCodeRules": ["no-storage-access", "no-network-without-permission"]
  }
}
allowedCodeRules

Rules defined by @xrift/code-security analyzer. By default, unsafe operations are blocked but can be relaxed when required.

CategoryRuleDescription
Dynamic Codeno-evalAllows eval()
Dynamic Codeno-new-functionAllows Function constructor
Dynamic Codeno-string-timeoutAllows setTimeout/setInterval with string args
Dynamic Codeno-javascript-blobAllows JavaScript Blob creation
Obfuscationno-obfuscationAllows obfuscated code patterns
Networkno-network-without-permissionAllows fetch, WebSocket, etc.
Networkno-unauthorized-domainAllows connections outside allowedDomains
Networkno-rtc-connectionAllows WebRTC peer connections
Networkno-external-importAllows external JS module imports
Storageno-storage-accessAllows localStorage/sessionStorage
Storageno-cookie-accessAllows cookie read/write
Storageno-indexeddb-accessAllows IndexedDB access
Storageno-storage-eventAllows storage event listening
DOMno-dangerous-domAllows innerHTML and script injection
Browser APIno-navigator-accessAllows geolocation, camera, mic, clipboard
Globalno-sensitive-api-overrideAllows overriding fetch, etc.
Globalno-global-overrideAllows overriding window, document
Globalno-prototype-pollutionAllows prototype modification

Command Reference

# Development
npm run dev        # Start dev server (http://localhost:5173)
npm run build      # Production build
npm run typecheck  # Type checking

# XRift CLI
xrift login        # Authenticate
xrift create world # Create new world project
xrift upload       # Upload (auto-detect from xrift.json)
xrift whoami       # Check logged-in user
xrift logout       # Log out

Development Environment

Run npm run dev to start the dev server. You can navigate and test the world in first-person view.

ActionKey
Look aroundClick to lock mouse, then move mouse
MoveW / A / S / D
Ascend / DescendE or Space / Q
InteractAim crosshair and click
Release mouse lockESC

Interactable component click behavior can also be tested in the dev environment (the center Raycaster detects the LAYERS.INTERACTABLE layer). Grabbable works too — G to grab and place, mouse wheel to adjust distance, click to confirm.

Seat and Vehicle only register themselves in the dev environment; sitting requires an avatar, a camera, and physics, so they do nothing until the world runs on XRift.

dev.tsx Structure

src/dev.tsx is the development-only entry point. It is not included in the production build.

Note: XRiftProvider is not needed in production (the frontend wraps it automatically).

Dependencies

Required (peerDependencies)
  • react / react-dom ^19.0.0
  • three ^0.182.0
  • @react-three/fiber ^9.3.0
  • @react-three/drei ^10.7.3
  • @react-three/rapier ^2.1.0
XRift-specific
  • @xrift/world-components - XRift hooks and components
Module Federation Shared パッケージ

ホスト(xrift.net)と shared で共有されるパッケージ。ワールドの vite.config.ts で shared に宣言すれば、ワールドチャンクにバンドルされずホストから提供される。

パッケージバージョン要件
react^19.0.0
react-dom^19.0.0
react-dom/client-
react/jsx-runtime^19.0.0
three^0.176.0
three/addons/loaders/GLTFLoader.js-
three/addons/loaders/DRACOLoader.js-
three/addons/loaders/KTX2Loader.js-
@react-three/fiber^9.0.0
@react-three/rapier^2.0.0
@react-three/drei^10.0.0
@react-three/uikit^1.0.0
@pmndrs/uikit^1.0.0
@xrift/world-components^0.1.0
three/addons の注意
  • three/addons バレルを shared にすると Lottie 由来の eval がバンドルに含まれるため、サブパス単位で shared にしている
  • ワールド側でも three/addons/loaders/DRACOLoader.js のようにサブパスで import & shared 宣言する
// vite.config.ts — shared の設定例(xrift-world-template 準拠)
federation({
  name: 'xrift_world_template',
  filename: 'remoteEntry.js',
  exposes: {
    './World': './src/index.tsx',
  },
  shared: {
    react: { singleton: true, requiredVersion: '^19.0.0' },
    'react-dom': { singleton: true, requiredVersion: '^19.0.0' },
    'react-dom/client': { singleton: true },
    'react/jsx-runtime': { singleton: true },
    three: { singleton: true, requiredVersion: '^0.176.0' },
    // three/addons はバレルではなくサブパス単位で宣言する
    'three/addons/loaders/DRACOLoader.js': { singleton: true },
    '@react-three/fiber': { singleton: true, requiredVersion: '^9.3.0' },
    '@react-three/rapier': { singleton: true, requiredVersion: '^2.1.0' },
    '@react-three/drei': { singleton: true, requiredVersion: '^10.7.3' },
    '@xrift/world-components': { singleton: true, requiredVersion: '^0.1.0' },
  },
}),

Troubleshooting

"useXRift must be used within XRiftProvider"

Cause: Not wrapped with XRiftProvider

Solution:

  • Check that src/dev.tsx uses XRiftProvider
  • When using Triplex: check .triplex/provider.tsx
Assets fail to load

Cause: Not using baseUrl, or incorrect path concatenation

Solution:

// Correct
const { baseUrl } = useXRift()
const model = useGLTF(`${baseUrl}robot.glb`)

// Wrong
const model = useGLTF('/robot.glb')
const model = useGLTF(`${baseUrl}/robot.glb`)
Physics not working

Cause: Not wrapped with Physics component, or missing RigidBody

Solution:

<Physics>
  <RigidBody type="fixed">  {/* or "dynamic" */}
    <mesh>...</mesh>
  </RigidBody>
</Physics>

Links

Example Implementations

  • GLB model: src/components/Duck/index.tsx
  • Skybox: src/components/Skybox/index.tsx
  • Animation: src/components/RotatingObject/index.tsx
  • Interaction: src/components/InteractableButton/index.tsx
  • User tracking: src/components/RemoteUserHUDs/index.tsx
  • Teleport: src/components/TeleportPortal/index.tsx
  • Main world: src/World.tsx

Comments

Markdown supported