@woosh/meep-engine 3.14.3 → 3.14.5

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 (137) hide show
  1. package/package.json +1 -1
  2. package/src/core/geom/3d/mat4/m4_rigidity_defect.d.ts +30 -0
  3. package/src/core/geom/3d/mat4/m4_rigidity_defect.d.ts.map +1 -0
  4. package/src/core/geom/3d/mat4/m4_rigidity_defect.js +71 -0
  5. package/src/engine/Engine.d.ts.map +1 -1
  6. package/src/engine/Engine.js +733 -726
  7. package/src/engine/network/NetworkSession.d.ts +24 -4
  8. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  9. package/src/engine/network/NetworkSession.js +28 -4
  10. package/src/engine/network/orchestrator/NetworkPeer.d.ts +96 -7
  11. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -1
  12. package/src/engine/network/orchestrator/NetworkPeer.js +392 -68
  13. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts +6 -1
  14. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -1
  15. package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +6 -0
  16. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts +105 -13
  17. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -1
  18. package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +306 -59
  19. package/src/engine/network/replication/Replicator.d.ts +43 -7
  20. package/src/engine/network/replication/Replicator.d.ts.map +1 -1
  21. package/src/engine/network/replication/Replicator.js +309 -111
  22. package/src/engine/network/sim/ActionLog.d.ts +23 -3
  23. package/src/engine/network/sim/ActionLog.d.ts.map +1 -1
  24. package/src/engine/network/sim/ActionLog.js +26 -3
  25. package/src/engine/network/sim/ActionRecordCursor.d.ts +82 -0
  26. package/src/engine/network/sim/ActionRecordCursor.d.ts.map +1 -0
  27. package/src/engine/network/sim/ActionRecordCursor.js +120 -0
  28. package/src/engine/network/sim/RewindEngine.d.ts.map +1 -1
  29. package/src/engine/network/sim/RewindEngine.js +13 -29
  30. package/src/engine/network/sim/SimAction.d.ts +15 -0
  31. package/src/engine/network/sim/SimAction.d.ts.map +1 -1
  32. package/src/engine/network/sim/SimAction.js +15 -0
  33. package/src/engine/network/sim/SimActionExecutor.d.ts +51 -2
  34. package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
  35. package/src/engine/network/sim/SimActionExecutor.js +74 -7
  36. package/src/engine/network/transport/Channel.d.ts +1 -1
  37. package/src/engine/network/transport/Channel.js +1 -1
  38. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  39. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  40. package/src/engine/simulation/Ticker.js +4 -1
  41. package/src/engine/ui/GUIEngine.d.ts.map +1 -1
  42. package/src/engine/ui/GUIEngine.js +6 -0
  43. package/src/shade/playground/particle_system/README.md +98 -0
  44. package/src/shade/playground/particle_system/index.html +124 -0
  45. package/src/shade/playground/particle_system/main.d.ts +2 -0
  46. package/src/shade/playground/particle_system/main.d.ts.map +1 -0
  47. package/src/shade/playground/particle_system/main.js +180 -0
  48. package/src/shade/playground/particle_system/particle_scene.d.ts +52 -0
  49. package/src/shade/playground/particle_system/particle_scene.d.ts.map +1 -0
  50. package/src/shade/playground/particle_system/particle_scene.js +553 -0
  51. package/src/shade/playground/skinned_mesh_soup/README.md +143 -0
  52. package/src/shade/playground/skinned_mesh_soup/index.html +202 -0
  53. package/src/shade/playground/skinned_mesh_soup/main.d.ts +7 -0
  54. package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -0
  55. package/src/shade/playground/skinned_mesh_soup/main.js +567 -0
  56. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts +29 -0
  57. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts.map +1 -0
  58. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +428 -0
  59. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  60. package/src/shade/renderer/animation/GPUAnimationManager.js +1958 -1796
  61. package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +357 -0
  62. package/src/shade/renderer/animation/skin_bind_transform.d.ts +25 -0
  63. package/src/shade/renderer/animation/skin_bind_transform.d.ts.map +1 -0
  64. package/src/shade/renderer/animation/skin_bind_transform.js +33 -0
  65. package/src/shade/renderer/animation/skin_clip_scale_conflicts.d.ts +67 -0
  66. package/src/shade/renderer/animation/skin_clip_scale_conflicts.d.ts.map +1 -0
  67. package/src/shade/renderer/animation/skin_clip_scale_conflicts.js +199 -0
  68. package/src/shade/renderer/animation/skin_frame_defect.d.ts +34 -0
  69. package/src/shade/renderer/animation/skin_frame_defect.d.ts.map +1 -0
  70. package/src/shade/renderer/animation/skin_frame_defect.js +132 -0
  71. package/src/shade/renderer/animation/skin_joint_matrix.d.ts +24 -0
  72. package/src/shade/renderer/animation/skin_joint_matrix.d.ts.map +1 -0
  73. package/src/shade/renderer/animation/skin_joint_matrix.js +46 -0
  74. package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts +70 -0
  75. package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts.map +1 -0
  76. package/src/shade/renderer/animation/skin_normalize_mesh_frame.js +216 -0
  77. package/src/shade/renderer/animation/skin_test_fixtures.d.ts +86 -0
  78. package/src/shade/renderer/animation/skin_test_fixtures.d.ts.map +1 -0
  79. package/src/shade/renderer/animation/skin_test_fixtures.js +250 -0
  80. package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.d.ts +18 -4
  81. package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.d.ts.map +1 -1
  82. package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.js +18 -4
  83. package/src/shade/renderer/particles/DESIGN.md +5 -5
  84. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts.map +1 -1
  85. package/src/shade/renderer/particles/cull/chunk_particle_cull.js +3 -1
  86. package/src/shade/renderer/particles/data/chunk_particle_emitter.js +1 -1
  87. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +43 -0
  88. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -0
  89. package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +44 -0
  90. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +33 -59
  91. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  92. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +185 -118
  93. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts +15 -10
  94. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
  95. package/src/shade/renderer/particles/graph/compile_particle_graph.js +205 -170
  96. package/src/shade/renderer/particles/graph/particle_graph_authoring.d.ts +44 -0
  97. package/src/shade/renderer/particles/graph/particle_graph_authoring.d.ts.map +1 -0
  98. package/src/shade/renderer/particles/graph/particle_graph_authoring.js +108 -0
  99. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +89 -0
  100. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -0
  101. package/src/shade/renderer/particles/isa/InstructionStream.js +162 -0
  102. package/src/shade/renderer/particles/isa/ParticleAssembler.d.ts +1 -48
  103. package/src/shade/renderer/particles/isa/ParticleAssembler.d.ts.map +1 -1
  104. package/src/shade/renderer/particles/isa/ParticleAssembler.js +25 -114
  105. package/src/shade/renderer/particles/particle_prototype.d.ts.map +1 -1
  106. package/src/shade/renderer/particles/particle_prototype.js +181 -180
  107. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +4 -4
  108. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
  109. package/src/shade/renderer/particles/runtime/create_particle_effect.js +19 -19
  110. package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.d.ts.map +1 -1
  111. package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.js +4 -2
  112. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +4 -4
  113. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts.map +1 -1
  114. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +7 -5
  115. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts.map +1 -1
  116. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +3 -1
  117. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  118. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +3 -1
  119. package/src/shade/renderer/particles/shaders/shader_particle_finalize.d.ts.map +1 -1
  120. package/src/shade/renderer/particles/shaders/shader_particle_finalize.js +5 -2
  121. package/src/shade/renderer/particles/shaders/shader_particle_render.d.ts.map +1 -1
  122. package/src/shade/renderer/particles/shaders/shader_particle_render.js +9 -2
  123. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  124. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +3 -1
  125. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +1 -1
  126. package/src/shade/renderer/scene/SkinnedMesh.d.ts +11 -0
  127. package/src/shade/renderer/scene/SkinnedMesh.d.ts.map +1 -1
  128. package/src/shade/renderer/scene/SkinnedMesh.js +11 -0
  129. package/src/shade/renderer/shader/chunk/geometry/quaternion/dual/chunk_dual_quat_from_m4.d.ts +33 -3
  130. package/src/shade/renderer/shader/chunk/geometry/quaternion/dual/chunk_dual_quat_from_m4.d.ts.map +1 -1
  131. package/src/shade/renderer/shader/chunk/geometry/quaternion/dual/chunk_dual_quat_from_m4.js +58 -37
  132. package/src/shade/renderer/particles/graph/ParticleGraph.d.ts +0 -54
  133. package/src/shade/renderer/particles/graph/ParticleGraph.d.ts.map +0 -1
  134. package/src/shade/renderer/particles/graph/ParticleGraph.js +0 -99
  135. package/src/shade/renderer/particles/prototypeParticleSystem.d.ts +0 -2
  136. package/src/shade/renderer/particles/prototypeParticleSystem.d.ts.map +0 -1
  137. package/src/shade/renderer/particles/prototypeParticleSystem.js +0 -448
@@ -14,7 +14,7 @@ import { FrameBufferRing } from "../state/FrameBufferRing.js";
14
14
  * uint32: prior_payload_len
15
15
  * bytes: prior_payload (adapter.serialize of the component's prior state)
16
16
  * uint8: action_type_id
17
- * uint8: sender_id (peer that originated the action; local-only,
17
+ * uint8: sender_id (provenance of the record; local-only,
18
18
  * STRIPPED by Replicator before send)
19
19
  * uint32: action_payload_len
20
20
  * bytes: action_payload (the action's own serialize output)
@@ -23,9 +23,21 @@ import { FrameBufferRing } from "../state/FrameBufferRing.js";
23
23
  * Self-describing: records can be skipped without consulting the action registry,
24
24
  * which means rewind code can walk records forward to find boundaries, then
25
25
  * iterate backward to apply prior states — no need to instantiate any actions.
26
+ * {@link ActionRecordCursor} is that walk; readers use it rather than parsing
27
+ * the layout themselves.
26
28
  *
27
- * Note that `sender_id` is recorded in-buffer for local rollback orchestrators
28
- * (stable-sort tie-breaking by sender on replay) but never crosses the wire —
29
+ * `sender_id` says where the record came from, which is what a rollback replay
30
+ * needs in order to decide what to do with it:
31
+ *
32
+ * - a peer id `[0, 253]` — arrived from that peer;
33
+ * - `SENDER_LOCAL` (255) — authored on this peer;
34
+ * - `SENDER_DERIVED` (254) — computed by this peer's simulation from the
35
+ * frame's own state. A replay of the frame recomputes these rather than
36
+ * reapplying them (see `ServerAuthoritativeServer.__read_historical`), so
37
+ * the sim's output does not accumulate a copy per replay.
38
+ *
39
+ * It also gives the replay a stable sort key, so multi-client action order is
40
+ * deterministic across peers. It never crosses the wire —
29
41
  * {@link Replicator#pack_for_peer} strips it and the receiver derives sender
30
42
  * from the inbound packet's peer_id, so a hostile peer cannot impersonate.
31
43
  *
@@ -102,6 +114,17 @@ export class ActionLog {
102
114
  this.#current_buffer = null;
103
115
  }
104
116
 
117
+ /**
118
+ * Is a frame open for writing? {@link current_buffer} — and therefore
119
+ * `SimActionExecutor.execute` — throws when it is not, so a caller that can
120
+ * run either inside or outside a frame checks this to pick its path.
121
+ *
122
+ * @returns {boolean}
123
+ */
124
+ has_open_frame() {
125
+ return this.#current_frame !== -1;
126
+ }
127
+
105
128
  /**
106
129
  * Get the buffer for the currently-open frame for direct writing.
107
130
  *
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Forward cursor over the records of one closed {@link ActionLog} frame.
3
+ *
4
+ * The record layout is self-describing (see {@link ActionLog}), so any reader
5
+ * can walk it — and five did, each with its own copy of the header parse: the
6
+ * replicator's scope scan and action copy, the rewind engine's boundary pass,
7
+ * and the rollback server's history read and retransmission check. This is
8
+ * that parse in one place. {@link next} reads one record's header and exposes
9
+ * the layout as positions into the frame's buffer; what a reader does with the
10
+ * prior-state entries or the action payload is its own business.
11
+ *
12
+ * Allocation-free after construction: a reader owns one cursor and re-opens
13
+ * it per frame. After `next` returns true the buffer's `position` is at the
14
+ * END of the record, so a reader that wants the prior-state entries sets
15
+ * `position = prior_start` and reads `prior_count` of them; `next` seeks from
16
+ * `record_end` regardless of where the reader left the position.
17
+ *
18
+ * ```
19
+ * cursor.open(action_log, frame);
20
+ * while (cursor.next()) {
21
+ * // cursor.action_type_id, cursor.sender_id,
22
+ * // cursor.buffer.raw_bytes[cursor.payload_start .. + cursor.payload_len]
23
+ * }
24
+ * ```
25
+ *
26
+ * @author Alex Goldring
27
+ * @copyright Company Named Limited (c) 2026
28
+ */
29
+ export class ActionRecordCursor {
30
+ /**
31
+ * The open frame's buffer, positioned at {@link record_end} after each
32
+ * successful {@link next}.
33
+ * @type {BinaryBuffer|null}
34
+ */
35
+ buffer: BinaryBuffer | null;
36
+ /** @type {number} first byte of the current record */
37
+ record_start: number;
38
+ /** @type {number} prior-state entries in the current record */
39
+ prior_count: number;
40
+ /**
41
+ * First byte of the first prior-state entry. Each entry is
42
+ * `varint entity_id, uint8 component_type_id, uint32 len, bytes[len]`.
43
+ * @type {number}
44
+ */
45
+ prior_start: number;
46
+ /** @type {number} */
47
+ action_type_id: number;
48
+ /**
49
+ * The record's provenance byte: a peer id, `SENDER_LOCAL` or
50
+ * `SENDER_DERIVED` (see {@link SimActionExecutor}).
51
+ * @type {number}
52
+ */
53
+ sender_id: number;
54
+ /** @type {number} first byte of the action payload */
55
+ payload_start: number;
56
+ /** @type {number} */
57
+ payload_len: number;
58
+ /**
59
+ * One past the last byte of the current record — and so the first byte of
60
+ * the next, which is where {@link next} resumes. `0` before the first
61
+ * record.
62
+ * @type {number}
63
+ */
64
+ record_end: number;
65
+ /**
66
+ * Position the cursor before the first record of `frame`, which must be
67
+ * closed and present in the log (see {@link ActionLog#buffer_for}).
68
+ *
69
+ * @param {ActionLog} action_log
70
+ * @param {number} frame
71
+ */
72
+ open(action_log: ActionLog, frame: number): void;
73
+ /**
74
+ * Advance to the next record. Returns false once the frame is exhausted,
75
+ * leaving the fields as they were.
76
+ *
77
+ * @returns {boolean}
78
+ */
79
+ next(): boolean;
80
+ #private;
81
+ }
82
+ //# sourceMappingURL=ActionRecordCursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionRecordCursor.d.ts","sourceRoot":"","sources":["../../../../../src/engine/network/sim/ActionRecordCursor.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH;IACI;;;;OAIG;IACH,QAFU,eAAa,IAAI,CAEb;IAEd,sDAAsD;IACtD,cADW,MAAM,CACA;IAEjB,+DAA+D;IAC/D,aADW,MAAM,CACD;IAEhB;;;;OAIG;IACH,aAFU,MAAM,CAEA;IAEhB,qBAAqB;IACrB,gBADW,MAAM,CACE;IAEnB;;;;OAIG;IACH,WAFU,MAAM,CAEF;IAEd,sDAAsD;IACtD,eADW,MAAM,CACC;IAElB,qBAAqB;IACrB,aADW,MAAM,CACD;IAEhB;;;;;OAKG;IACH,YAFU,MAAM,CAED;IAKf;;;;;;OAMG;IACH,mCAFW,MAAM,QAMhB;IAED;;;;;OAKG;IACH,QAFa,OAAO,CAyBnB;;CACJ"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Forward cursor over the records of one closed {@link ActionLog} frame.
3
+ *
4
+ * The record layout is self-describing (see {@link ActionLog}), so any reader
5
+ * can walk it — and five did, each with its own copy of the header parse: the
6
+ * replicator's scope scan and action copy, the rewind engine's boundary pass,
7
+ * and the rollback server's history read and retransmission check. This is
8
+ * that parse in one place. {@link next} reads one record's header and exposes
9
+ * the layout as positions into the frame's buffer; what a reader does with the
10
+ * prior-state entries or the action payload is its own business.
11
+ *
12
+ * Allocation-free after construction: a reader owns one cursor and re-opens
13
+ * it per frame. After `next` returns true the buffer's `position` is at the
14
+ * END of the record, so a reader that wants the prior-state entries sets
15
+ * `position = prior_start` and reads `prior_count` of them; `next` seeks from
16
+ * `record_end` regardless of where the reader left the position.
17
+ *
18
+ * ```
19
+ * cursor.open(action_log, frame);
20
+ * while (cursor.next()) {
21
+ * // cursor.action_type_id, cursor.sender_id,
22
+ * // cursor.buffer.raw_bytes[cursor.payload_start .. + cursor.payload_len]
23
+ * }
24
+ * ```
25
+ *
26
+ * @author Alex Goldring
27
+ * @copyright Company Named Limited (c) 2026
28
+ */
29
+ export class ActionRecordCursor {
30
+ /**
31
+ * The open frame's buffer, positioned at {@link record_end} after each
32
+ * successful {@link next}.
33
+ * @type {BinaryBuffer|null}
34
+ */
35
+ buffer = null;
36
+
37
+ /** @type {number} first byte of the current record */
38
+ record_start = 0;
39
+
40
+ /** @type {number} prior-state entries in the current record */
41
+ prior_count = 0;
42
+
43
+ /**
44
+ * First byte of the first prior-state entry. Each entry is
45
+ * `varint entity_id, uint8 component_type_id, uint32 len, bytes[len]`.
46
+ * @type {number}
47
+ */
48
+ prior_start = 0;
49
+
50
+ /** @type {number} */
51
+ action_type_id = 0;
52
+
53
+ /**
54
+ * The record's provenance byte: a peer id, `SENDER_LOCAL` or
55
+ * `SENDER_DERIVED` (see {@link SimActionExecutor}).
56
+ * @type {number}
57
+ */
58
+ sender_id = 0;
59
+
60
+ /** @type {number} first byte of the action payload */
61
+ payload_start = 0;
62
+
63
+ /** @type {number} */
64
+ payload_len = 0;
65
+
66
+ /**
67
+ * One past the last byte of the current record — and so the first byte of
68
+ * the next, which is where {@link next} resumes. `0` before the first
69
+ * record.
70
+ * @type {number}
71
+ */
72
+ record_end = 0;
73
+
74
+ /** @type {number} one past the last byte of the frame */
75
+ #end = 0;
76
+
77
+ /**
78
+ * Position the cursor before the first record of `frame`, which must be
79
+ * closed and present in the log (see {@link ActionLog#buffer_for}).
80
+ *
81
+ * @param {ActionLog} action_log
82
+ * @param {number} frame
83
+ */
84
+ open(action_log, frame) {
85
+ this.buffer = action_log.buffer_for(frame); // rewinds to 0
86
+ this.#end = action_log.write_end_for(frame);
87
+ this.record_end = 0;
88
+ }
89
+
90
+ /**
91
+ * Advance to the next record. Returns false once the frame is exhausted,
92
+ * leaving the fields as they were.
93
+ *
94
+ * @returns {boolean}
95
+ */
96
+ next() {
97
+ if (this.record_end >= this.#end) return false;
98
+
99
+ const buffer = this.buffer;
100
+ buffer.position = this.record_end;
101
+
102
+ this.record_start = buffer.position;
103
+ this.prior_count = buffer.readUintVar();
104
+ this.prior_start = buffer.position;
105
+ for (let i = 0; i < this.prior_count; i++) {
106
+ buffer.readUintVar(); // entity_id
107
+ buffer.readUint8(); // component_type_id
108
+ const prior_len = buffer.readUint32();
109
+ buffer.position += prior_len; // prior payload
110
+ }
111
+ this.action_type_id = buffer.readUint8();
112
+ this.sender_id = buffer.readUint8();
113
+ this.payload_len = buffer.readUint32();
114
+ this.payload_start = buffer.position;
115
+ this.record_end = this.payload_start + this.payload_len;
116
+ buffer.position = this.record_end;
117
+
118
+ return true;
119
+ }
120
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"RewindEngine.d.ts","sourceRoot":"","sources":["../../../../../src/engine/network/sim/RewindEngine.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IAQI;;;;;;OAMG;IACH,uDANW;QACV,UAAc,YAAY;QAC1B,KAAS,yBAAyB;QAClC,kBAAsB,8BAA8B;KACjD,EAiBH;IAdG;;OAEG;IACH,sBAA4B;IAE5B;;OAEG;IACH,8BAAkB;IAElB;;OAEG;IACH,gDAA4C;IAGhD;;;;;OAKG;IACH,kBAFW,MAAM,QA2BhB;IAED;;;;;;;;;OASG;IACH,yBAHW,MAAM,gBACN,MAAM,QAWhB;;CAwEJ"}
1
+ {"version":3,"file":"RewindEngine.d.ts","sourceRoot":"","sources":["../../../../../src/engine/network/sim/RewindEngine.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IAeI;;;;;;OAMG;IACH,uDANW;QACV,UAAc,YAAY;QAC1B,KAAS,yBAAyB;QAClC,kBAAsB,8BAA8B;KACjD,EAiBH;IAdG;;OAEG;IACH,sBAA4B;IAE5B;;OAEG;IACH,8BAAkB;IAElB;;OAEG;IACH,gDAA4C;IAGhD;;;;;OAKG;IACH,kBAFW,MAAM,QA0BhB;IAED;;;;;;;;;OASG;IACH,yBAHW,MAAM,gBACN,MAAM,QAWhB;;CAiDJ"}
@@ -1,4 +1,5 @@
1
1
  import { assert } from "../../../core/assert.js";
2
+ import { ActionRecordCursor } from "./ActionRecordCursor.js";
2
3
 
3
4
  /**
4
5
  * Walks the {@link ActionLog} backwards to restore prior component state.
@@ -28,6 +29,13 @@ export class RewindEngine {
28
29
  */
29
30
  #record_starts = new Int32Array(64);
30
31
 
32
+ /**
33
+ * Walks a frame's records to find where each starts.
34
+ * @type {ActionRecordCursor}
35
+ * @private
36
+ */
37
+ #cursor = new ActionRecordCursor();
38
+
31
39
  /**
32
40
  * @param {{
33
41
  * action_log: ActionLog,
@@ -64,20 +72,19 @@ export class RewindEngine {
64
72
  throw new Error(`RewindEngine.undo_frame: frame ${frame} is not present in the action log`);
65
73
  }
66
74
 
67
- const buffer = this.action_log.buffer_for(frame);
68
- const end = this.action_log.write_end_for(frame);
69
-
70
75
  // 1. First pass: walk forward to find record boundaries.
76
+ const cursor = this.#cursor;
77
+ cursor.open(this.action_log, frame);
71
78
  let record_count = 0;
72
- while (buffer.position < end) {
79
+ while (cursor.next()) {
73
80
  if (record_count >= this.#record_starts.length) {
74
81
  this.#grow_record_starts();
75
82
  }
76
- this.#record_starts[record_count++] = buffer.position;
77
- this.#skip_record(buffer);
83
+ this.#record_starts[record_count++] = cursor.record_start;
78
84
  }
79
85
 
80
86
  // 2. Second pass: iterate records in reverse, restoring prior state.
87
+ const buffer = cursor.buffer;
81
88
  for (let i = record_count - 1; i >= 0; i--) {
82
89
  buffer.position = this.#record_starts[i];
83
90
  this.#restore_prior_state(buffer);
@@ -106,29 +113,6 @@ export class RewindEngine {
106
113
  }
107
114
  }
108
115
 
109
- /**
110
- * Walk past a single record without restoring anything. Buffer position
111
- * advances to the start of the next record (or to `end` if this was the last).
112
- *
113
- * @param {BinaryBuffer} buffer
114
- * @private
115
- */
116
- #skip_record(buffer) {
117
- // Skip prior_state entries.
118
- const prior_count = buffer.readUintVar();
119
- for (let i = 0; i < prior_count; i++) {
120
- buffer.readUintVar(); // entity_id
121
- buffer.readUint8(); // component_type_id
122
- const len = buffer.readUint32();
123
- buffer.position += len; // skip prior payload
124
- }
125
- // Skip action.
126
- buffer.readUint8(); // action_type_id
127
- buffer.readUint8(); // sender_id
128
- const action_len = buffer.readUint32();
129
- buffer.position += action_len; // skip action payload
130
- }
131
-
132
116
  /**
133
117
  * Read the prior_state entries of the record at the buffer's current position
134
118
  * and write them back into the live components. Buffer position advances past
@@ -11,6 +11,21 @@
11
11
  * deterministic consequence of the simulation, or rewind / replay /
12
12
  * replication will desync.
13
13
  *
14
+ * "Deterministic consequence" is a narrow licence, and it is worth being exact
15
+ * about what it buys. A rewind restores component state from the prior-bytes
16
+ * captured per action record, so a mutation made outside an action is never
17
+ * undone — it survives into the replayed frame and the sim must overwrite it
18
+ * with the same answer it produced before. That holds for a function of the
19
+ * frame's post-input state that fully determines what it writes (a clamp, a
20
+ * position solved from inputs) and fails for anything that reads the value it
21
+ * is about to change (`hp -= 10`, a counter, an accumulator). Those need a
22
+ * `SimAction`, whose prior-bytes capture makes them reversible.
23
+ *
24
+ * Going through an action does not, on its own, make a mutation replayable
25
+ * input: on a rollback orchestrator, a record's `sender_id` marks whether it
26
+ * arrived, was authored, or was derived, and only the first two are reapplied
27
+ * from the log. See `ServerAuthoritativeServer#onLocalSim`.
28
+ *
14
29
  * Wire vs local: actions reference entities by `network_id` (peer-shared);
15
30
  * `executor.slot_table.entity_for(network_id)` translates to the local id.
16
31
  *
@@ -1 +1 @@
1
- {"version":3,"file":"SimAction.d.ts","sourceRoot":"","sources":["../../../../../src/engine/network/sim/SimAction.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH;IAEI;;;;OAIG;IACH,gBAFU,MAAM,CAEI;IAEpB;;;;;;;;;OASG;IACH,mEAFa,IAAI,CAIhB;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,qCAHoB,MAAM,qBAAa,IAAI,qCAK1C;IAED;;;;;;OAMG;IACH,iCAFa,IAAI,CAIhB;IAED;;;;;OAKG;IACH,mCAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,cAEC;IAGL;;;;OAIG;IACH,sBAFU,OAAO,CAEc;CAP9B;;IAwCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsCG;IACH;;;;;;;iBAmGC"}
1
+ {"version":3,"file":"SimAction.d.ts","sourceRoot":"","sources":["../../../../../src/engine/network/sim/SimAction.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH;IAEI;;;;OAIG;IACH,gBAFU,MAAM,CAEI;IAEpB;;;;;;;;;OASG;IACH,mEAFa,IAAI,CAIhB;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,qCAHoB,MAAM,qBAAa,IAAI,qCAK1C;IAED;;;;;;OAMG;IACH,iCAFa,IAAI,CAIhB;IAED;;;;;OAKG;IACH,mCAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,cAEC;IAGL;;;;OAIG;IACH,sBAFU,OAAO,CAEc;CAP9B;;IAwCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsCG;IACH;;;;;;;iBAmGC"}
@@ -13,6 +13,21 @@ import { FunctionCompiler } from "../../../core/function/FunctionCompiler.js";
13
13
  * deterministic consequence of the simulation, or rewind / replay /
14
14
  * replication will desync.
15
15
  *
16
+ * "Deterministic consequence" is a narrow licence, and it is worth being exact
17
+ * about what it buys. A rewind restores component state from the prior-bytes
18
+ * captured per action record, so a mutation made outside an action is never
19
+ * undone — it survives into the replayed frame and the sim must overwrite it
20
+ * with the same answer it produced before. That holds for a function of the
21
+ * frame's post-input state that fully determines what it writes (a clamp, a
22
+ * position solved from inputs) and fails for anything that reads the value it
23
+ * is about to change (`hp -= 10`, a counter, an accumulator). Those need a
24
+ * `SimAction`, whose prior-bytes capture makes them reversible.
25
+ *
26
+ * Going through an action does not, on its own, make a mutation replayable
27
+ * input: on a rollback orchestrator, a record's `sender_id` marks whether it
28
+ * arrived, was authored, or was derived, and only the first two are reapplied
29
+ * from the log. See `ServerAuthoritativeServer#onLocalSim`.
30
+ *
16
31
  * Wire vs local: actions reference entities by `network_id` (peer-shared);
17
32
  * `executor.slot_table.entity_for(network_id)` translates to the local id.
18
33
  *
@@ -2,11 +2,43 @@
2
2
  * Sentinel sender id for actions that originated on the local peer (not
3
3
  * received over the wire). Used as the default `sender_id` for
4
4
  * {@link SimActionExecutor#execute} so existing single-peer code keeps
5
- * working. Valid peer ids must therefore be in `[0, 254]`.
5
+ * working.
6
6
  *
7
7
  * @type {number}
8
8
  */
9
9
  export const SENDER_LOCAL: number;
10
+ /**
11
+ * Sentinel sender id recorded for actions the local simulation DERIVED from
12
+ * the frame's state, rather than received or authored. Written in place of
13
+ * the caller's `sender_id` while {@link SimActionExecutor#deriving} is set.
14
+ *
15
+ * The sender byte is the record's provenance, and provenance is what decides
16
+ * whether a rollback replay may reuse a record. Input — remote or locally
17
+ * authored — happened once and cannot be recomputed, so a replay reapplies it
18
+ * from the log. Derived output is a function of the frame's post-input state,
19
+ * which a replay recomputes anyway; reapplying the previous pass's copy on top
20
+ * of the recomputed one applies the effect twice. So the two are separated
21
+ * here, at the point of execution, where the distinction is actually known.
22
+ *
23
+ * Local-only, like `SENDER_LOCAL` — {@link Replicator#pack_for_peer} strips
24
+ * the byte before send, so this never reaches the wire.
25
+ *
26
+ * Both sentinels are reserved: valid peer ids are `[0, 253]`, enforced by
27
+ * {@link SimActionExecutor#execute} and at {@link NetworkPeer#connect_peer}.
28
+ * A peer allowed to take 254 would have its records read back as the local
29
+ * sim's own output and dropped from every replay — its input would apply once
30
+ * and then silently vanish the first time a rollback crossed its frame.
31
+ *
32
+ * @type {number}
33
+ */
34
+ export const SENDER_DERIVED: number;
35
+ /**
36
+ * Largest id a remote peer may take. Above this are the two local provenance
37
+ * sentinels, {@link SENDER_DERIVED} and {@link SENDER_LOCAL}.
38
+ *
39
+ * @type {number}
40
+ */
41
+ export const MAX_PEER_ID: number;
10
42
  /**
11
43
  * The single legitimate gateway for replicated state mutations.
12
44
  *
@@ -83,6 +115,23 @@ export class SimActionExecutor {
83
115
  * @type {((sender_id: number, entity_id: number, action: SimAction) => boolean) | null}
84
116
  */
85
117
  authorize: (sender_id: number, entity_id: number, action: SimAction) => boolean;
118
+ /**
119
+ * When true, records written by {@link execute} are stamped
120
+ * {@link SENDER_DERIVED} instead of the caller's `sender_id`, marking them
121
+ * as output the simulation recomputes rather than input it must replay.
122
+ *
123
+ * Set by a rollback orchestrator for the span in which the frame's local
124
+ * sim runs (see `ServerAuthoritativeServer.__replay_frame`) and cleared
125
+ * immediately after. Everything outside that span — arrived input,
126
+ * locally-authored actions — is left with its real sender.
127
+ *
128
+ * Only the RECORDED byte changes. `sender_id` still drives the
129
+ * {@link authorize} gate and {@link current_sender_id}, so an action that
130
+ * self-validates on its sender sees the truth.
131
+ *
132
+ * @type {boolean}
133
+ */
134
+ deriving: boolean;
86
135
  /**
87
136
  * @type {EntityComponentDataset}
88
137
  */
@@ -142,7 +191,7 @@ export class SimActionExecutor {
142
191
  * @param {SimAction} action
143
192
  * @param {number} [sender_id] peer that originated this action.
144
193
  * Defaults to {@link SENDER_LOCAL} for locally-originated actions.
145
- * Must be in `[0, 254]` for remote-originated actions.
194
+ * Must be in `[0, MAX_PEER_ID]` for remote-originated actions.
146
195
  * @returns {boolean} true if the action was applied; false if it was
147
196
  * rejected by the {@link authorize} gate (and therefore not applied or
148
197
  * logged).
@@ -1 +1 @@
1
- {"version":3,"file":"SimActionExecutor.d.ts","sourceRoot":"","sources":["../../../../../src/engine/network/sim/SimActionExecutor.js"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,2BAFU,MAAM,CAEiB;AAEjC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;IAyCI;;;;;;;;;OASG;IACH,sGATW;QACV,KAAS,yBAAyB;QAClC,UAAc,YAAY;QAC1B,eAAmB,oBAAoB;QACvC,kBAAsB,8BAA8B;QACpD,UAAc,uBAAuB;QACrC,gBAAoB,CAAC,mBAAmB;KACrC,EAyFH;IArID;;;;;;;;;OASG;IACH,gBAFU,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAEP;IAEtB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,uBAFuB,MAAM,aAAa,MAAM,wBAAwB,OAAO,CAE9D;IAab;;OAEG;IACH,8BAAkB;IAElB;;OAEG;IACH,sBAA4B;IAE5B;;OAEG;IACH,mCAAsC;IAEtC;;OAEG;IACH,gDAA4C;IAE5C;;;;OAIG;IACH,iCAA4B;IAE5B;;;;;;;;;;;OAWG;IACH,kBAFU,mBAAiB,IAAI,CAES;IA4BxC;;;;;;;OAOG;IACH,mBAFU,MAAM,CAEqB;IAErC;;;;;;;OAOG;IACH,kBAFU,MAAM,CAEoB;IAGxC;;;;;;;;;;OAUG;IACH,uCAPW,MAAM,GAGJ,OAAO,CAiInB;;CACJ;mBAxTkB,uCAAuC"}
1
+ {"version":3,"file":"SimActionExecutor.d.ts","sourceRoot":"","sources":["../../../../../src/engine/network/sim/SimActionExecutor.js"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,2BAFU,MAAM,CAEiB;AAEjC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,6BAFU,MAAM,CAEmB;AAEnC;;;;;GAKG;AACH,0BAFU,MAAM,CAEgB;AAEhC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;IA2DI;;;;;;;;;OASG;IACH,sGATW;QACV,KAAS,yBAAyB;QAClC,UAAc,YAAY;QAC1B,eAAmB,oBAAoB;QACvC,kBAAsB,8BAA8B;QACpD,UAAc,uBAAuB;QACrC,gBAAoB,CAAC,mBAAmB;KACrC,EAyFH;IAvJD;;;;;;;;;OASG;IACH,gBAFU,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAEP;IAEtB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,uBAFuB,MAAM,aAAa,MAAM,wBAAwB,OAAO,CAE9D;IAEjB;;;;;;;;;;;;;;;OAeG;IACH,UAFU,OAAO,CAEA;IAab;;OAEG;IACH,8BAAkB;IAElB;;OAEG;IACH,sBAA4B;IAE5B;;OAEG;IACH,mCAAsC;IAEtC;;OAEG;IACH,gDAA4C;IAE5C;;;;OAIG;IACH,iCAA4B;IAE5B;;;;;;;;;;;OAWG;IACH,kBAFU,mBAAiB,IAAI,CAES;IA4BxC;;;;;;;OAOG;IACH,mBAFU,MAAM,CAEqB;IAErC;;;;;;;OAOG;IACH,kBAFU,MAAM,CAEoB;IAGxC;;;;;;;;;;OAUG;IACH,uCAPW,MAAM,GAGJ,OAAO,CAgJnB;;CACJ;mBA3XkB,uCAAuC"}
@@ -5,12 +5,46 @@ import Signal from "../../../core/events/signal/Signal.js";
5
5
  * Sentinel sender id for actions that originated on the local peer (not
6
6
  * received over the wire). Used as the default `sender_id` for
7
7
  * {@link SimActionExecutor#execute} so existing single-peer code keeps
8
- * working. Valid peer ids must therefore be in `[0, 254]`.
8
+ * working.
9
9
  *
10
10
  * @type {number}
11
11
  */
12
12
  export const SENDER_LOCAL = 0xFF;
13
13
 
14
+ /**
15
+ * Sentinel sender id recorded for actions the local simulation DERIVED from
16
+ * the frame's state, rather than received or authored. Written in place of
17
+ * the caller's `sender_id` while {@link SimActionExecutor#deriving} is set.
18
+ *
19
+ * The sender byte is the record's provenance, and provenance is what decides
20
+ * whether a rollback replay may reuse a record. Input — remote or locally
21
+ * authored — happened once and cannot be recomputed, so a replay reapplies it
22
+ * from the log. Derived output is a function of the frame's post-input state,
23
+ * which a replay recomputes anyway; reapplying the previous pass's copy on top
24
+ * of the recomputed one applies the effect twice. So the two are separated
25
+ * here, at the point of execution, where the distinction is actually known.
26
+ *
27
+ * Local-only, like `SENDER_LOCAL` — {@link Replicator#pack_for_peer} strips
28
+ * the byte before send, so this never reaches the wire.
29
+ *
30
+ * Both sentinels are reserved: valid peer ids are `[0, 253]`, enforced by
31
+ * {@link SimActionExecutor#execute} and at {@link NetworkPeer#connect_peer}.
32
+ * A peer allowed to take 254 would have its records read back as the local
33
+ * sim's own output and dropped from every replay — its input would apply once
34
+ * and then silently vanish the first time a rollback crossed its frame.
35
+ *
36
+ * @type {number}
37
+ */
38
+ export const SENDER_DERIVED = 0xFE;
39
+
40
+ /**
41
+ * Largest id a remote peer may take. Above this are the two local provenance
42
+ * sentinels, {@link SENDER_DERIVED} and {@link SENDER_LOCAL}.
43
+ *
44
+ * @type {number}
45
+ */
46
+ export const MAX_PEER_ID = 0xFD;
47
+
14
48
  /**
15
49
  * The single legitimate gateway for replicated state mutations.
16
50
  *
@@ -75,6 +109,24 @@ export class SimActionExecutor {
75
109
  */
76
110
  authorize = null;
77
111
 
112
+ /**
113
+ * When true, records written by {@link execute} are stamped
114
+ * {@link SENDER_DERIVED} instead of the caller's `sender_id`, marking them
115
+ * as output the simulation recomputes rather than input it must replay.
116
+ *
117
+ * Set by a rollback orchestrator for the span in which the frame's local
118
+ * sim runs (see `ServerAuthoritativeServer.__replay_frame`) and cleared
119
+ * immediately after. Everything outside that span — arrived input,
120
+ * locally-authored actions — is left with its real sender.
121
+ *
122
+ * Only the RECORDED byte changes. `sender_id` still drives the
123
+ * {@link authorize} gate and {@link current_sender_id}, so an action that
124
+ * self-validates on its sender sees the truth.
125
+ *
126
+ * @type {boolean}
127
+ */
128
+ deriving = false;
129
+
78
130
  /**
79
131
  * @param {{
80
132
  * world: EntityComponentDataset,
@@ -180,7 +232,7 @@ export class SimActionExecutor {
180
232
  * @param {SimAction} action
181
233
  * @param {number} [sender_id] peer that originated this action.
182
234
  * Defaults to {@link SENDER_LOCAL} for locally-originated actions.
183
- * Must be in `[0, 254]` for remote-originated actions.
235
+ * Must be in `[0, MAX_PEER_ID]` for remote-originated actions.
184
236
  * @returns {boolean} true if the action was applied; false if it was
185
237
  * rejected by the {@link authorize} gate (and therefore not applied or
186
238
  * logged).
@@ -197,7 +249,18 @@ export class SimActionExecutor {
197
249
  `execute: action class '${action.constructor.action_type_name ?? action.constructor.name}' has no wire type_id — register it (NetworkSession.defineAction, or SimActionRegistry.register) before executing it`,
198
250
  );
199
251
  assert.isNonNegativeInteger(sender_id, 'sender_id');
200
- assert.ok(sender_id <= 0xFF, 'sender_id must fit in a uint8');
252
+ // A sender above the peer range is either the sim-derived sentinel —
253
+ // which a rollback replay reads back as "this record is mine to
254
+ // recompute", so the peer's input would apply once and then disappear
255
+ // on the first replay of its frame, with nothing logged — or a value
256
+ // that does not fit the record's one byte at all. SENDER_LOCAL itself
257
+ // is the caller saying "mine". Real runtime check: asserts strip in
258
+ // prod, and silent input loss is not something to ship behind one.
259
+ if (sender_id > MAX_PEER_ID && sender_id !== SENDER_LOCAL) {
260
+ throw new Error(
261
+ `SimActionExecutor.execute: sender_id ${sender_id} is not a peer id; remote peer ids must be in [0, ${MAX_PEER_ID}] — 254 and 255 are reserved provenance markers`,
262
+ );
263
+ }
201
264
 
202
265
  // Expose the originating sender to apply / affected_components / the
203
266
  // authorize policy before any of them run.
@@ -292,10 +355,14 @@ export class SimActionExecutor {
292
355
 
293
356
  // 5. Append the action itself.
294
357
  buffer.writeUint8(action.constructor.type_id);
295
- // sender_id: peer that originated this action. Local-only record; not
296
- // sent over the wire (Replicator strips it during pack). Used by
297
- // rollback orchestrators for stable-sort tie-breaking.
298
- buffer.writeUint8(sender_id);
358
+ // sender_id: where this record came from. Local-only; not sent over the
359
+ // wire (Replicator strips it during pack). Used by rollback
360
+ // orchestrators for stable-sort tie-breaking, and to tell input (which
361
+ // a replay reapplies) from derived output (which a replay recomputes).
362
+ // While `deriving` is set the record is stamped SENDER_DERIVED — the
363
+ // originating sender is not meaningful for output the sim computed for
364
+ // itself, and nothing reads it back on that path.
365
+ buffer.writeUint8(this.deriving ? SENDER_DERIVED : sender_id);
299
366
 
300
367
  // Reserve 4 bytes for action_payload_len, write payload, then back-patch.
301
368
  const action_len_position = buffer.position;
@@ -9,7 +9,7 @@ export class Channel {
9
9
  * an unacked seq falls more than half-range behind the newest sent, the
10
10
  * signed `seq16_distance` used for loss detection wraps and the entry can
11
11
  * neither be acked nor declared lost — a permanent leak (and a downstream
12
- * `seq_to_frame_end` leak in the orchestrator). Capping in-flight makes
12
+ * `seq_to_pending` leak in the orchestrator). Capping in-flight makes
13
13
  * that lap impossible. Default 1024 ≫ any realistic in-flight window
14
14
  * (RTT × send-rate) yet ≪ 32768. Only reached under a sustained one-way
15
15
  * stall, where eviction-as-lost is the correct verdict anyway.
@@ -64,7 +64,7 @@ export class Channel {
64
64
  * an unacked seq falls more than half-range behind the newest sent, the
65
65
  * signed `seq16_distance` used for loss detection wraps and the entry can
66
66
  * neither be acked nor declared lost — a permanent leak (and a downstream
67
- * `seq_to_frame_end` leak in the orchestrator). Capping in-flight makes
67
+ * `seq_to_pending` leak in the orchestrator). Capping in-flight makes
68
68
  * that lap impossible. Default 1024 ≫ any realistic in-flight window
69
69
  * (RTT × send-rate) yet ≪ 32768. Only reached under a sustained one-way
70
70
  * stall, where eviction-as-lost is the correct verdict anyway.
@@ -64,11 +64,11 @@ export class FluidObstacleSystem extends System<any> {
64
64
  /**
65
65
  * @param {FluidComponent} fluid
66
66
  */
67
- static "__#370@#refresh_masks"(fluid: FluidComponent): void;
67
+ static "__#371@#refresh_masks"(fluid: FluidComponent): void;
68
68
  /**
69
69
  * @param {FluidComponent} fluid
70
70
  */
71
- static "__#370@#clear_field"(fluid: FluidComponent): void;
71
+ static "__#371@#clear_field"(fluid: FluidComponent): void;
72
72
  /**
73
73
  * Mark every cell of `fluid` whose centre lies within `inflation` of the
74
74
  * posed shape as solid. Iteration is clipped to the shape's world AABB
@@ -80,7 +80,7 @@ export class FluidObstacleSystem extends System<any> {
80
80
  * @param {number} inflation world-units SDF threshold
81
81
  * @param {Float64Array} point length-3 scratch
82
82
  */
83
- static "__#370@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
83
+ static "__#371@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
84
84
  /**
85
85
  * Write the obstacle's translation velocity onto every face of every cell
86
86
  * it voxelized — the moving-wall boundary condition. Runs AFTER the mask
@@ -100,7 +100,7 @@ export class FluidObstacleSystem extends System<any> {
100
100
  * @param {number} wvy
101
101
  * @param {number} wvz
102
102
  */
103
- static "__#370@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
103
+ static "__#371@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
104
104
  constructor();
105
105
  dependencies: (typeof FluidObstacle)[];
106
106
  components_used: (ResourceAccessSpecification<typeof Transform> | ResourceAccessSpecification<typeof RigidBody> | ResourceAccessSpecification<typeof Collider> | ResourceAccessSpecification<typeof FluidComponent> | ResourceAccessSpecification<typeof FluidObstacle>)[];
@@ -1 +1 @@
1
- {"version":3,"file":"Ticker.d.ts","sourceRoot":"","sources":["../../../../src/engine/simulation/Ticker.js"],"names":[],"mappings":";AAIA;;;;;;;;;;;;;;GAcG;AACH;IACI;;;OAGG;IACH,gBAFU,KAAK,CAEK;IAEpB;;;;;;;;;;;;OAYG;IACH,uBAFU,OAAO,CAEY;IAkC7B;;;;OAIG;IACH,qBAAsB;IAUtB;;;;OAIG;IACH,yBAEC;IAED;;;;OAIG;IACH,yBAEC;IAuGD;;;OAGG;IACH,uBAFW,MAAM,QA8EhB;IAED,cAWC;IAED,eAaC;IAED,aAYC;;CACJ;kBAxUiB,aAAa"}
1
+ {"version":3,"file":"Ticker.d.ts","sourceRoot":"","sources":["../../../../src/engine/simulation/Ticker.js"],"names":[],"mappings":";AAIA;;;;;;;;;;;;;;GAcG;AACH;IACI;;;OAGG;IACH,gBAFU,KAAK,CAEK;IAEpB;;;;;;;;;;;;OAYG;IACH,uBAFU,OAAO,CAEY;IAkC7B;;;;OAIG;IACH,qBAAsB;IAUtB;;;;OAIG;IACH,yBAEC;IAED;;;;OAIG;IACH,yBAEC;IAuGD;;;OAGG;IACH,uBAFW,MAAM,QAiFhB;IAED,cAWC;IAED,eAaC;IAED,aAYC;;CACJ;kBA3UiB,aAAa"}