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.
Files changed (192) hide show
  1. package/AGENTS.md +147 -0
  2. package/LICENSE +22 -0
  3. package/README.md +129 -2
  4. package/distribution.json +197 -0
  5. package/docs/AI-WORKFLOW.md +517 -0
  6. package/docs/ARCHITECTURE.md +268 -0
  7. package/docs/CAPABILITIES.md +264 -0
  8. package/docs/DECISIONS.md +107 -0
  9. package/docs/M3-USAGE.md +192 -0
  10. package/docs/PELICAN-MIGRATION.md +38 -0
  11. package/docs/RENDER-BACKENDS.md +50 -0
  12. package/docs/ROADMAP.md +239 -0
  13. package/docs/THIRD-PARTY-NOTICES.md +151 -0
  14. package/docs/api/REFERENCE.md +1435 -0
  15. package/docs/api/index.json +1139 -0
  16. package/docs/npm/DISTRIBUTION.md +130 -0
  17. package/docs/npm/GAME-AUTHOR.md +147 -0
  18. package/engine.manifest.json +15 -0
  19. package/lib/assets/audio.js +67 -0
  20. package/lib/assets/errors.js +36 -0
  21. package/lib/assets/glb.js +277 -0
  22. package/lib/assets/index.js +53 -0
  23. package/lib/assets/jpeg.js +199 -0
  24. package/lib/assets/model.js +558 -0
  25. package/lib/assets/optimize.js +95 -0
  26. package/lib/assets/texture.js +187 -0
  27. package/lib/compiler/distribution.js +17 -0
  28. package/lib/compiler/extract.js +425 -0
  29. package/lib/compiler/graph.js +366 -0
  30. package/lib/compiler/index.js +574 -0
  31. package/lib/compiler/normalize.js +1194 -0
  32. package/lib/compiler/source-map.js +25 -0
  33. package/lib/compiler/types.js +2 -0
  34. package/lib/compiler/version.js +93 -0
  35. package/lib/experiments/simulation/index.js +2 -0
  36. package/lib/experiments/simulation/math.js +41 -0
  37. package/lib/experiments/simulation/probe.js +215 -0
  38. package/lib/experiments/simulation/scenes.js +192 -0
  39. package/lib/experiments/simulation/solver.js +346 -0
  40. package/lib/experiments/simulation/types.js +1 -0
  41. package/lib/experiments/world/adapters.js +30 -0
  42. package/lib/experiments/world/geometry.js +180 -0
  43. package/lib/experiments/world/index.js +2 -0
  44. package/lib/experiments/world/probe.js +288 -0
  45. package/lib/experiments/world/types.js +1 -0
  46. package/lib/experiments/world/world.js +599 -0
  47. package/lib/navigation/index.js +157 -0
  48. package/lib/physics/index.js +909 -0
  49. package/lib/protocol/index.js +92 -0
  50. package/lib/renderer/acceleration.js +609 -0
  51. package/lib/renderer/browser.js +2015 -0
  52. package/lib/renderer/bsdf.js +260 -0
  53. package/lib/renderer/checkpoint.js +88 -0
  54. package/lib/renderer/compute-executor.js +1034 -0
  55. package/lib/renderer/compute-texture-assets.js +49 -0
  56. package/lib/renderer/compute-view-contract.js +1 -0
  57. package/lib/renderer/denoiser.js +361 -0
  58. package/lib/renderer/dielectric.js +360 -0
  59. package/lib/renderer/embedded-image-pixels.js +368 -0
  60. package/lib/renderer/emissive-lights.js +67 -0
  61. package/lib/renderer/environment-importance.js +55 -0
  62. package/lib/renderer/environment.js +346 -0
  63. package/lib/renderer/gameplay.js +464 -0
  64. package/lib/renderer/geometry.js +103 -0
  65. package/lib/renderer/graph-expressions.js +485 -0
  66. package/lib/renderer/graph-tsl.js +141 -0
  67. package/lib/renderer/graph.js +214 -0
  68. package/lib/renderer/managed-texture-sampling.js +29 -0
  69. package/lib/renderer/material-graphs.js +297 -0
  70. package/lib/renderer/medium.js +348 -0
  71. package/lib/renderer/models.js +1053 -0
  72. package/lib/renderer/motion-shader.js +40 -0
  73. package/lib/renderer/path-shader.js +196 -0
  74. package/lib/renderer/pathtrace.js +324 -0
  75. package/lib/renderer/postprocess-contract.js +1 -0
  76. package/lib/renderer/postprocess.js +494 -0
  77. package/lib/renderer/render-buffers.js +132 -0
  78. package/lib/renderer/render-textures.js +155 -0
  79. package/lib/renderer/startup.js +50 -0
  80. package/lib/renderer/surface-capture.js +199 -0
  81. package/lib/renderer/surface-gpu.js +270 -0
  82. package/lib/renderer/surface-motion.js +84 -0
  83. package/lib/renderer/surface-ray-shader.js +91 -0
  84. package/lib/renderer/surface-shader.js +88 -0
  85. package/lib/renderer/surface-tracer.js +1720 -0
  86. package/lib/renderer/surface.js +1425 -0
  87. package/lib/renderer/temporal-filter.js +512 -0
  88. package/lib/renderer/texture-pixels.js +207 -0
  89. package/lib/renderer/traversal-nodes.js +54 -0
  90. package/lib/renderer/ui.js +446 -0
  91. package/lib/renderer/vertex-bounds.js +127 -0
  92. package/lib/renderer/vertex-contract.js +1 -0
  93. package/lib/renderer/vertex-graphs.js +197 -0
  94. package/lib/renderer/volume-shader.js +50 -0
  95. package/lib/runtime/compute-contract.js +1 -0
  96. package/lib/runtime/compute-service.js +674 -0
  97. package/lib/runtime/contracts.js +1 -0
  98. package/lib/runtime/error.js +37 -0
  99. package/lib/runtime/events.js +189 -0
  100. package/lib/runtime/game-services.js +772 -0
  101. package/lib/runtime/host.js +839 -0
  102. package/lib/runtime/material-parameters.js +145 -0
  103. package/lib/runtime/plugins.js +1 -0
  104. package/lib/runtime/postprocess-contract.js +1 -0
  105. package/lib/runtime/postprocess.js +189 -0
  106. package/lib/runtime/prefabs.js +13 -0
  107. package/lib/runtime/random.js +88 -0
  108. package/lib/runtime/render-buffer-contract.js +1 -0
  109. package/lib/runtime/render-buffers.js +243 -0
  110. package/lib/runtime/render-capabilities.js +17 -0
  111. package/lib/runtime/render-settings.js +249 -0
  112. package/lib/runtime/render-texture-contract.js +1 -0
  113. package/lib/runtime/render-textures.js +271 -0
  114. package/lib/runtime/resources.js +648 -0
  115. package/lib/runtime/scheduler.js +765 -0
  116. package/lib/runtime/storage.js +169 -0
  117. package/lib/runtime/world.js +594 -0
  118. package/lib/schema/index.js +24 -0
  119. package/lib/sdk/graph-values.js +16 -0
  120. package/lib/sdk/index.d.ts +800 -0
  121. package/lib/sdk/index.js +82 -0
  122. package/lib/tools/api-index.js +113 -0
  123. package/lib/tools/browser-session.js +89 -0
  124. package/lib/tools/cli.js +513 -0
  125. package/lib/tools/compress-dist.js +59 -0
  126. package/lib/tools/control-client.js +153 -0
  127. package/lib/tools/control-server.js +633 -0
  128. package/lib/tools/diagnostic-code.js +3 -0
  129. package/lib/tools/doctor.js +496 -0
  130. package/lib/tools/npm/browser-cli.js +6 -0
  131. package/lib/tools/npm/entry.js +40 -0
  132. package/lib/tools/npm/layout.js +195 -0
  133. package/lib/tools/setup.js +153 -0
  134. package/licenses/@dimforge/rapier2d-compat/LICENSE +201 -0
  135. package/licenses/@dimforge/rapier3d-compat/LICENSE +201 -0
  136. package/licenses/@gltf-transform/core/LICENSE.md +21 -0
  137. package/licenses/@gltf-transform/extensions/LICENSE.md +21 -0
  138. package/licenses/@gltf-transform/functions/LICENSE.md +21 -0
  139. package/licenses/@img/colour/LICENSE.md +82 -0
  140. package/licenses/@img/sharp-win32-x64/LICENSE +191 -0
  141. package/licenses/@oxc-project/types/LICENSE +22 -0
  142. package/licenses/@rolldown/pluginutils/LICENSE +21 -0
  143. package/licenses/@tweenjs/tween.js/LICENSE +23 -0
  144. package/licenses/@types/ndarray/LICENSE +21 -0
  145. package/licenses/@types/node/LICENSE +21 -0
  146. package/licenses/@types/stats.js/LICENSE +21 -0
  147. package/licenses/@types/three/@dimforge/rapier3d-compat/LICENSE +201 -0
  148. package/licenses/@types/three/LICENSE +21 -0
  149. package/licenses/@types/webxr/LICENSE +21 -0
  150. package/licenses/@webgpu/types/LICENSE +26 -0
  151. package/licenses/THIRD-PARTY-NOTICES.md +139 -0
  152. package/licenses/cwise-compiler/LICENSE +22 -0
  153. package/licenses/detect-libc/LICENSE +201 -0
  154. package/licenses/esbuild/LICENSE.md +21 -0
  155. package/licenses/fast-png/LICENSE +21 -0
  156. package/licenses/fdir/LICENSE +7 -0
  157. package/licenses/fflate/LICENSE +21 -0
  158. package/licenses/iobuffer/LICENSE +22 -0
  159. package/licenses/iota-array/LICENSE +22 -0
  160. package/licenses/is-buffer/LICENSE +21 -0
  161. package/licenses/ktx-parse/LICENSE +21 -0
  162. package/licenses/lightningcss/LICENSE +373 -0
  163. package/licenses/lightningcss-win32-x64-msvc/LICENSE +373 -0
  164. package/licenses/meshoptimizer/LICENSE.md +21 -0
  165. package/licenses/nanoid/LICENSE +20 -0
  166. package/licenses/ndarray/LICENSE +22 -0
  167. package/licenses/ndarray-lanczos/LICENSE +21 -0
  168. package/licenses/ndarray-ops/LICENSE +22 -0
  169. package/licenses/ndarray-pixels/LICENSE +21 -0
  170. package/licenses/ngraph.path/LICENSE +21 -0
  171. package/licenses/picocolors/LICENSE +15 -0
  172. package/licenses/picomatch/LICENSE +21 -0
  173. package/licenses/playwright/LICENSE +202 -0
  174. package/licenses/playwright/NOTICE +5 -0
  175. package/licenses/playwright-core/LICENSE +202 -0
  176. package/licenses/playwright-core/NOTICE +5 -0
  177. package/licenses/postcss/LICENSE +20 -0
  178. package/licenses/prettier/LICENSE +7 -0
  179. package/licenses/property-graph/LICENSE +21 -0
  180. package/licenses/rolldown/LICENSE +25 -0
  181. package/licenses/semver/LICENSE +15 -0
  182. package/licenses/sharp/LICENSE +191 -0
  183. package/licenses/source-map-js/LICENSE +28 -0
  184. package/licenses/three/LICENSE +21 -0
  185. package/licenses/tinyglobby/LICENSE +21 -0
  186. package/licenses/tsx/LICENSE +21 -0
  187. package/licenses/typescript/LICENSE.txt +55 -0
  188. package/licenses/undici-types/LICENSE +21 -0
  189. package/licenses/uniq/LICENSE +22 -0
  190. package/licenses/vite/LICENSE.md +2084 -0
  191. package/package.json +49 -4
  192. package/web/index.html +34 -0
@@ -0,0 +1,82 @@
1
+ /** Pelican Engine public API. No renderer or GPU implementation types escape this module. */
2
+ export const SDK_VERSION = "0.3.1";
3
+ export const SYSTEM_PHASES = [
4
+ "input",
5
+ "prePhysics",
6
+ "physics",
7
+ "postPhysics",
8
+ "update",
9
+ "presentation",
10
+ ];
11
+ export const GRAPH_TYPES = ["float", "vec2", "vec3", "vec4", "bool"];
12
+ export const GRAPH_INPUT_TYPES = {
13
+ uv: "vec2", uv1: "vec2", positionWorld: "vec3", normalWorld: "vec3",
14
+ viewDirectionWorld: "vec3", vertexColor: "vec4", index: "float",
15
+ screenSize: "vec2", texelSize: "vec2",
16
+ pixelCoord: "vec2", outputSize: "vec2",
17
+ positionLocal: "vec3", normalLocal: "vec3", vertexIndex: "float", instanceIndex: "float",
18
+ };
19
+ export const GRAPH_OPERATIONS = {
20
+ unary: ["sin", "cos", "abs", "floor", "ceil", "fract", "negate", "saturate", "normalize", "length", "safeSqrt"],
21
+ binary: ["add", "subtract", "multiply", "safeDivide", "min", "max", "dot", "cross", "step", "lessThan", "lessEqual", "greaterThan", "greaterEqual", "equal", "and", "or"],
22
+ ternary: ["mix", "clamp", "smoothstep", "select"],
23
+ };
24
+ export function defineComponent(input) {
25
+ return { ...input, kind: "component" };
26
+ }
27
+ export function defineMaterial(input) {
28
+ return { ...input, kind: "material" };
29
+ }
30
+ export function definePostProcess(input) {
31
+ return { ...input, kind: "postprocess" };
32
+ }
33
+ export function defineCompute(input) {
34
+ return { ...input, kind: "compute" };
35
+ }
36
+ export function defineAsset(input) {
37
+ return { ...input, kind: "asset" };
38
+ }
39
+ export function definePrefab(input) {
40
+ return { ...input, kind: "prefab" };
41
+ }
42
+ export function defineScene(input) {
43
+ return { ...input, kind: "scene" };
44
+ }
45
+ export function defineSystem(input) {
46
+ return { ...input, kind: "system" };
47
+ }
48
+ export function defineGame(input) {
49
+ return { ...input, kind: "game" };
50
+ }
51
+ /** Runtime wrapper used by compiled game.js. Source declarations are never imported by the compiler. */
52
+ export function instantiateGame(game, engine) {
53
+ let disposed = false;
54
+ const systems = [...(game.systems ?? [])];
55
+ engine.configureGameSystems?.(systems);
56
+ return {
57
+ update(dt) {
58
+ if (disposed)
59
+ throw new Error("TC_RUNTIME_DISPOSED: Game has been disposed.");
60
+ if (!Number.isFinite(dt) || dt < 0)
61
+ throw new Error("TC_RUNTIME_DT: Expected a finite, non-negative timestep.");
62
+ if (engine.runGameSystems)
63
+ engine.runGameSystems(systems, dt);
64
+ else {
65
+ // Compatibility for the M0 facade harness; the M1 browser host always owns scheduling.
66
+ const context = new Proxy(engine, {
67
+ get(target, key, receiver) {
68
+ if (["time", "entities", "random", "emit", "events"].includes(String(key)))
69
+ throw new Error(`TC_RUNTIME_SERVICE_UNAVAILABLE: ${String(key)} requires a pelican runtime host.`);
70
+ return Reflect.get(target, key, receiver);
71
+ },
72
+ });
73
+ for (const system of systems)
74
+ system.run(context, dt);
75
+ }
76
+ },
77
+ dispose() {
78
+ disposed = true;
79
+ systems.length = 0;
80
+ },
81
+ };
82
+ }
@@ -0,0 +1,113 @@
1
+ import ts from "typescript";
2
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { SDK_VERSION } from "../sdk/index.js";
6
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
7
+ export function queryApiSymbol(symbols, args) {
8
+ const positions = args.flatMap((arg, i) => arg === "--symbol" ? [i] : []);
9
+ if (positions.length === 0)
10
+ return undefined;
11
+ if (positions.length !== 1)
12
+ throw new Error("TC_API_SYMBOL_DUPLICATE: Supply --symbol exactly once.");
13
+ const name = args[positions[0] + 1];
14
+ if (!name || name.startsWith("--"))
15
+ throw new Error("TC_API_SYMBOL_REQUIRED: Supply a public symbol name after --symbol.");
16
+ const matches = symbols.filter((symbol) => symbol.name === name);
17
+ if (matches.length === 0)
18
+ throw new Error("TC_API_SYMBOL_UNKNOWN: Symbol not found; use pelican api to inspect the public index and check exact spelling and case.");
19
+ return matches;
20
+ }
21
+ /** Public SDK source is the sole signature source; this file does not maintain duplicate API declarations. */
22
+ export async function generateApiIndex(engineRoot = root) {
23
+ const filename = path.join(engineRoot, "packages/sdk/src/index.ts");
24
+ const source = await readFile(filename, "utf8");
25
+ const sf = ts.createSourceFile(filename, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
26
+ const symbols = [];
27
+ for (const statement of sf.statements) {
28
+ if (!ts.canHaveModifiers(statement) ||
29
+ !ts
30
+ .getModifiers(statement)
31
+ ?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword))
32
+ continue;
33
+ const location = sf.getLineAndCharacterOfPosition(statement.getStart());
34
+ if (ts.isVariableStatement(statement)) {
35
+ for (const declaration of statement.declarationList.declarations)
36
+ symbols.push({
37
+ name: declaration.name.getText(sf),
38
+ kind: "constant",
39
+ signature: declaration.getText(sf),
40
+ line: location.line + 1,
41
+ });
42
+ }
43
+ else if (ts.isInterfaceDeclaration(statement) ||
44
+ ts.isTypeAliasDeclaration(statement) ||
45
+ ts.isFunctionDeclaration(statement)) {
46
+ const name = statement.name?.text;
47
+ if (!name)
48
+ continue;
49
+ const signature = ts.isFunctionDeclaration(statement) && statement.body
50
+ ? statement
51
+ .getText(sf)
52
+ .slice(0, statement.body.getStart() - statement.getStart())
53
+ .trim() + ";"
54
+ : statement.getText(sf);
55
+ symbols.push({
56
+ name,
57
+ kind: ts.SyntaxKind[statement.kind],
58
+ signature,
59
+ line: location.line + 1,
60
+ ...(ts.isInterfaceDeclaration(statement)
61
+ ? {
62
+ fields: statement.members
63
+ .map((m) => m.name?.getText(sf))
64
+ .filter((v) => !!v),
65
+ }
66
+ : {}),
67
+ });
68
+ }
69
+ }
70
+ const index = {
71
+ format: "pelican.api-index",
72
+ version: 1,
73
+ engineVersion: SDK_VERSION,
74
+ entry: "pelican-engine",
75
+ source: "packages/sdk/src/index.ts",
76
+ symbols,
77
+ };
78
+ const output = path.join(engineRoot, "docs/api");
79
+ await mkdir(output, { recursive: true });
80
+ await writeFile(path.join(output, "index.json"), JSON.stringify(index, null, 2) + "\n");
81
+ const reference = [
82
+ `# pelican ${SDK_VERSION} API 索引`,
83
+ "",
84
+ "由公开 SDK 源码生成。签名以源码和 TypeScript 检查为准,不在文档维护第二套声明。",
85
+ "",
86
+ ...symbols.flatMap((symbol) => [
87
+ `## ${symbol.name}`,
88
+ "",
89
+ `来源:\`${index.source}:${symbol.line}\``,
90
+ "",
91
+ "```ts",
92
+ symbol.signature,
93
+ "```",
94
+ "",
95
+ ]),
96
+ ].join("\n");
97
+ await writeFile(path.join(output, "REFERENCE.md"), reference);
98
+ return index;
99
+ }
100
+ if (process.argv[1] &&
101
+ path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
102
+ generateApiIndex()
103
+ .then((index) => console.log(JSON.stringify({
104
+ status: "succeeded",
105
+ engineVersion: SDK_VERSION,
106
+ symbols: index.symbols.length,
107
+ artifacts: ["docs/api/index.json", "docs/api/REFERENCE.md"],
108
+ })))
109
+ .catch((error) => {
110
+ console.error(String(error));
111
+ process.exitCode = 1;
112
+ });
113
+ }
@@ -0,0 +1,89 @@
1
+ export class AutomationError extends Error {
2
+ code;
3
+ constructor(code, message, options) {
4
+ super(`${code}: ${message}`, options);
5
+ this.code = code;
6
+ this.name = "AutomationError";
7
+ }
8
+ }
9
+ function timeoutValue(timeoutMs) {
10
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 120_000)
11
+ throw new AutomationError("TC_AUTOMATION_TIMEOUT_RANGE", "timeoutMs must be an integer in [1,120000].");
12
+ return timeoutMs;
13
+ }
14
+ export function automationLaunchOptions(timeoutMs = 30_000) {
15
+ return {
16
+ headless: false,
17
+ timeout: timeoutValue(timeoutMs),
18
+ args: [
19
+ "--use-angle=d3d11",
20
+ "--disable-background-timer-throttling",
21
+ "--disable-renderer-backgrounding",
22
+ "--disable-backgrounding-occluded-windows",
23
+ "--disable-features=CalculateNativeWinOcclusion",
24
+ ],
25
+ };
26
+ }
27
+ export function automationURL(url) {
28
+ const target = new URL(url);
29
+ target.searchParams.set("automation", "1");
30
+ return target.href;
31
+ }
32
+ /** The caller owns cleanup; a frozen renderer must not control the Node deadline. */
33
+ export async function withAutomationDeadline(operation, timeoutMs = 30_000, label = "Browser operation") {
34
+ timeoutValue(timeoutMs);
35
+ let timer;
36
+ try {
37
+ return await Promise.race([
38
+ Promise.resolve().then(operation),
39
+ new Promise((_, reject) => {
40
+ timer = setTimeout(() => reject(new AutomationError("TC_AUTOMATION_TIMEOUT", `${label} exceeded its ${timeoutMs} ms Node deadline.`)), timeoutMs);
41
+ }),
42
+ ]);
43
+ }
44
+ finally {
45
+ clearTimeout(timer);
46
+ }
47
+ }
48
+ /** No RAF polling: Chromium can suspend animation frames in occluded windows. */
49
+ export async function waitForEngine(page, timeoutMs = 30_000, options = {}) {
50
+ timeoutValue(timeoutMs);
51
+ try {
52
+ await withAutomationDeadline(async () => {
53
+ const handle = await page.waitForFunction(({ production }) => {
54
+ const data = document.documentElement.dataset;
55
+ const runtime = globalThis;
56
+ const failure = runtime.__pelicanFailure || data.pelicanFailure;
57
+ if (failure)
58
+ return { state: "failed", detail: String(failure) };
59
+ if (data.pelicanReady !== "true")
60
+ return false;
61
+ if (!production &&
62
+ typeof runtime.__pelican?.command !== "function")
63
+ return false;
64
+ return { state: "ready" };
65
+ }, { production: options.production === true }, { polling: 100, timeout: timeoutMs });
66
+ try {
67
+ const status = await handle.jsonValue();
68
+ if (!status || typeof status !== "object" || !("state" in status))
69
+ throw new AutomationError("TC_AUTOMATION_READY_PROTOCOL", "The readiness probe returned an invalid result.");
70
+ if (status.state === "failed")
71
+ throw new AutomationError("TC_AUTOMATION_BOOT_FAILED", "detail" in status
72
+ ? String(status.detail)
73
+ : "Engine boot failed.");
74
+ if (status.state !== "ready")
75
+ throw new AutomationError("TC_AUTOMATION_READY_PROTOCOL", "The readiness probe returned an unknown state.");
76
+ }
77
+ finally {
78
+ await handle.dispose();
79
+ }
80
+ }, timeoutMs, "Engine readiness");
81
+ }
82
+ catch (error) {
83
+ if (error instanceof AutomationError)
84
+ throw error;
85
+ throw new AutomationError(error instanceof Error && error.name === "TimeoutError"
86
+ ? "TC_AUTOMATION_TIMEOUT"
87
+ : "TC_AUTOMATION_WAIT_FAILED", "Engine readiness failed; close the owned browser before retrying.", { cause: error });
88
+ }
89
+ }