react-three-game 0.0.60 → 0.0.61

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.
Files changed (58) hide show
  1. package/package.json +9 -3
  2. package/.gitattributes +0 -2
  3. package/.github/copilot-instructions.md +0 -83
  4. package/.github/workflows/nextjs.yml +0 -99
  5. package/.gitmodules +0 -3
  6. package/assets/architecture.png +0 -0
  7. package/assets/editor.gif +0 -0
  8. package/assets/favicon.ico +0 -0
  9. package/assets/react-three-game-logo.png +0 -0
  10. package/dist/tools/dragdrop/page.d.ts +0 -1
  11. package/dist/tools/dragdrop/page.js +0 -11
  12. package/dist/tools/prefabeditor/EntityEvents.d.ts +0 -54
  13. package/dist/tools/prefabeditor/EntityEvents.js +0 -85
  14. package/dist/tools/prefabeditor/page.d.ts +0 -1
  15. package/dist/tools/prefabeditor/page.js +0 -5
  16. package/react-three-game-skill/.gitattributes +0 -2
  17. package/react-three-game-skill/README.md +0 -7
  18. package/react-three-game-skill/react-three-game/SKILL.md +0 -514
  19. package/react-three-game-skill/react-three-game/rules/ADVANCED_PHYSICS.md +0 -472
  20. package/react-three-game-skill/react-three-game/rules/LIGHTING.md +0 -6
  21. package/src/helpers/SoundManager.ts +0 -130
  22. package/src/helpers/index.ts +0 -91
  23. package/src/index.ts +0 -59
  24. package/src/shared/ContactShadow.tsx +0 -74
  25. package/src/shared/GameCanvas.tsx +0 -52
  26. package/src/tools/assetviewer/page.tsx +0 -425
  27. package/src/tools/dragdrop/DragDropLoader.tsx +0 -159
  28. package/src/tools/dragdrop/index.ts +0 -4
  29. package/src/tools/dragdrop/modelLoader.ts +0 -204
  30. package/src/tools/dragdrop/page.tsx +0 -45
  31. package/src/tools/prefabeditor/Dropdown.tsx +0 -112
  32. package/src/tools/prefabeditor/EditorContext.tsx +0 -25
  33. package/src/tools/prefabeditor/EditorTree.tsx +0 -452
  34. package/src/tools/prefabeditor/EditorTreeMenus.tsx +0 -307
  35. package/src/tools/prefabeditor/EditorUI.tsx +0 -204
  36. package/src/tools/prefabeditor/EventSystem.tsx +0 -36
  37. package/src/tools/prefabeditor/GameEvents.ts +0 -191
  38. package/src/tools/prefabeditor/InstanceProvider.tsx +0 -466
  39. package/src/tools/prefabeditor/PrefabEditor.tsx +0 -256
  40. package/src/tools/prefabeditor/PrefabRoot.tsx +0 -767
  41. package/src/tools/prefabeditor/components/AmbientLightComponent.tsx +0 -34
  42. package/src/tools/prefabeditor/components/CameraComponent.tsx +0 -117
  43. package/src/tools/prefabeditor/components/ComponentRegistry.ts +0 -40
  44. package/src/tools/prefabeditor/components/DirectionalLightComponent.tsx +0 -210
  45. package/src/tools/prefabeditor/components/EnvironmentComponent.tsx +0 -47
  46. package/src/tools/prefabeditor/components/GeometryComponent.tsx +0 -133
  47. package/src/tools/prefabeditor/components/Input.tsx +0 -820
  48. package/src/tools/prefabeditor/components/MaterialComponent.tsx +0 -431
  49. package/src/tools/prefabeditor/components/ModelComponent.tsx +0 -176
  50. package/src/tools/prefabeditor/components/PhysicsComponent.tsx +0 -188
  51. package/src/tools/prefabeditor/components/SpotLightComponent.tsx +0 -109
  52. package/src/tools/prefabeditor/components/TextComponent.tsx +0 -137
  53. package/src/tools/prefabeditor/components/TransformComponent.tsx +0 -173
  54. package/src/tools/prefabeditor/components/index.ts +0 -26
  55. package/src/tools/prefabeditor/page.tsx +0 -10
  56. package/src/tools/prefabeditor/styles.ts +0 -235
  57. package/src/tools/prefabeditor/types.ts +0 -20
  58. package/src/tools/prefabeditor/utils.ts +0 -312
package/package.json CHANGED
@@ -1,14 +1,20 @@
1
1
  {
2
2
  "name": "react-three-game",
3
- "version": "0.0.60",
3
+ "version": "0.0.61",
4
4
  "description": "high performance 3D game engine for React",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "README.md",
11
+ "LICENSE"
12
+ ],
8
13
  "scripts": {
9
- "watch": "tsc --watch",
14
+ "clean": "rm -rf dist",
15
+ "watch": "npm run clean && tsc --watch",
10
16
  "dev": "concurrently \"npm run watch\" \"cd docs && npm run dev\"",
11
- "build": "tsc",
17
+ "build": "npm run clean && tsc",
12
18
  "release": "npm run build && npm publish --access public"
13
19
  },
14
20
  "keywords": [],
package/.gitattributes DELETED
@@ -1,2 +0,0 @@
1
- # Auto detect text files and perform LF normalization
2
- * text=auto
@@ -1,83 +0,0 @@
1
- # react-three-game - AI Coding Agent Instructions
2
-
3
- ## Project Overview
4
- AI-native 3D game engine where **scenes are JSON prefabs**. Unity-like GameObject+Component architecture built on React Three Fiber + WebGPU.
5
-
6
- ## Monorepo Structure
7
- - **`/src`** → Library source, builds to `/dist`, published as `react-three-game`
8
- - **`/docs`** → Next.js 16 site, imports library via `"react-three-game": "file:.."`
9
- - **`npm run dev`** → Runs `tsc --watch` + Next.js concurrently (hot reload works)
10
-
11
- ## Prefab JSON Schema
12
- ```typescript
13
- // See docs/app/samples/*.json for examples
14
- interface Prefab { id?: string; name?: string; root: GameObject; }
15
- interface GameObject {
16
- id: string; // Use crypto.randomUUID() for new nodes
17
- disabled?: boolean;
18
- components?: Record<string, { type: string; properties: any }>;
19
- children?: GameObject[];
20
- }
21
- ```
22
- **Transforms are LOCAL** (parent-relative). Rotations in radians. Colors as CSS strings.
23
-
24
- ## Component System (`src/tools/prefabeditor/components/`)
25
- Every component has `Editor` (inspector UI) + optional `View` (Three.js render):
26
- ```typescript
27
- const MyComponent: Component = {
28
- name: 'MyComponent', // TitleCase for registry, lowercase key in JSON
29
- Editor: ({ component, onUpdate }) => <input onChange={e => onUpdate({ value: e.target.value })} />,
30
- View: ({ properties, children }) => <group>{children}</group>, // Wrapper components accept children
31
- defaultProperties: { value: 0 }
32
- };
33
- ```
34
- **To add a component:** Create file → export from `components/index.ts` → auto-registered in `PrefabRoot.tsx`.
35
-
36
- ## Key Files
37
- | File | Purpose |
38
- |------|---------|
39
- | `src/index.ts` | All public exports - add new features here |
40
- | `src/tools/prefabeditor/PrefabRoot.tsx` | Pure renderer - renders prefab as Three.js objects for R3F integration |
41
- | `src/tools/prefabeditor/PrefabEditor.tsx` | Managed scene with editor UI and play/pause controls for physics |
42
- | `src/tools/prefabeditor/utils.ts` | Tree helpers: `findNode`, `updateNode`, `deleteNode`, `cloneNode` |
43
- | `src/shared/GameCanvas.tsx` | WebGPU renderer setup (use `MeshStandardNodeMaterial`) |
44
-
45
- ## Usage Modes
46
-
47
- **PrefabRoot**: Pure renderer for embedding prefab data in standard R3F applications. Render it inside a regular `@react-three/fiber` `Canvas`. `GameCanvas` provides the WebGPU canvas setup. Add a `Physics` wrapper to enable physics. Use this to integrate prefabs into larger R3F scenes.
48
-
49
- **PrefabEditor**: Managed scene with editor UI and play/pause controls for physics. Full authoring tool for level design and prototyping. Includes canvas, physics, transform gizmos, and inspector. Physics only runs in play mode. Can pass R3F components as children.
50
-
51
- ## Critical Patterns
52
-
53
- ### Tree Manipulation (Immutable)
54
- ```typescript
55
- import { updateNode, findNode, deleteNode } from 'react-three-game';
56
- const newRoot = updateNode(root, nodeId, node => ({ ...node, components: { ...node.components, physics: {...} } }));
57
- ```
58
-
59
- ### WebGPU Materials
60
- Use node materials only: `MeshStandardNodeMaterial`, `MeshBasicNodeMaterial` (not `MeshStandardMaterial`).
61
-
62
- ### Physics Wrapping
63
- `PhysicsComponent.View` wraps children in `<RigidBody>` only when `editMode=false`. Edit mode pauses physics.
64
-
65
- ### Model Instancing
66
- Set `model.properties.instanced = true` → uses `InstanceProvider.tsx` for batched rendering with physics.
67
-
68
- ## Built-in Components
69
- `Transform`, `Geometry` (box/sphere/plane/cylinder), `Material` (color/texture), `Physics` (dynamic/fixed), `Model` (GLB/FBX), `SpotLight`, `DirectionalLight`, `AmbientLight`, `Text`
70
-
71
- ## Custom Components (User-space)
72
- See `docs/app/demo/editor/RotatorComponent.tsx` for runtime behavior example using `useFrame`. Register with `registerComponent()` before rendering `<PrefabEditor>`.
73
-
74
- ## Development Workflow
75
- 1. **Edit library**: Modify `/src`, auto-rebuilds via `tsc --watch`
76
- 2. **Test in docs**: Changes reflect at `http://localhost:3000`
77
- 3. **Add sample prefabs**: `docs/app/samples/*.json`
78
- 4. **Release**: `npm run release` (builds + publishes)
79
-
80
- ## Conventions
81
- - Component keys: lowercase in JSON (`"transform"`), TitleCase in registry (`"Transform"`)
82
- - Asset paths: Relative to `/public` (e.g., `models/cars/taxi/model.glb`)
83
- - All Three.js renders must be inside `<GameCanvas>` (WebGPU init required)
@@ -1,99 +0,0 @@
1
- # Sample workflow for building and deploying a Next.js site to GitHub Pages
2
- #
3
- # To get started with Next.js see: https://nextjs.org/docs/getting-started
4
- #
5
- name: Deploy Next.js site to Pages
6
-
7
- on:
8
- # Runs on pushes targeting the default branch
9
- push:
10
- branches: ["main"]
11
-
12
- # Allows you to run this workflow manually from the Actions tab
13
- workflow_dispatch:
14
-
15
- # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
16
- permissions:
17
- contents: read
18
- pages: write
19
- id-token: write
20
-
21
- # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
22
- # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
23
- concurrency:
24
- group: "pages"
25
- cancel-in-progress: false
26
-
27
- jobs:
28
- # Build job
29
- build:
30
- runs-on: ubuntu-latest
31
- steps:
32
- - name: Checkout
33
- uses: actions/checkout@v4
34
- - name: Detect package manager
35
- id: detect-package-manager
36
- run: |
37
- if [ -f "${{ github.workspace }}/yarn.lock" ]; then
38
- echo "manager=yarn" >> $GITHUB_OUTPUT
39
- echo "command=install" >> $GITHUB_OUTPUT
40
- echo "runner=yarn" >> $GITHUB_OUTPUT
41
- exit 0
42
- elif [ -f "${{ github.workspace }}/package.json" ]; then
43
- echo "manager=npm" >> $GITHUB_OUTPUT
44
- echo "command=install" >> $GITHUB_OUTPUT
45
- echo "runner=npx --no-install" >> $GITHUB_OUTPUT
46
- exit 0
47
- else
48
- echo "Unable to determine package manager"
49
- exit 1
50
- fi
51
- - name: Setup Node
52
- uses: actions/setup-node@v4
53
- with:
54
- node-version: "20"
55
- cache: ${{ steps.detect-package-manager.outputs.manager }}
56
- - name: Setup Pages
57
- uses: actions/configure-pages@v5
58
- with:
59
- # Automatically inject basePath in your Next.js configuration file and disable
60
- # server side image optimization (https://nextjs.org/docs/api-reference/next/image#unoptimized).
61
- #
62
- # You may remove this line if you want to manage the configuration yourself.
63
- static_site_generator: next
64
- - name: Restore cache
65
- uses: actions/cache@v4
66
- with:
67
- path: |
68
- docs/.next/cache
69
- # Generate a new cache whenever packages or source files change.
70
- key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
71
- # If source files changed but packages didn't, rebuild from a prior cache.
72
- restore-keys: |
73
- ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-
74
- - name: Install root dependencies
75
- run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}
76
- - name: Build library
77
- run: npm run build
78
- - name: Install docs dependencies
79
- working-directory: ./docs
80
- run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}
81
- - name: Build Next.js docs
82
- working-directory: ./docs
83
- run: ${{ steps.detect-package-manager.outputs.runner }} next build
84
- - name: Upload artifact
85
- uses: actions/upload-pages-artifact@v3
86
- with:
87
- path: ./docs/out
88
-
89
- # Deployment job
90
- deploy:
91
- environment:
92
- name: github-pages
93
- url: ${{ steps.deployment.outputs.page_url }}
94
- runs-on: ubuntu-latest
95
- needs: build
96
- steps:
97
- - name: Deploy to GitHub Pages
98
- id: deployment
99
- uses: actions/deploy-pages@v4
package/.gitmodules DELETED
@@ -1,3 +0,0 @@
1
- [submodule "react-three-game-skill"]
2
- path = react-three-game-skill
3
- url = https://github.com/prnthh/react-three-game-skill
Binary file
package/assets/editor.gif DELETED
Binary file
Binary file
Binary file
@@ -1 +0,0 @@
1
- export default function Home(): import("react/jsx-runtime").JSX.Element;
@@ -1,11 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Physics, RigidBody } from "@react-three/rapier";
4
- import { OrbitControls } from "@react-three/drei";
5
- import { useState } from "react";
6
- import { DragDropLoader } from "./index";
7
- import GameCanvas from "../../shared/GameCanvas";
8
- export default function Home() {
9
- const [models, setModels] = useState([]);
10
- return (_jsx(DragDropLoader, { onModelLoaded: model => setModels(prev => [...prev, model]), className: "w-full items-center justify-items-center min-h-screen", style: { height: "100vh" }, children: _jsx("div", { className: "w-full items-center justify-items-center min-h-screen", style: { height: "100vh" }, children: _jsx(GameCanvas, { children: _jsxs(Physics, { children: [_jsx(RigidBody, { children: _jsxs("mesh", { castShadow: true, children: [_jsx("boxGeometry", { args: [1, 1, 1] }), _jsx("meshStandardMaterial", { color: "orange" })] }) }), _jsx(RigidBody, { type: "fixed", children: _jsxs("mesh", { position: [0, -2, 0], scale: [10, 0.1, 10], receiveShadow: true, children: [_jsx("boxGeometry", {}), _jsx("meshStandardMaterial", { color: "gray" })] }) }), models.map((model, idx) => (_jsx("primitive", { object: model, position: [0, 0, 0] }, idx))), _jsx("ambientLight", { intensity: 0.5 }), _jsx("pointLight", { position: [10, 10, 10], castShadow: true, intensity: 1000 }), _jsx(OrbitControls, {})] }) }) }) }));
11
- }
@@ -1,54 +0,0 @@
1
- import type { RapierRigidBody } from '@react-three/rapier';
2
- export type EntityEventType = 'sensor:enter' | 'sensor:exit' | 'collision:enter' | 'collision:exit';
3
- export interface EntityEventPayload {
4
- sourceEntityId: string;
5
- targetEntityId: string | null;
6
- targetRigidBody: RapierRigidBody | null | undefined;
7
- }
8
- type EventHandler = (payload: EntityEventPayload) => void;
9
- /**
10
- * Entity event system for physics interactions.
11
- *
12
- * Events:
13
- * - sensor:enter - Fired when something enters a sensor collider
14
- * - sensor:exit - Fired when something exits a sensor collider
15
- * - collision:enter - Fired when a collision starts
16
- * - collision:exit - Fired when a collision ends
17
- */
18
- export declare const entityEvents: {
19
- /**
20
- * Emit an event to all subscribers
21
- */
22
- emit(type: EntityEventType, payload: EntityEventPayload): void;
23
- /**
24
- * Subscribe to an event type
25
- * @returns Unsubscribe function
26
- */
27
- on(type: EntityEventType, handler: EventHandler): () => void;
28
- /**
29
- * Unsubscribe from an event type
30
- */
31
- off(type: EntityEventType, handler: EventHandler): void;
32
- /**
33
- * Remove all subscribers (useful for cleanup)
34
- */
35
- clear(): void;
36
- };
37
- /**
38
- * React hook to subscribe to entity events.
39
- * Automatically cleans up on unmount.
40
- *
41
- * @example
42
- * useEntityEvent('sensor:enter', (payload) => {
43
- * if (payload.sourceEntityId === 'trigger-zone') {
44
- * console.log('Player entered trigger zone!');
45
- * }
46
- * });
47
- */
48
- export declare function useEntityEvent(type: EntityEventType, handler: EventHandler, deps?: any[]): void;
49
- /**
50
- * Helper to extract entity ID from Rapier collision data.
51
- * Entity IDs are stored in RigidBody userData.
52
- */
53
- export declare function getEntityIdFromRigidBody(rigidBody: RapierRigidBody | null | undefined): string | null;
54
- export {};
@@ -1,85 +0,0 @@
1
- import { useEffect, useCallback } from 'react';
2
- // Internal subscriber storage
3
- const subscribers = new Map();
4
- /**
5
- * Entity event system for physics interactions.
6
- *
7
- * Events:
8
- * - sensor:enter - Fired when something enters a sensor collider
9
- * - sensor:exit - Fired when something exits a sensor collider
10
- * - collision:enter - Fired when a collision starts
11
- * - collision:exit - Fired when a collision ends
12
- */
13
- export const entityEvents = {
14
- /**
15
- * Emit an event to all subscribers
16
- */
17
- emit(type, payload) {
18
- const handlers = subscribers.get(type);
19
- if (handlers) {
20
- handlers.forEach(handler => {
21
- try {
22
- handler(payload);
23
- }
24
- catch (e) {
25
- console.error(`Error in entityEvents handler for ${type}:`, e);
26
- }
27
- });
28
- }
29
- },
30
- /**
31
- * Subscribe to an event type
32
- * @returns Unsubscribe function
33
- */
34
- on(type, handler) {
35
- if (!subscribers.has(type)) {
36
- subscribers.set(type, new Set());
37
- }
38
- subscribers.get(type).add(handler);
39
- return () => {
40
- var _a;
41
- (_a = subscribers.get(type)) === null || _a === void 0 ? void 0 : _a.delete(handler);
42
- };
43
- },
44
- /**
45
- * Unsubscribe from an event type
46
- */
47
- off(type, handler) {
48
- var _a;
49
- (_a = subscribers.get(type)) === null || _a === void 0 ? void 0 : _a.delete(handler);
50
- },
51
- /**
52
- * Remove all subscribers (useful for cleanup)
53
- */
54
- clear() {
55
- subscribers.clear();
56
- }
57
- };
58
- /**
59
- * React hook to subscribe to entity events.
60
- * Automatically cleans up on unmount.
61
- *
62
- * @example
63
- * useEntityEvent('sensor:enter', (payload) => {
64
- * if (payload.sourceEntityId === 'trigger-zone') {
65
- * console.log('Player entered trigger zone!');
66
- * }
67
- * });
68
- */
69
- export function useEntityEvent(type, handler, deps = []) {
70
- const stableHandler = useCallback(handler, deps);
71
- useEffect(() => {
72
- return entityEvents.on(type, stableHandler);
73
- }, [type, stableHandler]);
74
- }
75
- /**
76
- * Helper to extract entity ID from Rapier collision data.
77
- * Entity IDs are stored in RigidBody userData.
78
- */
79
- export function getEntityIdFromRigidBody(rigidBody) {
80
- var _a;
81
- if (!rigidBody)
82
- return null;
83
- const userData = rigidBody.userData;
84
- return (_a = userData === null || userData === void 0 ? void 0 : userData.entityId) !== null && _a !== void 0 ? _a : null;
85
- }
@@ -1 +0,0 @@
1
- export default function PrefabEditorPage(): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import PrefabEditor from "./PrefabEditor";
3
- export default function PrefabEditorPage() {
4
- return _jsx("div", { style: { width: '100%', height: '100%' }, children: _jsx(PrefabEditor, { children: _jsx("directionalLight", { position: [5, 10, 7.5], intensity: 1, castShadow: true }) }) });
5
- }
@@ -1,2 +0,0 @@
1
- # Auto detect text files and perform LF normalization
2
- * text=auto
@@ -1,7 +0,0 @@
1
- Agent skill for [react-three-game](https://github.com/prnthh/react-three-game)
2
-
3
- Gives your agent the ability to make 3D scenes, physics simulations and games.
4
-
5
- ```
6
- npx skills add https://github.com/prnthh/react-three-game-skill
7
- ```