react-three-game 0.0.46 → 0.0.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/skill/SKILL.md DELETED
@@ -1,491 +0,0 @@
1
- # react-three-game
2
-
3
- A Claude Code skill for working with react-three-game, a JSON-first 3D game engine built on React Three Fiber, WebGPU, and Rapier Physics.
4
-
5
- ## When to Use This Skill
6
-
7
- Use this skill when:
8
- - Creating or modifying 3D game scenes with react-three-game
9
- - Working with prefab JSON structures
10
- - Setting up physics-enabled game objects
11
- - Creating custom components with editor UI (see Editor Mode section)
12
-
13
- ## Core Concepts
14
-
15
- ### GameObject Structure
16
-
17
- Every game object follows this schema:
18
-
19
- ```typescript
20
- interface GameObject {
21
- id: string;
22
- disabled?: boolean;
23
- hidden?: boolean;
24
- components?: Record<string, { type: string; properties: any }>;
25
- children?: GameObject[];
26
- }
27
- ```
28
-
29
- ### Prefab JSON Format
30
-
31
- Scenes are defined as JSON prefabs with a root node containing children:
32
-
33
- ```json
34
- {
35
- "root": {
36
- "id": "scene",
37
- "children": [
38
- {
39
- "id": "my-object",
40
- "components": {
41
- "transform": { "type": "Transform", "properties": { "position": [0, 0, 0] } },
42
- "geometry": { "type": "Geometry", "properties": { "geometryType": "box" } },
43
- "material": { "type": "Material", "properties": { "color": "#ff0000" } }
44
- }
45
- }
46
- ]
47
- }
48
- }
49
- ```
50
-
51
- ## Built-in Components
52
-
53
- | Component | Type | Key Properties |
54
- |-----------|------|----------------|
55
- | Transform | `Transform` | `position: [x,y,z]`, `rotation: [x,y,z]` (radians), `scale: [x,y,z]` |
56
- | Geometry | `Geometry` | `geometryType`: box/sphere/plane/cylinder, `args`: dimension array |
57
- | Material | `Material` | `color`, `texture?`, `metalness?`, `roughness?`, `repeat?`, `repeatCount?` |
58
- | Physics | `Physics` | `type`: "dynamic" or "fixed" |
59
- | Model | `Model` | `filename` (GLB/FBX path), `instanced?` for GPU batching |
60
- | SpotLight | `SpotLight` | `color`, `intensity`, `angle`, `penumbra`, `distance?`, `castShadow?` |
61
- | DirectionalLight | `DirectionalLight` | `color`, `intensity`, `castShadow?`, `targetOffset?: [x,y,z]` |
62
- | Text | `Text` | `text`, `font`, `size`, `depth`, `width`, `align`, `color` |
63
-
64
- ### Geometry Args by Type
65
-
66
- | geometryType | args array |
67
- |--------------|------------|
68
- | `box` | `[width, height, depth]` |
69
- | `sphere` | `[radius, widthSegments, heightSegments]` |
70
- | `plane` | `[width, height]` |
71
- | `cylinder` | `[radiusTop, radiusBottom, height, radialSegments]` |
72
-
73
- ### Material Texture Options
74
-
75
- ```json
76
- {
77
- "type": "Material",
78
- "properties": {
79
- "color": "white",
80
- "texture": "/textures/path/to/texture.png",
81
- "repeat": true,
82
- "repeatCount": [4, 4]
83
- }
84
- }
85
- ```
86
-
87
- - Use `"color": "white"` with textures for accurate texture colors
88
- - `repeatCount: [x, y]` tiles the texture; match to geometry dimensions for proper scaling
89
-
90
- ### Rotation Reference
91
-
92
- Rotations use radians. Common values:
93
- - `1.57` = 90° (π/2)
94
- - `3.14` = 180° (π)
95
- - `-1.57` = -90° (rotate plane flat: `rotation: [-1.57, 0, 0]`)
96
-
97
- ## Common Patterns
98
-
99
- ### Usage Modes
100
-
101
- The library supports two modes:
102
-
103
- **Play Mode** (default) - Immediate rendering without any editor UI. Use `GameCanvas` with `PrefabRoot` for a clean game experience.
104
-
105
- **Editor Mode** - Visual GUI using `PrefabEditor` for scene inspection and custom component development. See the [Editor Mode](#editor-mode) section at the end of this document.
106
-
107
- ### Basic Scene Setup (Play Mode)
108
-
109
- ```jsx
110
- import { Physics } from '@react-three/rapier';
111
- import { GameCanvas, PrefabRoot } from 'react-three-game';
112
-
113
- <GameCanvas>
114
- <Physics>
115
- <PrefabRoot data={prefabData} />
116
- </Physics>
117
- </GameCanvas>
118
- ```
119
-
120
- ### Tree Manipulation Utilities
121
-
122
- ```typescript
123
- import { findNode, updateNode, updateNodeById, deleteNode, cloneNode } from 'react-three-game';
124
-
125
- // Update a node by ID (optimized - avoids unnecessary object creation)
126
- const updated = updateNodeById(root, nodeId, node => ({ ...node, disabled: true }));
127
-
128
- // Find a node
129
- const node = findNode(root, nodeId);
130
-
131
- // Delete a node
132
- const afterDelete = deleteNode(root, nodeId);
133
-
134
- // Clone a node
135
- const cloned = cloneNode(node);
136
- ```
137
-
138
- ## Building Game Levels
139
-
140
- ### Complete Prefab Structure
141
-
142
- ```json
143
- {
144
- "id": "level-id",
145
- "name": "Level Name",
146
- "root": {
147
- "id": "root",
148
- "enabled": true,
149
- "visible": true,
150
- "components": { ... },
151
- "children": [ ... ]
152
- }
153
- }
154
- ```
155
-
156
- ### Floor/Ground Pattern
157
-
158
- ```json
159
- {
160
- "id": "main-floor",
161
- "components": {
162
- "transform": { "type": "Transform", "properties": { "position": [0, -0.5, 0] } },
163
- "geometry": { "type": "Geometry", "properties": { "geometryType": "box", "args": [40, 1, 40] } },
164
- "material": { "type": "Material", "properties": { "color": "white", "texture": "/textures/GreyboxTextures/greybox_dark_grid.png", "repeat": true, "repeatCount": [20, 20] } },
165
- "physics": { "type": "Physics", "properties": { "type": "fixed" } }
166
- }
167
- }
168
- ```
169
-
170
- ### Platform Pattern
171
-
172
- Floating platforms use "fixed" physics and smaller box geometry:
173
-
174
- ```json
175
- {
176
- "id": "platform-1",
177
- "components": {
178
- "transform": { "type": "Transform", "properties": { "position": [-8, 2, -5] } },
179
- "geometry": { "type": "Geometry", "properties": { "geometryType": "box", "args": [6, 0.5, 4] } },
180
- "material": { "type": "Material", "properties": { "color": "white", "texture": "/textures/GreyboxTextures/greybox_teal_grid.png", "repeat": true, "repeatCount": [3, 2] } },
181
- "physics": { "type": "Physics", "properties": { "type": "fixed" } }
182
- }
183
- }
184
- ```
185
-
186
- ### Ramp Pattern
187
-
188
- Rotate on the Z-axis to create inclined surfaces:
189
-
190
- ```json
191
- {
192
- "id": "ramp",
193
- "components": {
194
- "transform": { "type": "Transform", "properties": { "position": [-12, 1, -5], "rotation": [0, 0, 0.3] } },
195
- "geometry": { "type": "Geometry", "properties": { "geometryType": "box", "args": [5, 0.3, 3] } },
196
- "physics": { "type": "Physics", "properties": { "type": "fixed" } }
197
- }
198
- }
199
- ```
200
-
201
- ### Wall Pattern
202
-
203
- Tall thin boxes positioned at boundaries:
204
-
205
- ```json
206
- {
207
- "id": "wall-back",
208
- "components": {
209
- "transform": { "type": "Transform", "properties": { "position": [0, 3, -20] } },
210
- "geometry": { "type": "Geometry", "properties": { "geometryType": "box", "args": [40, 7, 1] } },
211
- "physics": { "type": "Physics", "properties": { "type": "fixed" } }
212
- }
213
- }
214
- ```
215
-
216
- ### Three-Point Lighting Setup
217
-
218
- Good lighting uses main, fill, and accent lights:
219
-
220
- ```json
221
- [
222
- { "id": "main-light", "components": { "transform": { "properties": { "position": [10, 15, 10] } }, "spotlight": { "type": "SpotLight", "properties": { "color": "#ffffff", "intensity": 200, "angle": 0.8, "castShadow": true } } } },
223
- { "id": "fill-light", "components": { "transform": { "properties": { "position": [-10, 12, -5] } }, "spotlight": { "type": "SpotLight", "properties": { "color": "#b0c4de", "intensity": 80, "angle": 0.9 } } } },
224
- { "id": "accent-light", "components": { "transform": { "properties": { "position": [0, 10, -15] } }, "spotlight": { "type": "SpotLight", "properties": { "color": "#ffd700", "intensity": 50, "angle": 0.4 } } } }
225
- ]
226
- ```
227
-
228
- ### Available Greybox Textures
229
-
230
- Located in `/textures/GreyboxTextures/`:
231
- - `greybox_dark_grid.png` - dark floors
232
- - `greybox_light_grid.png` - light surfaces
233
- - `greybox_teal_grid.png`, `greybox_purple_grid.png`, `greybox_orange_grid.png` - colored platforms
234
- - `greybox_red_grid.png`, `greybox_blue_grid.png` - obstacles/hazards
235
- - `greybox_yellow_grid.png`, `greybox_lime_grid.png`, `greybox_green_grid.png` - special areas
236
-
237
- ### Metallic/Special Materials
238
-
239
- For goal platforms or special objects, use metalness and roughness:
240
-
241
- ```json
242
- {
243
- "type": "Material",
244
- "properties": {
245
- "color": "#FFD700",
246
- "metalness": 0.8,
247
- "roughness": 0.2
248
- }
249
- }
250
- ```
251
-
252
- ### Text Component
253
-
254
- 3D text rendering using `three-text`. The Text component is non-composable (cannot have children).
255
-
256
- | Property | Type | Default | Description |
257
- |----------|------|---------|-------------|
258
- | `text` | string | `"Hello World"` | Text content to display |
259
- | `color` | string | `"#888888"` | Text color (hex or CSS color) |
260
- | `font` | string | `"/fonts/NotoSans-Regular.ttf"` | Path to TTF font file |
261
- | `size` | number | `0.5` | Font size in world units |
262
- | `depth` | number | `0` | 3D extrusion depth (0 for flat text) |
263
- | `width` | number | `5` | Text block width for wrapping/alignment |
264
- | `align` | string | `"center"` | Horizontal alignment: `"left"`, `"center"`, `"right"` |
265
-
266
- ```json
267
- {
268
- "id": "title-text",
269
- "components": {
270
- "transform": { "type": "Transform", "properties": { "position": [0, 3, 0] } },
271
- "text": {
272
- "type": "Text",
273
- "properties": {
274
- "text": "Welcome",
275
- "color": "#ffffff",
276
- "size": 1,
277
- "depth": 0.1,
278
- "align": "center"
279
- }
280
- }
281
- }
282
- }
283
- ```
284
-
285
- ### Model Placement
286
-
287
- GLB models don't need geometry/material components:
288
-
289
- ```json
290
- {
291
- "id": "tree-1",
292
- "components": {
293
- "transform": { "type": "Transform", "properties": { "position": [-12, 0, 10], "scale": [1.5, 1.5, 1.5] } },
294
- "model": { "type": "Model", "properties": { "filename": "models/environment/tree.glb" } }
295
- }
296
- }
297
- ```
298
-
299
- Available models: `models/environment/tree.glb`, `models/environment/servers.glb`, `models/environment/cubeart.glb`
300
-
301
- ## Editor Mode
302
-
303
- Use editor mode when building scenes visually or creating custom components with inspector UI.
304
-
305
- ### Using the Visual Editor
306
-
307
- ```jsx
308
- import { PrefabEditor } from 'react-three-game';
309
-
310
- <PrefabEditor
311
- initialPrefab={sceneData}
312
- onPrefabChange={setSceneData}
313
- />
314
- ```
315
-
316
- The editor provides a full GUI with:
317
- - Scene hierarchy tree for navigating and selecting objects
318
- - Component inspector panel for editing properties
319
- - Transform gizmos for manipulating objects visually
320
- - Keyboard shortcuts: **T** (Translate), **R** (Rotate), **S** (Scale)
321
-
322
- ### Programmatic Updates with PrefabEditor
323
-
324
- Use the editor ref to update prefabs programmatically:
325
-
326
- ```jsx
327
- import { useRef } from 'react';
328
- import { PrefabEditor, updateNodeById } from 'react-three-game';
329
- import type { PrefabEditorRef, Prefab } from 'react-three-game';
330
-
331
- function Game() {
332
- const editorRef = useRef<PrefabEditorRef>(null);
333
-
334
- const movePlayer = () => {
335
- if (!editorRef.current) return;
336
- const prefab = editorRef.current.prefab;
337
- const newRoot = updateNodeById(prefab.root, "player", node => ({
338
- ...node,
339
- components: {
340
- ...node.components,
341
- transform: {
342
- ...node.components!.transform!,
343
- properties: { ...node.components!.transform!.properties, position: [5, 0, 0] }
344
- }
345
- }
346
- }));
347
- editorRef.current.setPrefab({ ...prefab, root: newRoot });
348
- };
349
-
350
- return (
351
- <PrefabEditor ref={editorRef} initialPrefab={sceneData}>
352
- {/* Children render inside the Canvas - can use useFrame here */}
353
- </PrefabEditor>
354
- );
355
- }
356
- ```
357
-
358
- The `PrefabEditorRef` provides:
359
- - `prefab` - current prefab state
360
- - `setPrefab(prefab)` - update the prefab
361
- - `screenshot()` - save canvas as PNG
362
- - `exportGLB()` - export scene as GLB
363
-
364
- ### Live Node Updates with useFrame
365
-
366
- To animate objects by updating the prefab JSON at runtime, pass a child component to `PrefabEditor` that uses `useFrame`:
367
-
368
- ```tsx
369
- import { useRef } from "react";
370
- import { useFrame } from "@react-three/fiber";
371
- import { PrefabEditor, updateNodeById } from "react-three-game";
372
- import type { Prefab, PrefabEditorRef } from "react-three-game";
373
-
374
- // Animation component runs inside the editor's Canvas
375
- function PlayerAnimator({ editorRef }: { editorRef: React.RefObject<PrefabEditorRef | null> }) {
376
- const velocityRef = useRef({ x: 0, z: 0 });
377
-
378
- useFrame(() => {
379
- if (!editorRef.current) return;
380
-
381
- const prefab = editorRef.current.prefab;
382
- const newRoot = updateNodeById(prefab.root, "player", (node) => {
383
- const transform = node.components?.transform?.properties;
384
- if (!transform) return node;
385
-
386
- const pos = transform.position as [number, number, number];
387
- return {
388
- ...node,
389
- components: {
390
- ...node.components,
391
- transform: {
392
- ...node.components!.transform!,
393
- properties: {
394
- ...transform,
395
- position: [pos[0] + velocityRef.current.x * 0.02, pos[1], pos[2] + velocityRef.current.z * 0.02],
396
- },
397
- },
398
- },
399
- };
400
- });
401
-
402
- if (newRoot !== prefab.root) {
403
- editorRef.current.setPrefab({ ...prefab, root: newRoot });
404
- }
405
- });
406
-
407
- return null;
408
- }
409
-
410
- // Usage
411
- function Game() {
412
- const editorRef = useRef<PrefabEditorRef>(null);
413
-
414
- return (
415
- <PrefabEditor ref={editorRef} initialPrefab={sceneData}>
416
- <PlayerAnimator editorRef={editorRef} />
417
- </PrefabEditor>
418
- );
419
- }
420
- ```
421
-
422
- Key points:
423
- - Pass animation components as `children` to `PrefabEditor` - they render inside the Canvas
424
- - Access prefab via `editorRef.current.prefab` and update via `editorRef.current.setPrefab()`
425
- - `updateNodeById` is optimized to avoid recreating unchanged branches
426
- - Store mutable state (velocities, timers) in refs to avoid re-renders
427
-
428
- ### Creating a Custom Component
429
-
430
- ```tsx
431
- import { Component, registerComponent, FieldRenderer, FieldDefinition } from 'react-three-game';
432
-
433
- const myFields: FieldDefinition[] = [
434
- { name: 'speed', type: 'number', label: 'Speed', step: 0.1 },
435
- { name: 'enabled', type: 'boolean', label: 'Enabled' },
436
- ];
437
-
438
- const MyComponent: Component = {
439
- name: 'MyComponent',
440
- Editor: ({ component, onUpdate }) => (
441
- <FieldRenderer fields={myFields} values={component.properties} onChange={onUpdate} />
442
- ),
443
- View: ({ properties, children }) => {
444
- // Runtime behavior here
445
- return <group>{children}</group>;
446
- },
447
- defaultProperties: { speed: 1, enabled: true }
448
- };
449
-
450
- registerComponent(MyComponent);
451
- ```
452
-
453
- ### Field Types for Editor UI
454
-
455
- | Type | Description | Options |
456
- |------|-------------|---------|
457
- | `vector3` | X/Y/Z inputs | `snap?: number` |
458
- | `number` | Numeric input | `min?`, `max?`, `step?` |
459
- | `string` | Text input | `placeholder?` |
460
- | `color` | Color picker | - |
461
- | `boolean` | Checkbox | - |
462
- | `select` | Dropdown | `options: { value, label }[]` |
463
- | `custom` | Custom render function | `render: (props) => ReactNode` |
464
-
465
- ## Dependencies
466
-
467
- Required peer dependencies:
468
- - `@react-three/fiber`
469
- - `@react-three/rapier`
470
- - `three`
471
-
472
- Install with:
473
- ```bash
474
- npm i react-three-game @react-three/fiber @react-three/rapier three
475
- ```
476
-
477
- ## File Structure
478
-
479
- ```
480
- /src → library source (published to npm)
481
- /docs → Next.js demo site
482
- /dist → built output
483
- ```
484
-
485
- ## Development Commands
486
-
487
- ```bash
488
- npm run dev # tsc --watch + docs site
489
- npm run build # build to /dist
490
- npm run release # build + publish
491
- ```
@@ -1,17 +0,0 @@
1
- {
2
- "name": "@react-three-game/skills",
3
- "version": "0.0.1",
4
- "description": "Agent skill for working with react-three-game - a JSON-first 3D game engine",
5
- "repository": {
6
- "url": "https://github.com/prnth/react-three-game/tree/main/skill"
7
- },
8
- "keywords": [
9
- "agentic",
10
- "skill",
11
- "react-three-fiber",
12
- "game-engine",
13
- "3d",
14
- "webgpu"
15
- ],
16
- "license": "MIT"
17
- }