skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
prnthh/react-three-game-skill142 installs

react-three-game

Build games with React Three Game using JSON prefab documents, R3F component composition, the scene and prefab runtime APIs, the optional editor entrypoint, and optional plugins such as Crashcat physics.

How do I install this agent skill?

npx skills add https://github.com/prnthh/react-three-game-skill --skill react-three-game
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    The skill provides documentation and development rules for 'react-three-game', a React Three Fiber-based scene authoring library. No security vulnerabilities, malicious patterns, or suspicious activities were detected.

  • Socketpass

    No alerts

  • Snykpass

    Risk: LOW · No issues

  • Runlayerwarn

    3/3 files flagged

What does this agent skill do?

react-three-game

React Three Game mounts serializable prefab documents as native React Three Fiber scenes. Components define the vocabulary; prefab JSON composes that vocabulary into entities.

Core model

ScopeMeaningAPI
SceneThe outer R3F scene shared by composed prefabsuseScene() → { root, mode }
PrefabOne serializable document with local node ids and shared materialsusePrefab() → PrefabApi
NodeOne entity in the active prefabuseNode(), useNodeObject(), useNodeHandle()
ComponentA registered renderer/editor capability selected by typeregisterComponent(component)

Child prefabs inherit the parent scene and receive their own prefab document scope.

Package entrypoints

ImportContents
react-three-gameGameCanvas, PrefabRoot, scene/prefab/node hooks, component registration, events, types, loaders
react-three-game/editorPrefabEditor, editor ref/context, fields, prefab-store hooks, import/export tools
react-three-game/plugins/crashcatCrashcat runtime, authored physics component, ragdoll helpers

Prefab syntax

interface Prefab {
  id?: string;
  name?: string;
  materials?: Record<string, PrefabMaterial>;
  root: GameObject;
}

interface GameObject {
  id: string;
  name?: string;
  disabled?: boolean;
  hidden?: boolean;
  locked?: boolean;
  components?: Record<string, ComponentData | undefined>;
  children?: GameObject[];
}

interface ComponentData<P extends object = Record<string, unknown>> {
  type: string;
  properties: P;
}

Use stable ids, local transforms, radians, and asset paths resolved from basePath.

{
  "id": "starter",
  "name": "Starter Scene",
  "materials": {
    "crate": {
      "name": "Crate",
      "materialType": "standard",
      "color": "#d97706",
      "roughness": 0.7,
      "metalness": 0.1
    }
  },
  "root": {
    "id": "root",
    "children": [
      {
        "id": "camera",
        "components": {
          "transform": {
            "type": "Transform",
            "properties": {
              "position": [0, 3, 8],
              "rotation": [-0.25, 0, 0],
              "scale": [1, 1, 1]
            }
          },
          "camera": {
            "type": "Camera",
            "properties": { "projection": "perspective", "fov": 50 }
          }
        }
      },
      {
        "id": "crate",
        "components": {
          "transform": {
            "type": "Transform",
            "properties": {
              "position": [0, 0.5, 0],
              "rotation": [0, 0, 0],
              "scale": [1, 1, 1]
            }
          },
          "mesh": {
            "type": "Mesh",
            "properties": { "castShadow": true, "receiveShadow": true }
          },
          "geometry": {
            "type": "Geometry",
            "properties": { "geometryType": "box", "args": [1, 1, 1] }
          },
          "material": {
            "type": "Material",
            "properties": { "materialId": "crate" }
          }
        }
      }
    ]
  }
}

Component composition

Components on a node compose like R3F children:

<mesh>
  <boxGeometry attach="geometry" />
  <meshStandardMaterial attach="material" />
  {children}
</mesh>
Built-in roleComponentsComposition
TransformTransformApplies the node's outer position, rotation, and scale
ObjectMesh, Model, Sprite, Text, lights, CameraOwns the node's Three.js object slot
AttachmentGeometry, BufferGeometry, MaterialAttaches to the enclosing object
WrapperSound, Data, PrefabRef, custom behaviorWraps the composed object and children

Materials live in Prefab.materials. A Material component selects one with materialId; every reference in that prefab shares the same Three.js material object. attach supports R3F attachment paths such as material.

Mounting

Runtime:

import { GameCanvas, PrefabRoot, type Prefab } from 'react-three-game';
import sceneJson from './scene.json';

const prefab = sceneJson as Prefab;

export function Game() {
  return (
    <GameCanvas>
      <PrefabRoot data={prefab} basePath="/game" />
    </GameCanvas>
  );
}

Editor:

import { PrefabEditor } from 'react-three-game/editor';

export function Authoring() {
  return <PrefabEditor prefab={prefab} basePath="/game" />;
}

PrefabRoot.data and PrefabEditor.prefab are document inputs. A new object value loads the new document. Editor mutations update the current document and ref.save() returns it. PrefabEditor.mode defaults to PrefabEditorMode.Edit and responds to new prop values.

Runtime scopes

import { useFrame } from '@react-three/fiber';
import {
  PrefabEditorMode,
  usePrefab,
  useScene,
} from 'react-three-game';

function SceneRuntime() {
  const scene = useScene();
  const prefab = usePrefab();

  useFrame((_, delta) => {
    if (scene.mode !== PrefabEditorMode.Play) return;
    const crate = prefab.getObject('crate');
    if (crate) crate.rotation.y += delta;
  });

  return null;
}
HookUseful members
useScene()root, mode
usePrefab()root, basePath, node/material CRUD, live objects, handles, loaded assets
useNode()nodeId, editMode, isSelected, interaction handlers, current-node getters
useNodeObject<T>()Live ref for the current node's Object3D
useNodeHandle<T>(kind)Live ref for a current-node runtime handle
useAssetRuntime()Shared model, texture, and sound cache

Core PrefabApi syntax:

prefab.get(id);
prefab.getObject(id);
prefab.getHandle(id, kind);
prefab.getModel(path);
prefab.getMaterial(materialId);

prefab.add(node, parentId);
prefab.update(id, node => nextNode);
prefab.setMaterial(materialId, material);
prefab.replaceNode(id, node);
prefab.remove(id);
prefab.duplicate(id);
prefab.move(id, targetId, 'inside');
prefab.replace(nextPrefab);

Authored changes use prefab mutations. Frame-by-frame motion uses live Three.js objects.

Custom components

Component fields infer their property names and value types from FieldDefinition<P>.

import { useFrame } from '@react-three/fiber';
import {
  registerComponent,
  useNode,
  useNodeObject,
  type Component,
  type ComponentViewProps,
} from 'react-three-game';
import {
  FieldRenderer,
  type ComponentEditorProps,
  type FieldDefinition,
} from 'react-three-game/editor';

type RotatorProperties = {
  speed?: number;
  axis?: 'x' | 'y' | 'z';
};

const fields = [
  { name: 'speed', type: 'number', label: 'Speed', step: 0.1 },
  {
    name: 'axis',
    type: 'select',
    label: 'Axis',
    options: [
      { value: 'x', label: 'X' },
      { value: 'y', label: 'Y' },
      { value: 'z', label: 'Z' },
    ],
  },
] satisfies FieldDefinition<RotatorProperties>[];

function RotatorEditor({ properties, update }: ComponentEditorProps<RotatorProperties>) {
  return <FieldRenderer fields={fields} values={properties} onChange={update} />;
}

function RotatorView({ properties, children }: ComponentViewProps<RotatorProperties>) {
  const { editMode } = useNode();
  const objectRef = useNodeObject();

  useFrame((_, delta) => {
    const object = objectRef.current;
    if (editMode || !object) return;
    object.rotation[properties.axis ?? 'y'] += delta * (properties.speed ?? 1);
  });

  return <>{children}</>;
}

const Rotator: Component<RotatorProperties> = {
  name: 'Rotator',
  Editor: RotatorEditor,
  View: RotatorView,
  defaultProperties: { speed: 1, axis: 'y' },
};

registerComponent(Rotator);

JSON usage:

{
  "rotator": {
    "type": "Rotator",
    "properties": { "speed": 1.5, "axis": "y" }
  }
}

Handles and events

import { useEffect, useRef } from 'react';
import {
  useNode,
  usePrefab,
  type ComponentViewProps,
} from 'react-three-game';

function DoorView({ children }: ComponentViewProps) {
  const { nodeId } = useNode();
  const prefab = usePrefab();
  const open = useRef(false);

  useEffect(() => {
    const handle = { open: () => { open.current = true; } };
    prefab.registerHandle(nodeId, 'door', handle);
    return () => prefab.registerHandle(nodeId, 'door', null);
  }, [nodeId, prefab]);

  return <>{children}</>;
}
CommunicationSyntax
BroadcastgameEvents.emit(name, payload) / useGameEvent(name, handler, deps)
Cross-node handleprefab.getHandle<T>(nodeId, kind)
Current-node handleuseNodeHandle<T>(kind).current
Node pointer streamonPointerEvent={(type, event, node) => ...}
Named clickMesh.properties.emitClickEvent + clickEventName

Nested prefabs and cameras

{
  "id": "room-instance",
  "components": {
    "prefab": {
      "type": "PrefabRef",
      "properties": { "url": "/prefabs/room.json" }
    }
  }
}

Each nested prefab keeps local node ids and materials while sharing the outer scene mode. Camera nodes become the default camera in Play mode and render as wireframes in Edit mode.

Built-ins

CategoryComponents
CoreTransform, Mesh, Geometry, BufferGeometry, Material
AssetsModel, Sprite, Text, Sound, PrefabRef
SceneCamera, Environment, AmbientLight, DirectionalLight, PointLight, SpotLight
DataData

Focused references

TaskReference
Runtime managers, handles, eventsrules/RUNTIME_INTEGRATIONS.md
Crashcat physicsrules/ADVANCED_PHYSICS.md
Authored lighting and shadowsrules/LIGHTING.md
Frame loops, instancing, streamingrules/PERFORMANCE.md

Validate consuming projects with a production build and exercise component behavior in Edit and Play modes.

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/prnthh/react-three-game-skill/react-three-game">View react-three-game on skillZs</a>