SuperAPI AI Directory

xrift-world

Agents & models

View repository

Updated 10-16 04:41

About this skill

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

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)

Field Type Default Description
gravity number 9.81 Gravity strength (positive value; Earth=9.81, Moon=1.62, Jupiter=24.79)
allowInfiniteJump boolean true Whether 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)

Field Type Description
near number Near clip distance (hides objects closer than this distance)
far number Far 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.

Value Description
UnsignedByteType 8-bit integer (default, standard rendering)
HalfFloatType 16-bit float (HDR and post-processing)
FloatType 32-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.

Field Type Description
allowedDomains string[] External domains the world communicates with
allowedCodeRules string[] 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.

Category Rule Description
Dynamic Code no-eval Allows eval()
Dynamic Code no-new-function Allows Function constructor
Dynamic Code no-string-timeout Allows setTimeout/setInterval with string args
Dynamic Code no-javascript-blob Allows JavaScript Blob creation
Obfuscation no-obfuscation Allows obfuscated code patterns
Network no-network-without-permission Allows fetch, WebSocket, etc.
Network no-unauthorized-domain Allows connections outside allowedDomains
Network no-rtc-connection Allows WebRTC peer connections
Network no-external-import Allows external JS module imports
Storage no-storage-access Allows localStorage/sessionStorage
Storage no-cookie-access Allows cookie read/write
Storage no-indexeddb-access Allows IndexedDB access
Storage no-storage-event Allows storage event listening
DOM no-dangerous-dom Allows innerHTML and script injection
Browser API no-navigator-access Allows geolocation, camera, mic, clipboard
Global no-sensitive-api-override Allows overriding fetch, etc.
Global no-global-override Allows overriding window, document
Global no-prototype-pollution Allows 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.

Action Key
Look around Click to lock mouse, then move mouse
Move W / A / S / D
Ascend / Descend E or Space / Q
Interact Aim crosshair and click
Release mouse lock ESC

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 Packages

Packages shared between the host (xrift.net) and shared. In the world's vite.config.ts if declared as shared, they are not bundled into the world chunk but provided by the host.

Package Version requirements
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

Notes on three/addons

  • three/addons If the barrel is made shared, the Lottie-derived eval is included in the bundle, soper subpathis made shared
  • On the world side too, three/addons/loaders/DRACOLoader.js import and declare as shared by subpath like this
// 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