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,157 @@
|
|
|
1
|
+
import { aStar } from "ngraph.path";
|
|
2
|
+
const DEFAULT_SEARCH_CELLS = 65536;
|
|
3
|
+
const fail = (code, detail) => { throw new Error(`TC_NAVIGATION_${code}: ${detail}`); };
|
|
4
|
+
const name = (value) => typeof value === "string" && value.trim().length > 0;
|
|
5
|
+
function parseGrid(value) {
|
|
6
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
7
|
+
return fail("GRID", "Expected a grid definition.");
|
|
8
|
+
const grid = value;
|
|
9
|
+
// JavaScript arrays have a maximum length of 2^32 - 1; linear cell indices must fit it.
|
|
10
|
+
if (!name(grid.id) || !name(grid.owner) || !Number.isSafeInteger(grid.width) || !Number.isSafeInteger(grid.height) || grid.width < 1 || grid.height < 1 || grid.width * grid.height > 0xffffffff)
|
|
11
|
+
return fail("GRID", "Grid requires id, owner and positive integer dimensions with at most 4294967295 cells (JavaScript array length limit); split larger grids.");
|
|
12
|
+
if (grid.blocked !== undefined && !Array.isArray(grid.blocked))
|
|
13
|
+
return fail("GRID", "blocked must be an array of cells.");
|
|
14
|
+
if (grid.searchCellBudget !== undefined && (!Number.isSafeInteger(grid.searchCellBudget) || grid.searchCellBudget < 1 || grid.searchCellBudget > 0xffffffff))
|
|
15
|
+
return fail("GRID", "searchCellBudget must be a positive integer no greater than 4294967295.");
|
|
16
|
+
const result = { id: grid.id, owner: grid.owner, width: grid.width, height: grid.height, blocked: [], ...(grid.searchCellBudget === undefined ? {} : { searchCellBudget: grid.searchCellBudget }) };
|
|
17
|
+
const seen = new Set();
|
|
18
|
+
for (const point of grid.blocked ?? []) {
|
|
19
|
+
const index = cell(result, point);
|
|
20
|
+
if (seen.has(index))
|
|
21
|
+
return fail("GRID", "Duplicate blocked cell.");
|
|
22
|
+
seen.add(index);
|
|
23
|
+
result.blocked.push(index);
|
|
24
|
+
}
|
|
25
|
+
result.blocked.sort((a, b) => a - b);
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
function cell(grid, point) {
|
|
29
|
+
if (!point || typeof point !== "object" || !Number.isSafeInteger(point.x) || !Number.isSafeInteger(point.y) || point.x < 0 || point.y < 0 || point.x >= grid.width || point.y >= grid.height)
|
|
30
|
+
return fail("CELL", `Cell must be within grid '${grid.id}'.`);
|
|
31
|
+
return point.y * grid.width + point.x;
|
|
32
|
+
}
|
|
33
|
+
function definition(grid) {
|
|
34
|
+
return { id: grid.id, owner: grid.owner, width: grid.width, height: grid.height, blocked: grid.blocked.map((i) => ({ x: i % grid.width, y: Math.floor(i / grid.width) })), ...(grid.searchCellBudget === undefined ? {} : { searchCellBudget: grid.searchCellBudget }) };
|
|
35
|
+
}
|
|
36
|
+
function blockedIndex(grid, index) {
|
|
37
|
+
let lower = 0, upper = grid.blocked.length;
|
|
38
|
+
while (lower < upper) {
|
|
39
|
+
const middle = lower + Math.floor((upper - lower) / 2);
|
|
40
|
+
if (grid.blocked[middle] < index)
|
|
41
|
+
lower = middle + 1;
|
|
42
|
+
else
|
|
43
|
+
upper = middle;
|
|
44
|
+
}
|
|
45
|
+
return lower;
|
|
46
|
+
}
|
|
47
|
+
function parseSnapshot(value) {
|
|
48
|
+
if (!value || typeof value !== "object" || value.version !== 1 || !Array.isArray(value.grids))
|
|
49
|
+
return fail("SNAPSHOT", "Invalid navigation snapshot.");
|
|
50
|
+
const result = new Map();
|
|
51
|
+
for (const item of value.grids) {
|
|
52
|
+
const grid = parseGrid(item);
|
|
53
|
+
if (result.has(grid.id))
|
|
54
|
+
return fail("SNAPSHOT", `Duplicate grid '${grid.id}'.`);
|
|
55
|
+
result.set(grid.id, grid);
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
export const createNavigationPlugin = () => {
|
|
60
|
+
let grids = new Map();
|
|
61
|
+
let disposed = false;
|
|
62
|
+
const alive = () => { if (disposed)
|
|
63
|
+
fail("DISPOSED", "Navigation is disposed."); };
|
|
64
|
+
const get = (id) => {
|
|
65
|
+
alive();
|
|
66
|
+
if (!name(id))
|
|
67
|
+
return fail("GRID", "Expected a non-empty grid id.");
|
|
68
|
+
return grids.get(id) ?? fail("MISSING", `Grid '${id}' does not exist.`);
|
|
69
|
+
};
|
|
70
|
+
const service = {
|
|
71
|
+
createGrid(input) {
|
|
72
|
+
alive();
|
|
73
|
+
const grid = parseGrid(input);
|
|
74
|
+
if (grids.has(grid.id))
|
|
75
|
+
fail("DUPLICATE", `Grid '${grid.id}' already exists.`);
|
|
76
|
+
grids.set(grid.id, grid);
|
|
77
|
+
},
|
|
78
|
+
getGrid(id) { return definition(get(id)); },
|
|
79
|
+
isBlocked(id, point) {
|
|
80
|
+
const grid = get(id), index = cell(grid, point);
|
|
81
|
+
return grid.blocked[blockedIndex(grid, index)] === index;
|
|
82
|
+
},
|
|
83
|
+
setBlocked(id, point, blocked) {
|
|
84
|
+
const grid = get(id), index = cell(grid, point);
|
|
85
|
+
if (typeof blocked !== "boolean")
|
|
86
|
+
fail("BLOCKED", "Expected a boolean.");
|
|
87
|
+
const lower = blockedIndex(grid, index);
|
|
88
|
+
const exists = grid.blocked[lower] === index;
|
|
89
|
+
if (blocked && !exists)
|
|
90
|
+
grid.blocked.splice(lower, 0, index);
|
|
91
|
+
else if (!blocked && exists)
|
|
92
|
+
grid.blocked.splice(lower, 1);
|
|
93
|
+
},
|
|
94
|
+
findPath(id, start, end) {
|
|
95
|
+
const grid = get(id), from = cell(grid, start), to = cell(grid, end);
|
|
96
|
+
const blocked = new Set(grid.blocked);
|
|
97
|
+
if (blocked.has(from) || blocked.has(to))
|
|
98
|
+
fail("BLOCKED", "Start or destination is blocked.");
|
|
99
|
+
const budget = grid.searchCellBudget ?? DEFAULT_SEARCH_CELLS;
|
|
100
|
+
const nodes = new Map();
|
|
101
|
+
const node = (index) => {
|
|
102
|
+
const existing = nodes.get(index);
|
|
103
|
+
if (existing)
|
|
104
|
+
return existing;
|
|
105
|
+
if (nodes.size >= budget)
|
|
106
|
+
return fail("CAPACITY", `Search on grid '${id}' exceeded searchCellBudget ${budget}; reduce or partition the search, or explicitly increase the budget after assessing memory and CPU cost.`);
|
|
107
|
+
const result = { id: index, x: index % grid.width, y: Math.floor(index / grid.width) };
|
|
108
|
+
nodes.set(index, result);
|
|
109
|
+
return result;
|
|
110
|
+
};
|
|
111
|
+
// The target and each discovered neighbor share identity with getNode's result.
|
|
112
|
+
const graph = {
|
|
113
|
+
getNode: (index) => node(index),
|
|
114
|
+
forEachLinkedNode(index, visit) {
|
|
115
|
+
const x = index % grid.width, y = Math.floor(index / grid.width);
|
|
116
|
+
const visitCell = (next) => {
|
|
117
|
+
if (!blocked.has(next))
|
|
118
|
+
visit(node(next), { fromId: index, toId: next });
|
|
119
|
+
};
|
|
120
|
+
if (y > 0)
|
|
121
|
+
visitCell(index - grid.width);
|
|
122
|
+
if (x > 0)
|
|
123
|
+
visitCell(index - 1);
|
|
124
|
+
if (x + 1 < grid.width)
|
|
125
|
+
visitCell(index + 1);
|
|
126
|
+
if (y + 1 < grid.height)
|
|
127
|
+
visitCell(index + grid.width);
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
const finder = aStar(graph, {
|
|
131
|
+
heuristic: (a, b) => Math.abs(a.x - b.x) + Math.abs(a.y - b.y),
|
|
132
|
+
});
|
|
133
|
+
const path = finder.find(from, to);
|
|
134
|
+
if (!path.length)
|
|
135
|
+
return fail("UNREACHABLE", `Destination is unreachable on grid '${id}'.`);
|
|
136
|
+
return path.reverse().map(({ x, y }) => ({ x, y }));
|
|
137
|
+
},
|
|
138
|
+
destroyGrid(id) { get(id); grids.delete(id); },
|
|
139
|
+
destroyOwner(owner) {
|
|
140
|
+
alive();
|
|
141
|
+
if (!name(owner))
|
|
142
|
+
fail("OWNER", "Expected a non-empty owner.");
|
|
143
|
+
for (const [id, grid] of grids)
|
|
144
|
+
if (grid.owner === owner)
|
|
145
|
+
grids.delete(id);
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
const empty = () => ({ version: 1, grids: [] });
|
|
149
|
+
return {
|
|
150
|
+
id: "$engine.navigation", version: "1", services: { navigation: service },
|
|
151
|
+
snapshot: () => ({ version: 1, grids: [...grids.values()].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0).map(definition) }),
|
|
152
|
+
legacySnapshot: empty,
|
|
153
|
+
validateSnapshot(value) { parseSnapshot(value); },
|
|
154
|
+
restore(value) { alive(); grids = parseSnapshot(value); },
|
|
155
|
+
dispose() { disposed = true; grids.clear(); },
|
|
156
|
+
};
|
|
157
|
+
};
|