@vgai/engine 0.2.0
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/LICENSE +202 -0
- package/README.md +35 -0
- package/package.json +55 -0
- package/src/adapter/authoring.ts +402 -0
- package/src/adapter/colyseus-networking-adapter.ts +72 -0
- package/src/adapter/first-party-systems.ts +103 -0
- package/src/adapter/game-adapter.ts +151 -0
- package/src/adapter/host-context.ts +77 -0
- package/src/adapter/index.ts +85 -0
- package/src/adapter/ingest/game-contract.ts +59 -0
- package/src/adapter/ingest/overlay-applier.ts +207 -0
- package/src/adapter/ingest/overlay-apply.ts +124 -0
- package/src/adapter/ingest/overlay-file.ts +126 -0
- package/src/adapter/ingest/overlay-report.ts +176 -0
- package/src/adapter/ingest/scene-capture.ts +307 -0
- package/src/adapter/ingest/upstream-pin.ts +52 -0
- package/src/adapter/loop-gate-report.ts +54 -0
- package/src/adapter/rapier-physics-adapter.ts +56 -0
- package/src/adapter/system-adapter.ts +154 -0
- package/src/adapter/transform.ts +18 -0
- package/src/adapter/vgai-scene-game-adapter.ts +886 -0
- package/src/adapter/world-kind.ts +34 -0
- package/src/ai/navigation.ts +164 -0
- package/src/animation/anim-graph-types.ts +56 -0
- package/src/animation/anim-graph.ts +406 -0
- package/src/animation/anim-system.ts +28 -0
- package/src/animation/blend-node.ts +119 -0
- package/src/animation/property-track.ts +178 -0
- package/src/animation/schema.ts +204 -0
- package/src/assets.ts +80 -0
- package/src/audio/ambient.ts +300 -0
- package/src/audio/impacts.ts +212 -0
- package/src/audio/index.ts +7 -0
- package/src/audio/movement.ts +140 -0
- package/src/audio/musical.ts +200 -0
- package/src/audio/ui-sounds.ts +171 -0
- package/src/audio/vehicle.ts +235 -0
- package/src/audio/weapons.ts +152 -0
- package/src/core/game-loop.ts +127 -0
- package/src/core/system-runner.ts +298 -0
- package/src/core/types.ts +58 -0
- package/src/dev/console-bridge.ts +83 -0
- package/src/dev/debug-draw.ts +80 -0
- package/src/dev/logger.ts +119 -0
- package/src/ecs/component-manager.ts +748 -0
- package/src/ecs/game-component.ts +147 -0
- package/src/ecs/hmr-swap-report.ts +65 -0
- package/src/input/input-manager.ts +439 -0
- package/src/input/input-types.ts +19 -0
- package/src/input/schema.ts +129 -0
- package/src/loader.ts +70 -0
- package/src/manifest/index.ts +24 -0
- package/src/manifest/load-file.ts +16 -0
- package/src/manifest/load.ts +378 -0
- package/src/manifest/schema.ts +375 -0
- package/src/physics/collision-system.ts +76 -0
- package/src/physics/physics-registry.ts +83 -0
- package/src/physics/transform-writer.ts +41 -0
- package/src/physics/trigger-dispatch.ts +97 -0
- package/src/react/game-state.tsx +172 -0
- package/src/render/auto-batcher.ts +169 -0
- package/src/render/render-batch-system.ts +268 -0
- package/src/render/render-features.ts +146 -0
- package/src/render/render-settings.ts +72 -0
- package/src/runtime/create-runtime.ts +1152 -0
- package/src/runtime/frame-selector-cache.ts +81 -0
- package/src/runtime/game.ts +1003 -0
- package/src/runtime/input-router.ts +213 -0
- package/src/runtime/mount-game.ts +269 -0
- package/src/runtime/mount-manifest.ts +361 -0
- package/src/runtime/scene-ui-bridge.ts +86 -0
- package/src/runtime/scene-ui-data.ts +119 -0
- package/src/runtime/state-bridge.ts +79 -0
- package/src/runtime/types.ts +196 -0
- package/src/scene/asset-loaders.ts +195 -0
- package/src/scene/asset-paths.ts +123 -0
- package/src/scene/asset-registry.ts +67 -0
- package/src/scene/collider-dimensions.ts +125 -0
- package/src/scene/component-registry.ts +40 -0
- package/src/scene/defaults.ts +164 -0
- package/src/scene/geometries/index.ts +7 -0
- package/src/scene/geometries/terrain.ts +42 -0
- package/src/scene/geometry-registry.ts +42 -0
- package/src/scene/instance-registry.ts +84 -0
- package/src/scene/instancers/grid.ts +38 -0
- package/src/scene/instancers/index.ts +7 -0
- package/src/scene/light-camera-factory.ts +97 -0
- package/src/scene/material-factory.ts +211 -0
- package/src/scene/material-registry.ts +73 -0
- package/src/scene/materials/index.ts +7 -0
- package/src/scene/materials/water.ts +56 -0
- package/src/scene/parse.ts +71 -0
- package/src/scene/particles-factory.ts +383 -0
- package/src/scene/scene-apply.ts +356 -0
- package/src/scene/scene-diff-schema.ts +115 -0
- package/src/scene/scene-diff-types.ts +29 -0
- package/src/scene/scene-loader.ts +1533 -0
- package/src/scene/scene-query.ts +63 -0
- package/src/scene/scene-types.ts +34 -0
- package/src/scene/scene-version.ts +40 -0
- package/src/scene/schema/animation.ts +95 -0
- package/src/scene/schema/audio.ts +25 -0
- package/src/scene/schema/camera.ts +21 -0
- package/src/scene/schema/collider.ts +69 -0
- package/src/scene/schema/entity-ref.ts +78 -0
- package/src/scene/schema/entity.ts +169 -0
- package/src/scene/schema/environment.ts +384 -0
- package/src/scene/schema/index.ts +95 -0
- package/src/scene/schema/instances.ts +35 -0
- package/src/scene/schema/joint.ts +26 -0
- package/src/scene/schema/light.ts +38 -0
- package/src/scene/schema/material.ts +113 -0
- package/src/scene/schema/mesh.ts +108 -0
- package/src/scene/schema/particles.ts +398 -0
- package/src/scene/schema/physics.ts +49 -0
- package/src/scene/schema/scene-file.ts +299 -0
- package/src/scene/schema/shadow.ts +24 -0
- package/src/scene/schema/spline.ts +21 -0
- package/src/scene/schema/tuples.ts +21 -0
- package/src/scene/schema/ui.ts +602 -0
- package/src/scene/user-data.ts +203 -0
- package/src/setup/setup-audio.ts +60 -0
- package/src/setup/setup-particles.ts +23 -0
- package/src/setup/setup-physics.ts +67 -0
- package/src/setup/setup-renderer.ts +529 -0
- package/src/types-n8ao.d.ts +37 -0
- package/src/types-realism-effects.d.ts +61 -0
- package/src/world2d/authoring-2d.ts +208 -0
- package/src/world2d/capture-to-scene2d.ts +52 -0
- package/src/world2d/collision-2d.ts +106 -0
- package/src/world2d/components-2d.ts +86 -0
- package/src/world2d/index.ts +66 -0
- package/src/world2d/ingest-iframe-2d.ts +255 -0
- package/src/world2d/ingest2d.ts +131 -0
- package/src/world2d/physics2d-registry.ts +49 -0
- package/src/world2d/pixi-game-adapter.ts +325 -0
- package/src/world2d/pixi-surface.ts +78 -0
- package/src/world2d/scene-capture-2d.ts +117 -0
- package/src/world2d/scene2d-loader.ts +308 -0
- package/src/world2d/schema/entity2d.ts +145 -0
- package/src/world2d/schema/physics2d.ts +53 -0
- package/src/world2d/schema/sprite.ts +71 -0
- package/src/world2d/schema/tilemap.ts +22 -0
- package/src/world2d/schema/tuples2d.ts +25 -0
- package/src/world2d/system-adapters-2d.ts +49 -0
- package/src/world2d/transform-writer-2d.ts +24 -0
- package/src/world2d/types.ts +55 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The render-feature registry — single source of truth for every togglable render
|
|
5
|
+
* setting. The scene schema (`SceneEnvironment.rendering`, `SceneEntity.render`),
|
|
6
|
+
* the cascade resolver (`resolveRenderSettings`), the editor UI, and the stats
|
|
7
|
+
* overlay are all derived from this list, so "everything togglable" stays
|
|
8
|
+
* consistent by construction (same posture as the component/material/instancer
|
|
9
|
+
* registries). Adding a feature here gives it a schema field + cascade entry for
|
|
10
|
+
* free. See docs/research/RENDER-SETTINGS-UX.md.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export type RenderFeatureValue = boolean | number | string;
|
|
14
|
+
|
|
15
|
+
export interface RenderFeature {
|
|
16
|
+
/** Stable key used in schema, cascade, and UI. */
|
|
17
|
+
key: string;
|
|
18
|
+
/** Editor display label. */
|
|
19
|
+
label: string;
|
|
20
|
+
/** Schema `.describe()` text (powers JSON Schema / inspector docs). */
|
|
21
|
+
description: string;
|
|
22
|
+
/** Control shape. */
|
|
23
|
+
kind: 'toggle' | 'number' | 'enum';
|
|
24
|
+
/** Engine default — the "fast by default" baseline. */
|
|
25
|
+
default: RenderFeatureValue;
|
|
26
|
+
/**
|
|
27
|
+
* `live` re-applies on change; `reload` needs a renderer re-init (e.g. backend,
|
|
28
|
+
* antialias). The editor badges `reload` features and re-inits the viewport.
|
|
29
|
+
*/
|
|
30
|
+
apply: 'live' | 'reload';
|
|
31
|
+
/** Whether this feature may be overridden per-entity (the entity cascade layer). */
|
|
32
|
+
perEntity: boolean;
|
|
33
|
+
/** Allowed values for `enum` kind. */
|
|
34
|
+
options?: readonly string[];
|
|
35
|
+
/** [min, max] for `number` kind. */
|
|
36
|
+
range?: readonly [number, number];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const RENDER_FEATURES: readonly RenderFeature[] = [
|
|
40
|
+
{
|
|
41
|
+
key: 'autoBatch',
|
|
42
|
+
label: 'Auto-batching',
|
|
43
|
+
description:
|
|
44
|
+
'Automatically batch entities sharing geometry+material into one draw call (InstancedMesh/BatchedMesh) while keeping each Object3D as the handle. The headline perf win; opt out per-entity for custom-shader/skinned meshes.',
|
|
45
|
+
kind: 'toggle',
|
|
46
|
+
default: true,
|
|
47
|
+
apply: 'live',
|
|
48
|
+
perEntity: true,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
key: 'frustumCulling',
|
|
52
|
+
label: 'Frustum culling',
|
|
53
|
+
description: 'Per-instance frustum culling for batched content.',
|
|
54
|
+
kind: 'toggle',
|
|
55
|
+
default: true,
|
|
56
|
+
apply: 'live',
|
|
57
|
+
perEntity: true,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
key: 'lod',
|
|
61
|
+
label: 'Level of detail',
|
|
62
|
+
description: 'Distance-based geometry swap (LOD) for eligible entities.',
|
|
63
|
+
kind: 'toggle',
|
|
64
|
+
default: true,
|
|
65
|
+
apply: 'live',
|
|
66
|
+
perEntity: true,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
key: 'shadows',
|
|
70
|
+
label: 'Shadows',
|
|
71
|
+
description: 'Enable the shadow map. Per-entity cast/receive still applies.',
|
|
72
|
+
kind: 'toggle',
|
|
73
|
+
default: true,
|
|
74
|
+
apply: 'live',
|
|
75
|
+
perEntity: true,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
key: 'postProcessing',
|
|
79
|
+
label: 'Post-processing',
|
|
80
|
+
description:
|
|
81
|
+
'Master switch for the post-processing stack (individual effects nest beneath it).',
|
|
82
|
+
kind: 'toggle',
|
|
83
|
+
default: true,
|
|
84
|
+
apply: 'live',
|
|
85
|
+
perEntity: false,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
key: 'resolutionScale',
|
|
89
|
+
label: 'Resolution scale',
|
|
90
|
+
description: 'Device-pixel-ratio multiplier (1.0 = native). The cheapest perf dial.',
|
|
91
|
+
kind: 'number',
|
|
92
|
+
default: 1,
|
|
93
|
+
apply: 'live',
|
|
94
|
+
perEntity: false,
|
|
95
|
+
range: [0.25, 2],
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
key: 'antialias',
|
|
99
|
+
label: 'Antialiasing',
|
|
100
|
+
description: 'MSAA via renderer construction. Applies on reload (renderer re-init).',
|
|
101
|
+
kind: 'toggle',
|
|
102
|
+
default: true,
|
|
103
|
+
apply: 'reload',
|
|
104
|
+
perEntity: false,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
key: 'backend',
|
|
108
|
+
label: 'Renderer backend',
|
|
109
|
+
description: 'GPU backend: auto picks WebGPU when available, else WebGL2. Applies on reload.',
|
|
110
|
+
kind: 'enum',
|
|
111
|
+
default: 'auto',
|
|
112
|
+
apply: 'reload',
|
|
113
|
+
perEntity: false,
|
|
114
|
+
options: ['auto', 'webgl', 'webgpu'],
|
|
115
|
+
},
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
/** Map for O(1) lookup by key. */
|
|
119
|
+
export const RENDER_FEATURE_BY_KEY: ReadonlyMap<string, RenderFeature> = new Map(
|
|
120
|
+
RENDER_FEATURES.map((f) => [f.key, f]),
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Build a Zod object for the render settings, derived from the registry so the
|
|
125
|
+
* schema can never drift from the feature list. All fields optional — absence
|
|
126
|
+
* means "inherit" in the cascade. `perEntityOnly` builds the per-entity override
|
|
127
|
+
* schema (only features whose `perEntity` is true).
|
|
128
|
+
*/
|
|
129
|
+
export function buildRenderingZod(opts: { perEntityOnly?: boolean } = {}): z.ZodTypeAny {
|
|
130
|
+
const shape: Record<string, z.ZodTypeAny> = {};
|
|
131
|
+
for (const f of RENDER_FEATURES) {
|
|
132
|
+
if (opts.perEntityOnly && !f.perEntity) continue;
|
|
133
|
+
let base: z.ZodTypeAny;
|
|
134
|
+
if (f.kind === 'toggle') base = z.boolean();
|
|
135
|
+
else if (f.kind === 'number') base = z.number();
|
|
136
|
+
else base = z.enum(f.options as [string, ...string[]]);
|
|
137
|
+
shape[f.key] = base.optional().describe(f.description);
|
|
138
|
+
}
|
|
139
|
+
return z
|
|
140
|
+
.object(shape)
|
|
141
|
+
.describe(
|
|
142
|
+
opts.perEntityOnly
|
|
143
|
+
? 'Per-entity render overrides (omit a field to inherit from the scene/engine default)'
|
|
144
|
+
: 'Scene render settings (omit a field to inherit the engine default)',
|
|
145
|
+
);
|
|
146
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { RENDER_FEATURES, type RenderFeatureValue } from './render-features';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cascade resolution for render settings: engine default → scene → entity, with
|
|
5
|
+
* tri-state inherit (an absent value inherits from the next level up). See
|
|
6
|
+
* docs/research/RENDER-SETTINGS-UX.md.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** A partial override map (scene-level or entity-level). Absent key = inherit. */
|
|
10
|
+
export type RenderScope = Partial<Record<string, RenderFeatureValue>>;
|
|
11
|
+
|
|
12
|
+
/** Fully-resolved settings: every registry key present. */
|
|
13
|
+
export type ResolvedRenderSettings = Record<string, RenderFeatureValue>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Resolve effective settings. `entity` overrides only apply to features whose
|
|
17
|
+
* `perEntity` flag is set; non-per-entity features resolve across engine→scene
|
|
18
|
+
* only. `??` walks up the chain on `undefined` (inherit) but lets an explicit
|
|
19
|
+
* `false`/`0` override (they are not nullish).
|
|
20
|
+
*/
|
|
21
|
+
export function resolveRenderSettings(
|
|
22
|
+
scene?: RenderScope,
|
|
23
|
+
entity?: RenderScope,
|
|
24
|
+
): ResolvedRenderSettings {
|
|
25
|
+
const out: ResolvedRenderSettings = {};
|
|
26
|
+
for (const f of RENDER_FEATURES) {
|
|
27
|
+
const entityVal = f.perEntity ? entity?.[f.key] : undefined;
|
|
28
|
+
out[f.key] = entityVal ?? scene?.[f.key] ?? f.default;
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A small observable holding the live scene-level resolved settings. Live
|
|
35
|
+
* features re-apply when a value changes (subscribers are notified with the
|
|
36
|
+
* changed key). This is the seam a future player-facing graphics menu would
|
|
37
|
+
* drive — for now it backs the editor toggles + the runtime systems.
|
|
38
|
+
*/
|
|
39
|
+
export class RenderSettings {
|
|
40
|
+
private values: ResolvedRenderSettings;
|
|
41
|
+
private listeners = new Set<(key: string, value: RenderFeatureValue) => void>();
|
|
42
|
+
|
|
43
|
+
constructor(scene?: RenderScope) {
|
|
44
|
+
this.values = resolveRenderSettings(scene);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
get(key: string): RenderFeatureValue {
|
|
48
|
+
return this.values[key]!;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Set a scene-level value; notifies subscribers if it changed. */
|
|
52
|
+
set(key: string, value: RenderFeatureValue): void {
|
|
53
|
+
if (this.values[key] === value) return;
|
|
54
|
+
this.values[key] = value;
|
|
55
|
+
for (const fn of this.listeners) fn(key, value);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Resolve the effective value for an entity (entity override → scene → default). */
|
|
59
|
+
forEntity(key: string, entity?: RenderScope): RenderFeatureValue {
|
|
60
|
+
const f = entity?.[key];
|
|
61
|
+
return f ?? this.values[key]!;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
subscribe(fn: (key: string, value: RenderFeatureValue) => void): () => void {
|
|
65
|
+
this.listeners.add(fn);
|
|
66
|
+
return () => this.listeners.delete(fn);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
snapshot(): ResolvedRenderSettings {
|
|
70
|
+
return { ...this.values };
|
|
71
|
+
}
|
|
72
|
+
}
|