nucleation 0.10.21 → 0.10.23

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 (314) hide show
  1. package/BlockPos.mjs +1 -0
  2. package/Dimensions.mjs +1 -0
  3. package/FieldRange.mjs +1 -0
  4. package/ItemScale.mjs +1 -0
  5. package/MeshBounds.mjs +1 -0
  6. package/MeshProgress.mjs +1 -0
  7. package/README.md +12 -0
  8. package/RegionBounds.mjs +1 -0
  9. package/Schematic.d.mts +32 -0
  10. package/Schematic.d.ts +32 -0
  11. package/Schematic.mjs +100 -0
  12. package/SdfBounds.mjs +1 -0
  13. package/SdfNormal.mjs +1 -0
  14. package/TextureInfo.mjs +1 -0
  15. package/diplomat-runtime.mjs +19 -14
  16. package/nucleation.wasm +0 -0
  17. package/package.json +7 -2
  18. package/renderer/AnimationEffect.d.mts +44 -0
  19. package/renderer/AnimationEffect.d.ts +44 -0
  20. package/renderer/AnimationEffect.mjs +204 -0
  21. package/renderer/Autostack.d.mts +43 -0
  22. package/renderer/Autostack.d.ts +43 -0
  23. package/renderer/Autostack.mjs +134 -0
  24. package/renderer/BlockPos.d.mts +28 -0
  25. package/renderer/BlockPos.d.ts +28 -0
  26. package/renderer/BlockPos.mjs +130 -0
  27. package/renderer/BlockState.d.mts +39 -0
  28. package/renderer/BlockState.d.ts +39 -0
  29. package/renderer/BlockState.mjs +134 -0
  30. package/renderer/Blocks.d.mts +91 -0
  31. package/renderer/Blocks.d.ts +91 -0
  32. package/renderer/Blocks.mjs +308 -0
  33. package/renderer/Brush.d.mts +99 -0
  34. package/renderer/Brush.d.ts +99 -0
  35. package/renderer/Brush.mjs +335 -0
  36. package/renderer/BuildAnimation.d.mts +179 -0
  37. package/renderer/BuildAnimation.d.ts +179 -0
  38. package/renderer/BuildAnimation.mjs +1148 -0
  39. package/renderer/BuildingTool.d.mts +46 -0
  40. package/renderer/BuildingTool.d.ts +46 -0
  41. package/renderer/BuildingTool.mjs +121 -0
  42. package/renderer/CellExecutor.d.mts +51 -0
  43. package/renderer/CellExecutor.d.ts +51 -0
  44. package/renderer/CellExecutor.mjs +171 -0
  45. package/renderer/CellularSdfConfig.d.mts +22 -0
  46. package/renderer/CellularSdfConfig.d.ts +22 -0
  47. package/renderer/CellularSdfConfig.mjs +69 -0
  48. package/renderer/ChunkMeshResult.d.mts +75 -0
  49. package/renderer/ChunkMeshResult.d.ts +75 -0
  50. package/renderer/ChunkMeshResult.mjs +253 -0
  51. package/renderer/CircuitBuilder.d.mts +118 -0
  52. package/renderer/CircuitBuilder.d.ts +118 -0
  53. package/renderer/CircuitBuilder.mjs +516 -0
  54. package/renderer/Curve3D.d.mts +27 -0
  55. package/renderer/Curve3D.d.ts +27 -0
  56. package/renderer/Curve3D.mjs +101 -0
  57. package/renderer/DefinitionRegion.d.mts +274 -0
  58. package/renderer/DefinitionRegion.d.ts +274 -0
  59. package/renderer/DefinitionRegion.mjs +973 -0
  60. package/renderer/Design.d.mts +348 -0
  61. package/renderer/Design.d.ts +348 -0
  62. package/renderer/Design.mjs +1334 -0
  63. package/renderer/Diff.d.mts +88 -0
  64. package/renderer/Diff.d.ts +88 -0
  65. package/renderer/Diff.mjs +316 -0
  66. package/renderer/Dimensions.d.mts +28 -0
  67. package/renderer/Dimensions.d.ts +28 -0
  68. package/renderer/Dimensions.mjs +130 -0
  69. package/renderer/DistanceField.d.mts +39 -0
  70. package/renderer/DistanceField.d.ts +39 -0
  71. package/renderer/DistanceField.mjs +114 -0
  72. package/renderer/ExecutionMode.d.mts +42 -0
  73. package/renderer/ExecutionMode.d.ts +42 -0
  74. package/renderer/ExecutionMode.mjs +127 -0
  75. package/renderer/Field3.d.mts +40 -0
  76. package/renderer/Field3.d.ts +40 -0
  77. package/renderer/Field3.mjs +160 -0
  78. package/renderer/FieldProgram.d.mts +40 -0
  79. package/renderer/FieldProgram.d.ts +40 -0
  80. package/renderer/FieldProgram.mjs +167 -0
  81. package/renderer/FieldProgramBinaryOp.d.mts +42 -0
  82. package/renderer/FieldProgramBinaryOp.d.ts +42 -0
  83. package/renderer/FieldProgramBinaryOp.mjs +118 -0
  84. package/renderer/FieldProgramBuilder.d.mts +104 -0
  85. package/renderer/FieldProgramBuilder.d.ts +104 -0
  86. package/renderer/FieldProgramBuilder.mjs +486 -0
  87. package/renderer/FieldProgramDistanceKind.d.mts +26 -0
  88. package/renderer/FieldProgramDistanceKind.d.ts +26 -0
  89. package/renderer/FieldProgramDistanceKind.mjs +78 -0
  90. package/renderer/FieldProgramUnaryOp.d.mts +34 -0
  91. package/renderer/FieldProgramUnaryOp.d.ts +34 -0
  92. package/renderer/FieldProgramUnaryOp.mjs +102 -0
  93. package/renderer/FieldProgramValueType.d.mts +25 -0
  94. package/renderer/FieldProgramValueType.d.ts +25 -0
  95. package/renderer/FieldProgramValueType.mjs +75 -0
  96. package/renderer/FieldRange.d.mts +15 -0
  97. package/renderer/FieldRange.d.ts +15 -0
  98. package/renderer/FieldRange.mjs +109 -0
  99. package/renderer/Fingerprint.d.mts +44 -0
  100. package/renderer/Fingerprint.d.ts +44 -0
  101. package/renderer/Fingerprint.mjs +197 -0
  102. package/renderer/GeneratedChunk.d.mts +35 -0
  103. package/renderer/GeneratedChunk.d.ts +35 -0
  104. package/renderer/GeneratedChunk.mjs +178 -0
  105. package/renderer/GeneratedChunkCoverage.d.mts +25 -0
  106. package/renderer/GeneratedChunkCoverage.d.ts +25 -0
  107. package/renderer/GeneratedChunkCoverage.mjs +75 -0
  108. package/renderer/GeneratedChunkOverlayMode.d.mts +24 -0
  109. package/renderer/GeneratedChunkOverlayMode.d.ts +24 -0
  110. package/renderer/GeneratedChunkOverlayMode.mjs +72 -0
  111. package/renderer/GeneratedWorldStream.d.mts +28 -0
  112. package/renderer/GeneratedWorldStream.d.ts +28 -0
  113. package/renderer/GeneratedWorldStream.mjs +86 -0
  114. package/renderer/Geo.d.mts +41 -0
  115. package/renderer/Geo.d.ts +41 -0
  116. package/renderer/Geo.mjs +121 -0
  117. package/renderer/Hdl.d.mts +56 -0
  118. package/renderer/Hdl.d.ts +56 -0
  119. package/renderer/Hdl.mjs +163 -0
  120. package/renderer/InterpolationSpace.d.mts +25 -0
  121. package/renderer/InterpolationSpace.d.ts +25 -0
  122. package/renderer/InterpolationSpace.mjs +73 -0
  123. package/renderer/IoLayout.d.mts +26 -0
  124. package/renderer/IoLayout.d.ts +26 -0
  125. package/renderer/IoLayout.mjs +81 -0
  126. package/renderer/IoLayoutBuilder.d.mts +73 -0
  127. package/renderer/IoLayoutBuilder.d.ts +73 -0
  128. package/renderer/IoLayoutBuilder.mjs +315 -0
  129. package/renderer/IoType.d.mts +41 -0
  130. package/renderer/IoType.d.ts +41 -0
  131. package/renderer/IoType.mjs +125 -0
  132. package/renderer/ItemModelConfig.d.mts +65 -0
  133. package/renderer/ItemModelConfig.d.ts +65 -0
  134. package/renderer/ItemModelConfig.mjs +223 -0
  135. package/renderer/ItemModelPackBuilder.d.mts +32 -0
  136. package/renderer/ItemModelPackBuilder.d.ts +32 -0
  137. package/renderer/ItemModelPackBuilder.mjs +104 -0
  138. package/renderer/ItemModelResult.d.mts +72 -0
  139. package/renderer/ItemModelResult.d.ts +72 -0
  140. package/renderer/ItemModelResult.mjs +268 -0
  141. package/renderer/ItemScale.d.mts +31 -0
  142. package/renderer/ItemScale.d.ts +31 -0
  143. package/renderer/ItemScale.mjs +133 -0
  144. package/renderer/LayoutFunction.d.mts +52 -0
  145. package/renderer/LayoutFunction.d.ts +52 -0
  146. package/renderer/LayoutFunction.mjs +159 -0
  147. package/renderer/MchprsWorld.d.mts +131 -0
  148. package/renderer/MchprsWorld.d.ts +131 -0
  149. package/renderer/MchprsWorld.mjs +423 -0
  150. package/renderer/MeshBounds.d.mts +40 -0
  151. package/renderer/MeshBounds.d.ts +40 -0
  152. package/renderer/MeshBounds.mjs +181 -0
  153. package/renderer/MeshConfig.d.mts +101 -0
  154. package/renderer/MeshConfig.d.ts +101 -0
  155. package/renderer/MeshConfig.mjs +306 -0
  156. package/renderer/MeshJob.d.mts +44 -0
  157. package/renderer/MeshJob.d.ts +44 -0
  158. package/renderer/MeshJob.mjs +116 -0
  159. package/renderer/MeshPhase.d.mts +38 -0
  160. package/renderer/MeshPhase.d.ts +38 -0
  161. package/renderer/MeshPhase.mjs +90 -0
  162. package/renderer/MeshProgress.d.mts +32 -0
  163. package/renderer/MeshProgress.d.ts +32 -0
  164. package/renderer/MeshProgress.mjs +134 -0
  165. package/renderer/MeshResult.d.mts +76 -0
  166. package/renderer/MeshResult.d.ts +76 -0
  167. package/renderer/MeshResult.mjs +269 -0
  168. package/renderer/MultiMeshResult.d.mts +50 -0
  169. package/renderer/MultiMeshResult.d.ts +50 -0
  170. package/renderer/MultiMeshResult.mjs +166 -0
  171. package/renderer/Nbt.d.mts +50 -0
  172. package/renderer/Nbt.d.ts +50 -0
  173. package/renderer/Nbt.mjs +161 -0
  174. package/renderer/NucleationError.d.mts +53 -0
  175. package/renderer/NucleationError.d.ts +53 -0
  176. package/renderer/NucleationError.mjs +136 -0
  177. package/renderer/OutputCondition.d.mts +45 -0
  178. package/renderer/OutputCondition.d.ts +45 -0
  179. package/renderer/OutputCondition.mjs +129 -0
  180. package/renderer/Palette.d.mts +157 -0
  181. package/renderer/Palette.d.ts +157 -0
  182. package/renderer/Palette.mjs +487 -0
  183. package/renderer/PaletteBuilder.d.mts +119 -0
  184. package/renderer/PaletteBuilder.d.ts +119 -0
  185. package/renderer/PaletteBuilder.mjs +457 -0
  186. package/renderer/README.md +67 -0
  187. package/renderer/RawMeshExport.d.mts +74 -0
  188. package/renderer/RawMeshExport.d.ts +74 -0
  189. package/renderer/RawMeshExport.mjs +243 -0
  190. package/renderer/RedstoneGraph.d.mts +58 -0
  191. package/renderer/RedstoneGraph.d.ts +58 -0
  192. package/renderer/RedstoneGraph.mjs +242 -0
  193. package/renderer/RegionBounds.d.mts +41 -0
  194. package/renderer/RegionBounds.d.ts +41 -0
  195. package/renderer/RegionBounds.mjs +182 -0
  196. package/renderer/RenderConfig.d.mts +101 -0
  197. package/renderer/RenderConfig.d.ts +101 -0
  198. package/renderer/RenderConfig.mjs +271 -0
  199. package/renderer/Renderer.d.mts +51 -0
  200. package/renderer/Renderer.d.ts +51 -0
  201. package/renderer/Renderer.mjs +219 -0
  202. package/renderer/ResourcePack.d.mts +105 -0
  203. package/renderer/ResourcePack.d.ts +105 -0
  204. package/renderer/ResourcePack.mjs +447 -0
  205. package/renderer/ResourcePackList.d.mts +32 -0
  206. package/renderer/ResourcePackList.d.ts +32 -0
  207. package/renderer/ResourcePackList.mjs +96 -0
  208. package/renderer/Routing.d.mts +66 -0
  209. package/renderer/Routing.d.ts +66 -0
  210. package/renderer/Routing.mjs +220 -0
  211. package/renderer/Schematic.d.mts +977 -0
  212. package/renderer/Schematic.d.ts +977 -0
  213. package/renderer/Schematic.mjs +3820 -0
  214. package/renderer/SchematicBuilder.d.mts +103 -0
  215. package/renderer/SchematicBuilder.d.ts +103 -0
  216. package/renderer/SchematicBuilder.mjs +401 -0
  217. package/renderer/SchematicRegions.d.mts +93 -0
  218. package/renderer/SchematicRegions.d.ts +93 -0
  219. package/renderer/SchematicRegions.mjs +411 -0
  220. package/renderer/SchematicSplitResult.d.mts +26 -0
  221. package/renderer/SchematicSplitResult.d.ts +26 -0
  222. package/renderer/SchematicSplitResult.mjs +84 -0
  223. package/renderer/Scripting.d.mts +40 -0
  224. package/renderer/Scripting.d.ts +40 -0
  225. package/renderer/Scripting.mjs +138 -0
  226. package/renderer/Sdf.d.mts +234 -0
  227. package/renderer/Sdf.d.ts +234 -0
  228. package/renderer/Sdf.mjs +1234 -0
  229. package/renderer/SdfAxis.d.mts +25 -0
  230. package/renderer/SdfAxis.d.ts +25 -0
  231. package/renderer/SdfAxis.mjs +75 -0
  232. package/renderer/SdfBounds.d.mts +19 -0
  233. package/renderer/SdfBounds.d.ts +19 -0
  234. package/renderer/SdfBounds.mjs +161 -0
  235. package/renderer/SdfCellMode.d.mts +26 -0
  236. package/renderer/SdfCellMode.d.ts +26 -0
  237. package/renderer/SdfCellMode.mjs +78 -0
  238. package/renderer/SdfNormal.d.mts +16 -0
  239. package/renderer/SdfNormal.d.ts +16 -0
  240. package/renderer/SdfNormal.mjs +122 -0
  241. package/renderer/Shape.d.mts +143 -0
  242. package/renderer/Shape.d.ts +143 -0
  243. package/renderer/Shape.mjs +458 -0
  244. package/renderer/SortStrategy.d.mts +86 -0
  245. package/renderer/SortStrategy.d.ts +86 -0
  246. package/renderer/SortStrategy.mjs +272 -0
  247. package/renderer/Store.d.mts +83 -0
  248. package/renderer/Store.d.ts +83 -0
  249. package/renderer/Store.mjs +369 -0
  250. package/renderer/StoreIo.d.mts +71 -0
  251. package/renderer/StoreIo.d.ts +71 -0
  252. package/renderer/StoreIo.mjs +292 -0
  253. package/renderer/TextureAtlas.d.mts +40 -0
  254. package/renderer/TextureAtlas.d.ts +40 -0
  255. package/renderer/TextureAtlas.mjs +122 -0
  256. package/renderer/TextureInfo.d.mts +34 -0
  257. package/renderer/TextureInfo.d.ts +34 -0
  258. package/renderer/TextureInfo.mjs +149 -0
  259. package/renderer/TickSettleMode.d.mts +34 -0
  260. package/renderer/TickSettleMode.d.ts +34 -0
  261. package/renderer/TickSettleMode.mjs +84 -0
  262. package/renderer/TickSimulation.d.mts +572 -0
  263. package/renderer/TickSimulation.d.ts +572 -0
  264. package/renderer/TickSimulation.mjs +1299 -0
  265. package/renderer/TypedCircuitExecutor.d.mts +101 -0
  266. package/renderer/TypedCircuitExecutor.d.ts +101 -0
  267. package/renderer/TypedCircuitExecutor.mjs +378 -0
  268. package/renderer/Value.d.mts +73 -0
  269. package/renderer/Value.d.ts +73 -0
  270. package/renderer/Value.mjs +275 -0
  271. package/renderer/VideoConfig.d.mts +15 -0
  272. package/renderer/VideoConfig.d.ts +15 -0
  273. package/renderer/VideoConfig.mjs +44 -0
  274. package/renderer/VoxelModel.d.mts +34 -0
  275. package/renderer/VoxelModel.d.ts +34 -0
  276. package/renderer/VoxelModel.mjs +113 -0
  277. package/renderer/Voxelizer.d.mts +80 -0
  278. package/renderer/Voxelizer.d.ts +80 -0
  279. package/renderer/Voxelizer.mjs +261 -0
  280. package/renderer/WorldChunkView.d.mts +75 -0
  281. package/renderer/WorldChunkView.d.ts +75 -0
  282. package/renderer/WorldChunkView.mjs +224 -0
  283. package/renderer/WorldGenerator.d.mts +75 -0
  284. package/renderer/WorldGenerator.d.ts +75 -0
  285. package/renderer/WorldGenerator.mjs +255 -0
  286. package/renderer/WorldSink.d.mts +50 -0
  287. package/renderer/WorldSink.d.ts +50 -0
  288. package/renderer/WorldSink.mjs +177 -0
  289. package/renderer/WorldStream.d.mts +45 -0
  290. package/renderer/WorldStream.d.ts +45 -0
  291. package/renderer/WorldStream.mjs +184 -0
  292. package/renderer/WsPartitionHints.d.mts +29 -0
  293. package/renderer/WsPartitionHints.d.ts +29 -0
  294. package/renderer/WsPartitionHints.mjs +102 -0
  295. package/renderer/WsProfile.d.mts +46 -0
  296. package/renderer/WsProfile.d.ts +46 -0
  297. package/renderer/WsProfile.mjs +152 -0
  298. package/renderer/WsRunResult.d.mts +83 -0
  299. package/renderer/WsRunResult.d.ts +83 -0
  300. package/renderer/WsRunResult.mjs +326 -0
  301. package/renderer/WsSegmentJob.d.mts +28 -0
  302. package/renderer/WsSegmentJob.d.ts +28 -0
  303. package/renderer/WsSegmentJob.mjs +81 -0
  304. package/renderer/diplomat-runtime.d.mts +15 -0
  305. package/renderer/diplomat-runtime.d.ts +15 -0
  306. package/renderer/diplomat-runtime.mjs +779 -0
  307. package/renderer/diplomat-wasm.mjs +52 -0
  308. package/renderer/diplomat.config.mjs +5 -0
  309. package/renderer/index.d.mts +193 -0
  310. package/renderer/index.d.ts +193 -0
  311. package/renderer/index.mjs +196 -0
  312. package/renderer/nucleation.wasm +0 -0
  313. package/renderer/veneer/design.d.ts +167 -0
  314. package/renderer/veneer/design.mjs +480 -0
@@ -0,0 +1,1299 @@
1
+ // generated by diplomat-tool
2
+ import { NucleationError } from "./NucleationError.mjs"
3
+ import { Schematic } from "./Schematic.mjs"
4
+ import { TickSettleMode } from "./TickSettleMode.mjs"
5
+ import wasm from "./diplomat-wasm.mjs";
6
+ import * as diplomatRuntime from "./diplomat-runtime.mjs";
7
+
8
+ const TickSimulation_box_destroy_registry = new FinalizationRegistry((ptr) => {
9
+ wasm.TickSimulation_destroy(ptr);
10
+ });
11
+
12
+ /**
13
+ * A headless, vanilla-accurate tick simulation of one structure.
14
+ */
15
+ export class TickSimulation {
16
+ // Internal ptr reference:
17
+ #ptr = null;
18
+
19
+ // Lifetimes are only to keep dependencies alive.
20
+ // Since JS won't garbage collect until there are no incoming edges.
21
+ #selfEdge = [];
22
+
23
+ #internalConstructor(symbol, ptr, selfEdge) {
24
+ if (symbol !== diplomatRuntime.internalConstructor) {
25
+ console.error("TickSimulation is an Opaque type. You cannot call its constructor.");
26
+ return;
27
+ }
28
+ this.#ptr = ptr;
29
+ this.#selfEdge = selfEdge;
30
+
31
+ // Are we being borrowed? If not, we can register.
32
+ if (this.#selfEdge.length === 0) {
33
+ TickSimulation_box_destroy_registry.register(this, this.#ptr);
34
+ }
35
+
36
+ return this;
37
+ }
38
+ /** @internal */
39
+ get ffiValue() {
40
+ return this.#ptr;
41
+ }
42
+
43
+
44
+ /**
45
+ * Why the last constructor on this thread failed, in words.
46
+ *
47
+ * The enum cannot carry a message, and "Simulation" is useless to
48
+ * someone holding a door that will not load: the engine already knows
49
+ * it is `minecraft:waxed_copper_bulb` at (4,2,1) and says so here.
50
+ * Empty when the last construction succeeded.
51
+ */
52
+ static lastErrorDetail() {
53
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
54
+
55
+ wasm.TickSimulation_last_error_detail(write.buffer);
56
+
57
+ try {
58
+ return write.readString8();
59
+ }
60
+
61
+ finally {
62
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
63
+ write.free();
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Largest build this will attempt, in cells.
69
+ *
70
+ * A 500x379x442 "door" is a saved world, and loading one exhausts the
71
+ * wasm heap — after which every later call on that instance traps,
72
+ * not just the one that overflowed. Refused up front instead.
73
+ */
74
+ static maxVolume() {
75
+
76
+ const result = wasm.TickSimulation_max_volume();
77
+
78
+ try {
79
+ return result;
80
+ }
81
+
82
+ finally {
83
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Load from Java structure SNBT text.
89
+ *
90
+ * `extra_states`: semicolon-separated block-state descriptors that
91
+ * later `place_block` calls may write (behaviours bind at
92
+ * construction). `minecraft:redstone_block` is always available.
93
+ * `origin_*`: where the build's (0,0,0) sits in world coordinates —
94
+ * wire update order hashes absolute positions.
95
+ *
96
+ * The text's own `DataVersion` selects `Entity.load` Motion semantics,
97
+ * exactly as {@link TickSimulation::from_schematic} uses the schematic's —
98
+ * so `gametest_snbt` → `from_snbt` keeps a nan-cart build's NaN
99
+ * velocities instead of quietly sanitising them. A text with no
100
+ * `DataVersion` gets the engine default (the modern, NaN-dropping
101
+ * rule); read {@link TickSimulation::motion_semantics} to see which
102
+ * applied.
103
+ */
104
+ static fromSnbt(snbt, settle, originX, originY, originZ, extraStates) {
105
+ let functionCleanupArena = new diplomatRuntime.CleanupArena();
106
+
107
+ const snbtSlice = functionCleanupArena.alloc(diplomatRuntime.DiplomatBuf.sliceWrapper(wasm, diplomatRuntime.DiplomatBuf.str8(wasm, snbt)));
108
+ const extraStatesSlice = functionCleanupArena.alloc(diplomatRuntime.DiplomatBuf.sliceWrapper(wasm, diplomatRuntime.DiplomatBuf.str8(wasm, extraStates)));
109
+ const diplomatReceive = new diplomatRuntime.DiplomatReceiveBuf(wasm, 5, 4, true);
110
+
111
+
112
+ const result = wasm.TickSimulation_from_snbt(diplomatReceive.buffer, snbtSlice.ptr, settle.ffiValue, originX, originY, originZ, extraStatesSlice.ptr);
113
+
114
+ try {
115
+ if (!diplomatReceive.resultFlag) {
116
+ const cause = new NucleationError(diplomatRuntime.internalConstructor, diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer));
117
+ throw new globalThis.Error('NucleationError.' + cause.value, { cause });
118
+ }
119
+ return new TickSimulation(diplomatRuntime.internalConstructor, diplomatRuntime.ptrRead(wasm, diplomatReceive.buffer), []);
120
+ }
121
+
122
+ finally {
123
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
124
+ functionCleanupArena.free();
125
+
126
+ diplomatReceive.free();
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Load from a schematic (any format nucleation can read), rendered
132
+ * to gametest-flavor structure SNBT for mc-tick's parser.
133
+ */
134
+ static fromSchematic(schematic, settle, originX, originY, originZ, extraStates) {
135
+ let functionCleanupArena = new diplomatRuntime.CleanupArena();
136
+
137
+ const extraStatesSlice = functionCleanupArena.alloc(diplomatRuntime.DiplomatBuf.sliceWrapper(wasm, diplomatRuntime.DiplomatBuf.str8(wasm, extraStates)));
138
+ const diplomatReceive = new diplomatRuntime.DiplomatReceiveBuf(wasm, 5, 4, true);
139
+
140
+
141
+ const result = wasm.TickSimulation_from_schematic(diplomatReceive.buffer, schematic.ffiValue, settle.ffiValue, originX, originY, originZ, extraStatesSlice.ptr);
142
+
143
+ try {
144
+ if (!diplomatReceive.resultFlag) {
145
+ const cause = new NucleationError(diplomatRuntime.internalConstructor, diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer));
146
+ throw new globalThis.Error('NucleationError.' + cause.value, { cause });
147
+ }
148
+ return new TickSimulation(diplomatRuntime.internalConstructor, diplomatRuntime.ptrRead(wasm, diplomatReceive.buffer), []);
149
+ }
150
+
151
+ finally {
152
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
153
+ functionCleanupArena.free();
154
+
155
+ diplomatReceive.free();
156
+ }
157
+ }
158
+
159
+ /**
160
+ * GA fast path: construct from a flat genome-cell array — no SNBT
161
+ * text built or parsed. Corridor layout matches the flying-ga app:
162
+ * machine at `x_off`, world size `[bx + travel, by + 2, bz + 2]`,
163
+ * cells flattened `((y * bz) + z) * bx + x`, `air_index` = empty
164
+ * cell. `palette` is the run's alphabet, semicolon-separated; every
165
+ * entry is pre-interned so behaviours bind exactly as the SNBT
166
+ * path's EXTRA_STATES did.
167
+ */
168
+ static fromBlocks(bx, by, bz, travel, xOff, palette, cells, airIndex, settle, originX, originY, originZ) {
169
+ let functionCleanupArena = new diplomatRuntime.CleanupArena();
170
+
171
+ const paletteSlice = functionCleanupArena.alloc(diplomatRuntime.DiplomatBuf.sliceWrapper(wasm, diplomatRuntime.DiplomatBuf.str8(wasm, palette)));
172
+ const cellsSlice = functionCleanupArena.alloc(diplomatRuntime.DiplomatBuf.sliceWrapper(wasm, diplomatRuntime.DiplomatBuf.slice(wasm, cells, "u16")));
173
+ const diplomatReceive = new diplomatRuntime.DiplomatReceiveBuf(wasm, 5, 4, true);
174
+
175
+
176
+ const result = wasm.TickSimulation_from_blocks(diplomatReceive.buffer, bx, by, bz, travel, xOff, paletteSlice.ptr, cellsSlice.ptr, airIndex, settle.ffiValue, originX, originY, originZ);
177
+
178
+ try {
179
+ if (!diplomatReceive.resultFlag) {
180
+ const cause = new NucleationError(diplomatRuntime.internalConstructor, diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer));
181
+ throw new globalThis.Error('NucleationError.' + cause.value, { cause });
182
+ }
183
+ return new TickSimulation(diplomatRuntime.internalConstructor, diplomatRuntime.ptrRead(wasm, diplomatReceive.buffer), []);
184
+ }
185
+
186
+ finally {
187
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
188
+ functionCleanupArena.free();
189
+
190
+ diplomatReceive.free();
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Evaluate a whole batch of kicked flights inside the engine — one
196
+ * wasm call per generation chunk instead of a dozen boundary calls
197
+ * per machine. `cells` holds N genomes concatenated (each
198
+ * `bx*by*bz` entries), `kicks` N structure-space `[x,y,z]` triples.
199
+ * The flight protocol, probe schedule and gait detection mirror the
200
+ * app's evalCore exactly; `early_exit` stops provably-frozen
201
+ * machines at tick 40 without changing any reported value. Writes
202
+ * JSON rows `[n0, startCom, startMinX, startMaxX, comAtMoveCheck |
203
+ * null, comAtMid, period, n1, endCom, endMinX, endMaxX]`.
204
+ */
205
+ static evalFlightBatch(bx, by, bz, travel, xOff, palette, cells, airIndex, kicks, evalTicks, seed, mustMoveByTick, needPeriod, earlyExit) {
206
+ let functionCleanupArena = new diplomatRuntime.CleanupArena();
207
+
208
+ const paletteSlice = functionCleanupArena.alloc(diplomatRuntime.DiplomatBuf.sliceWrapper(wasm, diplomatRuntime.DiplomatBuf.str8(wasm, palette)));
209
+ const cellsSlice = functionCleanupArena.alloc(diplomatRuntime.DiplomatBuf.sliceWrapper(wasm, diplomatRuntime.DiplomatBuf.slice(wasm, cells, "u16")));
210
+ const kicksSlice = functionCleanupArena.alloc(diplomatRuntime.DiplomatBuf.sliceWrapper(wasm, diplomatRuntime.DiplomatBuf.slice(wasm, kicks, "i32")));
211
+ const diplomatReceive = new diplomatRuntime.DiplomatReceiveBuf(wasm, 5, 4, true);
212
+
213
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
214
+
215
+
216
+ const result = wasm.TickSimulation_eval_flight_batch(diplomatReceive.buffer, bx, by, bz, travel, xOff, paletteSlice.ptr, cellsSlice.ptr, airIndex, kicksSlice.ptr, evalTicks, seed, mustMoveByTick, needPeriod, earlyExit, write.buffer);
217
+
218
+ try {
219
+ if (!diplomatReceive.resultFlag) {
220
+ const cause = new NucleationError(diplomatRuntime.internalConstructor, diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer));
221
+ throw new globalThis.Error('NucleationError.' + cause.value, { cause });
222
+ }
223
+ return write.readString8();
224
+ }
225
+
226
+ finally {
227
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
228
+ functionCleanupArena.free();
229
+
230
+ diplomatReceive.free();
231
+ write.free();
232
+ }
233
+ }
234
+
235
+ /**
236
+ * Seed the vanilla random source (`java.util.Random`'s LCG,
237
+ * bit-for-bit). Unseeded, jittering behaviours use each
238
+ * distribution's mean — fully deterministic, no noise.
239
+ */
240
+ setRngSeed(seed) {
241
+ wasm.TickSimulation_set_rng_seed(this.ffiValue, seed);
242
+
243
+ try {}
244
+
245
+ finally {
246
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
247
+ }
248
+ }
249
+
250
+ /**
251
+ * Advance one game tick.
252
+ */
253
+ step() {
254
+ wasm.TickSimulation_step(this.ffiValue);
255
+
256
+ try {}
257
+
258
+ finally {
259
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Advance `ticks` game ticks.
265
+ */
266
+ run(ticks) {
267
+ wasm.TickSimulation_run(this.ffiValue, ticks);
268
+
269
+ try {}
270
+
271
+ finally {
272
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
273
+ }
274
+ }
275
+
276
+ /**
277
+ * Run until nothing is scheduled or `budget` ticks pass. Returns
278
+ * whether the world went quiet.
279
+ */
280
+ runUntilQuiescent(budget) {
281
+
282
+ const result = wasm.TickSimulation_run_until_quiescent(this.ffiValue, budget);
283
+
284
+ try {
285
+ return result === 1;
286
+ }
287
+
288
+ finally {
289
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
290
+ }
291
+ }
292
+
293
+ /**
294
+ * Game ticks elapsed since settle.
295
+ */
296
+ tickCount() {
297
+
298
+ const result = wasm.TickSimulation_tick_count(this.ffiValue);
299
+
300
+ try {
301
+ return result;
302
+ }
303
+
304
+ finally {
305
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
306
+ }
307
+ }
308
+
309
+ /**
310
+ * Whether nothing is scheduled or queued.
311
+ */
312
+ isQuiescent() {
313
+
314
+ const result = wasm.TickSimulation_is_quiescent(this.ffiValue);
315
+
316
+ try {
317
+ return result === 1;
318
+ }
319
+
320
+ finally {
321
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
322
+ }
323
+ }
324
+
325
+ /**
326
+ * Right-click a block with an empty hand (lever, button, note block).
327
+ */
328
+ useBlock(x, y, z) {
329
+ wasm.TickSimulation_use_block(this.ffiValue, x, y, z);
330
+
331
+ try {}
332
+
333
+ finally {
334
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
335
+ }
336
+ }
337
+
338
+ /**
339
+ * Write a block state (`minecraft:air` breaks). The state must be in
340
+ * the structure, in `extra_states`, or `minecraft:redstone_block`.
341
+ */
342
+ placeBlock(x, y, z, state) {
343
+ let functionCleanupArena = new diplomatRuntime.CleanupArena();
344
+
345
+ const stateSlice = functionCleanupArena.alloc(diplomatRuntime.DiplomatBuf.sliceWrapper(wasm, diplomatRuntime.DiplomatBuf.str8(wasm, state)));
346
+ const diplomatReceive = new diplomatRuntime.DiplomatReceiveBuf(wasm, 5, 4, true);
347
+
348
+
349
+ const result = wasm.TickSimulation_place_block(diplomatReceive.buffer, this.ffiValue, x, y, z, stateSlice.ptr);
350
+
351
+ try {
352
+ if (!diplomatReceive.resultFlag) {
353
+ const cause = new NucleationError(diplomatRuntime.internalConstructor, diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer));
354
+ throw new globalThis.Error('NucleationError.' + cause.value, { cause });
355
+ }
356
+ }
357
+
358
+ finally {
359
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
360
+ functionCleanupArena.free();
361
+
362
+ diplomatReceive.free();
363
+ }
364
+ }
365
+
366
+ /**
367
+ * The block state descriptor at a position (`minecraft:air` for empty).
368
+ */
369
+ getBlock(x, y, z) {
370
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
371
+
372
+ wasm.TickSimulation_get_block(this.ffiValue, x, y, z, write.buffer);
373
+
374
+ try {
375
+ return write.readString8();
376
+ }
377
+
378
+ finally {
379
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
380
+ write.free();
381
+ }
382
+ }
383
+
384
+ /**
385
+ * Batched block-state reads: `positions_json` is `[[x,y,z], ...]`,
386
+ * the answer a JSON array of descriptors in the same order
387
+ * (`"minecraft:air"` for empty).
388
+ *
389
+ * A verification sweep over a computational build is thousands of
390
+ * probe reads per settle; one boundary call per sweep instead of one
391
+ * per probe is the difference between the FFI being the throughput
392
+ * ceiling and not.
393
+ */
394
+ readProbes(positionsJson) {
395
+ let functionCleanupArena = new diplomatRuntime.CleanupArena();
396
+
397
+ const positionsJsonSlice = functionCleanupArena.alloc(diplomatRuntime.DiplomatBuf.sliceWrapper(wasm, diplomatRuntime.DiplomatBuf.str8(wasm, positionsJson)));
398
+ const diplomatReceive = new diplomatRuntime.DiplomatReceiveBuf(wasm, 5, 4, true);
399
+
400
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
401
+
402
+
403
+ const result = wasm.TickSimulation_read_probes(diplomatReceive.buffer, this.ffiValue, positionsJsonSlice.ptr, write.buffer);
404
+
405
+ try {
406
+ if (!diplomatReceive.resultFlag) {
407
+ const cause = new NucleationError(diplomatRuntime.internalConstructor, diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer));
408
+ throw new globalThis.Error('NucleationError.' + cause.value, { cause });
409
+ }
410
+ return write.readString8();
411
+ }
412
+
413
+ finally {
414
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
415
+ functionCleanupArena.free();
416
+
417
+ diplomatReceive.free();
418
+ write.free();
419
+ }
420
+ }
421
+
422
+ /**
423
+ * Who powers this cell and why — a power-source tree from the
424
+ * simulation's current state, as JSON.
425
+ *
426
+ * Each node carries `pos`, `state`, `kind` (`wire` / `conductor` /
427
+ * `source` / `block`), the `power` the cell carries or emits, and
428
+ * `inputs`: the per-side contributions that explain it, each with a
429
+ * `mechanism` (`block_signal`, `wire`, `wire_up`, `wire_down`,
430
+ * `strong`, `signal`), the arriving `power`, and a recursive
431
+ * `source` node. Cycles stop with `"cycle": true`. Coordinates are
432
+ * the same structure-local space `get_block` reads.
433
+ *
434
+ * This is the static complement of running the sim: an open (a dead
435
+ * route that settles quiescent) shows up as an empty `inputs` list
436
+ * exactly where the feed should have been.
437
+ */
438
+ conductionTrace(x, y, z) {
439
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
440
+
441
+ wasm.TickSimulation_conduction_trace(this.ffiValue, x, y, z, write.buffer);
442
+
443
+ try {
444
+ return write.readString8();
445
+ }
446
+
447
+ finally {
448
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
449
+ write.free();
450
+ }
451
+ }
452
+
453
+ /**
454
+ * Write every settled non-air state back into `schematic` — the bulk
455
+ * form of `{simulate=true}`: settle once, keep the world the engine
456
+ * ended on. Returns how many blocks changed.
457
+ *
458
+ * The schematic's bounding-box minimum corresponds to the
459
+ * simulation's `(0, 0, 0)`, which is exactly how `from_schematic`
460
+ * loaded it. A file baked this way carries real wire connections and
461
+ * power in its palette, loads quiescent under `InWorld`, and renders
462
+ * correctly in any static consumer. Cells the simulation turned into
463
+ * air (a popped-off component) are left as the schematic had them.
464
+ */
465
+ bakeTo(schematic) {
466
+
467
+ const result = wasm.TickSimulation_bake_to(this.ffiValue, schematic.ffiValue);
468
+
469
+ try {
470
+ return result;
471
+ }
472
+
473
+ finally {
474
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
475
+ }
476
+ }
477
+
478
+ /**
479
+ * Snapshot the entire simulation; returns a checkpoint id.
480
+ */
481
+ checkpoint() {
482
+
483
+ const result = wasm.TickSimulation_checkpoint(this.ffiValue);
484
+
485
+ try {
486
+ return result;
487
+ }
488
+
489
+ finally {
490
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
491
+ }
492
+ }
493
+
494
+ /**
495
+ * Restore a checkpoint taken earlier on this simulation.
496
+ */
497
+ restore(id) {
498
+ const diplomatReceive = new diplomatRuntime.DiplomatReceiveBuf(wasm, 5, 4, true);
499
+
500
+
501
+ const result = wasm.TickSimulation_restore(diplomatReceive.buffer, this.ffiValue, id);
502
+
503
+ try {
504
+ if (!diplomatReceive.resultFlag) {
505
+ const cause = new NucleationError(diplomatRuntime.internalConstructor, diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer));
506
+ throw new globalThis.Error('NucleationError.' + cause.value, { cause });
507
+ }
508
+ }
509
+
510
+ finally {
511
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
512
+ diplomatReceive.free();
513
+ }
514
+ }
515
+
516
+ /**
517
+ * Render a schematic as gametest-flavor structure SNBT — the text
518
+ * `from_snbt` and the corpus/render tooling consume. Lets hosts hand
519
+ * a converted `.litematic`/`.schem` to the video renderer.
520
+ */
521
+ static gametestSnbt(schematic) {
522
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
523
+
524
+ wasm.TickSimulation_gametest_snbt(schematic.ffiValue, write.buffer);
525
+
526
+ try {
527
+ return write.readString8();
528
+ }
529
+
530
+ finally {
531
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
532
+ write.free();
533
+ }
534
+ }
535
+
536
+ /**
537
+ * Report blocks whose behaviour is defined by block-entity data the
538
+ * file does not carry.
539
+ *
540
+ * Some exporters write the blocks and drop the block entities. The
541
+ * build then loads clean and simulates *wrongly but plausibly*: a
542
+ * comparator with no `OutputSignal` reads 0, a barrel holding the
543
+ * item that latched a repeater reads empty, and the door quietly
544
+ * fails to reset. Two files with identical block arrays get
545
+ * different verdicts and nothing says why. `0.45_4x4_funnel.schem`
546
+ * is exactly this — 4 comparators, 2 furnaces, `BlockEntities` of
547
+ * length 0, while its `.litematic` twin carries all 9.
548
+ *
549
+ * This does not refuse the build; it names the doubt so a host can.
550
+ * JSON: `{"present":N,"missing_total":N,"missing":[{"name":..,
551
+ * "count":N}],"summary":"..."}` — `summary` is empty when nothing
552
+ * is missing, and otherwise a sentence fit to show as-is.
553
+ */
554
+ static blockEntityAuditJson(schematic) {
555
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
556
+
557
+ wasm.TickSimulation_block_entity_audit_json(schematic.ffiValue, write.buffer);
558
+
559
+ try {
560
+ return write.readString8();
561
+ }
562
+
563
+ finally {
564
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
565
+ write.free();
566
+ }
567
+ }
568
+
569
+ /**
570
+ * Start (or stop) recording every delivered redstone update.
571
+ *
572
+ * Off by default and much larger than the block-change log — a door's
573
+ * cycle runs several updates per change — so a propagation view asks
574
+ * for it explicitly and pages with
575
+ * {@link TickSimulation::updates_json_between}.
576
+ *
577
+ * Switching it off keeps what was recorded; use
578
+ * {@link TickSimulation::clear_updates} to free it.
579
+ */
580
+ recordUpdates(on) {
581
+ wasm.TickSimulation_record_updates(this.ffiValue, on);
582
+
583
+ try {}
584
+
585
+ finally {
586
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
587
+ }
588
+ }
589
+
590
+ /**
591
+ * Drop the recorded updates without changing whether recording is on.
592
+ *
593
+ * A cycle of a 6x6 door is tens of megabytes of log, so a page that
594
+ * certifies several builds on one instance needs to release one
595
+ * before recording the next.
596
+ */
597
+ clearUpdates() {
598
+ wasm.TickSimulation_clear_updates(this.ffiValue);
599
+
600
+ try {}
601
+
602
+ finally {
603
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
604
+ }
605
+ }
606
+
607
+ /**
608
+ * Start recording a run timeline from the current tick.
609
+ *
610
+ * A timeline is what makes a span of simulation reviewable after the
611
+ * fact: block deltas, the inputs that caused them and the piston
612
+ * strokes they drove, plus one whole-world frame to replay them from.
613
+ * Off by default — a simulation used for timing should not pay for it.
614
+ *
615
+ * Called again, it restarts from the current tick, and the previously
616
+ * stopped span is released.
617
+ *
618
+ * Starting a recording also wipes the plain block-change log that
619
+ * {@link TickSimulation::changes_json} and {@link TickSimulation::changes_count}
620
+ * read back to empty — a separate reset from
621
+ * {@link TickSimulation::record_updates}/{@link TickSimulation::clear_updates},
622
+ * which govern a different log. A host holding a cursor into the
623
+ * change log (the sim lab keeps a cumulative one) must reset that
624
+ * cursor when it calls this, or it will read past the end of a log
625
+ * that is no longer the one it was walking.
626
+ */
627
+ recordTimeline() {
628
+ wasm.TickSimulation_record_timeline(this.ffiValue);
629
+
630
+ try {}
631
+
632
+ finally {
633
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
634
+ }
635
+ }
636
+
637
+ /**
638
+ * End the recording, keeping the span readable.
639
+ *
640
+ * This is a host's Stop button, and it is not a rewind: the span stays
641
+ * readable and exportable until the next
642
+ * {@link TickSimulation::record_timeline}, while the simulation is free to
643
+ * run on without the recording following it. No-op if nothing was
644
+ * recording.
645
+ */
646
+ stopTimeline() {
647
+ wasm.TickSimulation_stop_timeline(this.ffiValue);
648
+
649
+ try {}
650
+
651
+ finally {
652
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
653
+ }
654
+ }
655
+
656
+ /**
657
+ * Where the recorded run was busy, as JSON:
658
+ * `{"start":T,"end":T,"ticks":[{"tick":T,"changes":N,"inputs":N,
659
+ * "pistons":N}]}`.
660
+ *
661
+ * The strip a host draws to let someone pick a span worth exporting.
662
+ * Only ticks that did something appear: an idle tick is **absent**
663
+ * rather than present with zeroes, so a build that sits still does not
664
+ * advance the strip and a long quiet run stays cheap to send.
665
+ *
666
+ * `{"start":0,"end":0,"ticks":[]}` when nothing has been recorded.
667
+ */
668
+ timelineActivityJson() {
669
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
670
+
671
+ wasm.TickSimulation_timeline_activity_json(this.ffiValue, write.buffer);
672
+
673
+ try {
674
+ return write.readString8();
675
+ }
676
+
677
+ finally {
678
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
679
+ write.free();
680
+ }
681
+ }
682
+
683
+ /**
684
+ * Exact and translated recurrence in the timeline a read query would
685
+ * resolve to (see {@link Self::timeline}), as JSON:
686
+ * `{"exact":{"start":T,"end":T,"period":N,"drift":[x,y,z]}|null,
687
+ * "translated":{...}|null}`.
688
+ *
689
+ * **An absent cycle is `null`, not an error.** Most builds — an
690
+ * adder, a door — never repeat their own state, and that is the
691
+ * ordinary outcome, not a failed search.
692
+ *
693
+ * **O(ticks × blocks): replays the whole recorded span to build one
694
+ * digest per tick boundary**, then rebuilds full frames for the
695
+ * handful of candidates that survive. This is an on-demand "find
696
+ * cycles" action for a host UI button, never something to call per
697
+ * tick or per frame — poll {@link Self::timeline_activity_json} instead.
698
+ *
699
+ * Materialises the whole recorded timeline once to answer this call
700
+ * (an owned `RunTimeline`'s `initial` frame copies every non-air
701
+ * block) — acceptable for one on-demand press, not for a loop.
702
+ *
703
+ * `{"exact":null,"translated":null}` when nothing has been recorded.
704
+ */
705
+ timelineCyclesJson() {
706
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
707
+
708
+ wasm.TickSimulation_timeline_cycles_json(this.ffiValue, write.buffer);
709
+
710
+ try {
711
+ return write.readString8();
712
+ }
713
+
714
+ finally {
715
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
716
+ write.free();
717
+ }
718
+ }
719
+
720
+ /**
721
+ * Project `[start_tick, end_tick)` of the timeline a read query would
722
+ * resolve to (see {@link Self::timeline}) into the animated-GLB mesher's
723
+ * `Timeline` JSON — `{"origin":[x,y,z],"tick_ms":F,
724
+ * "events":[{"kind":"set_block"|"piston",...}]}` — via
725
+ * `crate::tick_timeline::mesher_timeline_json`.
726
+ *
727
+ * **Materialises the whole recorded timeline to answer this call**
728
+ * (an owned `RunTimeline`'s `initial` frame copies every non-air
729
+ * block in the world) — this is an on-demand "export this
730
+ * selection" action, not something to call per frame or poll.
731
+ *
732
+ * Fails if no timeline has been recorded, or if `start_tick..
733
+ * end_tick` is empty or outside the recorded span.
734
+ */
735
+ animationTimelineJson(startTick, endTick, tickMs) {
736
+ const diplomatReceive = new diplomatRuntime.DiplomatReceiveBuf(wasm, 5, 4, true);
737
+
738
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
739
+
740
+
741
+ const result = wasm.TickSimulation_animation_timeline_json(diplomatReceive.buffer, this.ffiValue, startTick, endTick, tickMs, write.buffer);
742
+
743
+ try {
744
+ if (!diplomatReceive.resultFlag) {
745
+ const cause = new NucleationError(diplomatRuntime.internalConstructor, diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer));
746
+ throw new globalThis.Error('NucleationError.' + cause.value, { cause });
747
+ }
748
+ return write.readString8();
749
+ }
750
+
751
+ finally {
752
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
753
+ diplomatReceive.free();
754
+ write.free();
755
+ }
756
+ }
757
+
758
+ /**
759
+ * The selection's starting scene — `[start_tick, end_tick)` of the
760
+ * timeline a read query would resolve to (see {@link Self::timeline}) —
761
+ * as schematic bytes, base64-encoded.
762
+ *
763
+ * A WASM handle cannot cross a worker boundary, so this exists for a
764
+ * host to hand the bytes to a worker, which rebuilds the schematic
765
+ * with `Schematic.fromData`.
766
+ *
767
+ * **Materialises the whole recorded timeline to answer this call**
768
+ * — see {@link Self::animation_timeline_json}; an on-demand export
769
+ * action, not a per-frame poll.
770
+ *
771
+ * Fails if no timeline has been recorded, or if `start_tick..
772
+ * end_tick` is empty or outside the recorded span.
773
+ */
774
+ selectionSchematicB64(startTick, endTick) {
775
+ const diplomatReceive = new diplomatRuntime.DiplomatReceiveBuf(wasm, 5, 4, true);
776
+
777
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
778
+
779
+
780
+ const result = wasm.TickSimulation_selection_schematic_b64(diplomatReceive.buffer, this.ffiValue, startTick, endTick, write.buffer);
781
+
782
+ try {
783
+ if (!diplomatReceive.resultFlag) {
784
+ const cause = new NucleationError(diplomatRuntime.internalConstructor, diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer));
785
+ throw new globalThis.Error('NucleationError.' + cause.value, { cause });
786
+ }
787
+ return write.readString8();
788
+ }
789
+
790
+ finally {
791
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
792
+ diplomatReceive.free();
793
+ write.free();
794
+ }
795
+ }
796
+
797
+ /**
798
+ * How many updates have been recorded — page before pulling them.
799
+ */
800
+ updatesCount() {
801
+
802
+ const result = wasm.TickSimulation_updates_count(this.ffiValue);
803
+
804
+ try {
805
+ return result;
806
+ }
807
+
808
+ finally {
809
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
810
+ }
811
+ }
812
+
813
+ /**
814
+ * Every recorded update, in delivery order.
815
+ *
816
+ * `seq` counts from 0 within each tick: that is the sub-tick axis, and
817
+ * `(tick, seq)` is the order the engine actually delivered them in.
818
+ * `state` is the block as it stood **at dispatch time**, which is what
819
+ * makes intra-tick order legible — a snapshot cannot show it.
820
+ */
821
+ updatesJson() {
822
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
823
+
824
+ wasm.TickSimulation_updates_json(this.ffiValue, write.buffer);
825
+
826
+ try {
827
+ return write.readString8();
828
+ }
829
+
830
+ finally {
831
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
832
+ write.free();
833
+ }
834
+ }
835
+
836
+ /**
837
+ * The recorded updates for ticks in `[from_tick, to_tick)`.
838
+ *
839
+ * The whole log for a 6x6 door's cycle is megabytes; a scrubber only
840
+ * ever shows one tick, so it should ask for one tick.
841
+ */
842
+ updatesJsonBetween(fromTick, toTick) {
843
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
844
+
845
+ wasm.TickSimulation_updates_json_between(this.ffiValue, fromTick, toTick, write.buffer);
846
+
847
+ try {
848
+ return write.readString8();
849
+ }
850
+
851
+ finally {
852
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
853
+ write.free();
854
+ }
855
+ }
856
+
857
+ /**
858
+ * Per-tick, per-cell update counts for ticks in `[from_tick, to_tick)`.
859
+ *
860
+ * The resolution playback should run at: `{phases, ticks:[{tick, total,
861
+ * cells:[{p:[x,y,z], n, nb, sh, ph:[…]}]}]}`, where `nb`/`sh` split
862
+ * neighbour from shape and `ph` indexes the `phases` legend. Collapses
863
+ * a tick's tens of thousands of updates into a few hundred cells.
864
+ */
865
+ updatesHeatJson(fromTick, toTick) {
866
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
867
+
868
+ wasm.TickSimulation_updates_heat_json(this.ffiValue, fromTick, toTick, write.buffer);
869
+
870
+ try {
871
+ return write.readString8();
872
+ }
873
+
874
+ finally {
875
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
876
+ write.free();
877
+ }
878
+ }
879
+
880
+ /**
881
+ * One tick's updates in delivery order, as parallel arrays.
882
+ *
883
+ * For stepping *within* a tick: `seq` is the array index, `pos` is flat
884
+ * x,y,z triples, `kind`/`phase`/`from` are integer codes with legends
885
+ * in the payload, and `state` indexes a deduplicated `states` table.
886
+ */
887
+ updatesWaveJson(tick) {
888
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
889
+
890
+ wasm.TickSimulation_updates_wave_json(this.ffiValue, tick, write.buffer);
891
+
892
+ try {
893
+ return write.readString8();
894
+ }
895
+
896
+ finally {
897
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
898
+ write.free();
899
+ }
900
+ }
901
+
902
+ /**
903
+ * Every block a piston currently has in flight, as JSON:
904
+ * `[{"to":[x,y,z],"from":[x,y,z],"state":"...","carried":"...",
905
+ * "carried_short":"..."|null,"remains":"..."|null,"dir":"east",
906
+ * "extending":bool,"started":T,"lands":T,"source_piston":bool}]`.
907
+ *
908
+ * Draw `carried` travelling `from` -> `to`, and `remains` (when it is
909
+ * not null) parked at `to` for the whole move. They differ from
910
+ * `state` — what actually lands — only for a retracting piston, whose
911
+ * body stays put while its head comes home; vanilla's
912
+ * `PistonHeadRenderer` splits exactly these two slots.
913
+ *
914
+ * `carried_short` is the same arm with `short=true`. Draw it while the
915
+ * head is **within half a block of its body** — `progress <= 0.5`
916
+ * extending, `progress >= 0.5` retracting — or the shaft passes
917
+ * visibly through the back of the piston as it comes home. Which form
918
+ * to use is yours; naming the state is the engine's.
919
+ *
920
+ * What a renderer needs to animate a stroke, from the simulator that
921
+ * dispatched it. The block-change stream cannot answer this: it says a
922
+ * cell became a `moving_piston` placeholder, not which block set off,
923
+ * which cell it left, or which tick it arrives — so a host that
924
+ * reconstructs strokes from changes is reimplementing piston mechanics
925
+ * downstream of the engine, and animating on a clock the simulation
926
+ * does not share. That desync is what draws a block twice, leaves a
927
+ * gap where one should be, and shears a piston head off its load.
928
+ *
929
+ * `started` and `lands` are tick numbers in the engine's frame, where
930
+ * {@link Self::tick_count} counts *completed* ticks: after stepping to
931
+ * `tick_count == t`, a flight's progress is
932
+ * `(t - started) / (lands - started)`, clamped to 1. Draw it while it
933
+ * is listed and drop it when it stops being listed — the same call
934
+ * that stops reporting it is the tick the real block is written, so
935
+ * there is no frame with both and none with neither.
936
+ */
937
+ movingBlocksJson() {
938
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
939
+
940
+ wasm.TickSimulation_moving_blocks_json(this.ffiValue, write.buffer);
941
+
942
+ try {
943
+ return write.readString8();
944
+ }
945
+
946
+ finally {
947
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
948
+ write.free();
949
+ }
950
+ }
951
+
952
+ /**
953
+ * Drop the recorded block changes without stopping recording.
954
+ *
955
+ * The log grows for as long as the simulation runs and nothing
956
+ * empties it, so a long-running host — a browser session driving
957
+ * thousands of ticks — accumulates every block change forever. A
958
+ * host that has already consumed {@link TickSimulation::changes_json}
959
+ * can say so here and keep recording on. A host holding a cursor
960
+ * into the change log must reset that cursor when it calls this, or
961
+ * it will read past the end of a log that is no longer the one it
962
+ * was walking — the same hazard {@link TickSimulation::record_timeline}
963
+ * names for its own reset of this log.
964
+ *
965
+ * Refuses — and leaves the log untouched — while
966
+ * {@link TickSimulation::record_timeline} is recording: a run timeline
967
+ * is a seed frame plus this same log, and every timeline reader
968
+ * trusts that the log describes every mutation since recording
969
+ * began. Clearing it out from under a live recording would make
970
+ * replay silently wrong rather than fail loudly. Returns `true` if
971
+ * the log was cleared, `false` if the call was refused — following
972
+ * {@link TickSimulation::run_until_quiescent}'s convention of reporting
973
+ * whether the call achieved what it was asked, rather than swallowing
974
+ * a no-op.
975
+ */
976
+ clearChanges() {
977
+
978
+ const result = wasm.TickSimulation_clear_changes(this.ffiValue);
979
+
980
+ try {
981
+ return result === 1;
982
+ }
983
+
984
+ finally {
985
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
986
+ }
987
+ }
988
+
989
+ changesJson() {
990
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
991
+
992
+ wasm.TickSimulation_changes_json(this.ffiValue, write.buffer);
993
+
994
+ try {
995
+ return write.readString8();
996
+ }
997
+
998
+ finally {
999
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1000
+ write.free();
1001
+ }
1002
+ }
1003
+
1004
+ /**
1005
+ * The same JSON array {@link TickSimulation::changes_json} produces,
1006
+ * but only the entries from index `start` onward.
1007
+ *
1008
+ * Exists for a host draining the log every frame while a run
1009
+ * timeline recording refuses {@link TickSimulation::clear_changes}: the
1010
+ * log only ever grows in that state, so without this,
1011
+ * `changes_json` re-serialises the whole backlog on every single
1012
+ * drain — a cost that climbs for as long as the recording runs,
1013
+ * which is exactly when a session runs longest. Reading from a
1014
+ * cursor keeps a drain's cost to what is actually new.
1015
+ *
1016
+ * `start` at or past the end of the log yields `[]`, not an error —
1017
+ * a host racing a draining cursor against a growing log should not
1018
+ * have to special-case "nothing new yet".
1019
+ */
1020
+ changesJsonFrom(start) {
1021
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
1022
+
1023
+ wasm.TickSimulation_changes_json_from(this.ffiValue, start, write.buffer);
1024
+
1025
+ try {
1026
+ return write.readString8();
1027
+ }
1028
+
1029
+ finally {
1030
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1031
+ write.free();
1032
+ }
1033
+ }
1034
+
1035
+ /**
1036
+ * Live item entities and minecarts, as JSON:
1037
+ * `{"items":[{"id":N,"item":"...","count":N,"pos":[..],"vel":[..],
1038
+ * "on_ground":bool,"contents":[{"id":"...","count":N}]}],
1039
+ * "minecarts":[{"id":N,"kind":"...","pos":[..],"vel":[..]}]}`.
1040
+ */
1041
+ itemEntitiesJson() {
1042
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
1043
+
1044
+ wasm.TickSimulation_item_entities_json(this.ffiValue, write.buffer);
1045
+
1046
+ try {
1047
+ return write.readString8();
1048
+ }
1049
+
1050
+ finally {
1051
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1052
+ write.free();
1053
+ }
1054
+ }
1055
+
1056
+ /**
1057
+ * Which `Entity.load` Motion semantics this run uses:
1058
+ * `"clamp_abs_ten"` (DataVersion <= 4556 — NaN survives a cold load)
1059
+ * or `"drop_non_finite"` (>= 4671 — it does not).
1060
+ *
1061
+ * Exposed because a door built on nan carts is a *different machine*
1062
+ * under the two, and a caller that cannot tell them apart cannot
1063
+ * report why it came apart.
1064
+ */
1065
+ motionSemantics() {
1066
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
1067
+
1068
+ wasm.TickSimulation_motion_semantics(this.ffiValue, write.buffer);
1069
+
1070
+ try {
1071
+ return write.readString8();
1072
+ }
1073
+
1074
+ finally {
1075
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1076
+ write.free();
1077
+ }
1078
+ }
1079
+
1080
+ /**
1081
+ * How many times an entity stood in a **retracting** piston's sweep
1082
+ * that the engine could not reproduce.
1083
+ *
1084
+ * A tripwire from when retraction was unmodelled — extension
1085
+ * displacement was measured and implemented while
1086
+ * `tools/gametest/captures/piston_pull.entities.log`'s sub-0.03
1087
+ * movements, not uniformly backwards, had no model here. All three
1088
+ * retraction geometries are implemented now, so this reports **0**,
1089
+ * including on the record 3x3 door, which used to name six. It is kept
1090
+ * because the next geometry that turns out not to be covered should be
1091
+ * reported rather than guessed at: non-zero means this run leaned on
1092
+ * behaviour we do not reproduce and its result is not trustworthy.
1093
+ */
1094
+ pistonRetractContacts() {
1095
+
1096
+ const result = wasm.TickSimulation_piston_retract_contacts(this.ffiValue);
1097
+
1098
+ try {
1099
+ return result;
1100
+ }
1101
+
1102
+ finally {
1103
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1104
+ }
1105
+ }
1106
+
1107
+ /**
1108
+ * Per-tick aggregates over the recorded changes, as JSON:
1109
+ * `[{"tick":N,"changes":N,"piston":N,"redstone":N}]` — `piston`
1110
+ * counts changes touching piston blocks (base, head, moving), and
1111
+ * `redstone` changes touching wire/torch/repeater/comparator/
1112
+ * observer/lamp/lever/button/pressure-plate states.
1113
+ */
1114
+ eventsSummaryJson() {
1115
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
1116
+
1117
+ wasm.TickSimulation_events_summary_json(this.ffiValue, write.buffer);
1118
+
1119
+ try {
1120
+ return write.readString8();
1121
+ }
1122
+
1123
+ finally {
1124
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1125
+ write.free();
1126
+ }
1127
+ }
1128
+
1129
+ /**
1130
+ * Every non-air block, as JSON:
1131
+ * `[{"pos":[x,y,z],"state":"..."}]`.
1132
+ * How many non-air blocks stand in the world right now.
1133
+ */
1134
+ nonAirCount() {
1135
+
1136
+ const result = wasm.TickSimulation_non_air_count(this.ffiValue);
1137
+
1138
+ try {
1139
+ return result;
1140
+ }
1141
+
1142
+ finally {
1143
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1144
+ }
1145
+ }
1146
+
1147
+ /**
1148
+ * Center of mass (x) of every non-air block — the GA's displacement
1149
+ * metric without a JSON round-trip. NaN when the world is empty.
1150
+ */
1151
+ nonAirCenterX() {
1152
+
1153
+ const result = wasm.TickSimulation_non_air_center_x(this.ffiValue);
1154
+
1155
+ try {
1156
+ return result;
1157
+ }
1158
+
1159
+ finally {
1160
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1161
+ }
1162
+ }
1163
+
1164
+ /**
1165
+ * Smallest x holding a non-air block; `i32::MAX` when empty.
1166
+ */
1167
+ nonAirMinX() {
1168
+
1169
+ const result = wasm.TickSimulation_non_air_min_x(this.ffiValue);
1170
+
1171
+ try {
1172
+ return result;
1173
+ }
1174
+
1175
+ finally {
1176
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1177
+ }
1178
+ }
1179
+
1180
+ /**
1181
+ * Largest x holding a non-air block; `i32::MIN` when empty.
1182
+ */
1183
+ nonAirMaxX() {
1184
+
1185
+ const result = wasm.TickSimulation_non_air_max_x(this.ffiValue);
1186
+
1187
+ try {
1188
+ return result;
1189
+ }
1190
+
1191
+ finally {
1192
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1193
+ }
1194
+ }
1195
+
1196
+ /**
1197
+ * How many block changes recording has captured so far.
1198
+ */
1199
+ changesCount() {
1200
+
1201
+ const result = wasm.TickSimulation_changes_count(this.ffiValue);
1202
+
1203
+ try {
1204
+ return result;
1205
+ }
1206
+
1207
+ finally {
1208
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1209
+ }
1210
+ }
1211
+
1212
+ worldSnapshotJson() {
1213
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
1214
+
1215
+ wasm.TickSimulation_world_snapshot_json(this.ffiValue, write.buffer);
1216
+
1217
+ try {
1218
+ return write.readString8();
1219
+ }
1220
+
1221
+ finally {
1222
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1223
+ write.free();
1224
+ }
1225
+ }
1226
+
1227
+ /**
1228
+ * Static structural analysis of the build standing in this world.
1229
+ *
1230
+ * One call, one JSON document: adhesion groups, piston/observer/source
1231
+ * nodes, the four edge kinds, every minimal self-translating subgraph
1232
+ * (the engine), payload, kickers, dead weight, and any proof that the
1233
+ * machine cannot move.
1234
+ *
1235
+ * The analysis lives in the engine rather than in the caller on
1236
+ * purpose. Every "what would this piston move?" answer comes from
1237
+ * `resolve_push`/`resolve_pull` — the same oracle-verified resolver the
1238
+ * tick loop runs — and a second copy of Minecraft's push rules written
1239
+ * on the far side of this boundary would drift from it silently.
1240
+ */
1241
+ machineGraphJson() {
1242
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
1243
+
1244
+ wasm.TickSimulation_machine_graph_json(this.ffiValue, write.buffer);
1245
+
1246
+ try {
1247
+ return write.readString8();
1248
+ }
1249
+
1250
+ finally {
1251
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1252
+ write.free();
1253
+ }
1254
+ }
1255
+
1256
+ /**
1257
+ * GA pre-filter: static verdicts for a whole batch of genomes.
1258
+ *
1259
+ * Same flat-cell layout as {@link Self::eval_flight_batch}, and meant to run
1260
+ * immediately before it: whatever this rejects never needs simulating.
1261
+ * Writes one row per genome, `[rejected, rejected_for_sustained,
1262
+ * engine_cell_count, payload_cell_count, dead_cell_count, "codes"]`.
1263
+ *
1264
+ * The registry, behaviour table and movability rules are built once for
1265
+ * the batch — building them per genome costs more than the analysis.
1266
+ */
1267
+ static machineGraphBatchJson(bx, by, bz, travel, xOff, palette, cells, airIndex) {
1268
+ let functionCleanupArena = new diplomatRuntime.CleanupArena();
1269
+
1270
+ const paletteSlice = functionCleanupArena.alloc(diplomatRuntime.DiplomatBuf.sliceWrapper(wasm, diplomatRuntime.DiplomatBuf.str8(wasm, palette)));
1271
+ const cellsSlice = functionCleanupArena.alloc(diplomatRuntime.DiplomatBuf.sliceWrapper(wasm, diplomatRuntime.DiplomatBuf.slice(wasm, cells, "u16")));
1272
+ const diplomatReceive = new diplomatRuntime.DiplomatReceiveBuf(wasm, 5, 4, true);
1273
+
1274
+ const write = new diplomatRuntime.DiplomatWriteBuf(wasm);
1275
+
1276
+
1277
+ const result = wasm.TickSimulation_machine_graph_batch_json(diplomatReceive.buffer, bx, by, bz, travel, xOff, paletteSlice.ptr, cellsSlice.ptr, airIndex, write.buffer);
1278
+
1279
+ try {
1280
+ if (!diplomatReceive.resultFlag) {
1281
+ const cause = new NucleationError(diplomatRuntime.internalConstructor, diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer));
1282
+ throw new globalThis.Error('NucleationError.' + cause.value, { cause });
1283
+ }
1284
+ return write.readString8();
1285
+ }
1286
+
1287
+ finally {
1288
+ diplomatRuntime.FUNCTION_PARAM_ALLOC.clean();
1289
+ functionCleanupArena.free();
1290
+
1291
+ diplomatReceive.free();
1292
+ write.free();
1293
+ }
1294
+ }
1295
+
1296
+ constructor(symbol, ptr, selfEdge) {
1297
+ return this.#internalConstructor(...arguments)
1298
+ }
1299
+ }