react-three-game 0.0.1 → 0.0.2
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/.gitattributes +2 -0
- package/.github/copilot-instructions.md +207 -0
- package/LICENSE +661 -0
- package/README.md +664 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/shared/GameCanvas.d.ts +6 -0
- package/dist/shared/GameCanvas.js +48 -0
- package/dist/shared/extend-three.d.ts +1 -0
- package/dist/shared/extend-three.js +13 -0
- package/dist/tools/assetviewer/page.d.ts +21 -0
- package/dist/tools/assetviewer/page.js +153 -0
- package/dist/tools/dragdrop/DragDropLoader.d.ts +9 -0
- package/dist/tools/dragdrop/DragDropLoader.js +78 -0
- package/dist/tools/dragdrop/modelLoader.d.ts +7 -0
- package/dist/tools/dragdrop/modelLoader.js +53 -0
- package/dist/tools/dragdrop/page.d.ts +1 -0
- package/dist/tools/dragdrop/page.js +11 -0
- package/dist/tools/prefabeditor/EditorTree.d.ts +10 -0
- package/dist/tools/prefabeditor/EditorTree.js +182 -0
- package/dist/tools/prefabeditor/EditorUI.d.ts +11 -0
- package/dist/tools/prefabeditor/EditorUI.js +96 -0
- package/dist/tools/prefabeditor/EventSystem.d.ts +7 -0
- package/dist/tools/prefabeditor/EventSystem.js +23 -0
- package/dist/tools/prefabeditor/InstanceProvider.d.ts +30 -0
- package/dist/tools/prefabeditor/InstanceProvider.js +172 -0
- package/dist/tools/prefabeditor/PrefabEditor.d.ts +4 -0
- package/dist/tools/prefabeditor/PrefabEditor.js +89 -0
- package/dist/tools/prefabeditor/PrefabRoot.d.ts +12 -0
- package/dist/tools/prefabeditor/PrefabRoot.js +273 -0
- package/dist/tools/prefabeditor/components/ComponentRegistry.d.ts +13 -0
- package/dist/tools/prefabeditor/components/ComponentRegistry.js +13 -0
- package/dist/tools/prefabeditor/components/GeometryComponent.d.ts +3 -0
- package/dist/tools/prefabeditor/components/GeometryComponent.js +28 -0
- package/dist/tools/prefabeditor/components/MaterialComponent.d.ts +3 -0
- package/dist/tools/prefabeditor/components/MaterialComponent.js +66 -0
- package/dist/tools/prefabeditor/components/ModelComponent.d.ts +3 -0
- package/dist/tools/prefabeditor/components/ModelComponent.js +39 -0
- package/dist/tools/prefabeditor/components/PhysicsComponent.d.ts +3 -0
- package/dist/tools/prefabeditor/components/PhysicsComponent.js +19 -0
- package/dist/tools/prefabeditor/components/SpotLightComponent.d.ts +3 -0
- package/dist/tools/prefabeditor/components/SpotLightComponent.js +19 -0
- package/dist/tools/prefabeditor/components/TransformComponent.d.ts +8 -0
- package/dist/tools/prefabeditor/components/TransformComponent.js +22 -0
- package/dist/tools/prefabeditor/components/index.d.ts +2 -0
- package/dist/tools/prefabeditor/components/index.js +14 -0
- package/dist/tools/prefabeditor/page.d.ts +1 -0
- package/dist/tools/prefabeditor/page.js +5 -0
- package/dist/tools/prefabeditor/types.d.ts +29 -0
- package/dist/tools/prefabeditor/types.js +1 -0
- package/package.json +16 -4
- package/tsconfig.json +2 -1
- package/dist/GameCanvas.d.ts +0 -6
- package/dist/GameCanvas.js +0 -5
package/.gitattributes
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# react-three-game - AI Coding Agent Instructions
|
|
2
|
+
|
|
3
|
+
## Project Mission
|
|
4
|
+
The **first 3D game engine designed for AI-native development**. Everything is JSON-serializable prefabs that AI agents can generate, modify, and compose without writing imperative code. Think Unity's component system meets React's declarative paradigm.
|
|
5
|
+
|
|
6
|
+
## Why This Exists (Critical Context)
|
|
7
|
+
Traditional 3D engines (Unity, Unreal, Three.js) require imperative code that's hard for AI to generate reliably. We solve this by making **everything pure data structures**:
|
|
8
|
+
- ✅ Entire scenes are JSON objects
|
|
9
|
+
- ✅ Components are registered modules with Editor + View separation
|
|
10
|
+
- ✅ Visual prefab editor exports versionable JSON
|
|
11
|
+
- ✅ No manual scene graph manipulation required
|
|
12
|
+
|
|
13
|
+
## Architecture
|
|
14
|
+
|
|
15
|
+
### Dual-Structure Monorepo
|
|
16
|
+
- **`/src`**: Library source (TypeScript) → builds to `/dist` → published as `react-three-game` npm package
|
|
17
|
+
- **`/docs`**: Next.js 16 documentation site that imports library via `"react-three-game": "file:.."` in package.json
|
|
18
|
+
- Development command: `npm run dev` (runs `tsc --watch` + Next.js dev server concurrently via `concurrently`)
|
|
19
|
+
- **Hot reload works**: Changes to `/src` trigger rebuild → docs site sees updates
|
|
20
|
+
|
|
21
|
+
### Component-Based Prefab System
|
|
22
|
+
The core innovation is a **GameObject + Component** architecture similar to Unity/Unreal:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// Prefab JSON structure (see src/tools/prefabeditor/samples/*.json)
|
|
26
|
+
{
|
|
27
|
+
"id": "prefab-1",
|
|
28
|
+
"root": {
|
|
29
|
+
"id": "root",
|
|
30
|
+
"enabled": true,
|
|
31
|
+
"visible": true,
|
|
32
|
+
"components": {
|
|
33
|
+
"transform": { type: "Transform", properties: { position: [0,0,0], rotation: [0,0,0], scale: [1,1,1] } },
|
|
34
|
+
"geometry": { type: "Geometry", properties: { geometryType: "box", args: [1,1,1] } },
|
|
35
|
+
"material": { type: "Material", properties: { color: "#ffffff" } },
|
|
36
|
+
"physics": { type: "Physics", properties: { type: "dynamic" } }
|
|
37
|
+
},
|
|
38
|
+
"children": [ /* recursive GameObject[] */ ]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**AI agents can generate this entire structure from natural language prompts.**
|
|
44
|
+
|
|
45
|
+
### Component Registry Pattern (`src/tools/prefabeditor/components/`)
|
|
46
|
+
Every component implements:
|
|
47
|
+
```typescript
|
|
48
|
+
interface Component {
|
|
49
|
+
name: string;
|
|
50
|
+
Editor: FC<{ component: any; onUpdate: (newComp: any) => void }>; // Inspector UI
|
|
51
|
+
View?: FC<any>; // Three.js runtime renderer
|
|
52
|
+
defaultProperties: any;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Register in `components/index.ts` to make available in editor. Examples:
|
|
57
|
+
- **TransformComponent**: Position/rotation/scale (no View - handled by group wrapper)
|
|
58
|
+
- **PhysicsComponent**: Wraps children in `<RigidBody>` from @react-three/rapier (only in play mode)
|
|
59
|
+
- **MaterialComponent**: Renders as `<meshStandardNodeMaterial>` with texture support
|
|
60
|
+
- **ModelComponent**: Loads GLB/FBX via `modelLoader.ts`, supports instancing
|
|
61
|
+
|
|
62
|
+
### World Matrix Math (CRITICAL)
|
|
63
|
+
`PrefabRoot.tsx` maintains **parent-relative transforms** but uses **world matrices** for TransformControls:
|
|
64
|
+
- Each `GameObjectRenderer` computes `worldMatrix = parentMatrix * localMatrix`
|
|
65
|
+
- On transform drag: extract world matrix → compute parent inverse → derive new local transform
|
|
66
|
+
- Helper: `computeParentWorldMatrix(root, targetId)` traverses tree to get parent's world matrix
|
|
67
|
+
- **Never directly set world transforms in prefab JSON** - always store local transforms
|
|
68
|
+
|
|
69
|
+
### Instancing System (`InstanceProvider.tsx`)
|
|
70
|
+
Optimizes rendering of repeated models:
|
|
71
|
+
1. `GameInstanceProvider` flattens all model meshes into `flatMeshes` map
|
|
72
|
+
2. `GameInstance` component registers instance data (position/rotation/scale)
|
|
73
|
+
3. Provider renders once per unique mesh using `<Merged>` from drei + `<InstancedRigidBodies>`
|
|
74
|
+
4. Toggled by `model.properties.instanced = true` in prefab JSON
|
|
75
|
+
5. Physics instances use world-space transforms (not local)
|
|
76
|
+
|
|
77
|
+
## Key Files & Patterns
|
|
78
|
+
|
|
79
|
+
### `src/index.ts` - Library Exports
|
|
80
|
+
Main entry point for published package. When adding new features, export them here:
|
|
81
|
+
```typescript
|
|
82
|
+
export { default as GameCanvas } from './shared/GameCanvas';
|
|
83
|
+
export { default as PrefabEditor } from './tools/prefabeditor/PrefabEditor';
|
|
84
|
+
export { default as PrefabRoot } from './tools/prefabeditor/PrefabRoot';
|
|
85
|
+
export { DragDropLoader } from './tools/dragdrop/DragDropLoader';
|
|
86
|
+
// Add new exports as features are developed
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### `PrefabEditor.tsx` - Main Editor Wrapper
|
|
90
|
+
- Manages edit/play mode toggle (pauses Rapier physics in edit mode)
|
|
91
|
+
- Handles JSON import/export via file input
|
|
92
|
+
- Renders `<EditorUI>` (inspector + tree) and `<PrefabRoot>` (scene renderer)
|
|
93
|
+
|
|
94
|
+
### `PrefabRoot.tsx` - Recursive Scene Renderer
|
|
95
|
+
Three rendering paths:
|
|
96
|
+
1. **Instanced nodes**: Short-circuit to `<GameInstance>` (world-space, terminal node)
|
|
97
|
+
2. **Model nodes**: Render as `<primitive object={clonedModel}>` with material override
|
|
98
|
+
3. **Geometry nodes**: Render as `<mesh>` with geometry + material components
|
|
99
|
+
- Always wrap in physics if component exists (except edit mode)
|
|
100
|
+
- Children always use relative transforms in `<group>`
|
|
101
|
+
|
|
102
|
+
### `EditorUI.tsx` + `EditorTree.tsx`
|
|
103
|
+
- Tree view: Drag-to-reorder via pointer events (updates parent's children array)
|
|
104
|
+
- Inspector: Dynamically renders component editors from registry
|
|
105
|
+
- Transform modes: T/R/S keyboard shortcuts handled in PrefabEditor
|
|
106
|
+
|
|
107
|
+
### `GameCanvas.tsx` - WebGPU Renderer Wrapper
|
|
108
|
+
Uses Three.js WebGPU renderer (not WebGL):
|
|
109
|
+
```tsx
|
|
110
|
+
<Canvas gl={async ({ canvas }) => {
|
|
111
|
+
const renderer = new WebGPURenderer({ canvas, shadowMap: true });
|
|
112
|
+
await renderer.init(); // MUST await initialization
|
|
113
|
+
return renderer;
|
|
114
|
+
}}>
|
|
115
|
+
```
|
|
116
|
+
**Material nodes**: Use `MeshStandardNodeMaterial` not `MeshStandardMaterial` (extends for node materials)
|
|
117
|
+
|
|
118
|
+
## Development Workflows
|
|
119
|
+
|
|
120
|
+
### Adding New Components
|
|
121
|
+
1. Create `src/tools/prefabeditor/components/MyComponent.tsx`:
|
|
122
|
+
```typescript
|
|
123
|
+
const MyComponent: Component = {
|
|
124
|
+
name: 'MyComponent',
|
|
125
|
+
Editor: ({ component, onUpdate }) => { /* Inspector UI */ },
|
|
126
|
+
View: ({ properties, children }) => { /* Three.js render */ },
|
|
127
|
+
defaultProperties: { /* defaults */ }
|
|
128
|
+
};
|
|
129
|
+
export default MyComponent;
|
|
130
|
+
```
|
|
131
|
+
2. Export in `components/index.ts`
|
|
132
|
+
3. Auto-registers via `components.forEach(registerComponent)` in PrefabRoot
|
|
133
|
+
|
|
134
|
+
### Testing in Docs Site
|
|
135
|
+
1. Export new component from `src/index.ts`
|
|
136
|
+
2. Run `npm run dev` (rebuilds library on save)
|
|
137
|
+
3. Use in `docs/app/demo/page.tsx` or create new demo page
|
|
138
|
+
|
|
139
|
+
### Model Loading
|
|
140
|
+
- Supports GLB/GLTF (with Draco compression) and FBX
|
|
141
|
+
- Models auto-load when `model.properties.filename` detected in prefab tree
|
|
142
|
+
- Uses singleton loaders (don't recreate GLTFLoader instances)
|
|
143
|
+
- Draco decoder from CDN: `https://www.gstatic.com/draco/v1/decoders/`
|
|
144
|
+
|
|
145
|
+
## Common Patterns
|
|
146
|
+
|
|
147
|
+
### Update Prefab Node
|
|
148
|
+
```typescript
|
|
149
|
+
function updatePrefabNode(root: GameObject, id: string, update: (node: GameObject) => GameObject): GameObject {
|
|
150
|
+
if (root.id === id) return update(root);
|
|
151
|
+
if (root.children) {
|
|
152
|
+
return { ...root, children: root.children.map(child => updatePrefabNode(child, id, update)) };
|
|
153
|
+
}
|
|
154
|
+
return root;
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Three Object References
|
|
159
|
+
- `objectRefs.current[gameObjectId]` stores Three.Object3D for each node
|
|
160
|
+
- `registerRef(id, obj)` callback passed down hierarchy
|
|
161
|
+
- Used by TransformControls to manipulate objects directly
|
|
162
|
+
|
|
163
|
+
### Edit vs Play Mode
|
|
164
|
+
- Edit mode: `<MapControls>`, `<TransformControls>`, physics paused
|
|
165
|
+
- Play mode: Physics active, no editor UI
|
|
166
|
+
- Components check `editMode` prop to conditionally wrap (e.g., PhysicsComponent only wraps in play)
|
|
167
|
+
|
|
168
|
+
## Publishing
|
|
169
|
+
```bash
|
|
170
|
+
npm run build # tsc → dist/
|
|
171
|
+
npm publish --access public
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Conventions
|
|
175
|
+
- **IDs**: Use UUIDs for GameObjects (important for tree operations)
|
|
176
|
+
- **Transforms**: Always `[x, y, z]` number arrays, rotations in radians
|
|
177
|
+
- **Colors**: Accept CSS strings (hex codes or named colors) → convert to THREE.Color
|
|
178
|
+
- **Texture paths**: Relative to public root (e.g., `/textures/grid.png`)
|
|
179
|
+
- **Component keys**: Lowercase in prefab JSON (`"transform"`, `"physics"`) but TitleCase for registry (`"Transform"`, `"Physics"`)
|
|
180
|
+
|
|
181
|
+
## Tech Stack
|
|
182
|
+
- **React 19** + **TypeScript 5**
|
|
183
|
+
- **@react-three/fiber** (React renderer for Three.js)
|
|
184
|
+
- **@react-three/drei** (helpers: MapControls, TransformControls, Merged)
|
|
185
|
+
- **@react-three/rapier** (physics via Rapier WASM)
|
|
186
|
+
- **Three.js WebGPU** (cutting edge renderer, not WebGL)
|
|
187
|
+
- **Next.js 16** (docs site only)
|
|
188
|
+
- **Tailwind 4** (docs site styling)
|
|
189
|
+
|
|
190
|
+
## Design Principles
|
|
191
|
+
1. **AI-first**: Prefabs are JSON → LLMs can generate complete scenes
|
|
192
|
+
2. **Zero boilerplate**: No manual Three.js object creation in user code
|
|
193
|
+
3. **Component composition**: Mix physics + rendering + behavior via declarative components
|
|
194
|
+
4. **Visual editing**: Prefab editor generates JSON that can be version controlled
|
|
195
|
+
5. **Instancing by default**: Optimize repeated geometry automatically
|
|
196
|
+
|
|
197
|
+
## Coming Soon (Migration in Progress)
|
|
198
|
+
These features exist in another repo and are being migrated:
|
|
199
|
+
- **Input system**: Keyboard, gamepad, and touchscreen controls
|
|
200
|
+
- **Multiplayer primitives**: WebRTC-based state synchronization (Trystero)
|
|
201
|
+
- **Controller patterns**: First-person and third-person camera controllers
|
|
202
|
+
- **Touch UI**: Virtual joystick and button components for mobile
|
|
203
|
+
|
|
204
|
+
When implementing these, maintain the same philosophy:
|
|
205
|
+
- Controllers should work with prefab-based scenes
|
|
206
|
+
- Input should be declarative (hook-based, not imperative event listeners)
|
|
207
|
+
- Multiplayer state sync should serialize naturally with JSON prefabs
|