@vgai/engine 0.5.21 → 0.5.23
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/README.md +6 -3
- package/dist/adapter/adapter-module.d.ts.map +1 -1
- package/dist/adapter/adapter-module.js +2 -4
- package/dist/adapter/adapter-surface.d.ts +1 -1
- package/dist/adapter/adapter-surface.js +1 -1
- package/dist/adapter/authoring.d.ts +19 -21
- package/dist/adapter/authoring.d.ts.map +1 -1
- package/dist/adapter/authoring.js +2 -2
- package/dist/adapter/binding.d.ts +341 -0
- package/dist/adapter/binding.d.ts.map +1 -0
- package/dist/adapter/binding.js +148 -0
- package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -1
- package/dist/adapter/colyseus-networking-adapter.js +23 -4
- package/dist/adapter/entrypoint-selection-readers.d.ts +24 -0
- package/dist/adapter/entrypoint-selection-readers.d.ts.map +1 -0
- package/dist/adapter/entrypoint-selection-readers.js +63 -0
- package/dist/adapter/entrypoint-selection-source.d.ts.map +1 -1
- package/dist/adapter/entrypoint-selection-source.js +1 -44
- package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts.map +1 -1
- package/dist/adapter/finders/scenes-from-entrypoint-selection.js +1 -52
- package/dist/adapter/host-context.d.ts +46 -15
- package/dist/adapter/host-context.d.ts.map +1 -1
- package/dist/adapter/host-context.js +2 -9
- package/dist/adapter/index.d.ts +11 -12
- package/dist/adapter/index.d.ts.map +1 -1
- package/dist/adapter/index.js +9 -10
- package/dist/adapter/ingest/game-contract.d.ts +0 -3
- package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
- package/dist/adapter/ingest/game-contract.js +0 -3
- package/dist/adapter/ingest/scene-capture.d.ts +19 -23
- package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
- package/dist/adapter/ingest/scene-capture.js +143 -17
- package/dist/adapter/ingest/visible-capture-window.d.ts +34 -0
- package/dist/adapter/ingest/visible-capture-window.d.ts.map +1 -1
- package/dist/adapter/manifest-interpreter.d.ts +59 -0
- package/dist/adapter/manifest-interpreter.d.ts.map +1 -0
- package/dist/adapter/manifest-interpreter.js +50 -0
- package/dist/adapter/native-debug-module.d.ts +71 -3
- package/dist/adapter/native-debug-module.d.ts.map +1 -1
- package/dist/adapter/native-debug-module.js +146 -10
- package/dist/adapter/rapier-physics-adapter.d.ts +31 -1
- package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -1
- package/dist/adapter/rapier-physics-adapter.js +50 -36
- package/dist/adapter/renderer-config.d.ts +3 -3
- package/dist/adapter/renderer-config.js +3 -3
- package/dist/adapter/root-adapter.d.ts +7 -7
- package/dist/adapter/root-adapter.js +4 -4
- package/dist/adapter/system-adapter.d.ts +45 -7
- package/dist/adapter/system-adapter.d.ts.map +1 -1
- package/dist/adapter/system-seam-contract.d.ts +3 -3
- package/dist/adapter/system-seam-contract.js +3 -3
- package/dist/adapter/system-slot.d.ts +168 -0
- package/dist/adapter/system-slot.d.ts.map +1 -0
- package/dist/adapter/system-slot.js +229 -0
- package/dist/adapter/transform.d.ts +11 -1
- package/dist/adapter/transform.d.ts.map +1 -1
- package/dist/ai/navigation.d.ts +17 -1
- package/dist/ai/navigation.d.ts.map +1 -1
- package/dist/ai/navigation.js +26 -5
- package/dist/animation/anim-graph-types.d.ts +11 -3
- package/dist/animation/anim-graph-types.d.ts.map +1 -1
- package/dist/animation/theatre-clock-binding.d.ts +4 -4
- package/dist/animation/theatre-clock-binding.js +4 -4
- package/dist/animation/xstate-animation-binding.d.ts.map +1 -1
- package/dist/animation/xstate-animation-binding.js +2 -2
- package/dist/animation/xstate-animation-meta.d.ts +13 -0
- package/dist/animation/xstate-animation-meta.d.ts.map +1 -1
- package/dist/animation/xstate-animation-meta.js +14 -0
- package/dist/asset-formats/index.d.ts +4 -7
- package/dist/asset-formats/index.d.ts.map +1 -1
- package/dist/asset-formats/index.js +4 -7
- package/dist/asset-formats/render-env.d.ts +5 -8
- package/dist/asset-formats/render-env.d.ts.map +1 -1
- package/dist/asset-formats/render-env.js +3 -6
- package/dist/asset-parse-error.d.ts +2 -5
- package/dist/asset-parse-error.d.ts.map +1 -1
- package/dist/asset-parse-error.js +2 -5
- package/dist/audio/bus-mixer.d.ts +101 -0
- package/dist/audio/bus-mixer.d.ts.map +1 -0
- package/dist/audio/bus-mixer.js +115 -0
- package/dist/canvas-react/index.d.ts +5 -12
- package/dist/canvas-react/index.d.ts.map +1 -1
- package/dist/canvas-react/index.js +5 -12
- package/dist/canvas-react/pixi-react-root-factory.d.ts +34 -21
- package/dist/canvas-react/pixi-react-root-factory.d.ts.map +1 -1
- package/dist/canvas-react/pixi-react-root-factory.js +274 -36
- package/dist/core/countdown-timer.d.ts +118 -0
- package/dist/core/countdown-timer.d.ts.map +1 -0
- package/dist/core/countdown-timer.js +137 -0
- package/dist/core/deferred-commands.d.ts +127 -0
- package/dist/core/deferred-commands.d.ts.map +1 -0
- package/dist/core/deferred-commands.js +132 -0
- package/dist/core/frame-pacing.d.ts +1 -1
- package/dist/core/frame-pacing.js +2 -2
- package/dist/core/game-loop.d.ts +1 -3
- package/dist/core/game-loop.d.ts.map +1 -1
- package/dist/core/game-loop.js +1 -3
- package/dist/core/seeded-random.d.ts +1 -1
- package/dist/core/sim-clock.d.ts +19 -8
- package/dist/core/sim-clock.d.ts.map +1 -1
- package/dist/core/sim-clock.js +18 -7
- package/dist/core/types.d.ts +1 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/defaults.d.ts +6 -14
- package/dist/defaults.d.ts.map +1 -1
- package/dist/defaults.js +6 -14
- package/dist/dev/instruments.d.ts +38 -11
- package/dist/dev/instruments.d.ts.map +1 -1
- package/dist/dev/instruments.js +81 -11
- package/dist/dev/register-render-vitals.d.ts +1 -4
- package/dist/dev/register-render-vitals.d.ts.map +1 -1
- package/dist/dev/register-render-vitals.js +1 -4
- package/dist/dev/render-debug-adapter.d.ts +2 -3
- package/dist/dev/render-debug-adapter.d.ts.map +1 -1
- package/dist/dev/render-debug-adapter.js +2 -3
- package/dist/dev/render-vitals.d.ts +3 -3
- package/dist/dev/render-vitals.js +3 -3
- package/dist/dev/webgl-frame-capture.d.ts +1 -1
- package/dist/dev/webgl-frame-capture.js +1 -1
- package/dist/index.d.ts +2 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/input/host-pointer.d.ts +122 -0
- package/dist/input/host-pointer.d.ts.map +1 -0
- package/dist/input/host-pointer.js +160 -0
- package/dist/input/input-manager.d.ts +33 -5
- package/dist/input/input-manager.d.ts.map +1 -1
- package/dist/input/input-manager.js +48 -13
- package/dist/input/rebind-controller.d.ts.map +1 -1
- package/dist/input/rebind-controller.js +6 -8
- package/dist/input/schema.d.ts.map +1 -1
- package/dist/input/schema.js +56 -28
- package/dist/manifest/filename.d.ts.map +1 -1
- package/dist/manifest/filename.js +8 -12
- package/dist/manifest/load.d.ts +10 -10
- package/dist/manifest/load.d.ts.map +1 -1
- package/dist/manifest/load.js +9 -6
- package/dist/manifest/schema.d.ts +17 -21
- package/dist/manifest/schema.d.ts.map +1 -1
- package/dist/manifest/schema.js +45 -35
- package/dist/physics/collider-dimensions.d.ts +8 -12
- package/dist/physics/collider-dimensions.d.ts.map +1 -1
- package/dist/physics/collider-dimensions.js +8 -12
- package/dist/pixi/scene-capture.d.ts +11 -13
- package/dist/pixi/scene-capture.d.ts.map +1 -1
- package/dist/react/world-state.d.ts +1 -1
- package/dist/react/world-state.d.ts.map +1 -1
- package/dist/render/directional-shadow-fit.d.ts +88 -0
- package/dist/render/directional-shadow-fit.d.ts.map +1 -0
- package/dist/render/directional-shadow-fit.js +133 -0
- package/dist/render/environment-capture.d.ts +68 -0
- package/dist/render/environment-capture.d.ts.map +1 -0
- package/dist/render/environment-capture.js +90 -0
- package/dist/render/ibl-override-material.d.ts +97 -0
- package/dist/render/ibl-override-material.d.ts.map +1 -0
- package/dist/render/ibl-override-material.js +114 -0
- package/dist/render/light-camera-factory.d.ts +5 -7
- package/dist/render/light-camera-factory.d.ts.map +1 -1
- package/dist/render/light-camera-factory.js +8 -11
- package/dist/render/material-factory.js +1 -1
- package/dist/render/render-batch-system.d.ts.map +1 -1
- package/dist/render/render-features.d.ts +17 -6
- package/dist/render/render-features.d.ts.map +1 -1
- package/dist/render/render-features.js +0 -28
- package/dist/runtime/create-runtime.d.ts +34 -25
- package/dist/runtime/create-runtime.d.ts.map +1 -1
- package/dist/runtime/create-runtime.js +218 -93
- package/dist/runtime/debug-registry.d.ts +77 -8
- package/dist/runtime/debug-registry.d.ts.map +1 -1
- package/dist/runtime/debug-registry.js +3 -3
- package/dist/runtime/dev-build.d.ts +2 -2
- package/dist/runtime/dev-build.js +2 -2
- package/dist/runtime/game-input-seams.d.ts +51 -0
- package/dist/runtime/game-input-seams.d.ts.map +1 -0
- package/dist/runtime/game-input-seams.js +86 -0
- package/dist/runtime/game.d.ts +104 -40
- package/dist/runtime/game.d.ts.map +1 -1
- package/dist/runtime/game.js +119 -61
- package/dist/runtime/mount-game.d.ts +0 -16
- package/dist/runtime/mount-game.d.ts.map +1 -1
- package/dist/runtime/mount-game.js +26 -41
- package/dist/runtime/mount-manifest.d.ts +22 -14
- package/dist/runtime/mount-manifest.d.ts.map +1 -1
- package/dist/runtime/mount-manifest.js +22 -20
- package/dist/runtime/playtest.d.ts +22 -0
- package/dist/runtime/playtest.d.ts.map +1 -0
- package/dist/runtime/playtest.js +12 -0
- package/dist/runtime/state-bridge.d.ts +2 -3
- package/dist/runtime/state-bridge.d.ts.map +1 -1
- package/dist/runtime/state-bridge.js +1 -0
- package/dist/setup/setup-audio.d.ts +12 -0
- package/dist/setup/setup-audio.d.ts.map +1 -1
- package/dist/setup/setup-audio.js +9 -10
- package/dist/setup/setup-renderer.d.ts +2 -25
- package/dist/setup/setup-renderer.d.ts.map +1 -1
- package/dist/setup/setup-renderer.js +2 -31
- package/dist/world3d-react/index.d.ts +15 -25
- package/dist/world3d-react/index.d.ts.map +1 -1
- package/dist/world3d-react/index.js +15 -25
- package/dist/world3d-react/r3f-root-factory.d.ts +28 -34
- package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -1
- package/dist/world3d-react/r3f-root-factory.js +403 -57
- package/dist/world3d-react/rapier-physics-bridge.d.ts +30 -17
- package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -1
- package/dist/world3d-react/rapier-physics-bridge.js +143 -58
- package/package.json +1 -1
- package/schemas/engine-capabilities.json +16 -14
- package/schemas/vgai-project.schema.json +35 -26
- package/src/adapter/adapter-module.ts +2 -4
- package/src/adapter/adapter-surface.ts +1 -1
- package/src/adapter/authoring.ts +19 -21
- package/src/adapter/binding.ts +468 -0
- package/src/adapter/colyseus-networking-adapter.ts +20 -5
- package/src/adapter/entrypoint-selection-readers.ts +66 -0
- package/src/adapter/entrypoint-selection-source.ts +1 -40
- package/src/adapter/finders/scenes-from-entrypoint-selection.ts +1 -48
- package/src/adapter/host-context.ts +45 -15
- package/src/adapter/index.ts +23 -11
- package/src/adapter/ingest/game-contract.ts +0 -3
- package/src/adapter/ingest/scene-capture.ts +190 -39
- package/src/adapter/ingest/visible-capture-window.ts +35 -0
- package/src/adapter/manifest-interpreter.ts +64 -0
- package/src/adapter/native-debug-module.ts +248 -15
- package/src/adapter/rapier-physics-adapter.ts +76 -20
- package/src/adapter/renderer-config.ts +3 -3
- package/src/adapter/root-adapter.ts +7 -7
- package/src/adapter/system-adapter.ts +43 -8
- package/src/adapter/system-seam-contract.ts +3 -3
- package/src/adapter/system-slot.ts +291 -0
- package/src/adapter/transform.ts +18 -1
- package/src/ai/navigation.ts +30 -3
- package/src/animation/anim-graph-types.ts +11 -3
- package/src/animation/theatre-clock-binding.ts +4 -4
- package/src/animation/xstate-animation-binding.ts +2 -2
- package/src/animation/xstate-animation-meta.ts +16 -0
- package/src/asset-formats/index.ts +4 -7
- package/src/asset-formats/render-env.ts +3 -6
- package/src/asset-parse-error.ts +2 -5
- package/src/audio/bus-mixer.ts +161 -0
- package/src/canvas-react/index.ts +5 -21
- package/src/canvas-react/pixi-react-root-factory.tsx +301 -39
- package/src/core/countdown-timer.ts +188 -0
- package/src/core/deferred-commands.ts +174 -0
- package/src/core/frame-pacing.ts +2 -2
- package/src/core/game-loop.ts +1 -3
- package/src/core/seeded-random.ts +1 -1
- package/src/core/sim-clock.ts +19 -8
- package/src/core/types.ts +1 -3
- package/src/defaults.ts +6 -14
- package/src/dev/instruments.ts +108 -11
- package/src/dev/register-render-vitals.ts +1 -4
- package/src/dev/render-debug-adapter.ts +2 -3
- package/src/dev/render-vitals.ts +3 -3
- package/src/dev/webgl-frame-capture.ts +1 -1
- package/src/index.ts +2 -5
- package/src/input/host-pointer.ts +230 -0
- package/src/input/input-manager.ts +49 -13
- package/src/input/input-types.ts +1 -1
- package/src/input/rebind-controller.ts +6 -8
- package/src/input/schema.ts +216 -188
- package/src/manifest/filename.ts +8 -12
- package/src/manifest/load.ts +17 -13
- package/src/manifest/schema.ts +55 -47
- package/src/physics/collider-dimensions.ts +8 -12
- package/src/pixi/scene-capture.ts +12 -15
- package/src/react/world-state.tsx +1 -1
- package/src/render/directional-shadow-fit.ts +156 -0
- package/src/render/environment-capture.ts +102 -0
- package/src/render/ibl-override-material.ts +170 -0
- package/src/render/light-camera-factory.ts +8 -11
- package/src/render/material-factory.ts +1 -1
- package/src/render/render-batch-system.ts +14 -6
- package/src/render/render-features.ts +17 -35
- package/src/runtime/create-runtime.ts +270 -108
- package/src/runtime/debug-registry.ts +84 -8
- package/src/runtime/dev-build.ts +2 -2
- package/src/runtime/game-input-seams.ts +108 -0
- package/src/runtime/game.ts +231 -85
- package/src/runtime/mount-game.ts +31 -57
- package/src/runtime/mount-manifest.ts +47 -36
- package/src/runtime/playtest.ts +22 -0
- package/src/runtime/state-bridge.ts +3 -3
- package/src/setup/setup-audio.ts +21 -11
- package/src/setup/setup-renderer.ts +2 -61
- package/src/world3d-react/index.ts +15 -31
- package/src/world3d-react/r3f-root-factory.tsx +451 -60
- package/src/world3d-react/rapier-physics-bridge.tsx +154 -58
- package/dist/adapter/setup-three-root-adapter.d.ts +0 -86
- package/dist/adapter/setup-three-root-adapter.d.ts.map +0 -1
- package/dist/adapter/setup-three-root-adapter.js +0 -908
- package/dist/animation/clip-map.d.ts +0 -12
- package/dist/animation/clip-map.d.ts.map +0 -1
- package/dist/animation/clip-map.js +0 -31
- package/dist/asset-registry.d.ts +0 -38
- package/dist/asset-registry.d.ts.map +0 -1
- package/dist/asset-registry.js +0 -66
- package/dist/canvas-react/engine-bridge.d.ts +0 -45
- package/dist/canvas-react/engine-bridge.d.ts.map +0 -1
- package/dist/canvas-react/engine-bridge.js +0 -45
- package/dist/canvas-react/pixi-react-adapter.d.ts +0 -77
- package/dist/canvas-react/pixi-react-adapter.d.ts.map +0 -1
- package/dist/canvas-react/pixi-react-adapter.js +0 -294
- package/dist/canvas-react/world-context.d.ts +0 -98
- package/dist/canvas-react/world-context.d.ts.map +0 -1
- package/dist/canvas-react/world-context.js +0 -173
- package/dist/dev/debug-draw.d.ts +0 -24
- package/dist/dev/debug-draw.d.ts.map +0 -1
- package/dist/dev/debug-draw.js +0 -73
- package/dist/render/auto-batcher.d.ts +0 -34
- package/dist/render/auto-batcher.d.ts.map +0 -1
- package/dist/render/auto-batcher.js +0 -140
- package/dist/render/lod.d.ts +0 -13
- package/dist/render/lod.d.ts.map +0 -1
- package/dist/render/lod.js +0 -16
- package/dist/runtime/types.d.ts +0 -303
- package/dist/runtime/types.d.ts.map +0 -1
- package/dist/runtime/types.js +0 -1
- package/dist/world3d-react/engine-bridge.d.ts +0 -47
- package/dist/world3d-react/engine-bridge.d.ts.map +0 -1
- package/dist/world3d-react/engine-bridge.js +0 -73
- package/dist/world3d-react/r3f-adapter.d.ts +0 -58
- package/dist/world3d-react/r3f-adapter.d.ts.map +0 -1
- package/dist/world3d-react/r3f-adapter.js +0 -634
- package/dist/world3d-react/world-context.d.ts +0 -182
- package/dist/world3d-react/world-context.d.ts.map +0 -1
- package/dist/world3d-react/world-context.js +0 -235
- package/src/adapter/setup-three-root-adapter.ts +0 -1032
- package/src/animation/clip-map.ts +0 -34
- package/src/asset-registry.ts +0 -89
- package/src/canvas-react/engine-bridge.ts +0 -59
- package/src/canvas-react/pixi-react-adapter.tsx +0 -356
- package/src/canvas-react/world-context.ts +0 -253
- package/src/dev/debug-draw.ts +0 -80
- package/src/render/auto-batcher.ts +0 -168
- package/src/render/lod.ts +0 -17
- package/src/runtime/types.ts +0 -328
- package/src/world3d-react/engine-bridge.ts +0 -86
- package/src/world3d-react/r3f-adapter.tsx +0 -717
- package/src/world3d-react/world-context.ts +0 -358
|
@@ -12,21 +12,25 @@
|
|
|
12
12
|
// callers register, but it registers NONE itself. In particular there is no
|
|
13
13
|
// built-in 'canvas'/'react' registration here (that would require this file
|
|
14
14
|
// to value-import `pixi.js`/`react`/`react-dom`, exactly what `mount-manifest
|
|
15
|
-
// .ts` forbids); a project that has a canvas or react world MUST
|
|
16
|
-
// factory for that kind itself —
|
|
17
|
-
//
|
|
18
|
-
//
|
|
15
|
+
// .ts` forbids); a project that has a three, canvas, or react world MUST
|
|
16
|
+
// register a factory for that kind itself — the factories live with the
|
|
17
|
+
// modules that own their dependencies (`r3fRootFactory` in
|
|
18
|
+
// `@engine/world3d-react`, its Pixi twin in `@engine/canvas-react`), never
|
|
19
|
+
// wired up here automatically.
|
|
19
20
|
|
|
21
|
+
import { declaredRoots } from '../adapter/manifest-interpreter';
|
|
20
22
|
import {
|
|
21
23
|
installNativeDebugBindings,
|
|
24
|
+
installNativeSystemsBindings,
|
|
22
25
|
type NativeDebugBinding,
|
|
26
|
+
type NativeSystemsBinding,
|
|
23
27
|
nativeDebugBindingFromEntryModule,
|
|
28
|
+
nativeSystemsBindingFromEntryModule,
|
|
24
29
|
} from '../adapter/native-debug-module';
|
|
25
|
-
import
|
|
30
|
+
import { publishDevInstruments } from '../dev/instruments';
|
|
26
31
|
import type { ResolvedAdapterRoot } from '../manifest/load';
|
|
27
32
|
import type { GameSession } from './create-runtime';
|
|
28
33
|
import { type MountEntry, mountManifestRoots, resolveManifest } from './mount-manifest';
|
|
29
|
-
import type { GameSetupFn } from './types';
|
|
30
34
|
import { assertExportedOrInEditor } from './unexported-game-trap';
|
|
31
35
|
|
|
32
36
|
// ---------------------------------------------------------------------------
|
|
@@ -144,50 +148,6 @@ export function __clearAdapterSurfaceRegistryForTests(): void {
|
|
|
144
148
|
registry.clear();
|
|
145
149
|
}
|
|
146
150
|
|
|
147
|
-
// ---------------------------------------------------------------------------
|
|
148
|
-
// `defaultThreeAdapterFactory` — an OPT-IN convenience, never auto-registered
|
|
149
|
-
// ---------------------------------------------------------------------------
|
|
150
|
-
|
|
151
|
-
/** The entry-module export shape every first-party entry module follows
|
|
152
|
-
* (an explicit world entry module, including `examples/*` projects'
|
|
153
|
-
* `src/index.ts` — see CLAUDE.md's "Adding an example project"). */
|
|
154
|
-
interface ThreeEntryModuleExports {
|
|
155
|
-
readonly adapter?: RootAdapter;
|
|
156
|
-
readonly setup?: GameSetupFn;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* A ready-to-register {@link AdapterSurfaceFactory} for `kind: 'three'` roots
|
|
161
|
-
* that follow the first-party entry-module convention (`export const
|
|
162
|
-
* adapter` and/or `export async function setup`). Threejs is safe to
|
|
163
|
-
* ship as an exported convenience (unlike canvas/react) because `three`/
|
|
164
|
-
* `SetupThreeRootAdapter` are already unconditional engine dependencies —
|
|
165
|
-
* see `mount-manifest.ts`'s header comment. Still never auto-registered:
|
|
166
|
-
* the registry itself stays zero-policy (see this file's header comment) —
|
|
167
|
-
* a caller opts in with `registerAdapter('three', defaultThreeAdapterFactory)`.
|
|
168
|
-
*
|
|
169
|
-
* Resolution mirrors `mount-manifest.ts`'s own `resolveThreeAdapter` branch
|
|
170
|
-
* order: an entry module's `adapter` export wins outright; else its `setup`
|
|
171
|
-
* export (wrapping via `fromSetup` happens inside `mountManifestRoots`
|
|
172
|
-
* itself — this factory just returns the `MountEntry` shape).
|
|
173
|
-
*/
|
|
174
|
-
export const defaultThreeAdapterFactory: AdapterSurfaceFactory = (world, ctx) => {
|
|
175
|
-
const mod = ctx.entryModule as ThreeEntryModuleExports | undefined;
|
|
176
|
-
if (mod?.adapter) return { kind: 'three', adapter: mod.adapter };
|
|
177
|
-
if (mod?.setup) return { kind: 'three', setup: mod.setup };
|
|
178
|
-
if (world.entry !== undefined) {
|
|
179
|
-
throw new Error(
|
|
180
|
-
`defaultThreeAdapterFactory: entry module "${world.entry}" for world "${world.id}" exports ` +
|
|
181
|
-
'neither `adapter` nor `setup` — every first-party entry module exports at least one ' +
|
|
182
|
-
'(export one from the declared entry module).',
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
throw new Error(
|
|
186
|
-
`defaultThreeAdapterFactory: world "${world.id}" declares no \`entry\` — a three root is ` +
|
|
187
|
-
'authored as a TSX/R3F world module; point `entry` at it.',
|
|
188
|
-
);
|
|
189
|
-
};
|
|
190
|
-
|
|
191
151
|
// ---------------------------------------------------------------------------
|
|
192
152
|
// The composer
|
|
193
153
|
// ---------------------------------------------------------------------------
|
|
@@ -203,12 +163,9 @@ export interface MountGameOptions {
|
|
|
203
163
|
/** True for the one shape `mountManifestRoots` can ALREADY mount with zero
|
|
204
164
|
* `entries[id]` at all.
|
|
205
165
|
*
|
|
206
|
-
*
|
|
207
|
-
* `default`-adapter, SCENE-driven, no-`entry` three world, which
|
|
208
|
-
* `resolveThreeAdapter`'s scene branch could mount from the manifest alone —
|
|
209
|
-
* died with the `.vscn.json` format. `load.ts` now rejects a three root with no
|
|
166
|
+
* NOTHING is self-sufficient: `load.ts` rejects a three root with no
|
|
210
167
|
* `entry` outright, so every world needs a registered factory or an explicit
|
|
211
|
-
* entry
|
|
168
|
+
* entry. This predicate is retained so the loud-degrade error stays the
|
|
212
169
|
* documented outcome rather than a silent skip. */
|
|
213
170
|
function worldIsSelfSufficient(_world: ResolvedAdapterRoot): boolean {
|
|
214
171
|
return false;
|
|
@@ -223,6 +180,15 @@ function nativeDebugForEntry(
|
|
|
223
180
|
return binding ? [binding] : [];
|
|
224
181
|
}
|
|
225
182
|
|
|
183
|
+
function nativeSystemsForEntry(
|
|
184
|
+
world: ResolvedAdapterRoot,
|
|
185
|
+
entryModule: unknown,
|
|
186
|
+
): NativeSystemsBinding[] {
|
|
187
|
+
if (entryModule === undefined || world.adapter.type !== 'builtin') return [];
|
|
188
|
+
const binding = nativeSystemsBindingFromEntryModule(world.id, entryModule, world.surface);
|
|
189
|
+
return binding ? [binding] : [];
|
|
190
|
+
}
|
|
191
|
+
|
|
226
192
|
/**
|
|
227
193
|
* Mount every world declared by a `vgai.project.json` manifest onto `host
|
|
228
194
|
* .container`, resolving each world's kind through the `registerAdapter`
|
|
@@ -255,8 +221,9 @@ export async function mountGameFromManifest(
|
|
|
255
221
|
const manifest = resolveManifest(manifestInput);
|
|
256
222
|
const entries: Record<string, MountEntry> = { ...opts.entries };
|
|
257
223
|
const nativeDebug: NativeDebugBinding[] = [];
|
|
224
|
+
const nativeSystems: NativeSystemsBinding[] = [];
|
|
258
225
|
|
|
259
|
-
for (const world of manifest
|
|
226
|
+
for (const world of declaredRoots(manifest)) {
|
|
260
227
|
if (entries[world.id] !== undefined) continue; // explicit entry always wins
|
|
261
228
|
|
|
262
229
|
const factory = registry.get(world.adapter.identity);
|
|
@@ -266,6 +233,7 @@ export async function mountGameFromManifest(
|
|
|
266
233
|
? await host.loadEntryModule(world.entry)
|
|
267
234
|
: undefined;
|
|
268
235
|
nativeDebug.push(...nativeDebugForEntry(world, entryModule));
|
|
236
|
+
nativeSystems.push(...nativeSystemsForEntry(world, entryModule));
|
|
269
237
|
entries[world.id] = await factory(world, { host, entryModule });
|
|
270
238
|
continue;
|
|
271
239
|
}
|
|
@@ -276,7 +244,7 @@ export async function mountGameFromManifest(
|
|
|
276
244
|
`mountGameFromManifest: root "${world.id}" (adapter "${world.adapter.identity}") has no registered ` +
|
|
277
245
|
`adapter factory and no explicit entries["${world.id}"] — call ` +
|
|
278
246
|
`registerAdapter("${world.adapter.identity}", factory) before mounting (see ` +
|
|
279
|
-
'`
|
|
247
|
+
'`r3fRootFactory` in `@vgai/engine/world3d-react` for the worked three factory), or pass ' +
|
|
280
248
|
`opts.entries["${world.id}"] directly (see mount-manifest.ts's \`MountEntry\`).`,
|
|
281
249
|
);
|
|
282
250
|
}
|
|
@@ -290,5 +258,11 @@ export async function mountGameFromManifest(
|
|
|
290
258
|
headless: host.headless,
|
|
291
259
|
});
|
|
292
260
|
installNativeDebugBindings(session.game, nativeDebug);
|
|
261
|
+
installNativeSystemsBindings(session.game, nativeSystems);
|
|
262
|
+
// The universal instruments are host furniture on EVERY mount path — the
|
|
263
|
+
// editor installs them in its own bindings pass; the standalone composer
|
|
264
|
+
// installs them here. The disposer is deliberately dropped: the set's one
|
|
265
|
+
// resource lives on this Game and dies with it.
|
|
266
|
+
publishDevInstruments(session.game);
|
|
293
267
|
return session;
|
|
294
268
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// The standalone manifest-mount helper: an ENGINE-side generalization of
|
|
2
2
|
// `examples/tri-world/src/main.ts`'s hand-built `RootMountSpec[]`.
|
|
3
3
|
//
|
|
4
|
-
// `resolveAllRoots`/`
|
|
5
|
-
//
|
|
4
|
+
// `resolveAllRoots`/`resolveRootBinding` (`packages/editor/src/
|
|
5
|
+
// binding-resolver.ts`) already do this translation for the EDITOR, but they
|
|
6
6
|
// are Vite-coupled by construction (`/@fs/` dynamic imports of project files
|
|
7
7
|
// through the dev server, §0.1/§0.5 of the design doc) — unusable from a
|
|
8
8
|
// plain static build. This module mirrors their per-kind dispatch
|
|
@@ -17,17 +17,15 @@
|
|
|
17
17
|
// type-only import): this file never value-imports
|
|
18
18
|
// `pixi.js`, `react`, or `react-dom` — a
|
|
19
19
|
// canvas or react world's adapter is ALWAYS supplied already-constructed via
|
|
20
|
-
// `entries[id].adapter` (the caller's own module graph built it)
|
|
21
|
-
//
|
|
22
|
-
// `SetupThreeRootAdapter` are already unconditional dependencies of every
|
|
23
|
-
// caller of `createGameRuntime`, so wrapping a `setup` with
|
|
24
|
-
// `fromSetup` here adds no NEW bundle weight — only pixi/react are avoided.
|
|
20
|
+
// `entries[id].adapter` (the caller's own module graph built it), so no
|
|
21
|
+
// surface's library is pulled into a game that has no world on it.
|
|
25
22
|
|
|
26
23
|
import { assertNever } from '../adapter/adapter-surface';
|
|
24
|
+
import type { RootDeclaration } from '../adapter/binding';
|
|
25
|
+
import { declaredRoots } from '../adapter/manifest-interpreter';
|
|
27
26
|
import type { RootAdapter } from '../adapter/root-adapter';
|
|
28
27
|
// Value-imported from the implementer's OWN path, not the type-only
|
|
29
28
|
// `../adapter` barrel (P-6).
|
|
30
|
-
import { fromSetup } from '../adapter/setup-three-root-adapter';
|
|
31
29
|
import {
|
|
32
30
|
loadGameManifest,
|
|
33
31
|
type ResolvedAdapterRoot,
|
|
@@ -37,8 +35,8 @@ import { createGameRuntime, type GameSession, type RootMountSpec } from './creat
|
|
|
37
35
|
import { type DebugBridgeWindowTarget, maybeInstallDebugBridge } from './debug-bridge';
|
|
38
36
|
import { getDebugRegistry } from './debug-registry';
|
|
39
37
|
import { getGameplayRngTrapControl } from './gameplay-rng-trap';
|
|
38
|
+
import type { PlaytestContext } from './playtest';
|
|
40
39
|
import { RENDER_SEED_QUERY_PARAM } from './render-seed';
|
|
41
|
-
import type { GameSetupFn, PlaytestContext } from './types';
|
|
42
40
|
|
|
43
41
|
// ---------------------------------------------------------------------------
|
|
44
42
|
// The `entries` contract
|
|
@@ -52,20 +50,28 @@ import type { GameSetupFn, PlaytestContext } from './types';
|
|
|
52
50
|
* - `{ adapter }` — a fully-constructed {@link RootAdapter} (first-party or
|
|
53
51
|
* not). Always wins if present, regardless of the world's `entry` field —
|
|
54
52
|
* full caller control, including for a `{ module }`-adapter world
|
|
55
|
-
* (mountManifestRoots cannot import an arbitrary module path itself
|
|
56
|
-
*
|
|
57
|
-
* `
|
|
58
|
-
*
|
|
59
|
-
* `SetupThreeRootAdapter` here, mirroring `resolveDefaultThreeAdapter`'s
|
|
60
|
-
* entry branch exactly.
|
|
61
|
-
*
|
|
62
|
-
* The former third shape, `{ componentRegistry }` for a `scene`-declaring
|
|
63
|
-
* world, went with the `.vscn.json` format in WO-8.
|
|
53
|
+
* (mountManifestRoots cannot import an arbitrary module path itself —
|
|
54
|
+
* for a default-exported world, build the adapter with
|
|
55
|
+
* `resolveR3FEntryAdapter(entryModule, worldId)` from
|
|
56
|
+
* `@vgai/engine/world3d-react` and pass it here).
|
|
64
57
|
*/
|
|
65
|
-
export interface ThreeMountEntry {
|
|
58
|
+
export interface ThreeMountEntry extends MountEntryDeclaration {
|
|
66
59
|
readonly kind: 'three';
|
|
67
60
|
readonly adapter?: RootAdapter | undefined;
|
|
68
|
-
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The half of a root's binding declaration a CALLER holds — everything in
|
|
65
|
+
* `adapter/binding.ts`'s {@link RootDeclaration} except `root`, which this
|
|
66
|
+
* file already has from the manifest it just resolved.
|
|
67
|
+
*
|
|
68
|
+
* Optional throughout, and absent is the honest state for a caller who built
|
|
69
|
+
* an adapter by hand out of its own module graph: there is no entry namespace
|
|
70
|
+
* to report a static surface for, so the root registers with `binding: null`
|
|
71
|
+
* rather than one describing a module nobody loaded.
|
|
72
|
+
*/
|
|
73
|
+
export interface MountEntryDeclaration {
|
|
74
|
+
readonly declaration?: Omit<RootDeclaration, 'root'> | undefined;
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
/**
|
|
@@ -76,7 +82,7 @@ export interface ThreeMountEntry {
|
|
|
76
82
|
* `pixi.js`, which it deliberately never does (see this file's header
|
|
77
83
|
* comment).
|
|
78
84
|
*/
|
|
79
|
-
export interface PixiMountEntry {
|
|
85
|
+
export interface PixiMountEntry extends MountEntryDeclaration {
|
|
80
86
|
readonly kind: 'canvas';
|
|
81
87
|
readonly adapter: RootAdapter<'canvas'>;
|
|
82
88
|
}
|
|
@@ -94,7 +100,7 @@ export interface PixiMountEntry {
|
|
|
94
100
|
* itself (see this file's header comment) — building the adapter is
|
|
95
101
|
* entirely the caller's job.
|
|
96
102
|
*/
|
|
97
|
-
export interface ReactMountEntry {
|
|
103
|
+
export interface ReactMountEntry extends MountEntryDeclaration {
|
|
98
104
|
readonly kind: 'dom';
|
|
99
105
|
readonly adapter: RootAdapter<'dom'>;
|
|
100
106
|
}
|
|
@@ -243,8 +249,8 @@ export function resolveManifest(raw: unknown): ResolvedGameManifest {
|
|
|
243
249
|
}
|
|
244
250
|
|
|
245
251
|
// ---------------------------------------------------------------------------
|
|
246
|
-
// Per-kind entry -> adapter resolution (mirrors `
|
|
247
|
-
// per-identity dispatch, `packages/editor/src/
|
|
252
|
+
// Per-kind entry -> adapter resolution (mirrors `resolveRootBinding`'s
|
|
253
|
+
// per-identity dispatch, `packages/editor/src/binding-resolver.ts`)
|
|
248
254
|
// ---------------------------------------------------------------------------
|
|
249
255
|
|
|
250
256
|
function resolveThreeAdapter(
|
|
@@ -273,19 +279,17 @@ function resolveThreeAdapter(
|
|
|
273
279
|
|
|
274
280
|
// type === 'default'
|
|
275
281
|
if (world.entry !== undefined) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}
|
|
284
|
-
return fromSetup(world.id, entry.setup);
|
|
282
|
+
throw new Error(
|
|
283
|
+
`mountManifestRoots: world "${world.id}" (three) declares \`entry\` "${world.entry}" ` +
|
|
284
|
+
`— supply entries["${world.id}"] = { kind: 'three', adapter } (for a default-exported ` +
|
|
285
|
+
'world, build it with `resolveR3FEntryAdapter(entryModule, worldId)` from ' +
|
|
286
|
+
'`@vgai/engine/world3d-react`). Got ' +
|
|
287
|
+
`${entry === undefined ? 'no entry at all' : 'an entry with no `adapter`'}.`,
|
|
288
|
+
);
|
|
285
289
|
}
|
|
286
290
|
// Unreachable in practice: `load.ts`'s `checkAdapterSceneEntryRules` requires
|
|
287
291
|
// `entry` for every 'default' THREE adapter world at manifest-load time (and
|
|
288
|
-
// rejects
|
|
292
|
+
// rejects any other content declaration on one outright).
|
|
289
293
|
throw new Error(
|
|
290
294
|
`mountManifestRoots: world "${world.id}" is default-three with no \`entry\` — this ` +
|
|
291
295
|
'should have been rejected by manifest validation.',
|
|
@@ -336,6 +340,12 @@ function buildRootMountSpec(
|
|
|
336
340
|
id: world.id,
|
|
337
341
|
zOrder: world.zOrder,
|
|
338
342
|
pausable: world.pausable,
|
|
343
|
+
// `root` is this file's own resolved manifest record; the rest — the
|
|
344
|
+
// parsed `vgai.adapter.ts`, the entry namespace, the entry's declared
|
|
345
|
+
// debug/systems bindings — only the caller who loaded the entry can know.
|
|
346
|
+
...(entry?.declaration === undefined
|
|
347
|
+
? {}
|
|
348
|
+
: { declaration: { root: world, ...entry.declaration } }),
|
|
339
349
|
};
|
|
340
350
|
|
|
341
351
|
// `entry`'s `kind` is guaranteed to agree with `world.kind` past the guard
|
|
@@ -382,12 +392,13 @@ function buildRootMountSpec(
|
|
|
382
392
|
*/
|
|
383
393
|
export async function mountManifestRoots(opts: MountManifestOptions): Promise<GameSession> {
|
|
384
394
|
const manifest = resolveManifest(opts.manifest);
|
|
385
|
-
|
|
395
|
+
const mountPlan = declaredRoots(manifest);
|
|
396
|
+
if (mountPlan.length === 0) {
|
|
386
397
|
throw new Error('mountManifestRoots: manifest declares no roots — nothing to mount.');
|
|
387
398
|
}
|
|
388
399
|
const entries = opts.entries ?? {};
|
|
389
400
|
|
|
390
|
-
const roots: RootMountSpec[] =
|
|
401
|
+
const roots: RootMountSpec[] = mountPlan.map((world) =>
|
|
391
402
|
buildRootMountSpec(world, entries[world.id]),
|
|
392
403
|
);
|
|
393
404
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHO IS PLAYING, and under what identity — the host's own declaration for one
|
|
3
|
+
* private play run or coordinated team test.
|
|
4
|
+
*
|
|
5
|
+
* Its own module because it is a PUBLISHED path: a project's Colyseus
|
|
6
|
+
* networking adapter (the `colyseus` capability, copied into every game) names
|
|
7
|
+
* this type, so it must live somewhere that survives. The engine never joins a
|
|
8
|
+
* room and never couples this authoring identity to a networking library —
|
|
9
|
+
* games may pass `roomKey` as a Colyseus filter/join option, and that is the
|
|
10
|
+
* whole of the coupling.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** Host-supplied identity for one private play run or coordinated team test.
|
|
14
|
+
* Games may pass `roomKey` as a Colyseus filter/join option; the engine never
|
|
15
|
+
* joins a room or couples this authoring identity to a networking library. */
|
|
16
|
+
export interface PlaytestContext {
|
|
17
|
+
readonly mode: 'private' | 'team';
|
|
18
|
+
readonly id: string;
|
|
19
|
+
readonly roomKey: string;
|
|
20
|
+
readonly revision: number | null;
|
|
21
|
+
readonly participantId: string | null;
|
|
22
|
+
}
|
|
@@ -48,9 +48,8 @@ export interface GameStateBridge {
|
|
|
48
48
|
export interface GameStateBridgeInternal extends GameStateBridge {
|
|
49
49
|
/** Bump `frameVersion` by one and notify every current subscriber, in
|
|
50
50
|
* subscription order. Subscriber errors are isolated (per-subscriber
|
|
51
|
-
* try/catch, loud `console.error`, never swallowed silently)
|
|
52
|
-
*
|
|
53
|
-
* `update()` calls: one offending subscriber must not stop its siblings
|
|
51
|
+
* try/catch, loud `console.error`, never swallowed silently): one
|
|
52
|
+
* offending subscriber must not stop its siblings
|
|
54
53
|
* from being notified, and must not break the frame loop. */
|
|
55
54
|
bump(): void;
|
|
56
55
|
}
|
|
@@ -84,6 +83,7 @@ export function createStateBridge(): GameStateBridgeInternal {
|
|
|
84
83
|
try {
|
|
85
84
|
onFrame();
|
|
86
85
|
} catch (err) {
|
|
86
|
+
// biome-ignore lint/suspicious/noConsole: a throwing subscriber must not take the notify loop down, and the console (captured by the editor session ledger) is the engine runtime's one report channel.
|
|
87
87
|
console.error('[state-bridge] subscriber threw:', err);
|
|
88
88
|
}
|
|
89
89
|
}
|
package/src/setup/setup-audio.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
+
import { type AudioBusMixer, createAudioBusMixer } from '../audio/bus-mixer';
|
|
2
3
|
|
|
3
4
|
export interface AudioContext {
|
|
4
5
|
listener: THREE.AudioListener;
|
|
@@ -8,10 +9,24 @@ export interface AudioContext {
|
|
|
8
9
|
sfx: GainNode;
|
|
9
10
|
voice: GainNode;
|
|
10
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* The named-bus mixer the three below are buses OF (`../audio/bus-mixer.ts`).
|
|
14
|
+
*
|
|
15
|
+
* `buses` is a fixed struct because those three names are the ones the engine
|
|
16
|
+
* itself routes; a game with an `ambience`, a `ui` or a per-character bus asks
|
|
17
|
+
* the mixer for it by name — `audio.mixer.bus('ambience', 'master')` mints it
|
|
18
|
+
* under the master gain, `audio.mixer.setDb('ambience', -6)` sets it in
|
|
19
|
+
* decibels — and `audio.mixer.disconnect()` is the ONE teardown for all of
|
|
20
|
+
* them, the three struct members included.
|
|
21
|
+
*/
|
|
22
|
+
mixer: AudioBusMixer;
|
|
11
23
|
/** Call this on first user interaction (click/key) to resume audio context */
|
|
12
24
|
resume: () => void;
|
|
13
25
|
}
|
|
14
26
|
|
|
27
|
+
/** The bus every other bus routes into, and the node `masterGain` is. */
|
|
28
|
+
const MASTER_BUS = 'master';
|
|
29
|
+
|
|
15
30
|
/**
|
|
16
31
|
* Creates the audio listener and bus hierarchy.
|
|
17
32
|
*
|
|
@@ -23,25 +38,19 @@ export function setupAudio(camera: THREE.Camera): AudioContext {
|
|
|
23
38
|
camera.add(listener);
|
|
24
39
|
|
|
25
40
|
const ctx = listener.context;
|
|
26
|
-
const
|
|
27
|
-
masterGain.
|
|
41
|
+
const mixer = createAudioBusMixer({ context: ctx, destination: ctx.destination });
|
|
42
|
+
const masterGain = mixer.bus(MASTER_BUS);
|
|
28
43
|
|
|
29
44
|
// Route the Three.js listener through masterGain so that THREE.Audio /
|
|
30
45
|
// THREE.PositionalAudio objects are also silenced by the mute button.
|
|
31
46
|
listener.gain.disconnect();
|
|
32
47
|
listener.gain.connect(masterGain);
|
|
33
48
|
|
|
34
|
-
const musicGain =
|
|
49
|
+
const musicGain = mixer.bus('music', MASTER_BUS);
|
|
35
50
|
musicGain.gain.value = 0.7;
|
|
36
|
-
musicGain.connect(masterGain);
|
|
37
|
-
|
|
38
|
-
const sfxGain = ctx.createGain();
|
|
39
|
-
sfxGain.gain.value = 1.0;
|
|
40
|
-
sfxGain.connect(masterGain);
|
|
41
51
|
|
|
42
|
-
const
|
|
43
|
-
voiceGain
|
|
44
|
-
voiceGain.connect(masterGain);
|
|
52
|
+
const sfxGain = mixer.bus('sfx', MASTER_BUS);
|
|
53
|
+
const voiceGain = mixer.bus('voice', MASTER_BUS);
|
|
45
54
|
|
|
46
55
|
return {
|
|
47
56
|
listener,
|
|
@@ -51,6 +60,7 @@ export function setupAudio(camera: THREE.Camera): AudioContext {
|
|
|
51
60
|
sfx: sfxGain,
|
|
52
61
|
voice: voiceGain,
|
|
53
62
|
},
|
|
63
|
+
mixer,
|
|
54
64
|
resume() {
|
|
55
65
|
if (ctx.state === 'suspended') {
|
|
56
66
|
ctx.resume();
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
DepthOfFieldEffect,
|
|
10
10
|
DotScreenEffect,
|
|
11
11
|
type Effect,
|
|
12
|
-
EffectComposer,
|
|
12
|
+
type EffectComposer,
|
|
13
13
|
EffectPass,
|
|
14
14
|
GlitchEffect,
|
|
15
15
|
GodRaysEffect,
|
|
@@ -42,13 +42,6 @@ import { DEFAULTS } from '../defaults';
|
|
|
42
42
|
import { detectKtx2Support } from '../loader';
|
|
43
43
|
import { type RenderScope, resolveRenderSettings } from '../render/render-settings';
|
|
44
44
|
|
|
45
|
-
export interface RendererContext {
|
|
46
|
-
renderer: THREE.WebGLRenderer;
|
|
47
|
-
scene: THREE.Scene;
|
|
48
|
-
camera: THREE.PerspectiveCamera;
|
|
49
|
-
composer: EffectComposer;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
45
|
/**
|
|
53
46
|
* Apply the live renderer-level render settings (shadows, resolution scale) from
|
|
54
47
|
* the resolved cascade. `antialias`/`backend` are reload-only (renderer re-init)
|
|
@@ -73,7 +66,7 @@ export function applyRendererSettings(
|
|
|
73
66
|
/**
|
|
74
67
|
* Create ONLY the WebGL renderer. The HOST owns the renderer (see
|
|
75
68
|
* `ThreeHostContext.renderer`); the game/adapter owns the scene/camera/composer it
|
|
76
|
-
* renders into.
|
|
69
|
+
* renders into.
|
|
77
70
|
*
|
|
78
71
|
* `rendering` is the scene-level render scope (`env.rendering`); it seeds the
|
|
79
72
|
* reload-only `antialias` option at construction and the live shadow/resolution
|
|
@@ -118,58 +111,6 @@ export function createHostRenderer(
|
|
|
118
111
|
return renderer;
|
|
119
112
|
}
|
|
120
113
|
|
|
121
|
-
/**
|
|
122
|
-
* Create the scene, camera, and postprocessing composer that a first-party game
|
|
123
|
-
* renders into, given a host-provided renderer. The GPU-only `composer` is
|
|
124
|
-
* created here; a headless host (no GPU) skips this entirely.
|
|
125
|
-
*/
|
|
126
|
-
export function createSceneView(
|
|
127
|
-
renderer: THREE.WebGLRenderer,
|
|
128
|
-
width = window.innerWidth,
|
|
129
|
-
height = window.innerHeight,
|
|
130
|
-
): { scene: THREE.Scene; camera: THREE.PerspectiveCamera; composer: EffectComposer } {
|
|
131
|
-
const safeWidth = Math.max(1, width);
|
|
132
|
-
const safeHeight = Math.max(1, height);
|
|
133
|
-
const scene = new THREE.Scene();
|
|
134
|
-
scene.background = new THREE.Color(0x1a1a2e);
|
|
135
|
-
|
|
136
|
-
const camera = new THREE.PerspectiveCamera(
|
|
137
|
-
DEFAULTS.camera.fov,
|
|
138
|
-
safeWidth / safeHeight,
|
|
139
|
-
DEFAULTS.camera.near,
|
|
140
|
-
DEFAULTS.camera.far,
|
|
141
|
-
);
|
|
142
|
-
camera.position.set(0, 5, 10);
|
|
143
|
-
camera.lookAt(0, 0, 0);
|
|
144
|
-
|
|
145
|
-
const composer = new EffectComposer(renderer);
|
|
146
|
-
composer.addPass(new RenderPass(scene, camera));
|
|
147
|
-
composer.addPass(
|
|
148
|
-
new EffectPass(
|
|
149
|
-
camera,
|
|
150
|
-
new BloomEffect({ luminanceThreshold: DEFAULTS.postProcessing.bloom.luminanceThreshold }),
|
|
151
|
-
),
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
return { scene, camera, composer };
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Creates the Three.js renderer, scene, camera, and postprocessing pipeline.
|
|
159
|
-
*
|
|
160
|
-
* This is direct Three.js setup — no abstraction. Edit freely. (Now a thin
|
|
161
|
-
* combination of {@link createHostRenderer} + {@link createSceneView}.)
|
|
162
|
-
*/
|
|
163
|
-
export function setupRenderer(
|
|
164
|
-
canvas: HTMLCanvasElement,
|
|
165
|
-
width = window.innerWidth,
|
|
166
|
-
height = window.innerHeight,
|
|
167
|
-
): RendererContext {
|
|
168
|
-
const renderer = createHostRenderer(canvas, width, height);
|
|
169
|
-
const { scene, camera, composer } = createSceneView(renderer, width, height);
|
|
170
|
-
return { renderer, scene, camera, composer };
|
|
171
|
-
}
|
|
172
|
-
|
|
173
114
|
const toneMappingModes: Record<string, THREE.ToneMapping> = {
|
|
174
115
|
none: THREE.NoToneMapping,
|
|
175
116
|
linear: THREE.LinearToneMapping,
|
|
@@ -2,11 +2,8 @@
|
|
|
2
2
|
* world3d-react — the react-three-fiber bridge for vgai's three surface
|
|
3
3
|
* (`@engine/world3d-react`).
|
|
4
4
|
*
|
|
5
|
-
* An OPT-IN module,
|
|
6
|
-
*
|
|
7
|
-
* decision D24 — R3F TSX is the blessed three.js authoring path). Mirrors how
|
|
8
|
-
* `pixi/` is the PixiJS surface's opt-in home: a peer surface module the engine
|
|
9
|
-
* CORE never imports (enforced by
|
|
5
|
+
* An OPT-IN module, mirroring how `pixi/` is the PixiJS surface's opt-in home:
|
|
6
|
+
* a peer surface module the engine CORE never imports (enforced by
|
|
10
7
|
* `packages/engine/test/react-core-import-ban.test.ts` — this directory is an
|
|
11
8
|
* allowed react-importing entry alongside `react/`, and core files may not
|
|
12
9
|
* import it).
|
|
@@ -14,27 +11,23 @@
|
|
|
14
11
|
* Peer contract: an importing PROJECT already depends on `react`,
|
|
15
12
|
* `@react-three/fiber`, and `three` (fiber's three must be deduped to the
|
|
16
13
|
* host's single instance — `resolve.dedupe: ['three', 'react', 'react-dom']`
|
|
17
|
-
* in the project's Vite config
|
|
18
|
-
*
|
|
19
|
-
*
|
|
14
|
+
* in the project's Vite config). The engine package deliberately declares no
|
|
15
|
+
* hard dependency on fiber: only projects that already mount through fiber
|
|
16
|
+
* ever import this module.
|
|
20
17
|
*
|
|
21
18
|
* Surface:
|
|
22
|
-
* - `
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* does not build are absent from that type — see its doc comment for what
|
|
29
|
-
* to use instead.
|
|
30
|
-
* - `EngineBridge` / `EngineBridgeValue` — the context contract, exported
|
|
31
|
-
* for advanced adopters building their own bridge.
|
|
19
|
+
* - `r3fRootFactory` / `resolveR3FEntryAdapter` — what a three entry module
|
|
20
|
+
* MEANS: a default-exported component (`export default function World()`),
|
|
21
|
+
* mounted as a first-party `kind: "three"` world under the host's gated
|
|
22
|
+
* loop. The world's vgai surface is its entry module's static exports
|
|
23
|
+
* (`export { debug, systems } from './commands'`), connected by the host
|
|
24
|
+
* at mount.
|
|
32
25
|
*
|
|
33
26
|
* Deliberately NOT re-exported here: `<RapierPhysicsBridge>`
|
|
34
|
-
* (`@engine/world3d-react/rapier-physics-bridge`), which
|
|
35
|
-
* world's `@react-three/rapier` physics
|
|
36
|
-
* `
|
|
37
|
-
* editor's transform coordination can see it. It imports
|
|
27
|
+
* (`@engine/world3d-react/rapier-physics-bridge`), which publishes an R3F
|
|
28
|
+
* world's `@react-three/rapier` physics to the module slot the entry's
|
|
29
|
+
* `systems.physics` declaration forwards — so the colliders instrument and
|
|
30
|
+
* the editor's transform coordination can see it. It imports
|
|
38
31
|
* `@react-three/rapier`, and only a world that already depends on that library
|
|
39
32
|
* should pull it into its graph; a deep import keeps this barrel's peer
|
|
40
33
|
* contract to `react`/`@react-three/fiber`/`three` alone.
|
|
@@ -46,13 +39,4 @@ export {
|
|
|
46
39
|
type WorldRendererConfig,
|
|
47
40
|
type WorldToneMapping,
|
|
48
41
|
} from '../adapter/renderer-config';
|
|
49
|
-
export { EngineBridge, type EngineBridgeValue, useGameContext } from './engine-bridge';
|
|
50
|
-
export { type CreateR3FAdapterOptions, createR3FAdapter } from './r3f-adapter';
|
|
51
42
|
export { r3fRootFactory, resolveR3FEntryAdapter } from './r3f-root-factory';
|
|
52
|
-
export {
|
|
53
|
-
createR3FRootContext,
|
|
54
|
-
DEFAULT_INPUT_MAP_PATH,
|
|
55
|
-
type R3FGameContext,
|
|
56
|
-
type R3FRootContextOptions,
|
|
57
|
-
type R3FRootRuntime,
|
|
58
|
-
} from './world-context';
|