pelican-engine 0.0.0-stage → 0.3.1
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/AGENTS.md +147 -0
- package/LICENSE +22 -0
- package/README.md +129 -2
- package/distribution.json +197 -0
- package/docs/AI-WORKFLOW.md +517 -0
- package/docs/ARCHITECTURE.md +268 -0
- package/docs/CAPABILITIES.md +264 -0
- package/docs/DECISIONS.md +107 -0
- package/docs/M3-USAGE.md +192 -0
- package/docs/PELICAN-MIGRATION.md +38 -0
- package/docs/RENDER-BACKENDS.md +50 -0
- package/docs/ROADMAP.md +239 -0
- package/docs/THIRD-PARTY-NOTICES.md +151 -0
- package/docs/api/REFERENCE.md +1435 -0
- package/docs/api/index.json +1139 -0
- package/docs/npm/DISTRIBUTION.md +130 -0
- package/docs/npm/GAME-AUTHOR.md +147 -0
- package/engine.manifest.json +15 -0
- package/lib/assets/audio.js +67 -0
- package/lib/assets/errors.js +36 -0
- package/lib/assets/glb.js +277 -0
- package/lib/assets/index.js +53 -0
- package/lib/assets/jpeg.js +199 -0
- package/lib/assets/model.js +558 -0
- package/lib/assets/optimize.js +95 -0
- package/lib/assets/texture.js +187 -0
- package/lib/compiler/distribution.js +17 -0
- package/lib/compiler/extract.js +425 -0
- package/lib/compiler/graph.js +366 -0
- package/lib/compiler/index.js +574 -0
- package/lib/compiler/normalize.js +1194 -0
- package/lib/compiler/source-map.js +25 -0
- package/lib/compiler/types.js +2 -0
- package/lib/compiler/version.js +93 -0
- package/lib/experiments/simulation/index.js +2 -0
- package/lib/experiments/simulation/math.js +41 -0
- package/lib/experiments/simulation/probe.js +215 -0
- package/lib/experiments/simulation/scenes.js +192 -0
- package/lib/experiments/simulation/solver.js +346 -0
- package/lib/experiments/simulation/types.js +1 -0
- package/lib/experiments/world/adapters.js +30 -0
- package/lib/experiments/world/geometry.js +180 -0
- package/lib/experiments/world/index.js +2 -0
- package/lib/experiments/world/probe.js +288 -0
- package/lib/experiments/world/types.js +1 -0
- package/lib/experiments/world/world.js +599 -0
- package/lib/navigation/index.js +157 -0
- package/lib/physics/index.js +909 -0
- package/lib/protocol/index.js +92 -0
- package/lib/renderer/acceleration.js +609 -0
- package/lib/renderer/browser.js +2015 -0
- package/lib/renderer/bsdf.js +260 -0
- package/lib/renderer/checkpoint.js +88 -0
- package/lib/renderer/compute-executor.js +1034 -0
- package/lib/renderer/compute-texture-assets.js +49 -0
- package/lib/renderer/compute-view-contract.js +1 -0
- package/lib/renderer/denoiser.js +361 -0
- package/lib/renderer/dielectric.js +360 -0
- package/lib/renderer/embedded-image-pixels.js +368 -0
- package/lib/renderer/emissive-lights.js +67 -0
- package/lib/renderer/environment-importance.js +55 -0
- package/lib/renderer/environment.js +346 -0
- package/lib/renderer/gameplay.js +464 -0
- package/lib/renderer/geometry.js +103 -0
- package/lib/renderer/graph-expressions.js +485 -0
- package/lib/renderer/graph-tsl.js +141 -0
- package/lib/renderer/graph.js +214 -0
- package/lib/renderer/managed-texture-sampling.js +29 -0
- package/lib/renderer/material-graphs.js +297 -0
- package/lib/renderer/medium.js +348 -0
- package/lib/renderer/models.js +1053 -0
- package/lib/renderer/motion-shader.js +40 -0
- package/lib/renderer/path-shader.js +196 -0
- package/lib/renderer/pathtrace.js +324 -0
- package/lib/renderer/postprocess-contract.js +1 -0
- package/lib/renderer/postprocess.js +494 -0
- package/lib/renderer/render-buffers.js +132 -0
- package/lib/renderer/render-textures.js +155 -0
- package/lib/renderer/startup.js +50 -0
- package/lib/renderer/surface-capture.js +199 -0
- package/lib/renderer/surface-gpu.js +270 -0
- package/lib/renderer/surface-motion.js +84 -0
- package/lib/renderer/surface-ray-shader.js +91 -0
- package/lib/renderer/surface-shader.js +88 -0
- package/lib/renderer/surface-tracer.js +1720 -0
- package/lib/renderer/surface.js +1425 -0
- package/lib/renderer/temporal-filter.js +512 -0
- package/lib/renderer/texture-pixels.js +207 -0
- package/lib/renderer/traversal-nodes.js +54 -0
- package/lib/renderer/ui.js +446 -0
- package/lib/renderer/vertex-bounds.js +127 -0
- package/lib/renderer/vertex-contract.js +1 -0
- package/lib/renderer/vertex-graphs.js +197 -0
- package/lib/renderer/volume-shader.js +50 -0
- package/lib/runtime/compute-contract.js +1 -0
- package/lib/runtime/compute-service.js +674 -0
- package/lib/runtime/contracts.js +1 -0
- package/lib/runtime/error.js +37 -0
- package/lib/runtime/events.js +189 -0
- package/lib/runtime/game-services.js +772 -0
- package/lib/runtime/host.js +839 -0
- package/lib/runtime/material-parameters.js +145 -0
- package/lib/runtime/plugins.js +1 -0
- package/lib/runtime/postprocess-contract.js +1 -0
- package/lib/runtime/postprocess.js +189 -0
- package/lib/runtime/prefabs.js +13 -0
- package/lib/runtime/random.js +88 -0
- package/lib/runtime/render-buffer-contract.js +1 -0
- package/lib/runtime/render-buffers.js +243 -0
- package/lib/runtime/render-capabilities.js +17 -0
- package/lib/runtime/render-settings.js +249 -0
- package/lib/runtime/render-texture-contract.js +1 -0
- package/lib/runtime/render-textures.js +271 -0
- package/lib/runtime/resources.js +648 -0
- package/lib/runtime/scheduler.js +765 -0
- package/lib/runtime/storage.js +169 -0
- package/lib/runtime/world.js +594 -0
- package/lib/schema/index.js +24 -0
- package/lib/sdk/graph-values.js +16 -0
- package/lib/sdk/index.d.ts +800 -0
- package/lib/sdk/index.js +82 -0
- package/lib/tools/api-index.js +113 -0
- package/lib/tools/browser-session.js +89 -0
- package/lib/tools/cli.js +513 -0
- package/lib/tools/compress-dist.js +59 -0
- package/lib/tools/control-client.js +153 -0
- package/lib/tools/control-server.js +633 -0
- package/lib/tools/diagnostic-code.js +3 -0
- package/lib/tools/doctor.js +496 -0
- package/lib/tools/npm/browser-cli.js +6 -0
- package/lib/tools/npm/entry.js +40 -0
- package/lib/tools/npm/layout.js +195 -0
- package/lib/tools/setup.js +153 -0
- package/licenses/@dimforge/rapier2d-compat/LICENSE +201 -0
- package/licenses/@dimforge/rapier3d-compat/LICENSE +201 -0
- package/licenses/@gltf-transform/core/LICENSE.md +21 -0
- package/licenses/@gltf-transform/extensions/LICENSE.md +21 -0
- package/licenses/@gltf-transform/functions/LICENSE.md +21 -0
- package/licenses/@img/colour/LICENSE.md +82 -0
- package/licenses/@img/sharp-win32-x64/LICENSE +191 -0
- package/licenses/@oxc-project/types/LICENSE +22 -0
- package/licenses/@rolldown/pluginutils/LICENSE +21 -0
- package/licenses/@tweenjs/tween.js/LICENSE +23 -0
- package/licenses/@types/ndarray/LICENSE +21 -0
- package/licenses/@types/node/LICENSE +21 -0
- package/licenses/@types/stats.js/LICENSE +21 -0
- package/licenses/@types/three/@dimforge/rapier3d-compat/LICENSE +201 -0
- package/licenses/@types/three/LICENSE +21 -0
- package/licenses/@types/webxr/LICENSE +21 -0
- package/licenses/@webgpu/types/LICENSE +26 -0
- package/licenses/THIRD-PARTY-NOTICES.md +139 -0
- package/licenses/cwise-compiler/LICENSE +22 -0
- package/licenses/detect-libc/LICENSE +201 -0
- package/licenses/esbuild/LICENSE.md +21 -0
- package/licenses/fast-png/LICENSE +21 -0
- package/licenses/fdir/LICENSE +7 -0
- package/licenses/fflate/LICENSE +21 -0
- package/licenses/iobuffer/LICENSE +22 -0
- package/licenses/iota-array/LICENSE +22 -0
- package/licenses/is-buffer/LICENSE +21 -0
- package/licenses/ktx-parse/LICENSE +21 -0
- package/licenses/lightningcss/LICENSE +373 -0
- package/licenses/lightningcss-win32-x64-msvc/LICENSE +373 -0
- package/licenses/meshoptimizer/LICENSE.md +21 -0
- package/licenses/nanoid/LICENSE +20 -0
- package/licenses/ndarray/LICENSE +22 -0
- package/licenses/ndarray-lanczos/LICENSE +21 -0
- package/licenses/ndarray-ops/LICENSE +22 -0
- package/licenses/ndarray-pixels/LICENSE +21 -0
- package/licenses/ngraph.path/LICENSE +21 -0
- package/licenses/picocolors/LICENSE +15 -0
- package/licenses/picomatch/LICENSE +21 -0
- package/licenses/playwright/LICENSE +202 -0
- package/licenses/playwright/NOTICE +5 -0
- package/licenses/playwright-core/LICENSE +202 -0
- package/licenses/playwright-core/NOTICE +5 -0
- package/licenses/postcss/LICENSE +20 -0
- package/licenses/prettier/LICENSE +7 -0
- package/licenses/property-graph/LICENSE +21 -0
- package/licenses/rolldown/LICENSE +25 -0
- package/licenses/semver/LICENSE +15 -0
- package/licenses/sharp/LICENSE +191 -0
- package/licenses/source-map-js/LICENSE +28 -0
- package/licenses/three/LICENSE +21 -0
- package/licenses/tinyglobby/LICENSE +21 -0
- package/licenses/tsx/LICENSE +21 -0
- package/licenses/typescript/LICENSE.txt +55 -0
- package/licenses/undici-types/LICENSE +21 -0
- package/licenses/uniq/LICENSE +22 -0
- package/licenses/vite/LICENSE.md +2084 -0
- package/package.json +49 -4
- package/web/index.html +34 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SYSTEM_PHASES } from "../sdk/index.js";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function diagnosticFrom(error, context = {}) {
|
|
2
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3
|
+
return {
|
|
4
|
+
code: message.match(/\bTC_[A-Z0-9_]+/)?.[0] ?? "TC_RUNTIME_FAILURE",
|
|
5
|
+
severity: "error",
|
|
6
|
+
message,
|
|
7
|
+
remediation: "Inspect the referenced entity, system or resource; correct the source and rerun the failing operation.",
|
|
8
|
+
...context,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function assertJSON(value, label = "state") {
|
|
12
|
+
const ancestors = new Set();
|
|
13
|
+
function visit(item) {
|
|
14
|
+
if (item === null || typeof item === "string" || typeof item === "boolean")
|
|
15
|
+
return;
|
|
16
|
+
if (typeof item === "number" && Number.isFinite(item))
|
|
17
|
+
return;
|
|
18
|
+
if (typeof item !== "object" ||
|
|
19
|
+
!item ||
|
|
20
|
+
(Object.getPrototypeOf(item) !== Object.prototype && !Array.isArray(item)))
|
|
21
|
+
throw new Error(`TC_STATE_SERIALIZATION: ${label} must contain only finite JSON data.`);
|
|
22
|
+
if (ancestors.has(item))
|
|
23
|
+
throw new Error(`TC_STATE_CYCLE: ${label} contains a cycle.`);
|
|
24
|
+
ancestors.add(item);
|
|
25
|
+
if (Array.isArray(item))
|
|
26
|
+
for (const child of item)
|
|
27
|
+
visit(child);
|
|
28
|
+
else
|
|
29
|
+
for (const [key, child] of Object.entries(item)) {
|
|
30
|
+
if (["__proto__", "constructor", "prototype"].includes(key))
|
|
31
|
+
throw new Error(`TC_STATE_KEY: Invalid key in ${label}.`);
|
|
32
|
+
visit(child);
|
|
33
|
+
}
|
|
34
|
+
ancestors.delete(item);
|
|
35
|
+
}
|
|
36
|
+
visit(value);
|
|
37
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { cloneSerializable } from "./random.js";
|
|
2
|
+
export function validateEventSnapshot(value, completedTick = 0) {
|
|
3
|
+
const data = cloneSerializable(value);
|
|
4
|
+
if (!data ||
|
|
5
|
+
data.format !== "pelican.events" ||
|
|
6
|
+
data.version !== 1 ||
|
|
7
|
+
!Number.isSafeInteger(data.nextSequence) ||
|
|
8
|
+
data.nextSequence < 0 ||
|
|
9
|
+
!Array.isArray(data.queue))
|
|
10
|
+
throw new Error("TC_EVENT_SNAPSHOT: Unsupported or malformed event snapshot.");
|
|
11
|
+
const sequences = new Set();
|
|
12
|
+
for (const e of data.queue) {
|
|
13
|
+
if (!e ||
|
|
14
|
+
typeof e.type !== "string" ||
|
|
15
|
+
!e.type.trim() ||
|
|
16
|
+
!Object.hasOwn(e, "payload") ||
|
|
17
|
+
!Number.isSafeInteger(e.tick) ||
|
|
18
|
+
e.tick <= completedTick ||
|
|
19
|
+
!Number.isSafeInteger(e.sequence) ||
|
|
20
|
+
e.sequence < 0 ||
|
|
21
|
+
e.sequence >= data.nextSequence ||
|
|
22
|
+
sequences.has(e.sequence) ||
|
|
23
|
+
!["input", "external", "scheduled", "system"].includes(e.source))
|
|
24
|
+
throw new Error("TC_EVENT_SNAPSHOT: Invalid queued event or duplicate sequence.");
|
|
25
|
+
sequences.add(e.sequence);
|
|
26
|
+
}
|
|
27
|
+
return data;
|
|
28
|
+
}
|
|
29
|
+
/** Due events are detached as a batch. Listener errors do not discard other
|
|
30
|
+
* listeners/events: finish the batch, return all faults, scheduler then pauses.
|
|
31
|
+
* Events emitted during delivery target a later tick, never recurse this batch. */
|
|
32
|
+
export function createEventBus(options = {}) {
|
|
33
|
+
let queue = [], nextSequence = 0, nextListener = 0, cursor = 0, delivering = false, disposed = false;
|
|
34
|
+
const tick = () => Math.max(cursor, options.currentTick?.() ?? 0);
|
|
35
|
+
const ensure = () => {
|
|
36
|
+
if (disposed)
|
|
37
|
+
throw new Error("TC_EVENT_DISPOSED: Event bus is disposed.");
|
|
38
|
+
};
|
|
39
|
+
const listeners = new Map();
|
|
40
|
+
return {
|
|
41
|
+
on(type, callback, config = {}) {
|
|
42
|
+
ensure();
|
|
43
|
+
options.beforeSubscribe?.();
|
|
44
|
+
if (typeof type !== "string" ||
|
|
45
|
+
!type.trim() ||
|
|
46
|
+
typeof callback !== "function")
|
|
47
|
+
throw new Error("TC_EVENT_LISTENER: Expected event type and callback.");
|
|
48
|
+
if (callback.constructor.name === "AsyncFunction")
|
|
49
|
+
throw new Error("TC_EVENT_ASYNC: Listeners must be synchronous.");
|
|
50
|
+
const id = config.id ?? `listener:${nextListener++}`;
|
|
51
|
+
if (!id.trim() || listeners.has(id))
|
|
52
|
+
throw new Error(`TC_EVENT_LISTENER: Duplicate or empty listener id ${id}.`);
|
|
53
|
+
const listener = {
|
|
54
|
+
type,
|
|
55
|
+
callback,
|
|
56
|
+
access: cloneSerializable(config.access ?? {}),
|
|
57
|
+
};
|
|
58
|
+
listeners.set(id, listener);
|
|
59
|
+
return () => {
|
|
60
|
+
if (disposed)
|
|
61
|
+
return;
|
|
62
|
+
options.beforeSubscribe?.();
|
|
63
|
+
if (listeners.get(id) === listener)
|
|
64
|
+
listeners.delete(id);
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
emit(type, payload, config = {}) {
|
|
68
|
+
ensure();
|
|
69
|
+
const target = config.tick ?? tick() + 1;
|
|
70
|
+
const source = config.source ?? options.defaultSource?.() ?? "external";
|
|
71
|
+
if (typeof type !== "string" ||
|
|
72
|
+
!type.trim() ||
|
|
73
|
+
!Number.isSafeInteger(target) ||
|
|
74
|
+
target <= tick() ||
|
|
75
|
+
!["input", "external", "scheduled", "system"].includes(source))
|
|
76
|
+
throw new Error("TC_EVENT_EMIT: Expected a named event targeting a future integer tick.");
|
|
77
|
+
if (!Number.isSafeInteger(nextSequence + 1))
|
|
78
|
+
throw new Error("TC_EVENT_LIMIT: Event sequence exhausted.");
|
|
79
|
+
const event = {
|
|
80
|
+
type,
|
|
81
|
+
payload: cloneSerializable(payload),
|
|
82
|
+
tick: target,
|
|
83
|
+
sequence: nextSequence,
|
|
84
|
+
source,
|
|
85
|
+
};
|
|
86
|
+
options.beforeEmit?.(cloneSerializable(event));
|
|
87
|
+
queue.push(event);
|
|
88
|
+
nextSequence++;
|
|
89
|
+
return cloneSerializable(event);
|
|
90
|
+
},
|
|
91
|
+
deliver(targetTick) {
|
|
92
|
+
ensure();
|
|
93
|
+
if (delivering)
|
|
94
|
+
throw new Error("TC_EVENT_REENTRANT: Nested delivery is forbidden.");
|
|
95
|
+
if (!Number.isSafeInteger(targetTick) || targetTick < tick())
|
|
96
|
+
throw new Error("TC_EVENT_TICK: Delivery requires a non-decreasing integer tick.");
|
|
97
|
+
const due = queue
|
|
98
|
+
.filter((e) => e.tick <= targetTick)
|
|
99
|
+
.sort((a, b) => a.tick - b.tick || a.sequence - b.sequence);
|
|
100
|
+
queue = queue.filter((e) => e.tick > targetTick);
|
|
101
|
+
const batchListeners = [...listeners];
|
|
102
|
+
const report = {
|
|
103
|
+
delivered: due.length,
|
|
104
|
+
notifications: 0,
|
|
105
|
+
faults: [],
|
|
106
|
+
};
|
|
107
|
+
delivering = true;
|
|
108
|
+
cursor = targetTick;
|
|
109
|
+
try {
|
|
110
|
+
options.onDelivery?.(cloneSerializable(due));
|
|
111
|
+
for (const event of due)
|
|
112
|
+
for (const [id, listener] of batchListeners) {
|
|
113
|
+
if (listener.type !== event.type)
|
|
114
|
+
continue;
|
|
115
|
+
let asynchronous = false;
|
|
116
|
+
try {
|
|
117
|
+
const call = () => {
|
|
118
|
+
const result = listener.callback(cloneSerializable(event));
|
|
119
|
+
if (result &&
|
|
120
|
+
(typeof result === "object" ||
|
|
121
|
+
typeof result === "function") &&
|
|
122
|
+
"then" in result) {
|
|
123
|
+
asynchronous = true;
|
|
124
|
+
void Promise.resolve(result).catch(() => { });
|
|
125
|
+
throw new Error("Event listeners must complete synchronously.");
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
if (options.dispatch)
|
|
129
|
+
options.dispatch(id, listener.access, call);
|
|
130
|
+
else
|
|
131
|
+
call();
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
report.faults.push({
|
|
135
|
+
code: asynchronous ? "TC_EVENT_ASYNC" : "TC_EVENT_LISTENER",
|
|
136
|
+
listener: id,
|
|
137
|
+
type: event.type,
|
|
138
|
+
sequence: event.sequence,
|
|
139
|
+
message: error instanceof Error ? error.message : String(error),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
report.notifications++;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
delivering = false;
|
|
147
|
+
}
|
|
148
|
+
return report;
|
|
149
|
+
},
|
|
150
|
+
snapshot() {
|
|
151
|
+
ensure();
|
|
152
|
+
return cloneSerializable({
|
|
153
|
+
format: "pelican.events",
|
|
154
|
+
version: 1,
|
|
155
|
+
nextSequence,
|
|
156
|
+
queue,
|
|
157
|
+
});
|
|
158
|
+
},
|
|
159
|
+
restore(value, completedTick = tick()) {
|
|
160
|
+
ensure();
|
|
161
|
+
if (delivering)
|
|
162
|
+
throw new Error("TC_EVENT_REENTRANT: Cannot restore during delivery.");
|
|
163
|
+
if (!Number.isSafeInteger(completedTick) || completedTick < 0)
|
|
164
|
+
throw new Error("TC_EVENT_TICK: Invalid checkpoint tick.");
|
|
165
|
+
const data = validateEventSnapshot(value, completedTick);
|
|
166
|
+
queue = data.queue;
|
|
167
|
+
nextSequence = data.nextSequence;
|
|
168
|
+
cursor = completedTick;
|
|
169
|
+
},
|
|
170
|
+
inspect() {
|
|
171
|
+
return {
|
|
172
|
+
queued: queue.length,
|
|
173
|
+
nextSequence,
|
|
174
|
+
listeners: [...listeners].map(([id, listener]) => ({
|
|
175
|
+
id,
|
|
176
|
+
type: listener.type,
|
|
177
|
+
access: cloneSerializable(listener.access),
|
|
178
|
+
})),
|
|
179
|
+
};
|
|
180
|
+
},
|
|
181
|
+
dispose() {
|
|
182
|
+
if (delivering)
|
|
183
|
+
throw new Error("TC_EVENT_REENTRANT: Cannot dispose during delivery.");
|
|
184
|
+
queue = [];
|
|
185
|
+
listeners.clear();
|
|
186
|
+
disposed = true;
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
}
|