@woosh/meep-engine 3.60.4 → 3.60.6

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 (419) hide show
  1. package/CHANGELOG.md +2621 -0
  2. package/CONTRIBUTING.md +7 -0
  3. package/MIGRATION_2_TO_3.md +136 -0
  4. package/SECURITY.md +4 -0
  5. package/editor/EditorCameraNavigation.d.ts +2 -1
  6. package/editor/EditorCameraNavigation.d.ts.map +1 -1
  7. package/editor/EditorCameraNavigation.js +51 -57
  8. package/package.json +6 -2
  9. package/src/engine/EngineHarness.d.ts +3 -9
  10. package/src/engine/EngineHarness.d.ts.map +1 -1
  11. package/src/engine/EngineHarness.js +6 -8
  12. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +9 -6
  13. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
  14. package/src/engine/graphics/camera/makeOrbitalCameraController.js +44 -71
  15. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts +64 -0
  16. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts.map +1 -0
  17. package/src/engine/graphics/camera/orbital/MomentumAxis.js +187 -0
  18. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts +86 -0
  19. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts.map +1 -0
  20. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.js +319 -0
  21. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +34 -10
  22. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
  23. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +116 -30
  24. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -7
  25. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
  26. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +1 -37
  27. package/src/engine/graphics/ecs/water/Water.d.ts +8 -0
  28. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  29. package/src/engine/graphics/ecs/water/Water.js +8 -0
  30. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  31. package/src/engine/graphics3/WaterSystem.js +731 -734
  32. package/src/engine/graphics3/decal/DecalTileShader.d.ts +61 -0
  33. package/src/engine/graphics3/decal/DecalTileShader.d.ts.map +1 -0
  34. package/src/engine/graphics3/decal/DecalTileShader.js +138 -0
  35. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts +10 -4
  36. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts.map +1 -1
  37. package/src/engine/graphics3/decal/GPUDecalRenderer.js +149 -44
  38. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts +25 -0
  39. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts.map +1 -0
  40. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.js +55 -0
  41. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts +22 -0
  42. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts.map +1 -0
  43. package/src/engine/graphics3/decal/graph_gather_decal_tiles.js +70 -0
  44. package/src/engine/graphics3/decal/shader_decal_composite.d.ts +7 -5
  45. package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
  46. package/src/engine/graphics3/decal/shader_decal_composite.js +48 -44
  47. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts +12 -0
  48. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts.map +1 -0
  49. package/src/engine/graphics3/decal/shader_decal_tile_copy.js +78 -0
  50. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts +11 -0
  51. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts.map +1 -0
  52. package/src/engine/graphics3/decal/shader_gather_decal_tiles.js +80 -0
  53. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts +13 -0
  54. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts.map +1 -0
  55. package/src/engine/input/devices/mouse/MouseEventButtons.js +23 -0
  56. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts +4 -0
  57. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts.map +1 -1
  58. package/src/engine/input/ecs/controllers/KeyboardCameraController.js +9 -45
  59. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  60. package/src/shade/playground/water_refraction/README.md +5 -6
  61. package/src/shade/playground/water_refraction/index.html +1 -1
  62. package/src/shade/renderer/Renderer.d.ts +11 -0
  63. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  64. package/src/shade/renderer/Renderer.js +50 -6
  65. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
  66. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
  67. package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
  68. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  69. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  70. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  71. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  72. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  73. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +28 -45
  74. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  75. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +111 -119
  76. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +22 -3
  77. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  78. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +84 -3
  79. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts +19 -0
  80. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.d.ts.map +1 -0
  81. package/src/shade/renderer/geometry/virtual/proxy/vgeo_proxy_triangle_limit.js +25 -0
  82. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
  83. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
  84. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
  85. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts +15 -0
  86. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts.map +1 -1
  87. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.js +38 -0
  88. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
  89. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
  90. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
  91. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
  92. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
  93. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts +28 -59
  94. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.d.ts.map +1 -1
  95. package/src/shade/renderer/geometry/virtual/sdf/VGeoSDFProxies.js +84 -789
  96. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -8
  98. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +7 -6
  99. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  100. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +12 -11
  101. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts +2 -2
  102. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.js +2 -2
  103. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +1 -4
  104. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  105. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +1 -10
  106. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
  107. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
  108. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
  109. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  110. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
  111. package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
  112. package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
  113. package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
  114. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
  115. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
  116. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
  117. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
  118. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
  119. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
  120. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
  121. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  122. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
  123. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
  124. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
  125. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
  126. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
  127. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
  128. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
  129. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
  130. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
  131. package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
  132. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
  133. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  134. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
  135. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
  136. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
  137. package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
  138. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  139. package/src/shade/renderer/material/GPUMaterialManager.d.ts +11 -1
  140. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  141. package/src/shade/renderer/material/GPUMaterialManager.js +16 -8
  142. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
  143. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  144. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
  145. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +7 -3
  146. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  147. package/src/shade/renderer/postprocess/gtao/GTAO.js +26 -13
  148. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts +14 -0
  149. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
  150. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +196 -68
  151. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  152. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +42 -28
  153. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
  154. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +429 -414
  155. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts +16 -0
  156. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.d.ts.map +1 -0
  157. package/src/shade/renderer/postprocess/gtao/shader_gtao_spatial_denoise.js +156 -0
  158. package/src/shade/renderer/scene/GPUSceneContext.d.ts +2 -2
  159. package/src/shade/renderer/scene/GPUSceneContext.js +5 -5
  160. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  161. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
  162. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
  163. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  164. package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
  165. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
  166. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
  167. package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
  168. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  169. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  170. package/src/shade/renderer/water/shader_water.js +22 -13
  171. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  172. package/src/shade/renderer/water/shader_water_avboit.js +7 -7
  173. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
  174. package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
  175. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
  176. package/editor/REWORK_PLAN_2026_08.md +0 -692
  177. package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
  178. package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
  179. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
  180. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
  181. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
  182. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
  183. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
  184. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
  185. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
  186. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
  187. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
  188. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
  189. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
  190. package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
  191. package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
  192. package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
  193. package/src/REVIEW_2026_08_06/adv-core.md +0 -511
  194. package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
  195. package/src/REVIEW_2026_08_06/adv-view.md +0 -446
  196. package/src/REVIEW_2026_08_06/api-core.md +0 -296
  197. package/src/REVIEW_2026_08_06/api-engine.md +0 -195
  198. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
  199. package/src/REVIEW_2026_08_06/core-binary.md +0 -348
  200. package/src/REVIEW_2026_08_06/core-collection.md +0 -376
  201. package/src/REVIEW_2026_08_06/core-math.md +0 -221
  202. package/src/REVIEW_2026_08_06/core-process.md +0 -266
  203. package/src/REVIEW_2026_08_06/core-science.md +0 -223
  204. package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
  205. package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
  206. package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
  207. package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
  208. package/src/REVIEW_2026_08_06/engine-input.md +0 -197
  209. package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
  210. package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
  211. package/src/REVIEW_2026_08_06/generation.md +0 -176
  212. package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
  213. package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
  214. package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
  215. package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
  216. package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
  217. package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
  218. package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
  219. package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
  220. package/src/REVIEW_2026_08_06/view.md +0 -667
  221. package/src/REVIEW_2026_08_06.md +0 -610
  222. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
  223. package/src/core/bvh2/bvh3/NOTES.md +0 -2
  224. package/src/core/bvh8/NOTES.md +0 -63
  225. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
  226. package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
  227. package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
  228. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
  229. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
  230. package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
  231. package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
  232. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
  233. package/src/core/geom/3d/gjk/NOTES.md +0 -8
  234. package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
  235. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
  236. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
  237. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
  238. package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
  239. package/src/engine/REVIEW_2026_07_03.md +0 -211
  240. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
  241. package/src/engine/control/first-person/DESIGN.md +0 -658
  242. package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
  243. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
  244. package/src/engine/control/first-person/TODO.md +0 -160
  245. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
  246. package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
  247. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
  248. package/src/engine/ecs/ik/PLAN.md +0 -179
  249. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
  250. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
  251. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
  252. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
  253. package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
  254. package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
  255. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
  256. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
  257. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
  258. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
  259. package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
  260. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
  261. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
  262. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
  263. package/src/engine/network/CONGESTION_CONTROL.md +0 -87
  264. package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
  265. package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
  266. package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
  267. package/src/engine/physics/cloth/PLAN.md +0 -3056
  268. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
  269. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
  270. package/src/engine/physics/fluid/solver/NOTES.md +0 -46
  271. package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
  272. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
  273. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
  274. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
  275. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
  276. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
  277. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
  278. package/src/format/image/avif/DECISIONS.md +0 -545
  279. package/src/format/image/jpeg/NOTES.md +0 -3
  280. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
  281. package/src/generation/COORDINATES.md +0 -54
  282. package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
  283. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
  284. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
  285. package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
  286. package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
  287. package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
  288. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
  289. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
  290. package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
  291. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
  292. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
  293. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
  294. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
  295. package/src/shade/RENDERER_CONTRACT.md +0 -697
  296. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
  297. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
  298. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
  299. package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
  300. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
  301. package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
  302. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
  303. package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
  304. package/src/shade/renderer/NOTES.md +0 -78
  305. package/src/shade/renderer/PLAN.md +0 -8
  306. package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
  307. package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
  308. package/src/shade/renderer/atmosphere/NOTES.md +0 -6
  309. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
  310. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
  311. package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
  312. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
  313. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
  314. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
  315. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
  316. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
  317. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
  318. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
  319. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
  320. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
  321. package/src/shade/renderer/camera/orbital/README.md +0 -81
  322. package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
  323. package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
  324. package/src/shade/renderer/camera/orbital/index.js +0 -9
  325. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
  326. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
  327. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
  328. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
  329. package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
  330. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
  331. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
  332. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
  333. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
  334. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -481
  335. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
  336. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
  337. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
  338. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
  339. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
  340. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
  341. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
  342. package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -529
  343. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts +0 -47
  344. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.d.ts.map +0 -1
  345. package/src/shade/renderer/geometry/virtual/sdf/VGEO_SDF.js +0 -80
  346. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts +0 -16
  347. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.d.ts.map +0 -1
  348. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_collect.js +0 -67
  349. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts +0 -17
  350. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.d.ts.map +0 -1
  351. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_decode.js +0 -145
  352. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts +0 -12
  353. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.d.ts.map +0 -1
  354. package/src/shade/renderer/geometry/virtual/sdf/shader_vgeo_sdf_traverse.js +0 -105
  355. package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
  356. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4306
  357. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
  358. package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
  359. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
  360. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
  361. package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
  362. package/src/shade/renderer/hiz/NOTES.md +0 -3
  363. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
  364. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
  365. package/src/shade/renderer/light/cluster/NOTES.md +0 -11
  366. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
  367. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
  368. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
  369. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
  370. package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
  371. package/src/shade/renderer/particles/DESIGN.md +0 -1011
  372. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -280
  373. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
  374. package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
  375. package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
  376. package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
  377. package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
  378. package/src/shade/renderer/postprocess/nss/NOTES.md +0 -332
  379. package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
  380. package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
  381. package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
  382. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
  383. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
  384. package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
  385. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
  386. package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
  387. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
  388. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
  389. package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
  390. package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
  391. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -391
  392. package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -153
  393. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
  394. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
  395. package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
  396. package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
  397. package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
  398. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
  399. package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
  400. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
  401. package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
  402. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -927
  403. package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
  404. package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
  405. package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
  406. package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
  407. package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
  408. package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
  409. package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
  410. package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
  411. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
  412. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
  413. package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -3
  414. package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
  415. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
  416. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
  417. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
  418. package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
  419. package/src/shade/wgsl/NOTES.md +0 -4
@@ -1,272 +0,0 @@
1
- # Binary serialization coverage
2
-
3
- What verifies the save format, what does not, and what is known to be wrong with it.
4
-
5
- This file exists because three aggregate specs that used to answer those questions were deleted. They are
6
- worth understanding before adding anything like them back.
7
-
8
- ## Why the aggregate harnesses went
9
-
10
- `binary_adapter_round_trip.spec.js`, `upgrader_chain_contract.spec.js` and
11
- `upgrader_execution_contract.spec.js` walked the source tree with `fs.readdirSync`, dynamically imported every
12
- match, and drove each adapter through reflection.
13
-
14
- They found real defects — that was never in doubt. They were removed anyway, for reasons that are worth
15
- keeping:
16
-
17
- * **40% of the green was hollow.** The round-trip harness reported 78 passing tests. **31 of them asserted
18
- nothing:** 20 "not checked" (16 of those because the harness's own perturbation produced an object that
19
- violated the component's invariants and `serialize` threw — *"Expected 'Managed' flag to be set"*,
20
- *"Incorrect height data size. 4 !== 256"*), 4 whose state is `#private` and therefore invisible to
21
- structural comparison, and 7 the perturber could not vary. `Tag`, `Blackboard`, `UUID`, `Terrain`,
22
- `FogOfWar`, `AudioEmitter`, `SoundEmitter`, `ParticleEmitter` and `AnimationGraph` were all reported green
23
- and none of them were checked. The list was printed by `console.log` in an `afterAll`, invisible in a normal
24
- run.
25
- * **It asserted that the broken things were exactly the broken things.** `KNOWN_DIVERGENCE` was, in its own
26
- words, "a baseline, not a specification" — nine real defects encoded as expected values. A test that passes
27
- *because* the bug is still present is worse than no test.
28
- * **It hid a bug of exactly the kind it existed to catch.** See "Found and fixed" below.
29
- * **The reflection was the failure surface.** `perturb()` and `divergentPaths()` were ~250 lines of
30
- special-cased traversal (`isColor`, `isQuaternion`, typed arrays, `getValue`/`set`, `__validSet`,
31
- writability probing, depth limits, `Math.fround` tolerance). Whenever a test failed, the first question was
32
- whether the harness or the adapter was wrong.
33
- * **The dynamic imports flaked.** On Windows the transform cache lost `rename` races —
34
- `EPERM: operation not permitted, rename ...\ssr\.tmp-... -> ...\ssr\<hash>` — failing whichever adapter
35
- happened to be importing. The flake was read as a serialization bug more than once.
36
-
37
- The replacement is one hand-written spec per adapter, colocated with it, in the style of
38
- [`TagSerializationAdapter.spec.js`](../../components/TagSerializationAdapter.spec.js): construct an instance
39
- with distinctive values, serialize, deserialize into a fresh one, assert. Explicit, verbose, no reflection, no
40
- allow-lists, and each one states what the format actually promises.
41
-
42
- **The upgrade-path property is not reproduced.** `upgrader_chain_contract.spec.js` checked that every
43
- historical version could reach the current one. That property matters to a *consumer* of the engine shipping
44
- saved data, not to the engine, so it belongs in the consumer's suite.
45
-
46
- ## Found and fixed on the way out
47
-
48
- `FailingBehavior` and `SucceedingBehavior` **could not be serialized at all.** Both adapters wrote
49
- `value.delayTicks` — a constructor parameter that was deprecated and removed from both classes — so
50
- `writeUintVar(undefined)` threw on *any* instance, and a behaviour tree containing either could not be saved.
51
-
52
- The harness reported both green. `perturb()` found no field it knew how to vary, pushed them onto the
53
- "nothing the harness could vary" list, and returned before ever calling `serialize`.
54
-
55
- Both adapters now write nothing, because the classes carry no state. No version bump: since `serialize` always
56
- threw, no save containing these behaviours can exist, so there is no data to stay compatible with.
57
-
58
- ## Adapters still without a spec
59
-
60
- 28 files, of which `BinaryClassSerializationAdapter.js` (the base class) and
61
- `ObjectBasedClassSerializationAdapter.js` (a helper) are not adapters — so **26 real ones**. Every entry is an
62
- adapter nothing currently verifies.
63
-
64
- Sixteen of these are the ones whose `serialize` threw under the old harness. That is not a coincidence and it
65
- is where the interesting bugs are: those components have invariants, so a spec for one needs a hand-built
66
- fixture rather than a default instance. `FogOfWar` needs correctly-sized height data, `GUIElement` needs its
67
- `Managed` flag, `Terrain` needs a height array matching its resolution.
68
-
69
- | Class | Adapter |
70
- |---|---|
71
- | `Animation` | `engine/ecs/animation/AnimationSerializationAdapter.js` |
72
- | `FogOfWar` | `engine/ecs/fow/serialization/FogOfWarSerializationAdapter.js` |
73
- | `GUIElement` | `engine/ecs/gui/GUIElementSerializationAdapter.js` |
74
- | `Book` | `engine/ecs/storage/binary/BinaryClassSerializationAdapter.js` |
75
- | `?` | `engine/ecs/storage/binary/object/ObjectBasedClassSerializationAdapter.js` |
76
- | `Terrain` | `engine/ecs/terrain/serialization/TerrainSerializationAdapter.js` |
77
- | `AnimationController` | `engine/graphics/ecs/animation/AnimationControllerSerializationAdapter.js` |
78
- | `AnimationGraph` | `engine/graphics/ecs/animation/animator/graph/AnimationGraphSerializationAdapter.js` |
79
- | `AnimationGraphDefinition` | `engine/graphics/ecs/animation/animator/graph/definition/serialization/AnimationGraphDefinitionSerializationAdapter.js` |
80
- | `Camera` | `engine/graphics/ecs/camera/serialization/CameraSerializationAdapter.js` |
81
- | `TopDownCameraController` | `engine/graphics/ecs/camera/topdown/TopDownCameraControllerSerializationAdapter.js` |
82
- | `Decal` | `engine/graphics/ecs/decal/v2/DecalSerializationAdapter.js` |
83
- | `Highlight` | `engine/graphics/ecs/highlight/HighlightSerializationAdapter.js` |
84
- | `Mesh` | `engine/graphics/ecs/mesh/serialization/MeshSerializationAdapter.js` |
85
- | `Water` | `engine/graphics/ecs/water/WaterSerializationAdapter.js` |
86
- | `LightProbeVolume` | `engine/graphics/sh3/lpv/serialization/LightProbeVolumeSerializationAdapter.js` |
87
- | `Sampler2D` | `engine/graphics/texture/sampler/serialization/Sampler2DSerializationAdapter.js` |
88
- | `GridPosition2Transform` | `engine/grid/grid2transform/GridPosition2TransformSerializationAdapter.js` |
89
- | `GridObstacle` | `engine/grid/obstacle/GridObstacleSerializationAdapter.js` |
90
- | `ParallelBehavior` | `engine/intelligence/behavior/composite/ParallelBehaviorSerializationAdapter.js` |
91
- | `SequenceBehavior` | `engine/intelligence/behavior/composite/SequenceBehaviorSerializationAdapter.js` |
92
- | `InvertStatusBehavior` | `engine/intelligence/behavior/decorator/InvertStatusBehaviorSerializationAdapter.js` |
93
- | `RepeatBehavior` | `engine/intelligence/behavior/decorator/RepeatBehaviorSerializationAdapter.js` |
94
- | `BehaviorComponent` | `engine/intelligence/behavior/ecs/BehaviorComponentSerializationAdapter.js` |
95
- | `Transform` | `engine/interpolation/TransformPoseSerializationAdapter.js` |
96
- | `AcousticProbeField` | `engine/sound/simulation/probe/AcousticProbeFieldSerializationAdapter.js` |
97
-
98
- ## Upgraders
99
-
100
- 24 upgraders in the tree. Ten had a hand-written golden — an explicit byte layout in the version the upgrader
101
- reads — and those goldens are the one genuinely brutalist thing in the deleted files. They are preserved here
102
- verbatim so porting them to per-upgrader specs is transcription rather than archaeology.
103
-
104
- The per-upgrader spec should assert **the restored field values**, not the byte count the deleted harness
105
- asserted. The byte count was a proxy it used because it had no idea what the values ought to be; a spec that
106
- names one upgrader does know, and should say so.
107
-
108
- Upgraders added since carry that spec from the start. The first was IK's, which wrote a version 0 constraint
109
- field by field, ran it through the chain the engine registry hands a load, and asserted every restored field;
110
- it went with the component it upgraded (2026-10-06, a hard break: IK's goals live on bones, which are never
111
- saved).
112
-
113
- ### Goldens to port
114
-
115
- ```js
116
- const GOLDENS = {
117
- "CameraSerializationUpgrader_0_1.js": buffer => {
118
- buffer.writeUint8(1); // autoClip
119
- buffer.writeUint8(1); // active, an ObservedBoolean, one byte
120
- },
121
-
122
- "ClingToTerrainSerializationUpgrader_0_1.js": buffer => {
123
- buffer.writeUint8(1); // normalAlign
124
- },
125
-
126
- "DecalSerializationUpgrader_0_1.js": buffer => {
127
- buffer.writeUTF8String("data/textures/decal/circle1.png");
128
- buffer.writeFloat32(0); // priority
129
- buffer.writeFloat32Array([1, 1, 1, 1], 0, 4); // colour
130
- },
131
-
132
- "HighlightSerializationUpgrader_0_1.js": buffer => {
133
- buffer.writeFloat32(0.25); // r
134
- buffer.writeFloat32(0.5); // g
135
- buffer.writeFloat32(0.75); // b
136
- buffer.writeFloat32(1); // a
137
- },
138
-
139
- "PathSerializationUpgrader_0_1.js": buffer => {
140
- buffer.writeUint32(2); // point count
141
-
142
- for (let i = 0; i < 6; i++) {
143
- buffer.writeFloat64(i);
144
- }
145
- },
146
-
147
- "PathSerializationUpgrader_1_2.js": buffer => {
148
- buffer.writeUint8(0); // interpolation
149
- buffer.writeUintVar(0); // marker index
150
- buffer.writeFloat32(0); // marker offset
151
- buffer.writeUintVar(2); // point count
152
-
153
- for (let i = 0; i < 6; i++) {
154
- buffer.writeFloat32(i);
155
- }
156
- },
157
-
158
- "PathSerializationUpgrader_2_3.js": buffer => {
159
- buffer.writeUint8(0); // interpolation
160
- buffer.writeUintVar(2); // point count
161
- buffer.writeUintVar(3); // elements per point
162
-
163
- for (let i = 0; i < 6; i++) {
164
- buffer.writeFloat32(i);
165
- }
166
- },
167
-
168
- "TagSerializationUpgrader_0_1.js": buffer => {
169
- buffer.writeUTF8String("a-tag");
170
- },
171
-
172
- "TopDownCameraControllerSerializationUpgrader_0_1.js": buffer => {
173
- // target x/y/z, pitch, yaw, distance, distanceMin, distanceMax
174
- for (let i = 0; i < 8; i++) {
175
- buffer.writeFloat64(i + 1);
176
- }
177
- },
178
-
179
- "TransformSerializationUpgrader_0_1.js": buffer => {
180
- buffer.writeFloat64(1); // position x
181
- buffer.writeFloat64(2); // position y
182
- buffer.writeFloat64(3); // position z
183
-
184
- buffer.writeUint32(0); // encoded rotation
185
-
186
- buffer.writeFloat32(1); // scale x
187
- buffer.writeFloat32(2); // scale y
188
- buffer.writeFloat32(3); // scale z
189
- }
190
- };
191
- ```
192
-
193
- ### Upgraders with no golden
194
-
195
- Thirteen versions of the save format that nothing verifies can still be read. This was already an admitted gap
196
- in the deleted spec; it is not a new one.
197
-
198
- > The two `SoundEmitter` upgraders, its v2 adapter and the `SoundController` adapter now live under
199
- > `engine/sound/sopra/legacy/` alongside the components they read. Those components are frozen readers with no
200
- > runtime behaviour: they exist so that pre-`AudioEmitter` saves still deserialize, and are fed to
201
- > `convertLegacySoundComponents`, which turns them into `AudioEmitter` / `AudioEventTrigger`. They stay
202
- > registered here for exactly that reason — de-registering them would make old saves unreadable.
203
-
204
- ```js
205
- const WITHOUT_GOLDEN = [
206
- "FogOfWarSerializationUpdater_0_1.js",
207
- "GridPosition2TransformSerializationUpgrader_0_1.js",
208
- "GridPositionSerializationUpdater_0_1.js",
209
- "PathFollowerSerializationUpgrader_0_1.js",
210
- "PathFollowerSerializationUpgrader_1_2.js",
211
- "PathFollowerSerializationUpgrader_2_3.js",
212
- "PathFollowerSerializationUpgrader_3_4.js",
213
- "RigidBodySerializationUpgrader_0_1.js",
214
- "SoundEmitterSerializationUpgrader_0_1.js",
215
- "SoundEmitterSerializationUpgrader_1_2.js",
216
- "TerrainSerializationUpgrader_0_1.js",
217
- "TerrainSerializationUpgrader_1_2.js",
218
- "WaterSerializationUpgrader_0_1.js"
219
- ];
220
- ```
221
-
222
- ## Known defects in the format
223
-
224
- These came out of `KNOWN_DIVERGENCE`, where they were encoded as expected values so the suite stayed green
225
- with the bugs in place. They are real: an entity saved with any of these set does not come back the same.
226
- Preserved here as a defect list, which is what they always were.
227
-
228
- Where a spec has since been written for the adapter, the divergence is asserted explicitly *with its reason*,
229
- so the behaviour is visible at the adapter rather than in a table keyed by file path — see
230
- `LightSerializationAdapter.spec.js` (packed RGB drops alpha, harmless for a light and stated as such) and
231
- `WaitForEventBehaviorSerializationAdapter.spec.js` (the event name survives, the wait state does not, which is
232
- a defect and says so).
233
-
234
- ```js
235
- const KNOWN_DIVERGENCE = {
236
- // Color.toUint() is documented as RGB-only (uint24) and both adapters use
237
- // it, so alpha is dropped by design. Kept visible rather than exempted:
238
- // a light has no meaningful alpha, but water's might, and that is a call
239
- // for whoever owns the water shader.
240
- "engine/graphics/ecs/light/LightSerializationAdapter.js": ["color.a"],
241
- "engine/graphics/ecs/water/WaterSerializationAdapter.js": ["color.a", "shoreColor.a"],
242
-
243
- // flag fields dropped wholesale
244
- "engine/grid/grid2transform/GridPosition2TransformSerializationAdapter.js": ["flags"],
245
- "engine/ecs/transform/TransformSerializationAdapter.js": ["flags"],
246
- "engine/graphics/ecs/mesh/serialization/MeshSerializationAdapter.js": ["flags"],
247
-
248
- // a behaviour tree restored mid-run resumes from the wrong child
249
- "engine/intelligence/behavior/composite/SequenceBehaviorSerializationAdapter.js": [
250
- "__currentBehaviourIndex", "__currentBehaviourState"
251
- ],
252
- "engine/intelligence/behavior/ecs/BehaviorComponentSerializationAdapter.js": ["__behavior"],
253
-
254
- // the event it is waiting for is dropped, so it waits forever
255
- "engine/intelligence/behavior/ecs/WaitForEventBehaviorSerializationAdapter.js": [
256
- "detected", "entity", "target"
257
- ],
258
-
259
- "engine/sound/simulation/ecs/AcousticVolumeSerializationAdapter.js": ["shape.radius"]
260
- };
261
- ```
262
-
263
- Worth separating when these are worked through:
264
-
265
- * **Deliberate and harmless** — `Light.color.a`: `Color.toUint()` is documented RGB-only. A light has no
266
- meaningful alpha.
267
- * **Deliberate and questionable** — `Water.color.a`, `Water.shoreColor.a`: same encoding, but water's alpha
268
- might mean something. A call for whoever owns that shader.
269
- * **Straightforwardly broken** — `flags` dropped wholesale on `Transform`, `Mesh` and
270
- `GridPosition2Transform`; `SequenceBehavior` resuming from the wrong child; `BehaviorComponent` losing its
271
- behaviour entirely; `WaitForEventBehavior` restored on the wrong side of the event it waits for, so it waits
272
- forever; `AcousticVolume` losing its radius.
@@ -1,199 +0,0 @@
1
- # Object-graph binary serialization — design
2
-
3
- ## 1. Purpose
4
-
5
- A **general-purpose** binary serializer for arbitrary JavaScript object graphs, layered on the existing
6
- [`BinaryClassSerializationAdapter`](../BinaryClassSerializationAdapter.js) / upgrader / registry machinery.
7
-
8
- The defining goal — and the thing an earlier draft got wrong — is that you can serialize an object of class `X`
9
- **without hand-writing an adapter for it**. Classes are serialized by reflection over their own fields by default; a
10
- hand-written adapter is an *optional override* for classes that want a compact or custom encoding.
11
-
12
- What it does:
13
-
14
- - **Reflection by default.** Plain objects and class instances are serialized field-by-field with no per-class setup.
15
- - **Adapters as an override.** If a class has an adapter registered in the [`BinarySerializationRegistry`](../BinarySerializationRegistry.js),
16
- that adapter owns the encoding (compact, custom, versioned). Reflection is the fallback, not the only path.
17
- - **Reference semantics.** Shared references are preserved as one instance, and cycles are handled — objects are
18
- tracked by identity and re-encoded as back-references.
19
- - **Compact framing.** Class names and reflective field-name sets ("shapes") are interned into two tables written
20
- ahead of the body and referenced by a small integer, so a thousand same-class objects pay for the name once.
21
- - **Versioning + bidirectional migration.** Adapter-backed classes carry a version; on read, a mismatch is migrated
22
- through the registered [`BinaryClassUpgrader`](../BinaryClassUpgrader.js) chain in *either* direction.
23
- - **Minification-safe identity.** A class is identified by its adapter registration or its static `typeName`, never by
24
- the minifier-mangled `constructor.name`.
25
-
26
- ## 2. Where it sits
27
-
28
- ```
29
- BinaryBuffer byte stream
30
- └─ BinaryClassSerializationAdapter per-class hand-written serialize/deserialize (optional override)
31
- └─ BinarySerializationRegistry typeName → adapter, migrator graph, class → typeName
32
- └─ ModuleRegistry typeName → class (for reflective reconstruction)
33
- └─ BinaryObjectSerializer / BinaryObjectDeSerializer ← THIS: reflection + adapters + references + tables
34
- ```
35
-
36
- This complements the existing storage layer rather than duplicating it. [`BinaryBufferSerializer`](../../BinaryBufferSerializer.js)
37
- serializes an ECS dataset as *homogeneous collections of components* (one class name per collection, delegating nested
38
- objects to the older adapter-only `object/BinaryObjectSerializationAdapter`). This system is the general graph tool it
39
- was missing: heterogeneous graphs, adapter-less classes, and shared/cyclic references. It could serve as a drop-in for
40
- that nested-object role; that integration is deliberately out of scope here.
41
-
42
- ## 3. Wire format
43
-
44
- ```
45
- DOCUMENT := HEADER CLASS_TABLE SHAPE_TABLE BODY
46
-
47
- HEADER := u16(OBJECT_MAGIC=0x4F33) u8(OBJECT_FORMAT_VERSION=1)
48
-
49
- CLASS_TABLE := uvar(count) record* record := utf8(typeName) uvar(version)
50
- SHAPE_TABLE := uvar(count) shape* shape := uvar(fieldCount) utf8(name)*
51
-
52
- BODY := VALUE
53
-
54
- VALUE := u8(TAG_NULL) | u8(TAG_UNDEFINED) | u8(TAG_FALSE) | u8(TAG_TRUE)
55
- | u8(TAG_POS_INT) uvar(n) // n >= 0, fits a varint
56
- | u8(TAG_NEG_INT) uvar(-n) // n < 0, fits a varint
57
- | u8(TAG_FLOAT) float64 // any other number (float, NaN, ±Infinity, huge int)
58
- | u8(TAG_STRING) utf8
59
- | u8(TAG_BIGINT) utf8(decimal)
60
- | u8(TAG_REF) uvar(objectIndex) // back-reference to an already-seen object/array
61
- | u8(TAG_ARRAY) uvar(length) VALUE*
62
- | u8(TAG_PLAIN_OBJECT) uvar(shapeIdx) VALUE* // reconstructed as {}
63
- | u8(TAG_REFLECT_OBJECT) uvar(classIdx) uvar(shapeIdx) VALUE* // new Klass() + field assignment
64
- | u8(TAG_ADAPTER_OBJECT) uvar(classIdx) <adapter payload>
65
- ```
66
-
67
- **Object indices.** Every `ARRAY`, `PLAIN_OBJECT`, `REFLECT_OBJECT` and `ADAPTER_OBJECT` is assigned an index in
68
- first-seen order — the writer keeps an identity `Map`, the reader an array. Indices are *not written* for new objects
69
- (both sides count in lock-step); only `TAG_REF` carries an explicit index. Both sides register an object **before**
70
- reading/writing its contents, so a cyclic child resolves to the (partially built) parent.
71
-
72
- **Two version numbers.** `OBJECT_FORMAT_VERSION` versions the framing; the per-class `version` in the class table
73
- versions one class's payload and drives migration. They never interfere.
74
-
75
- **Prepended tables.** The body is built into a scratch buffer while the class/shape tables fill; the document then
76
- writes header + tables + a byte-copy of the body. Reading is a single forward pass (the tables come first). The only
77
- cost over single-pass writing is that final copy — as intended.
78
-
79
- ## 4. Reflection
80
-
81
- A class instance with no adapter, or a plain object, is written by enumerating `Object.keys(value)` (own enumerable
82
- string keys, in insertion order). The ordered name list is interned into the shape table; the body carries the shape
83
- index and one `VALUE` per field. This *reads* the instance's fields but never mutates it, and assumes no special field
84
- names — it serializes whatever is there.
85
-
86
- On read:
87
- - `PLAIN_OBJECT` → `{}`, fields assigned.
88
- - `REFLECT_OBJECT` → `new Klass()` (from the module registry, or the adapter's `klass` if one happens to be
89
- registered), fields assigned over it.
90
-
91
- Because the shape is self-describing, reflective encoding is naturally tolerant of additive field changes: a reader
92
- simply materialises whatever fields the shape lists. Semantic changes that need real migration are a reason to graduate
93
- the class to an adapter.
94
-
95
- **Strings and keys are NUL-safe.** All strings this system writes itself — type names, field names, string values and
96
- bigints — use a byte-length-prefixed UTF-8 codec ([`objectStringCodec.js`](./objectStringCodec.js)), not
97
- `BinaryBuffer.writeUTF8String`. The latter is NUL-*terminated* on read, so it cannot round-trip a string (or object
98
- key) containing `U+0000`; the byte-length prefix has no terminator and round-trips every code point. (Strings an
99
- *adapter* writes with `buffer.writeUTF8String` still follow that primitive's own behaviour — another reason adapters
100
- own their encoding.)
101
-
102
- ## 5. Adapters (the override)
103
-
104
- When the writer's registry has an adapter for a value's class, the value is written as `ADAPTER_OBJECT`: a class-table
105
- index plus the adapter's own payload. The adapter fully controls the bytes (e.g. three `float64`s for a `Vector3`,
106
- skipping field names and per-value tags), and can recurse into arbitrary children through the driving context via
107
- `this.context.writeValue` / `readValue` (see [`ObjectSerializationAdapter`](./ObjectSerializationAdapter.js)). Adapter
108
- objects participate in the same reference table, so shared/cyclic adapter instances work too.
109
-
110
- Adapters are the extension point for anything reflection shouldn't own: `Vector3`, typed arrays, `Map`/`Set`/`Date`,
111
- quantised or bit-packed encodings, or classes needing explicit migration.
112
-
113
- ## 6. Reference semantics
114
-
115
- Objects and arrays are tracked by **identity**. The first time an instance is seen it is encoded in full and assigned
116
- the next index; every later occurrence — whether a shared child or a cycle back to an ancestor — is a `TAG_REF` to that
117
- index. This preserves object identity across the graph (`restored.a === restored.b`) and makes cyclic graphs
118
- serialisable instead of stack-overflowing. Primitives are never reference-tracked.
119
-
120
- ## 7. Versioning & migration
121
-
122
- Adapter classes store their `version` once per class in the table. On read, the deserializer resolves migration
123
- **lazily, on the first `ADAPTER_OBJECT` of the class** — never at class-table time — because whether a class was written
124
- via an adapter (and so whether the version means anything) is a property of the body tag, not of the reader's registry.
125
- If the stored version differs from the reader's adapter version (in *either* direction), the payload is run through the
126
- shortest [`BinaryClassUpgrader`](../BinaryClassUpgrader.js) chain the registry can find. The chain is really a
127
- *migrator*: it can move down a version as readily as up, so there is no artificial "data must not be newer" rule — only
128
- "a path must exist".
129
-
130
- Reflective classes are stored at version 0 and are never migrated (their shapes already make them additively tolerant).
131
-
132
- **Nesting caveat.** A migrator reads one object's payload and rewrites it; the fresh scratch buffers make this
133
- re-entrant. As with the existing collection path, migrating an *adapter class whose payload itself nests other objects*
134
- requires the migrator to reproduce that nested framing — rare, and a reason to migrate leaf classes or use reflection.
135
-
136
- ## 8. Class identity & minification
137
-
138
- The name written for a class is resolved, in order:
139
- 1. the name its adapter is registered under (`registry.getClassName(constructor)` — a reverse index keyed on the
140
- constructor object, so it survives minification), else
141
- 2. the class's static `typeName` (the deliberate escape hatch: a minifier mangles `constructor.name` but leaves a
142
- `static typeName = "Foo"` string intact).
143
-
144
- A class instance with neither an adapter nor a `typeName` cannot be safely round-tripped and is rejected at write time
145
- with a message pointing at the fix. Plain objects (prototype `Object.prototype` or null) need no name — they round-trip
146
- as `{}`.
147
-
148
- ## 9. Registries
149
-
150
- - **Serializer** needs only a `BinarySerializationRegistry` (adapters + `getClassName` + versions).
151
- - **Deserializer** needs the same registry plus a `ModuleRegistry` (`typeName → class`) to reconstruct reflective
152
- class instances. The module registry is optional when the data has no reflective class instances (plain objects,
153
- arrays and adapter-backed classes don't need it). A reflective class missing from it is a clear read-time error.
154
-
155
- ## 10. Non-goals & limitations
156
-
157
- - **Not self-contained for exotic built-ins.** `Date`, `Map`, `Set`, `RegExp`, typed arrays and `ArrayBuffer` are not
158
- handled natively — register an adapter for them. This keeps the core small; the adapter mechanism is the seam.
159
- - **Functions and symbols** cannot be serialized (thrown at write). Symbol-keyed and non-enumerable properties are
160
- ignored (`Object.keys` semantics), matching JSON expectations.
161
- - **Reconstruction uses `new Klass()`** — classes need a usable no-argument constructor. Null-prototype objects come
162
- back as ordinary `{}`.
163
- - **Depth, not breadth, is the limit.** References make cyclic/shared graphs safe, but a pathologically deep graph can
164
- still exhaust the call stack.
165
-
166
- ## 11. Security posture
167
-
168
- Deserialization only ever constructs (a) classes with a registered adapter, or (b) classes present in the module
169
- registry, or (c) plain objects/arrays. It never instantiates an attacker-named arbitrary type and never invokes
170
- stream-driven methods beyond a class's own `deserialize`. This registry/module allow-list is the standard mitigation
171
- for the reflective-deserializer RCE lineage (Java `Serializable`, `pickle`, .NET `BinaryFormatter`). Reflection does
172
- read *all* own-enumerable fields of the objects you hand it — use an adapter when a class must control or withhold
173
- fields.
174
-
175
- ## 12. API
176
-
177
- `BinaryObjectSerializer(registry)` — `serialize(buffer, value)`, `writeValue(buffer, value)` (for nesting adapters).
178
-
179
- `BinaryObjectDeSerializer(registry, modules?)` — `deserialize(buffer)`, `readValue(buffer)` (for nesting adapters),
180
- `setModuleRegistry(modules)`.
181
-
182
- `ObjectSerializationAdapter extends BinaryClassSerializationAdapter` — base for nesting adapters; `initialize(context)`
183
- captures the serializer/deserializer into `this.context`.
184
-
185
- `BinarySerializationRegistry.getClassName(klass)` — reverse of `registerAdapter`; constructor → registered name.
186
-
187
- ## 13. Tests
188
-
189
- - `*.reflection.spec.js` — primitives (incl. bigint, NaN/±Infinity, large-int→float), plain objects, arrays, reflective
190
- class instances, nesting, field-order preservation, no-mutation.
191
- - `*.references.spec.js` — shared references, self-cycles, mutual cycles, self-containing arrays, cycles through class
192
- instances and container adapters.
193
- - `*.adapters.spec.js` — adapter used & respected, adapter framing vs reflective, adapter objects nested/shared,
194
- container adapter recursing through the context.
195
- - `*.versioning.spec.js` — forward migration, **backward** migration, version-match no-op, missing-path error, shared
196
- class-table migration.
197
- - `*.errors.spec.js` — function/symbol rejection, missing typeName, missing module registry, bad magic / format
198
- version, `typeName`-as-identity, class+shape interning, large homogeneous collection.
199
- - `BinarySerializationRegistry.spec.js` — `getClassName` reverse-lookup.