@vgai/engine 0.5.13 → 0.5.14

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/dist/adapter/adapter-module.d.ts +447 -0
  2. package/dist/adapter/adapter-module.d.ts.map +1 -0
  3. package/dist/adapter/adapter-module.js +308 -0
  4. package/dist/adapter/authoring.d.ts +357 -10
  5. package/dist/adapter/authoring.d.ts.map +1 -1
  6. package/dist/adapter/authoring.js +87 -1
  7. package/dist/adapter/constraint.d.ts +9 -3
  8. package/dist/adapter/constraint.d.ts.map +1 -1
  9. package/dist/adapter/finders/finder-result.d.ts +28 -0
  10. package/dist/adapter/finders/finder-result.d.ts.map +1 -0
  11. package/dist/adapter/finders/finder-result.js +10 -0
  12. package/dist/adapter/finders/index.d.ts +38 -0
  13. package/dist/adapter/finders/index.d.ts.map +1 -0
  14. package/dist/adapter/finders/index.js +41 -0
  15. package/dist/adapter/finders/prefabs-from-stories.d.ts +64 -0
  16. package/dist/adapter/finders/prefabs-from-stories.d.ts.map +1 -0
  17. package/dist/adapter/finders/prefabs-from-stories.js +92 -0
  18. package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts +67 -0
  19. package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts.map +1 -0
  20. package/dist/adapter/finders/scenes-from-entrypoint-selection.js +226 -0
  21. package/dist/adapter/first-party-systems.d.ts.map +1 -1
  22. package/dist/adapter/first-party-systems.js +29 -0
  23. package/dist/adapter/index.d.ts +7 -3
  24. package/dist/adapter/index.d.ts.map +1 -1
  25. package/dist/adapter/index.js +5 -2
  26. package/dist/adapter/ingest/contract-system-adapters.d.ts +24 -1
  27. package/dist/adapter/ingest/contract-system-adapters.d.ts.map +1 -1
  28. package/dist/adapter/ingest/contract-system-adapters.js +100 -34
  29. package/dist/adapter/ingest/game-contract.d.ts +188 -2
  30. package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
  31. package/dist/adapter/ingest/game-contract.js +107 -0
  32. package/dist/adapter/ingest/mount-readiness.d.ts +84 -0
  33. package/dist/adapter/ingest/mount-readiness.d.ts.map +1 -0
  34. package/dist/adapter/ingest/mount-readiness.js +81 -0
  35. package/dist/adapter/ingest/scene-capture.d.ts +91 -2
  36. package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
  37. package/dist/adapter/ingest/scene-capture.js +110 -18
  38. package/dist/adapter/ingest/structural-ids.d.ts +11 -5
  39. package/dist/adapter/ingest/structural-ids.d.ts.map +1 -1
  40. package/dist/adapter/ingest/structural-ids.js +18 -9
  41. package/dist/adapter/ingest/upstream-pin.d.ts +4 -2
  42. package/dist/adapter/ingest/upstream-pin.d.ts.map +1 -1
  43. package/dist/adapter/ingest/upstream-pin.js +4 -2
  44. package/dist/adapter/ingest/visible-capture-window.d.ts +116 -0
  45. package/dist/adapter/ingest/visible-capture-window.d.ts.map +1 -0
  46. package/dist/adapter/ingest/visible-capture-window.js +141 -0
  47. package/dist/adapter/loop-gate-report.d.ts +3 -4
  48. package/dist/adapter/loop-gate-report.d.ts.map +1 -1
  49. package/dist/adapter/loop-gate-report.js +3 -4
  50. package/dist/adapter/root-adapter.d.ts +22 -2
  51. package/dist/adapter/root-adapter.d.ts.map +1 -1
  52. package/dist/adapter/setup-three-root-adapter.d.ts.map +1 -1
  53. package/dist/adapter/setup-three-root-adapter.js +15 -0
  54. package/dist/adapter/system-adapter.d.ts +161 -2
  55. package/dist/adapter/system-adapter.d.ts.map +1 -1
  56. package/dist/adapter/system-adapter.js +18 -1
  57. package/dist/animation/camera-ownership.d.ts +4 -2
  58. package/dist/animation/camera-ownership.d.ts.map +1 -1
  59. package/dist/animation/camera-ownership.js +58 -1
  60. package/dist/animation/runtime-inspection.d.ts +70 -0
  61. package/dist/animation/runtime-inspection.d.ts.map +1 -0
  62. package/dist/animation/runtime-inspection.js +25 -0
  63. package/dist/animation/xstate-animation-binding.d.ts +9 -1
  64. package/dist/animation/xstate-animation-binding.d.ts.map +1 -1
  65. package/dist/animation/xstate-animation-binding.js +48 -1
  66. package/dist/asset-formats/material.d.ts +1 -1
  67. package/dist/asset-formats/mesh.d.ts +1 -1
  68. package/dist/asset-formats/particles.d.ts +13 -0
  69. package/dist/asset-formats/particles.d.ts.map +1 -1
  70. package/dist/asset-formats/particles.js +28 -0
  71. package/dist/behavior/xstate-inspection.d.ts +24 -0
  72. package/dist/behavior/xstate-inspection.d.ts.map +1 -0
  73. package/dist/behavior/xstate-inspection.js +25 -0
  74. package/dist/core/game-loop.d.ts +7 -5
  75. package/dist/core/game-loop.d.ts.map +1 -1
  76. package/dist/core/game-loop.js +39 -18
  77. package/dist/core/types.d.ts +11 -12
  78. package/dist/core/types.d.ts.map +1 -1
  79. package/dist/data/data-asset.js +1 -1
  80. package/dist/dev/instruments.d.ts.map +1 -1
  81. package/dist/dev/instruments.js +5 -1
  82. package/dist/dev/render-debug-adapter.d.ts +19 -2
  83. package/dist/dev/render-debug-adapter.d.ts.map +1 -1
  84. package/dist/dev/render-debug-adapter.js +10 -0
  85. package/dist/ecs/user-data.d.ts +10 -2
  86. package/dist/ecs/user-data.d.ts.map +1 -1
  87. package/dist/ecs/user-data.js +6 -2
  88. package/dist/input/binding-identity.d.ts +10 -0
  89. package/dist/input/binding-identity.d.ts.map +1 -0
  90. package/dist/input/binding-identity.js +36 -0
  91. package/dist/input/input-manager.d.ts +18 -185
  92. package/dist/input/input-manager.d.ts.map +1 -1
  93. package/dist/input/input-manager.js +78 -68
  94. package/dist/manifest/load.d.ts +14 -0
  95. package/dist/manifest/load.d.ts.map +1 -1
  96. package/dist/manifest/load.js +6 -1
  97. package/dist/manifest/schema.d.ts +18 -0
  98. package/dist/manifest/schema.d.ts.map +1 -1
  99. package/dist/manifest/schema.js +64 -7
  100. package/dist/pixi/authoring.d.ts +27 -0
  101. package/dist/pixi/authoring.d.ts.map +1 -1
  102. package/dist/pixi/authoring.js +10 -3
  103. package/dist/pixi/index.d.ts +1 -1
  104. package/dist/pixi/index.d.ts.map +1 -1
  105. package/dist/pixi/index.js +1 -1
  106. package/dist/pixi/ingest.d.ts +8 -0
  107. package/dist/pixi/ingest.d.ts.map +1 -1
  108. package/dist/pixi/ingest.js +10 -1
  109. package/dist/pixi/render-pass-bracket.d.ts +56 -0
  110. package/dist/pixi/render-pass-bracket.d.ts.map +1 -0
  111. package/dist/pixi/render-pass-bracket.js +98 -0
  112. package/dist/pixi/scene-capture.d.ts +32 -1
  113. package/dist/pixi/scene-capture.d.ts.map +1 -1
  114. package/dist/pixi/scene-capture.js +21 -9
  115. package/dist/pixi/system-adapters.d.ts +29 -0
  116. package/dist/pixi/system-adapters.d.ts.map +1 -1
  117. package/dist/pixi/system-adapters.js +27 -0
  118. package/dist/render/particles-factory.d.ts +16 -2
  119. package/dist/render/particles-factory.d.ts.map +1 -1
  120. package/dist/render/particles-factory.js +88 -5
  121. package/dist/render/soft-particle-depth.d.ts +149 -0
  122. package/dist/render/soft-particle-depth.d.ts.map +1 -0
  123. package/dist/render/soft-particle-depth.js +305 -0
  124. package/dist/render/voxel-surface.d.ts +117 -0
  125. package/dist/render/voxel-surface.d.ts.map +1 -0
  126. package/dist/render/voxel-surface.js +263 -0
  127. package/dist/runtime/create-runtime.js +7 -0
  128. package/dist/runtime/debug-bridge.d.ts +15 -15
  129. package/dist/runtime/debug-bridge.d.ts.map +1 -1
  130. package/dist/runtime/debug-bridge.js +27 -26
  131. package/dist/runtime/game.d.ts.map +1 -1
  132. package/dist/runtime/game.js +1 -2
  133. package/dist/setup/setup-particles.d.ts.map +1 -1
  134. package/dist/setup/setup-particles.js +9 -0
  135. package/dist/world3d-react/r3f-adapter.d.ts.map +1 -1
  136. package/dist/world3d-react/r3f-adapter.js +42 -3
  137. package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -1
  138. package/dist/world3d-react/rapier-physics-bridge.js +201 -11
  139. package/dist-config/config.js.map +1 -1
  140. package/package.json +4 -2
  141. package/schemas/engine-capabilities.json +12 -12
  142. package/schemas/vgai-project.schema.json +41 -2
  143. package/src/adapter/adapter-module.ts +607 -0
  144. package/src/adapter/authoring.ts +440 -10
  145. package/src/adapter/constraint.ts +10 -3
  146. package/src/adapter/finders/finder-result.ts +29 -0
  147. package/src/adapter/finders/index.ts +62 -0
  148. package/src/adapter/finders/prefabs-from-stories.ts +142 -0
  149. package/src/adapter/finders/scenes-from-entrypoint-selection.ts +304 -0
  150. package/src/adapter/first-party-systems.ts +30 -0
  151. package/src/adapter/index.ts +32 -1
  152. package/src/adapter/ingest/contract-system-adapters.ts +116 -32
  153. package/src/adapter/ingest/game-contract.ts +265 -2
  154. package/src/adapter/ingest/mount-readiness.ts +140 -0
  155. package/src/adapter/ingest/scene-capture.ts +199 -22
  156. package/src/adapter/ingest/structural-ids.ts +21 -9
  157. package/src/adapter/ingest/upstream-pin.ts +4 -2
  158. package/src/adapter/ingest/visible-capture-window.ts +213 -0
  159. package/src/adapter/loop-gate-report.ts +3 -4
  160. package/src/adapter/root-adapter.ts +22 -2
  161. package/src/adapter/setup-three-root-adapter.ts +16 -0
  162. package/src/adapter/system-adapter.ts +188 -2
  163. package/src/animation/camera-ownership.ts +68 -3
  164. package/src/animation/runtime-inspection.ts +104 -0
  165. package/src/animation/xstate-animation-binding.ts +53 -1
  166. package/src/asset-formats/particles.ts +31 -0
  167. package/src/behavior/xstate-inspection.ts +51 -0
  168. package/src/core/game-loop.ts +39 -17
  169. package/src/core/types.ts +11 -12
  170. package/src/data/data-asset.ts +1 -1
  171. package/src/dev/instruments.ts +5 -1
  172. package/src/dev/render-debug-adapter.ts +22 -2
  173. package/src/ecs/user-data.ts +10 -2
  174. package/src/input/binding-identity.ts +37 -0
  175. package/src/input/input-manager.ts +93 -68
  176. package/src/manifest/load.ts +23 -2
  177. package/src/manifest/schema.ts +76 -7
  178. package/src/pixi/authoring.ts +37 -5
  179. package/src/pixi/index.ts +2 -0
  180. package/src/pixi/ingest.ts +15 -2
  181. package/src/pixi/render-pass-bracket.ts +117 -0
  182. package/src/pixi/scene-capture.ts +63 -13
  183. package/src/pixi/system-adapters.ts +41 -0
  184. package/src/render/particles-factory.ts +89 -6
  185. package/src/render/soft-particle-depth.ts +336 -0
  186. package/src/render/voxel-surface.ts +358 -0
  187. package/src/runtime/create-runtime.ts +7 -0
  188. package/src/runtime/debug-bridge.ts +32 -31
  189. package/src/runtime/game.ts +1 -2
  190. package/src/setup/setup-particles.ts +9 -0
  191. package/src/world3d-react/r3f-adapter.tsx +48 -2
  192. package/src/world3d-react/rapier-physics-bridge.tsx +249 -11
@@ -0,0 +1,117 @@
1
+ /**
2
+ * A face-culled surface mesh for a dense grid of cubic cells, as one real `THREE.BufferGeometry`.
3
+ *
4
+ * A game that stores its world as a grid of cubes — terrain a player digs, a builder's block
5
+ * palette, a level authored as a 3D tilemap — cannot draw a `BoxGeometry` per cell: a modest
6
+ * 80×7×80 volume is 44 800 boxes, and the ones buried inside the solid are invisible forever. The
7
+ * fix is a single surface built from only the faces that touch an empty neighbour. That is what
8
+ * this file is, and it is the whole of it.
9
+ *
10
+ * ## It is a HELPER, not a wrapper
11
+ *
12
+ * `buildVoxelSurface` takes plain arrays and hands back three's own `BufferGeometry`. Every call
13
+ * after it is three's API — pick your own material, wrap it in a `Mesh` or an `InstancedMesh`,
14
+ * `.translate()` it, hand it to Rapier's trimesh collider. Nothing here holds a scene, a camera, a
15
+ * frame loop or a cache, and nothing here is a class you inherit from.
16
+ *
17
+ * ## The rung audit that put ~200 lines here instead of a dependency (2026-08-14)
18
+ *
19
+ * Checked against the npm registry on the day this landed, not from memory:
20
+ *
21
+ * - **`voxel-mesh` 0.3.0** (voxel.js) — last publish **2013-06-13**. Its `index.js` builds a
22
+ * `THREE.Geometry` out of `THREE.Face3`, both REMOVED from three in r125. It cannot run against
23
+ * this repo's three at all.
24
+ * - **`voxel-mesher` 0.14.4** (2016-03-26) and **`greedy-mesher` 1.0.3** (2016-02-12) — the
25
+ * voxel.js meshing pair. Both are `ndarray`-shaped, untyped, and stop at a list of quads: the
26
+ * `BufferGeometry` is still yours to write. `voxel-mesher` additionally pulls a WebGL1 buffer
27
+ * stack (`gl-buffer`, `gl-vao`) that has nothing to do with three.
28
+ * - **`voxel-engine` 0.20.2** (2015-04-11) — a whole game framework (20 dependencies, its own
29
+ * camera, controls and physics). The thing this rule bans.
30
+ * - **`@voxelize/core` 3.0.0** (2026-08-03) — the one MAINTAINED option, and the one to say no to
31
+ * deliberately. It is a client for a multiplayer voxel platform: `socket.io-client`, its own
32
+ * wire protocol, its own physics engine and a WASM mesher fed by its own chunk/world objects.
33
+ * You do not call its mesher; you build your game inside it. Adopting it to draw a static grid
34
+ * would put a platform between the game and three.
35
+ *
36
+ * So: every maintained option is an ENGINE you build inside, and every option that is a helper died
37
+ * with voxel.js a decade ago against a three that no longer exists. The general shape *is* ready —
38
+ * "cull the hidden faces of a dense grid" has been settled since 2012 — it is the packaging that is
39
+ * not. Hence a helper here, in host vocabulary, that hands back three's own object.
40
+ *
41
+ * ## What is deliberately NOT here
42
+ *
43
+ * **Greedy meshing.** Merging coplanar same-type faces into larger quads is the standard next step
44
+ * and it does not fall out of this one: it needs a per-slice sweep with its own visited mask and
45
+ * its own bugs, and it changes the vertex↔cell relationship that per-face culling keeps exact.
46
+ * Per-face culling already removes the interior, which is the order-of-magnitude win. Add greedy
47
+ * meshing the day a measured frame budget asks for it, as its own function beside this one.
48
+ *
49
+ * **Lighting, ambient occlusion, textures, atlases, transparency sorting and chunking.** Each is a
50
+ * real decision a game makes for itself; this returns geometry and gets out of the way.
51
+ */
52
+ import { BufferGeometry } from 'three';
53
+ /**
54
+ * A dense grid of cubic cells.
55
+ *
56
+ * `cells` is indexed **Y-major, then Z, then X** — `((y * sizeZ) + z) * sizeX + x`. Y outermost is
57
+ * the ordering that makes each horizontal LAYER contiguous, which is what lets a mostly-flat world
58
+ * ship as a handful of runs (see {@link expandVoxelRuns}) instead of a megabyte of literals.
59
+ */
60
+ export interface VoxelVolume {
61
+ /** Cell counts along X, Y and Z. */
62
+ readonly size: readonly [number, number, number];
63
+ /** `sizeX * sizeY * sizeZ` type ids. `0` is empty unless {@link VoxelSurfaceOptions.emptyType}. */
64
+ readonly cells: ArrayLike<number>;
65
+ /** World position of the volume's minimum corner. Defaults to the origin. */
66
+ readonly origin?: readonly [number, number, number];
67
+ /** World edge length of one cell. Defaults to 1. */
68
+ readonly cellSize?: number;
69
+ }
70
+ export interface VoxelSurfaceOptions {
71
+ /**
72
+ * Type id → `0xRRGGBB`, written into the geometry's `color` attribute. Supply it and the mesh
73
+ * draws with `vertexColors: true` in one draw call; omit it and the geometry carries no colour
74
+ * attribute at all. A solid type absent from the map is an ERROR, not a silent default: a
75
+ * missing colour is the shape of a forgotten row, and a mesh that quietly paints it white looks
76
+ * like a lighting bug three files away.
77
+ */
78
+ readonly colors?: ReadonlyMap<number, number>;
79
+ /** The type id that means "no cell here". Defaults to `0`. */
80
+ readonly emptyType?: number;
81
+ /**
82
+ * Whether cells just outside the volume count as solid. `false` (the default) walls the volume
83
+ * in — the right answer for a standalone model. `true` leaves the boundary open, which is what a
84
+ * chunk meshed beside its neighbours wants.
85
+ */
86
+ readonly closedBoundary?: boolean;
87
+ }
88
+ export interface VoxelSurface {
89
+ /** Indexed, with `position`, `normal` and (when colours were supplied) `color`. */
90
+ readonly geometry: BufferGeometry;
91
+ /** Faces that survived culling. `vertices` is `4 ×` this, `triangles` `2 ×`. */
92
+ readonly quads: number;
93
+ readonly vertices: number;
94
+ readonly triangles: number;
95
+ /** Cells whose type is not the empty type — the input's own size, for a sanity check. */
96
+ readonly solidCells: number;
97
+ /** Faces contributed per type id, in ascending id order. */
98
+ readonly quadsByType: ReadonlyMap<number, number>;
99
+ }
100
+ export declare class VoxelSurfaceError extends Error {
101
+ constructor(message: string);
102
+ }
103
+ /**
104
+ * Expand `[count, type, count, type, …]` run pairs into a dense cell array.
105
+ *
106
+ * A voxel volume is enormous and almost entirely repetitive, so the compact form is what a game
107
+ * SHIPS — in a source file, in a save, over the wire — and the dense form is what it meshes. The
108
+ * total of the counts must be exactly `cellCount`: a short or long run list is a corrupt volume,
109
+ * and silently padding it with empties would mesh a plausible wrong world.
110
+ */
111
+ export declare function expandVoxelRuns(runs: ArrayLike<number>, cellCount: number): Uint16Array | Uint32Array;
112
+ /**
113
+ * Build the visible surface of a voxel volume: one indexed `BufferGeometry` carrying every face
114
+ * that touches an empty neighbour, and nothing else.
115
+ */
116
+ export declare function buildVoxelSurface(volume: VoxelVolume, options?: VoxelSurfaceOptions): VoxelSurface;
117
+ //# sourceMappingURL=voxel-surface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voxel-surface.d.ts","sourceRoot":"","sources":["../../src/render/voxel-surface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,OAAO,EAAmB,cAAc,EAAS,MAAM,OAAO,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,mGAAmG;IACnG,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAClC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpD,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yFAAyF;IACzF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnD;AAED,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAkED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EACvB,SAAS,EAAE,MAAM,GAChB,WAAW,GAAG,WAAW,CA2B3B;AA2ED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,OAAO,GAAE,mBAAwB,GAChC,YAAY,CA+Dd"}
@@ -0,0 +1,263 @@
1
+ /**
2
+ * A face-culled surface mesh for a dense grid of cubic cells, as one real `THREE.BufferGeometry`.
3
+ *
4
+ * A game that stores its world as a grid of cubes — terrain a player digs, a builder's block
5
+ * palette, a level authored as a 3D tilemap — cannot draw a `BoxGeometry` per cell: a modest
6
+ * 80×7×80 volume is 44 800 boxes, and the ones buried inside the solid are invisible forever. The
7
+ * fix is a single surface built from only the faces that touch an empty neighbour. That is what
8
+ * this file is, and it is the whole of it.
9
+ *
10
+ * ## It is a HELPER, not a wrapper
11
+ *
12
+ * `buildVoxelSurface` takes plain arrays and hands back three's own `BufferGeometry`. Every call
13
+ * after it is three's API — pick your own material, wrap it in a `Mesh` or an `InstancedMesh`,
14
+ * `.translate()` it, hand it to Rapier's trimesh collider. Nothing here holds a scene, a camera, a
15
+ * frame loop or a cache, and nothing here is a class you inherit from.
16
+ *
17
+ * ## The rung audit that put ~200 lines here instead of a dependency (2026-08-14)
18
+ *
19
+ * Checked against the npm registry on the day this landed, not from memory:
20
+ *
21
+ * - **`voxel-mesh` 0.3.0** (voxel.js) — last publish **2013-06-13**. Its `index.js` builds a
22
+ * `THREE.Geometry` out of `THREE.Face3`, both REMOVED from three in r125. It cannot run against
23
+ * this repo's three at all.
24
+ * - **`voxel-mesher` 0.14.4** (2016-03-26) and **`greedy-mesher` 1.0.3** (2016-02-12) — the
25
+ * voxel.js meshing pair. Both are `ndarray`-shaped, untyped, and stop at a list of quads: the
26
+ * `BufferGeometry` is still yours to write. `voxel-mesher` additionally pulls a WebGL1 buffer
27
+ * stack (`gl-buffer`, `gl-vao`) that has nothing to do with three.
28
+ * - **`voxel-engine` 0.20.2** (2015-04-11) — a whole game framework (20 dependencies, its own
29
+ * camera, controls and physics). The thing this rule bans.
30
+ * - **`@voxelize/core` 3.0.0** (2026-08-03) — the one MAINTAINED option, and the one to say no to
31
+ * deliberately. It is a client for a multiplayer voxel platform: `socket.io-client`, its own
32
+ * wire protocol, its own physics engine and a WASM mesher fed by its own chunk/world objects.
33
+ * You do not call its mesher; you build your game inside it. Adopting it to draw a static grid
34
+ * would put a platform between the game and three.
35
+ *
36
+ * So: every maintained option is an ENGINE you build inside, and every option that is a helper died
37
+ * with voxel.js a decade ago against a three that no longer exists. The general shape *is* ready —
38
+ * "cull the hidden faces of a dense grid" has been settled since 2012 — it is the packaging that is
39
+ * not. Hence a helper here, in host vocabulary, that hands back three's own object.
40
+ *
41
+ * ## What is deliberately NOT here
42
+ *
43
+ * **Greedy meshing.** Merging coplanar same-type faces into larger quads is the standard next step
44
+ * and it does not fall out of this one: it needs a per-slice sweep with its own visited mask and
45
+ * its own bugs, and it changes the vertex↔cell relationship that per-face culling keeps exact.
46
+ * Per-face culling already removes the interior, which is the order-of-magnitude win. Add greedy
47
+ * meshing the day a measured frame budget asks for it, as its own function beside this one.
48
+ *
49
+ * **Lighting, ambient occlusion, textures, atlases, transparency sorting and chunking.** Each is a
50
+ * real decision a game makes for itself; this returns geometry and gets out of the way.
51
+ */
52
+ import { BufferAttribute, BufferGeometry, Color } from 'three';
53
+ export class VoxelSurfaceError extends Error {
54
+ constructor(message) {
55
+ super(message);
56
+ this.name = 'VoxelSurfaceError';
57
+ }
58
+ }
59
+ /**
60
+ * The six faces of the unit cell, each as four corners in counter-clockwise order seen from
61
+ * OUTSIDE — which is the winding three's default `FrontSide` draws.
62
+ */
63
+ const FACES = [
64
+ {
65
+ normal: [1, 0, 0],
66
+ corners: [
67
+ [1, 0, 1],
68
+ [1, 0, 0],
69
+ [1, 1, 0],
70
+ [1, 1, 1],
71
+ ],
72
+ },
73
+ {
74
+ normal: [-1, 0, 0],
75
+ corners: [
76
+ [0, 0, 0],
77
+ [0, 0, 1],
78
+ [0, 1, 1],
79
+ [0, 1, 0],
80
+ ],
81
+ },
82
+ {
83
+ normal: [0, 1, 0],
84
+ corners: [
85
+ [0, 1, 1],
86
+ [1, 1, 1],
87
+ [1, 1, 0],
88
+ [0, 1, 0],
89
+ ],
90
+ },
91
+ {
92
+ normal: [0, -1, 0],
93
+ corners: [
94
+ [0, 0, 0],
95
+ [1, 0, 0],
96
+ [1, 0, 1],
97
+ [0, 0, 1],
98
+ ],
99
+ },
100
+ {
101
+ normal: [0, 0, 1],
102
+ corners: [
103
+ [0, 0, 1],
104
+ [1, 0, 1],
105
+ [1, 1, 1],
106
+ [0, 1, 1],
107
+ ],
108
+ },
109
+ {
110
+ normal: [0, 0, -1],
111
+ corners: [
112
+ [1, 0, 0],
113
+ [0, 0, 0],
114
+ [0, 1, 0],
115
+ [1, 1, 0],
116
+ ],
117
+ },
118
+ ];
119
+ /**
120
+ * Expand `[count, type, count, type, …]` run pairs into a dense cell array.
121
+ *
122
+ * A voxel volume is enormous and almost entirely repetitive, so the compact form is what a game
123
+ * SHIPS — in a source file, in a save, over the wire — and the dense form is what it meshes. The
124
+ * total of the counts must be exactly `cellCount`: a short or long run list is a corrupt volume,
125
+ * and silently padding it with empties would mesh a plausible wrong world.
126
+ */
127
+ export function expandVoxelRuns(runs, cellCount) {
128
+ if (runs.length % 2 !== 0) {
129
+ throw new VoxelSurfaceError(`a run list is [count, type] pairs, so its length must be even; got ${runs.length}`);
130
+ }
131
+ let widest = 0;
132
+ let total = 0;
133
+ for (let pair = 0; pair < runs.length; pair += 2) {
134
+ const count = runs[pair];
135
+ if (!Number.isInteger(count) || count <= 0) {
136
+ throw new VoxelSurfaceError(`run ${pair / 2} has a count of ${count}; counts are positive`);
137
+ }
138
+ total += count;
139
+ widest = Math.max(widest, runs[pair + 1]);
140
+ }
141
+ if (total !== cellCount) {
142
+ throw new VoxelSurfaceError(`the runs cover ${total} cells; the volume holds ${cellCount}`);
143
+ }
144
+ const cells = widest > 0xffff ? new Uint32Array(cellCount) : new Uint16Array(cellCount);
145
+ let at = 0;
146
+ for (let pair = 0; pair < runs.length; pair += 2) {
147
+ const count = runs[pair];
148
+ cells.fill(runs[pair + 1], at, at + count);
149
+ at += count;
150
+ }
151
+ return cells;
152
+ }
153
+ /** The volume's size, after checking that the cell array is exactly the size it claims. */
154
+ function assertVolumeShape(volume) {
155
+ const [sizeX, sizeY, sizeZ] = volume.size;
156
+ if (sizeX <= 0 || sizeY <= 0 || sizeZ <= 0) {
157
+ throw new VoxelSurfaceError(`a volume needs a positive size on every axis; got ${volume.size}`);
158
+ }
159
+ const cellCount = sizeX * sizeY * sizeZ;
160
+ if (volume.cells.length !== cellCount) {
161
+ throw new VoxelSurfaceError(`a ${sizeX}×${sizeY}×${sizeZ} volume holds ${cellCount} cells; got ${volume.cells.length}`);
162
+ }
163
+ return [sizeX, sizeY, sizeZ];
164
+ }
165
+ /** The linear-space vertex colour for one type, or `undefined` when colours were not asked for. */
166
+ function vertexColor(colors, type, where, into) {
167
+ if (colors === undefined)
168
+ return undefined;
169
+ const hex = colors.get(type);
170
+ if (hex === undefined) {
171
+ throw new VoxelSurfaceError(`no colour for type ${type}, which cell ${where} holds — every solid type in the volume ` +
172
+ 'needs a row, so a forgotten one fails here rather than drawing white');
173
+ }
174
+ // `setHex` defaults to `SRGBColorSpace` and converts INTO the working space itself, which is
175
+ // exactly what a material does with a colour uniform. Do not convert again on top of it: an
176
+ // extra `convertSRGBToLinear()` here squared the conversion and drew a mid-green world in near
177
+ // black, with every channel still plausible enough to read as a lighting problem.
178
+ return into.setHex(hex);
179
+ }
180
+ /** Append the faces of one solid cell that face an empty neighbour. Returns how many. */
181
+ function emitCellFaces(buffers, cell, type, color, solidAt, place) {
182
+ const [x, y, z] = cell;
183
+ let emitted = 0;
184
+ for (const face of FACES) {
185
+ const [nx, ny, nz] = face.normal;
186
+ if (solidAt(x + nx, y + ny, z + nz))
187
+ continue;
188
+ const base = buffers.positions.length / 3;
189
+ for (const [cx, cy, cz] of face.corners) {
190
+ buffers.positions.push(...place(x + cx, y + cy, z + cz));
191
+ buffers.normals.push(nx, ny, nz);
192
+ if (color !== undefined)
193
+ buffers.colors.push(color.r, color.g, color.b);
194
+ }
195
+ buffers.indices.push(base, base + 1, base + 2, base, base + 2, base + 3);
196
+ buffers.quadsByType.set(type, (buffers.quadsByType.get(type) ?? 0) + 1);
197
+ emitted += 1;
198
+ }
199
+ return emitted;
200
+ }
201
+ /**
202
+ * Build the visible surface of a voxel volume: one indexed `BufferGeometry` carrying every face
203
+ * that touches an empty neighbour, and nothing else.
204
+ */
205
+ export function buildVoxelSurface(volume, options = {}) {
206
+ const [sizeX, sizeY, sizeZ] = assertVolumeShape(volume);
207
+ const empty = options.emptyType ?? 0;
208
+ const openBoundary = options.closedBoundary !== true;
209
+ const scale = volume.cellSize ?? 1;
210
+ const [originX, originY, originZ] = volume.origin ?? [0, 0, 0];
211
+ const cells = volume.cells;
212
+ const at = (x, y, z) => cells[(y * sizeZ + z) * sizeX + x];
213
+ const solidAt = (x, y, z) => {
214
+ const outsideVolume = x < 0 || y < 0 || z < 0 || x >= sizeX || y >= sizeY || z >= sizeZ;
215
+ return outsideVolume ? !openBoundary : at(x, y, z) !== empty;
216
+ };
217
+ const place = (x, y, z) => [
218
+ originX + x * scale,
219
+ originY + y * scale,
220
+ originZ + z * scale,
221
+ ];
222
+ const buffers = {
223
+ positions: [],
224
+ normals: [],
225
+ colors: [],
226
+ indices: [],
227
+ quadsByType: new Map(),
228
+ };
229
+ const scratch = new Color();
230
+ let solidCells = 0;
231
+ let quads = 0;
232
+ for (let y = 0; y < sizeY; y += 1) {
233
+ for (let z = 0; z < sizeZ; z += 1) {
234
+ for (let x = 0; x < sizeX; x += 1) {
235
+ const type = at(x, y, z);
236
+ if (type === empty)
237
+ continue;
238
+ solidCells += 1;
239
+ const color = vertexColor(options.colors, type, `(${x}, ${y}, ${z})`, scratch);
240
+ quads += emitCellFaces(buffers, [x, y, z], type, color, solidAt, place);
241
+ }
242
+ }
243
+ }
244
+ const geometry = new BufferGeometry();
245
+ geometry.setAttribute('position', new BufferAttribute(new Float32Array(buffers.positions), 3));
246
+ geometry.setAttribute('normal', new BufferAttribute(new Float32Array(buffers.normals), 3));
247
+ if (options.colors !== undefined) {
248
+ geometry.setAttribute('color', new BufferAttribute(new Float32Array(buffers.colors), 3));
249
+ }
250
+ const vertices = buffers.positions.length / 3;
251
+ const indices = vertices > 0xffff ? new Uint32Array(buffers.indices) : new Uint16Array(buffers.indices);
252
+ geometry.setIndex(new BufferAttribute(indices, 1));
253
+ geometry.computeBoundingSphere();
254
+ geometry.computeBoundingBox();
255
+ return {
256
+ geometry,
257
+ quads,
258
+ vertices,
259
+ triangles: quads * 2,
260
+ solidCells,
261
+ quadsByType: new Map([...buffers.quadsByType].sort(([a], [b]) => a - b)),
262
+ };
263
+ }
@@ -478,6 +478,13 @@ async function createRootsGameRuntime(config) {
478
478
  const isReact = kindById.get(entry.id) === 'dom';
479
479
  const surface = document.createElement(isReact ? 'div' : 'canvas');
480
480
  surface.dataset['vgaiRootSurface'] = 'true';
481
+ // WHICH ROOT THIS SURFACE PRESENTS — the host mounted it, so the host
482
+ // knows, and stamping it here is the difference between a declaration and
483
+ // the guess every late reader had to make instead ("the first <canvas> in
484
+ // DOM order is the game's"). Read by `packages/editor/src/presentation-
485
+ // surface.ts`, which is the one door the capture/staleness/screenshot
486
+ // sites now ask (ARCHITECTURE-CORE §The editor protocol, zero inference).
487
+ surface.dataset['vgaiRootId'] = entry.id;
481
488
  // The capture's marker (`composite-screenshot.ts` reads exactly this
482
489
  // attribute): a dev layer is excluded from a play capture unless the
483
490
  // capture asks for it, because a contaminated "does the game look right"
@@ -110,10 +110,10 @@ export interface VgaiDebugInputHandle {
110
110
  * `state` from another). */
111
111
  export interface VgaiDebugSnapshot {
112
112
  /** `loopLiveness` (issue #175): the REAL `GameLoop.liveness` behind this
113
- * session — `'hidden-paused'` while the T2.1 idle throttle has stopped
114
- * the loop (tab hidden), `null` only when no loop is wired at all (a
115
- * bare debug-registry test stand-in with no real `Game`). Never a
116
- * fabricated `'running'`. */
113
+ * session — `'loop-starved'` when no recent host rAF progress was observed,
114
+ * `null` only when no loop is wired at all (a bare debug-registry test
115
+ * stand-in with no real `Game`). Never a fabricated `'running'` and never
116
+ * a conclusion about tab visibility. */
117
117
  time: {
118
118
  simSeconds: number;
119
119
  tick: number;
@@ -227,13 +227,13 @@ export interface MaybeInstallDebugBridgeOptions {
227
227
  * touching (or requiring) the global object. */
228
228
  readonly window?: DebugBridgeWindowTarget | undefined;
229
229
  }
230
- /** The message a hold gets when the loop is hidden-paused and NOTHING can
230
+ /** The message a hold gets when the loop is loop-starved and NOTHING can
231
231
  * drive it — the one case where the platform genuinely prevents the verb
232
232
  * from working. Names the cause and the fix rather than expiring into a
233
233
  * generic stall (which reported the wrong cause: "play stopped during
234
234
  * hold"). One exported constant so both doors and their tests read the same
235
235
  * string. */
236
- export declare const HOLD_HIDDEN_NO_DRIVER_REASON: string;
236
+ export declare const HOLD_STARVED_NO_DRIVER_REASON: string;
237
237
  /**
238
238
  * Resolves once `simSeconds` of sim time has elapsed since the call, or once
239
239
  * the wait provably cannot make progress. Never rejects. Exported (not just
@@ -249,8 +249,8 @@ export declare const HOLD_HIDDEN_NO_DRIVER_REASON: string;
249
249
  * `HOLD_FOR_POLL_MS` and gives up after `HOLD_FOR_STALL_POLL_LIMIT`
250
250
  * consecutive unchanged-tick polls (`stalled: true` — play stopped/paused).
251
251
  *
252
- * - **Hidden-paused**: the host loop has stopped outright (T2.1's idle
253
- * throttle), so sim time only moves if this drives it. It therefore drives
252
+ * - **Loop-starved**: no recent host rAF progress is observable, so sim time
253
+ * only moves reliably if this drives it. It therefore drives
254
254
  * the WHOLE remaining budget in synchronous batches, yielding a MICROTASK
255
255
  * between them — never a timer. That distinction is load-bearing, not
256
256
  * stylistic: a hidden tab clamps `setTimeout` to ~1s (and to ~1/minute under
@@ -263,18 +263,18 @@ export declare const HOLD_HIDDEN_NO_DRIVER_REASON: string;
263
263
  * are not throttled, so the hidden path now costs sim-work time and nothing
264
264
  * else.
265
265
  *
266
- * The regime is re-read every iteration, so a tab foregrounded (or hidden)
267
- * mid-hold crosses over without restarting the budget.
266
+ * The regime is re-read every iteration, so an rAF chain that resumes or
267
+ * becomes starved mid-hold crosses over without restarting the budget.
268
268
  *
269
- * `hiddenWithoutDriver: true` is the one honest refusal: hidden-paused with
270
- * no `driveHiddenTicks` hook means nothing in this process can advance the
269
+ * `starvedWithoutDriver: true` is the one honest refusal: loop-starved with
270
+ * no `driveStarvedTicks` hook means nothing in this process can advance the
271
271
  * clock, so it reports that IMMEDIATELY (see
272
- * {@link HOLD_HIDDEN_NO_DRIVER_REASON}) instead of burning the stall guard
272
+ * {@link HOLD_STARVED_NO_DRIVER_REASON}) instead of burning the stall guard
273
273
  * and then blaming a stopped game.
274
274
  */
275
- export declare function waitForHoldBudget(adapter: DebugAdapter, simSeconds: number, driveHiddenTicks?: (n: number) => void): Promise<{
275
+ export declare function waitForHoldBudget(adapter: DebugAdapter, simSeconds: number, driveStarvedTicks?: (n: number) => void): Promise<{
276
276
  stalled: boolean;
277
- hiddenWithoutDriver?: boolean;
277
+ starvedWithoutDriver?: boolean;
278
278
  }>;
279
279
  /**
280
280
  * Install `window.__vgai` iff the page opted in (`?vgai-debug=1`) AND D18's
@@ -1 +1 @@
1
- {"version":3,"file":"debug-bridge.d.ts","sourceRoot":"","sources":["../../src/runtime/debug-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAc,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExF;;yEAEyE;AACzE,eAAO,MAAM,sBAAsB,eAAe,CAAC;AAEnD;;;kBAGkB;AAClB,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;CACtE;AAED;;;;;;;;2EAQ2E;AAC3E,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,CACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAClD,OAAO,CAAC,EAAE,MAAM,GACf;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5F,mBAAmB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C;;;;;;;;;;;;;;;;;;OAkBG;IACH,oBAAoB,CAClB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAClD,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAAC;IACR;;;+CAG2C;IAC3C,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,oEAAoE;IACpE,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,+CAA+C;IAC/C,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC;;;;;mDAK+C;IAC/C,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9F;;;;iFAI6E;IAC7E,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClG;AAED;;;6BAG6B;AAC7B,MAAM,WAAW,iBAAiB;IAChC;;;;kCAI8B;IAC9B,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAA;KAAE,CAAC;IAClF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;0EAG0E;AAC1E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,SAAS,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;IACrC,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IAC7B,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IACnC,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IACnC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC/B,KAAK,EAAE,oBAAoB,CAAC;IAC5B;;;4BAGwB;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAAC;IAC/C;;;;;;;;;OASG;IACH,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAClD;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,OAAO,CACL,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD;;;;;;;OAOG;IACH,SAAS,IAAI,IAAI,CAAC;CACnB;AAED;;8EAE8E;AAC9E,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,CAAC,CACf,IAAI,EAAE,OAAO,GAAG,oBAAoB,EACpC,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GACjF,IAAI,CAAC;IACR;;;qDAGiD;IACjD,mBAAmB,CAAC,CAClB,IAAI,EAAE,OAAO,GAAG,oBAAoB,EACpC,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GACjF,IAAI,CAAC;IACR,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,8BAA8B;IAC7C;;yDAEqD;IACrD,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC;;yEAEqE;IACrE,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACvD;;qDAEiD;IACjD,QAAQ,CAAC,MAAM,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;CACvD;AA6BD;;;;;cAKc;AACd,eAAO,MAAM,4BAA4B,QAGoD,CAAC;AAU9F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,MAAM,EAClB,gBAAgB,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GACrC,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAqC9D;AA8JD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,8BAA8B,GACnC,eAAe,GAAG,SAAS,CAwB7B"}
1
+ {"version":3,"file":"debug-bridge.d.ts","sourceRoot":"","sources":["../../src/runtime/debug-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAc,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExF;;yEAEyE;AACzE,eAAO,MAAM,sBAAsB,eAAe,CAAC;AAEnD;;;kBAGkB;AAClB,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;CACtE;AAED;;;;;;;;2EAQ2E;AAC3E,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,CACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAClD,OAAO,CAAC,EAAE,MAAM,GACf;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5F,mBAAmB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C;;;;;;;;;;;;;;;;;;OAkBG;IACH,oBAAoB,CAClB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAClD,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAAC;IACR;;;+CAG2C;IAC3C,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,oEAAoE;IACpE,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,+CAA+C;IAC/C,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC;;;;;mDAK+C;IAC/C,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9F;;;;iFAI6E;IAC7E,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClG;AAED;;;6BAG6B;AAC7B,MAAM,WAAW,iBAAiB;IAChC;;;;6CAIyC;IACzC,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAA;KAAE,CAAC;IAClF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;0EAG0E;AAC1E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,SAAS,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;IACrC,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IAC7B,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IACnC,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IACnC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC/B,KAAK,EAAE,oBAAoB,CAAC;IAC5B;;;4BAGwB;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAAC;IAC/C;;;;;;;;;OASG;IACH,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAClD;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,OAAO,CACL,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD;;;;;;;OAOG;IACH,SAAS,IAAI,IAAI,CAAC;CACnB;AAED;;8EAE8E;AAC9E,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,CAAC,CACf,IAAI,EAAE,OAAO,GAAG,oBAAoB,EACpC,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GACjF,IAAI,CAAC;IACR;;;qDAGiD;IACjD,mBAAmB,CAAC,CAClB,IAAI,EAAE,OAAO,GAAG,oBAAoB,EACpC,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GACjF,IAAI,CAAC;IACR,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,8BAA8B;IAC7C;;yDAEqD;IACrD,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC;;yEAEqE;IACrE,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACvD;;qDAEiD;IACjD,QAAQ,CAAC,MAAM,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;CACvD;AA6BD;;;;;cAKc;AACd,eAAO,MAAM,6BAA6B,QAInB,CAAC;AAUxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,MAAM,EAClB,iBAAiB,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GACtC,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAqC/D;AA8JD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,8BAA8B,GACnC,eAAe,GAAG,SAAS,CAwB7B"}
@@ -31,25 +31,26 @@ const HOLD_FOR_POLL_MS = 50;
31
31
  * faster in-process interval so the wall-clock grace period (~5s) lands in
32
32
  * the same neighborhood. */
33
33
  const HOLD_FOR_STALL_POLL_LIMIT = 100;
34
- /** Ticks driven per synchronous hidden-tab batch. Sized like
34
+ /** Ticks driven per synchronous starved-loop batch. Sized like
35
35
  * `fast-forward.ts`'s own batching rationale: big enough that per-batch
36
36
  * bookkeeping is negligible, small enough that one batch of a complex game's
37
37
  * phases stays a short synchronous burst. */
38
- const HIDDEN_DRIVE_BATCH_TICKS = 60;
39
- /** Hard ceiling on hidden-drive batches for ONE hold — `HIDDEN_DRIVE_BATCH_TICKS
38
+ const STARVED_DRIVE_BATCH_TICKS = 60;
39
+ /** Hard ceiling on starved-drive batches for ONE hold — `STARVED_DRIVE_BATCH_TICKS
40
40
  * * this` ≈ 33 sim-minutes. A bound, not a timeout: it exists so a
41
41
  * `runTicks` target that advances the tick counter without advancing the sim
42
42
  * clock can never spin forever, and it is far past any honest hold. */
43
- const HIDDEN_DRIVE_MAX_BATCHES = 2000;
44
- /** The message a hold gets when the loop is hidden-paused and NOTHING can
43
+ const STARVED_DRIVE_MAX_BATCHES = 2000;
44
+ /** The message a hold gets when the loop is loop-starved and NOTHING can
45
45
  * drive it — the one case where the platform genuinely prevents the verb
46
46
  * from working. Names the cause and the fix rather than expiring into a
47
47
  * generic stall (which reported the wrong cause: "play stopped during
48
48
  * hold"). One exported constant so both doors and their tests read the same
49
49
  * string. */
50
- export const HOLD_HIDDEN_NO_DRIVER_REASON = 'the editor tab is hidden and this session has no way to drive ticks — the engine ' +
51
- 'hidden-pauses its loop while document.hidden, so zero ticks are happening. Bring the ' +
52
- 'editor tab to the foreground (or start play, which wires the run-ticks target) and retry.';
50
+ export const HOLD_STARVED_NO_DRIVER_REASON = "the host loop reported liveness 'loop-starved' and this session has no way to drive " +
51
+ 'ticks no recent rAF progress was observed. Check `vgai status` for the separate ' +
52
+ 'visibility readings; foreground/reload the editor, or start play to wire the run-ticks ' +
53
+ 'target, then retry.';
53
54
  /**
54
55
  * Resolves once `simSeconds` of sim time has elapsed since the call, or once
55
56
  * the wait provably cannot make progress. Never rejects. Exported (not just
@@ -65,8 +66,8 @@ export const HOLD_HIDDEN_NO_DRIVER_REASON = 'the editor tab is hidden and this s
65
66
  * `HOLD_FOR_POLL_MS` and gives up after `HOLD_FOR_STALL_POLL_LIMIT`
66
67
  * consecutive unchanged-tick polls (`stalled: true` — play stopped/paused).
67
68
  *
68
- * - **Hidden-paused**: the host loop has stopped outright (T2.1's idle
69
- * throttle), so sim time only moves if this drives it. It therefore drives
69
+ * - **Loop-starved**: no recent host rAF progress is observable, so sim time
70
+ * only moves reliably if this drives it. It therefore drives
70
71
  * the WHOLE remaining budget in synchronous batches, yielding a MICROTASK
71
72
  * between them — never a timer. That distinction is load-bearing, not
72
73
  * stylistic: a hidden tab clamps `setTimeout` to ~1s (and to ~1/minute under
@@ -79,32 +80,32 @@ export const HOLD_HIDDEN_NO_DRIVER_REASON = 'the editor tab is hidden and this s
79
80
  * are not throttled, so the hidden path now costs sim-work time and nothing
80
81
  * else.
81
82
  *
82
- * The regime is re-read every iteration, so a tab foregrounded (or hidden)
83
- * mid-hold crosses over without restarting the budget.
83
+ * The regime is re-read every iteration, so an rAF chain that resumes or
84
+ * becomes starved mid-hold crosses over without restarting the budget.
84
85
  *
85
- * `hiddenWithoutDriver: true` is the one honest refusal: hidden-paused with
86
- * no `driveHiddenTicks` hook means nothing in this process can advance the
86
+ * `starvedWithoutDriver: true` is the one honest refusal: loop-starved with
87
+ * no `driveStarvedTicks` hook means nothing in this process can advance the
87
88
  * clock, so it reports that IMMEDIATELY (see
88
- * {@link HOLD_HIDDEN_NO_DRIVER_REASON}) instead of burning the stall guard
89
+ * {@link HOLD_STARVED_NO_DRIVER_REASON}) instead of burning the stall guard
89
90
  * and then blaming a stopped game.
90
91
  */
91
- export async function waitForHoldBudget(adapter, simSeconds, driveHiddenTicks) {
92
+ export async function waitForHoldBudget(adapter, simSeconds, driveStarvedTicks) {
92
93
  const readTime = () => adapter.state('time');
93
94
  const start = readTime();
94
95
  let lastTick = start.tick;
95
96
  let stalledPolls = 0;
96
- let hiddenBatches = 0;
97
+ let starvedBatches = 0;
97
98
  for (;;) {
98
99
  const current = readTime();
99
100
  if (current.simSeconds - start.simSeconds >= simSeconds)
100
101
  return { stalled: false };
101
- if (current.loopLiveness === 'hidden-paused') {
102
- if (!driveHiddenTicks)
103
- return { stalled: true, hiddenWithoutDriver: true };
104
- if (hiddenBatches >= HIDDEN_DRIVE_MAX_BATCHES)
102
+ if (current.loopLiveness === 'loop-starved') {
103
+ if (!driveStarvedTicks)
104
+ return { stalled: true, starvedWithoutDriver: true };
105
+ if (starvedBatches >= STARVED_DRIVE_MAX_BATCHES)
105
106
  return { stalled: true };
106
- hiddenBatches += 1;
107
- driveHiddenTicks(HIDDEN_DRIVE_BATCH_TICKS);
107
+ starvedBatches += 1;
108
+ driveStarvedTicks(STARVED_DRIVE_BATCH_TICKS);
108
109
  const after = readTime();
109
110
  // A batch that moved neither the tick counter nor the sim clock means
110
111
  // the drive is a no-op (paused game, torn-down runtime) — the same
@@ -116,7 +117,7 @@ export async function waitForHoldBudget(adapter, simSeconds, driveHiddenTicks) {
116
117
  lastTick = after.tick;
117
118
  stalledPolls = 0;
118
119
  // Yield so the page can service other work between batches, WITHOUT
119
- // handing control to a clock a hidden tab is allowed to starve.
120
+ // handing control to the same timer lane the browser may be starving.
120
121
  await Promise.resolve();
121
122
  continue;
122
123
  }
@@ -229,13 +230,13 @@ function buildDebugHandle(opts) {
229
230
  : { delivered: false };
230
231
  }
231
232
  const runTicksTarget = registry.getRunTicksTarget();
232
- const { stalled, hiddenWithoutDriver } = await waitForHoldBudget(adapter, simSeconds, runTicksTarget ? (n) => runTicksTarget.runTicks(n, { render: 'last' }) : undefined);
233
+ const { stalled, starvedWithoutDriver } = await waitForHoldBudget(adapter, simSeconds, runTicksTarget ? (n) => runTicksTarget.runTicks(n, { render: 'last' }) : undefined);
233
234
  target.clearVirtualActions();
234
235
  if (!stalled)
235
236
  return { delivered: true };
236
237
  return {
237
238
  delivered: false,
238
- reason: hiddenWithoutDriver ? HOLD_HIDDEN_NO_DRIVER_REASON : 'play stopped during hold',
239
+ reason: starvedWithoutDriver ? HOLD_STARVED_NO_DRIVER_REASON : 'play stopped during hold',
239
240
  };
240
241
  },
241
242
  uninstall() {
@@ -1 +1 @@
1
- {"version":3,"file":"game.d.ts","sourceRoot":"","sources":["../../src/runtime/game.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"game.d.ts","sourceRoot":"","sources":["../../src/runtime/game.ts"],"names":[],"mappings":"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"}
@@ -416,8 +416,7 @@ export function createGame(opts) {
416
416
  // Other native `console.warn`/`console.error` call sites in this file are
417
417
  // unsuppressed and already counted in the lint baseline (see `runFrame`'s
418
418
  // impl below); this one is a NEW site, so it's suppressed to keep this
419
- // task's diff at zero NEW warnings (same reasoning as `achieved-tier.ts`'s
420
- // identical suppression).
419
+ // task's diff at zero NEW warnings.
421
420
  // biome-ignore lint/suspicious/noConsole: see comment above
422
421
  console.warn(message);
423
422
  }