@fundamental-engine/core 0.4.0

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 (371) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +128 -0
  3. package/dist/agents/element-agent.d.ts +38 -0
  4. package/dist/agents/element-agent.d.ts.map +1 -0
  5. package/dist/agents/element-agent.js +70 -0
  6. package/dist/agents/element-agent.js.map +1 -0
  7. package/dist/agents/event-agent.d.ts +47 -0
  8. package/dist/agents/event-agent.d.ts.map +1 -0
  9. package/dist/agents/event-agent.js +82 -0
  10. package/dist/agents/event-agent.js.map +1 -0
  11. package/dist/agents/index.d.ts +17 -0
  12. package/dist/agents/index.d.ts.map +1 -0
  13. package/dist/agents/index.js +57 -0
  14. package/dist/agents/index.js.map +1 -0
  15. package/dist/agents/region-agents.d.ts +40 -0
  16. package/dist/agents/region-agents.d.ts.map +1 -0
  17. package/dist/agents/region-agents.js +22 -0
  18. package/dist/agents/region-agents.js.map +1 -0
  19. package/dist/agents/relationship.d.ts +55 -0
  20. package/dist/agents/relationship.d.ts.map +1 -0
  21. package/dist/agents/relationship.js +40 -0
  22. package/dist/agents/relationship.js.map +1 -0
  23. package/dist/agents/user-agent.d.ts +57 -0
  24. package/dist/agents/user-agent.d.ts.map +1 -0
  25. package/dist/agents/user-agent.js +45 -0
  26. package/dist/agents/user-agent.js.map +1 -0
  27. package/dist/config/forces.config.d.ts +101 -0
  28. package/dist/config/forces.config.d.ts.map +1 -0
  29. package/dist/config/forces.config.js +239 -0
  30. package/dist/config/forces.config.js.map +1 -0
  31. package/dist/config/manual.d.ts +134 -0
  32. package/dist/config/manual.d.ts.map +1 -0
  33. package/dist/config/manual.js +604 -0
  34. package/dist/config/manual.js.map +1 -0
  35. package/dist/config/palettes.d.ts +18 -0
  36. package/dist/config/palettes.d.ts.map +1 -0
  37. package/dist/config/palettes.js +34 -0
  38. package/dist/config/palettes.js.map +1 -0
  39. package/dist/config/presets.d.ts +48 -0
  40. package/dist/config/presets.d.ts.map +1 -0
  41. package/dist/config/presets.js +87 -0
  42. package/dist/config/presets.js.map +1 -0
  43. package/dist/config/tokens.d.ts +3 -0
  44. package/dist/config/tokens.d.ts.map +1 -0
  45. package/dist/config/tokens.js +16 -0
  46. package/dist/config/tokens.js.map +1 -0
  47. package/dist/conformance/expectations.d.ts +40 -0
  48. package/dist/conformance/expectations.d.ts.map +1 -0
  49. package/dist/conformance/expectations.js +347 -0
  50. package/dist/conformance/expectations.js.map +1 -0
  51. package/dist/conformance/experiments.d.ts +17 -0
  52. package/dist/conformance/experiments.d.ts.map +1 -0
  53. package/dist/conformance/experiments.js +875 -0
  54. package/dist/conformance/experiments.js.map +1 -0
  55. package/dist/conformance/run.d.ts +18 -0
  56. package/dist/conformance/run.d.ts.map +1 -0
  57. package/dist/conformance/run.js +240 -0
  58. package/dist/conformance/run.js.map +1 -0
  59. package/dist/conformance/types.d.ts +100 -0
  60. package/dist/conformance/types.d.ts.map +1 -0
  61. package/dist/conformance/types.js +2 -0
  62. package/dist/conformance/types.js.map +1 -0
  63. package/dist/contracts/guards.d.ts +51 -0
  64. package/dist/contracts/guards.d.ts.map +1 -0
  65. package/dist/contracts/guards.js +100 -0
  66. package/dist/contracts/guards.js.map +1 -0
  67. package/dist/contracts/index.d.ts +18 -0
  68. package/dist/contracts/index.d.ts.map +1 -0
  69. package/dist/contracts/index.js +107 -0
  70. package/dist/contracts/index.js.map +1 -0
  71. package/dist/contracts/passport.d.ts +88 -0
  72. package/dist/contracts/passport.d.ts.map +1 -0
  73. package/dist/contracts/passport.js +135 -0
  74. package/dist/contracts/passport.js.map +1 -0
  75. package/dist/contracts/types.d.ts +120 -0
  76. package/dist/contracts/types.d.ts.map +1 -0
  77. package/dist/contracts/types.js +24 -0
  78. package/dist/contracts/types.js.map +1 -0
  79. package/dist/core/accretion.d.ts +50 -0
  80. package/dist/core/accretion.d.ts.map +1 -0
  81. package/dist/core/accretion.js +98 -0
  82. package/dist/core/accretion.js.map +1 -0
  83. package/dist/core/agents.d.ts +31 -0
  84. package/dist/core/agents.d.ts.map +1 -0
  85. package/dist/core/agents.js +51 -0
  86. package/dist/core/agents.js.map +1 -0
  87. package/dist/core/attention.d.ts +72 -0
  88. package/dist/core/attention.d.ts.map +1 -0
  89. package/dist/core/attention.js +122 -0
  90. package/dist/core/attention.js.map +1 -0
  91. package/dist/core/causality.d.ts +38 -0
  92. package/dist/core/causality.d.ts.map +1 -0
  93. package/dist/core/causality.js +64 -0
  94. package/dist/core/causality.js.map +1 -0
  95. package/dist/core/conditions.d.ts +10 -0
  96. package/dist/core/conditions.d.ts.map +1 -0
  97. package/dist/core/conditions.js +22 -0
  98. package/dist/core/conditions.js.map +1 -0
  99. package/dist/core/currents.d.ts +53 -0
  100. package/dist/core/currents.d.ts.map +1 -0
  101. package/dist/core/currents.js +65 -0
  102. package/dist/core/currents.js.map +1 -0
  103. package/dist/core/dock.d.ts +35 -0
  104. package/dist/core/dock.d.ts.map +1 -0
  105. package/dist/core/dock.js +39 -0
  106. package/dist/core/dock.js.map +1 -0
  107. package/dist/core/events.d.ts +23 -0
  108. package/dist/core/events.d.ts.map +1 -0
  109. package/dist/core/events.js +34 -0
  110. package/dist/core/events.js.map +1 -0
  111. package/dist/core/feedback-sink.d.ts +32 -0
  112. package/dist/core/feedback-sink.d.ts.map +1 -0
  113. package/dist/core/feedback-sink.js +53 -0
  114. package/dist/core/feedback-sink.js.map +1 -0
  115. package/dist/core/feedback.d.ts +11 -0
  116. package/dist/core/feedback.d.ts.map +1 -0
  117. package/dist/core/feedback.js +16 -0
  118. package/dist/core/feedback.js.map +1 -0
  119. package/dist/core/field-store.d.ts +26 -0
  120. package/dist/core/field-store.d.ts.map +1 -0
  121. package/dist/core/field-store.js +54 -0
  122. package/dist/core/field-store.js.map +1 -0
  123. package/dist/core/field.d.ts +18 -0
  124. package/dist/core/field.d.ts.map +1 -0
  125. package/dist/core/field.js +1943 -0
  126. package/dist/core/field.js.map +1 -0
  127. package/dist/core/fieldline-seeds.d.ts +25 -0
  128. package/dist/core/fieldline-seeds.d.ts.map +1 -0
  129. package/dist/core/fieldline-seeds.js +32 -0
  130. package/dist/core/fieldline-seeds.js.map +1 -0
  131. package/dist/core/fieldlines.d.ts +75 -0
  132. package/dist/core/fieldlines.d.ts.map +1 -0
  133. package/dist/core/fieldlines.js +111 -0
  134. package/dist/core/fieldlines.js.map +1 -0
  135. package/dist/core/flow.d.ts +38 -0
  136. package/dist/core/flow.d.ts.map +1 -0
  137. package/dist/core/flow.js +27 -0
  138. package/dist/core/flow.js.map +1 -0
  139. package/dist/core/formations.d.ts +11 -0
  140. package/dist/core/formations.d.ts.map +1 -0
  141. package/dist/core/formations.js +22 -0
  142. package/dist/core/formations.js.map +1 -0
  143. package/dist/core/geometry.d.ts +67 -0
  144. package/dist/core/geometry.d.ts.map +1 -0
  145. package/dist/core/geometry.js +68 -0
  146. package/dist/core/geometry.js.map +1 -0
  147. package/dist/core/heatmap.d.ts +22 -0
  148. package/dist/core/heatmap.d.ts.map +1 -0
  149. package/dist/core/heatmap.js +55 -0
  150. package/dist/core/heatmap.js.map +1 -0
  151. package/dist/core/host.d.ts +46 -0
  152. package/dist/core/host.d.ts.map +1 -0
  153. package/dist/core/host.js +11 -0
  154. package/dist/core/host.js.map +1 -0
  155. package/dist/core/integrator.d.ts +24 -0
  156. package/dist/core/integrator.d.ts.map +1 -0
  157. package/dist/core/integrator.js +375 -0
  158. package/dist/core/integrator.js.map +1 -0
  159. package/dist/core/math.d.ts +37 -0
  160. package/dist/core/math.d.ts.map +1 -0
  161. package/dist/core/math.js +77 -0
  162. package/dist/core/math.js.map +1 -0
  163. package/dist/core/reactions.d.ts +32 -0
  164. package/dist/core/reactions.d.ts.map +1 -0
  165. package/dist/core/reactions.js +45 -0
  166. package/dist/core/reactions.js.map +1 -0
  167. package/dist/core/registry.d.ts +13 -0
  168. package/dist/core/registry.d.ts.map +1 -0
  169. package/dist/core/registry.js +20 -0
  170. package/dist/core/registry.js.map +1 -0
  171. package/dist/core/render-backend.d.ts +46 -0
  172. package/dist/core/render-backend.d.ts.map +1 -0
  173. package/dist/core/render-backend.js +75 -0
  174. package/dist/core/render-backend.js.map +1 -0
  175. package/dist/core/render-modes.d.ts +42 -0
  176. package/dist/core/render-modes.d.ts.map +1 -0
  177. package/dist/core/render-modes.js +141 -0
  178. package/dist/core/render-modes.js.map +1 -0
  179. package/dist/core/reservoir.d.ts +43 -0
  180. package/dist/core/reservoir.d.ts.map +1 -0
  181. package/dist/core/reservoir.js +207 -0
  182. package/dist/core/reservoir.js.map +1 -0
  183. package/dist/core/scalar-grid.d.ts +51 -0
  184. package/dist/core/scalar-grid.d.ts.map +1 -0
  185. package/dist/core/scalar-grid.js +146 -0
  186. package/dist/core/scalar-grid.js.map +1 -0
  187. package/dist/core/scanner.d.ts +59 -0
  188. package/dist/core/scanner.d.ts.map +1 -0
  189. package/dist/core/scanner.js +260 -0
  190. package/dist/core/scanner.js.map +1 -0
  191. package/dist/core/shadow.d.ts +69 -0
  192. package/dist/core/shadow.d.ts.map +1 -0
  193. package/dist/core/shadow.js +84 -0
  194. package/dist/core/shadow.js.map +1 -0
  195. package/dist/core/spatial-hash.d.ts +30 -0
  196. package/dist/core/spatial-hash.d.ts.map +1 -0
  197. package/dist/core/spatial-hash.js +64 -0
  198. package/dist/core/spatial-hash.js.map +1 -0
  199. package/dist/core/streamlines.d.ts +29 -0
  200. package/dist/core/streamlines.d.ts.map +1 -0
  201. package/dist/core/streamlines.js +70 -0
  202. package/dist/core/streamlines.js.map +1 -0
  203. package/dist/core/surface.d.ts +19 -0
  204. package/dist/core/surface.d.ts.map +1 -0
  205. package/dist/core/surface.js +21 -0
  206. package/dist/core/surface.js.map +1 -0
  207. package/dist/core/temporal.d.ts +110 -0
  208. package/dist/core/temporal.d.ts.map +1 -0
  209. package/dist/core/temporal.js +139 -0
  210. package/dist/core/temporal.js.map +1 -0
  211. package/dist/core/thermo.d.ts +48 -0
  212. package/dist/core/thermo.d.ts.map +1 -0
  213. package/dist/core/thermo.js +48 -0
  214. package/dist/core/thermo.js.map +1 -0
  215. package/dist/core/types.d.ts +610 -0
  216. package/dist/core/types.d.ts.map +1 -0
  217. package/dist/core/types.js +2 -0
  218. package/dist/core/types.js.map +1 -0
  219. package/dist/core/weights.d.ts +111 -0
  220. package/dist/core/weights.d.ts.map +1 -0
  221. package/dist/core/weights.js +128 -0
  222. package/dist/core/weights.js.map +1 -0
  223. package/dist/diagnostics/energy.d.ts +21 -0
  224. package/dist/diagnostics/energy.d.ts.map +1 -0
  225. package/dist/diagnostics/energy.js +27 -0
  226. package/dist/diagnostics/energy.js.map +1 -0
  227. package/dist/diagnostics/fields.d.ts +23 -0
  228. package/dist/diagnostics/fields.d.ts.map +1 -0
  229. package/dist/diagnostics/fields.js +30 -0
  230. package/dist/diagnostics/fields.js.map +1 -0
  231. package/dist/diagnostics/index.d.ts +46 -0
  232. package/dist/diagnostics/index.d.ts.map +1 -0
  233. package/dist/diagnostics/index.js +23 -0
  234. package/dist/diagnostics/index.js.map +1 -0
  235. package/dist/diagnostics/modes.d.ts +108 -0
  236. package/dist/diagnostics/modes.d.ts.map +1 -0
  237. package/dist/diagnostics/modes.js +181 -0
  238. package/dist/diagnostics/modes.js.map +1 -0
  239. package/dist/diagnostics/potential.d.ts +30 -0
  240. package/dist/diagnostics/potential.d.ts.map +1 -0
  241. package/dist/diagnostics/potential.js +43 -0
  242. package/dist/diagnostics/potential.js.map +1 -0
  243. package/dist/diagnostics/probes.d.ts +31 -0
  244. package/dist/diagnostics/probes.d.ts.map +1 -0
  245. package/dist/diagnostics/probes.js +61 -0
  246. package/dist/diagnostics/probes.js.map +1 -0
  247. package/dist/diagnostics/render.d.ts +49 -0
  248. package/dist/diagnostics/render.d.ts.map +1 -0
  249. package/dist/diagnostics/render.js +132 -0
  250. package/dist/diagnostics/render.js.map +1 -0
  251. package/dist/export.d.ts +18 -0
  252. package/dist/export.d.ts.map +1 -0
  253. package/dist/export.js +17 -0
  254. package/dist/export.js.map +1 -0
  255. package/dist/forces/extended.d.ts +121 -0
  256. package/dist/forces/extended.d.ts.map +1 -0
  257. package/dist/forces/extended.js +674 -0
  258. package/dist/forces/extended.js.map +1 -0
  259. package/dist/forces/index.d.ts +33 -0
  260. package/dist/forces/index.d.ts.map +1 -0
  261. package/dist/forces/index.js +237 -0
  262. package/dist/forces/index.js.map +1 -0
  263. package/dist/forces/natural.d.ts +106 -0
  264. package/dist/forces/natural.d.ts.map +1 -0
  265. package/dist/forces/natural.js +385 -0
  266. package/dist/forces/natural.js.map +1 -0
  267. package/dist/index.d.ts +59 -0
  268. package/dist/index.d.ts.map +1 -0
  269. package/dist/index.js +71 -0
  270. package/dist/index.js.map +1 -0
  271. package/dist/inspect/budget.d.ts +17 -0
  272. package/dist/inspect/budget.d.ts.map +1 -0
  273. package/dist/inspect/budget.js +19 -0
  274. package/dist/inspect/budget.js.map +1 -0
  275. package/dist/inspect/index.d.ts +10 -0
  276. package/dist/inspect/index.d.ts.map +1 -0
  277. package/dist/inspect/index.js +10 -0
  278. package/dist/inspect/index.js.map +1 -0
  279. package/dist/inspect/report.d.ts +17 -0
  280. package/dist/inspect/report.d.ts.map +1 -0
  281. package/dist/inspect/report.js +44 -0
  282. package/dist/inspect/report.js.map +1 -0
  283. package/dist/inspect/snapshot.d.ts +21 -0
  284. package/dist/inspect/snapshot.d.ts.map +1 -0
  285. package/dist/inspect/snapshot.js +30 -0
  286. package/dist/inspect/snapshot.js.map +1 -0
  287. package/dist/recipes/catalog.d.ts +51 -0
  288. package/dist/recipes/catalog.d.ts.map +1 -0
  289. package/dist/recipes/catalog.js +1496 -0
  290. package/dist/recipes/catalog.js.map +1 -0
  291. package/dist/recipes/charge.d.ts +18 -0
  292. package/dist/recipes/charge.d.ts.map +1 -0
  293. package/dist/recipes/charge.js +27 -0
  294. package/dist/recipes/charge.js.map +1 -0
  295. package/dist/recipes/compile.d.ts +93 -0
  296. package/dist/recipes/compile.d.ts.map +1 -0
  297. package/dist/recipes/compile.js +113 -0
  298. package/dist/recipes/compile.js.map +1 -0
  299. package/dist/recipes/explain.d.ts +8 -0
  300. package/dist/recipes/explain.d.ts.map +1 -0
  301. package/dist/recipes/explain.js +46 -0
  302. package/dist/recipes/explain.js.map +1 -0
  303. package/dist/recipes/gallery.d.ts +6 -0
  304. package/dist/recipes/gallery.d.ts.map +1 -0
  305. package/dist/recipes/gallery.js +6 -0
  306. package/dist/recipes/gallery.js.map +1 -0
  307. package/dist/recipes/gravity.d.ts +16 -0
  308. package/dist/recipes/gravity.d.ts.map +1 -0
  309. package/dist/recipes/gravity.js +27 -0
  310. package/dist/recipes/gravity.js.map +1 -0
  311. package/dist/recipes/index.d.ts +18 -0
  312. package/dist/recipes/index.d.ts.map +1 -0
  313. package/dist/recipes/index.js +36 -0
  314. package/dist/recipes/index.js.map +1 -0
  315. package/dist/recipes/intent.d.ts +44 -0
  316. package/dist/recipes/intent.d.ts.map +1 -0
  317. package/dist/recipes/intent.js +46 -0
  318. package/dist/recipes/intent.js.map +1 -0
  319. package/dist/recipes/schema.d.ts +103 -0
  320. package/dist/recipes/schema.d.ts.map +1 -0
  321. package/dist/recipes/schema.js +123 -0
  322. package/dist/recipes/schema.js.map +1 -0
  323. package/dist/recipes/wayfinding.d.ts +39 -0
  324. package/dist/recipes/wayfinding.d.ts.map +1 -0
  325. package/dist/recipes/wayfinding.js +77 -0
  326. package/dist/recipes/wayfinding.js.map +1 -0
  327. package/dist/semantic/index.d.ts +13 -0
  328. package/dist/semantic/index.d.ts.map +1 -0
  329. package/dist/semantic/index.js +31 -0
  330. package/dist/semantic/index.js.map +1 -0
  331. package/dist/semantic/layers.d.ts +24 -0
  332. package/dist/semantic/layers.d.ts.map +1 -0
  333. package/dist/semantic/layers.js +27 -0
  334. package/dist/semantic/layers.js.map +1 -0
  335. package/dist/semantic/materials.d.ts +20 -0
  336. package/dist/semantic/materials.d.ts.map +1 -0
  337. package/dist/semantic/materials.js +17 -0
  338. package/dist/semantic/materials.js.map +1 -0
  339. package/dist/semantic/states.d.ts +11 -0
  340. package/dist/semantic/states.d.ts.map +1 -0
  341. package/dist/semantic/states.js +26 -0
  342. package/dist/semantic/states.js.map +1 -0
  343. package/dist/visual/channels.d.ts +71 -0
  344. package/dist/visual/channels.d.ts.map +1 -0
  345. package/dist/visual/channels.js +70 -0
  346. package/dist/visual/channels.js.map +1 -0
  347. package/dist/visual/index.d.ts +39 -0
  348. package/dist/visual/index.d.ts.map +1 -0
  349. package/dist/visual/index.js +30 -0
  350. package/dist/visual/index.js.map +1 -0
  351. package/dist/visual/lint.d.ts +41 -0
  352. package/dist/visual/lint.d.ts.map +1 -0
  353. package/dist/visual/lint.js +58 -0
  354. package/dist/visual/lint.js.map +1 -0
  355. package/dist/visual/mapping.d.ts +13 -0
  356. package/dist/visual/mapping.d.ts.map +1 -0
  357. package/dist/visual/mapping.js +43 -0
  358. package/dist/visual/mapping.js.map +1 -0
  359. package/dist/visual/semantic-text.d.ts +28 -0
  360. package/dist/visual/semantic-text.d.ts.map +1 -0
  361. package/dist/visual/semantic-text.js +36 -0
  362. package/dist/visual/semantic-text.js.map +1 -0
  363. package/dist/visual/tokens.d.ts +23 -0
  364. package/dist/visual/tokens.d.ts.map +1 -0
  365. package/dist/visual/tokens.js +54 -0
  366. package/dist/visual/tokens.js.map +1 -0
  367. package/dist/visual/visualization.d.ts +31 -0
  368. package/dist/visual/visualization.d.ts.map +1 -0
  369. package/dist/visual/visualization.js +47 -0
  370. package/dist/visual/visualization.js.map +1 -0
  371. package/package.json +60 -0
@@ -0,0 +1,375 @@
1
+ /**
2
+ * The integrator — advances the field one tick (§2.2, §7).
3
+ *
4
+ * For each free particle: apply DOM-body forces (§4), the formation bias (§7),
5
+ * then integrate and damp. Under first-class mass (§21.3) each additive body force is
6
+ * scaled by `1/m` as it applies, while velocity-replacing (`kinematic`) forces are left
7
+ * untouched. Reduced motion (`dt = 0`) freezes the sim (§18).
8
+ */
9
+ import { accretionTarget } from "./formations.js";
10
+ import { waveYat, waveSlope } from "./currents.js";
11
+ import { netField } from "./streamlines.js";
12
+ import { screenFactor } from "./math.js";
13
+ import { classifyBodyTokens } from "../config/forces.config.js";
14
+ export const FRICTION = 0.95;
15
+ export const HEAT_DECAY = 0.972;
16
+ const EDGE = 10;
17
+ function passes(conds, b, p, env) {
18
+ if (!b.when)
19
+ return true;
20
+ const fn = conds[b.when];
21
+ return fn ? fn(b, p, env) : true;
22
+ }
23
+ /**
24
+ * The body's classified token sets (the modifier contract, workover v0.3). The scanner fills
25
+ * `b.classified` at parse time; bodies built elsewhere (conformance, tests, shadow paths) get
26
+ * it memoized here on first touch — `tokens` never changes after construction, so the memo is
27
+ * safe. The integrator iterates modifiers in the formalized order `spotlight → screen →
28
+ * resonate`, then the core forces in authored order, then sources (the source pass).
29
+ */
30
+ function classified(b) {
31
+ return b.classified ?? (b.classified = classifyBodyTokens(b.tokens));
32
+ }
33
+ /**
34
+ * Apply one force to a particle, honouring first-class mass (§21.3): an *additive* force's
35
+ * velocity change is scaled by `1/m` (a = F/m, so heavier matter moves less), while a
36
+ * `kinematic` force (a reflection / rotation / relaunch) sets velocity outright and is left
37
+ * unscaled. `inv === 1` (the default, `m = 1`) is the identity path either way. The z lane is
38
+ * scaled identically so depth-enabled fields keep `a = F/m` on all three axes (a heavy particle
39
+ * pushed off-plane accelerates as little along z as it does in x/y).
40
+ */
41
+ function applyForce(f, b, p, env, inv) {
42
+ if (inv === 1 || f.kinematic) {
43
+ f.apply(b, p, env);
44
+ return;
45
+ }
46
+ const bvx = p.vx;
47
+ const bvy = p.vy;
48
+ const bvz = p.vz ?? 0;
49
+ f.apply(b, p, env);
50
+ p.vx = bvx + (p.vx - bvx) * inv;
51
+ p.vy = bvy + (p.vy - bvy) * inv;
52
+ // only rescale z when the force actually engaged the lane — never materialize a spurious 0
53
+ // on a flat (z-less) particle.
54
+ if (p.vz !== undefined)
55
+ p.vz = bvz + (p.vz - bvz) * inv;
56
+ }
57
+ export function step(input) {
58
+ const { store, bodies, env, forces, conditions, waves } = input;
59
+ const dt = env.dt;
60
+ if (dt === 0)
61
+ return;
62
+ const { W, H, form } = env;
63
+ // expose the net structure field so field-following forces (`fieldflow`) can read the
64
+ // superposition of every body's field() — the same vector the streamlines view draws.
65
+ env.fieldAt = (x, y) => netField(bodies, forces, x, y);
66
+ for (const b of bodies) {
67
+ b.count = 0;
68
+ // thermodynamic accumulators (workover v0.3 §"Metrics") share the density window/cadence.
69
+ const th = b.thermo;
70
+ if (th) {
71
+ th.n = 0;
72
+ th.sx = 0;
73
+ th.sy = 0;
74
+ th.ss = 0;
75
+ th.ss2 = 0;
76
+ th.sh = 0;
77
+ }
78
+ }
79
+ // visible `screen` bodies (workover v0.3): each damps OTHER bodies' forces on matter inside
80
+ // its range (quiet zones / text shielding). No screens on the page (the common case) ⇒ this
81
+ // stays null and the whole pass is skipped — zero cost and zero behavior change.
82
+ let screens = null;
83
+ for (const b of bodies) {
84
+ if (b.vis && b.tokens.length > 0 && classified(b).modifiers.indexOf('screen') >= 0)
85
+ (screens ??= []).push(b);
86
+ }
87
+ const screenFall = screens ? new Array(screens.length) : null;
88
+ const hasWaves = !!waves && waves.length > 0;
89
+ const hasBodies = bodies.length > 0;
90
+ let dead = null; // mortal (spawned) matter that expired this tick
91
+ // the accretion target for `conv` — the first visible sink body (§7).
92
+ const conv = form.conv > 0.02 ? accretionTarget(bodies) : null;
93
+ // the optional z lane (z-axis.md): D = 0 — the default — is the flat field, where
94
+ // every z term below is exactly 0 and the 2D behavior is preserved bit-for-bit.
95
+ const D = env.D ?? 0;
96
+ for (const p of store.particles) {
97
+ // captured matter is held inside a sink core, drifting to it (§6.9). The core
98
+ // lives on the z = 0 plane, so held matter also settles flat.
99
+ if (p.cap) {
100
+ p.x += (p.cap.cx - p.x) * 0.18;
101
+ p.y += (p.cap.cy - p.y) * 0.18;
102
+ if (p.z)
103
+ p.z += -p.z * 0.18;
104
+ continue;
105
+ }
106
+ // normalize the optional lane once: after this the lane is concrete numbers for
107
+ // the rest of this particle's frame (forces and the integrate step write through).
108
+ if (p.z === undefined)
109
+ p.z = 0;
110
+ if (p.vz === undefined)
111
+ p.vz = 0;
112
+ const pz = p.z;
113
+ // wave current (§2.3): near a wave line, drift along its slope like debris.
114
+ if (hasWaves) {
115
+ let near = null;
116
+ let nd = 1e9;
117
+ for (const w of waves) {
118
+ const d = Math.abs(waveYat(w, p.x, env.t, H) - p.y);
119
+ if (d < nd) {
120
+ nd = d;
121
+ near = w;
122
+ }
123
+ }
124
+ if (near && nd < 70) {
125
+ p.vx += near.dir * 0.035 * (1 - nd / 70);
126
+ p.vy += waveSlope(near, p.x, env.t) * 0.1 * (1 - nd / 70);
127
+ }
128
+ }
129
+ // formation currents (§7), before the body forces: a lateral lane, an
130
+ // even-scatter pull toward a per-particle target, and convergence to the core.
131
+ if (form.driftX)
132
+ p.vx += form.driftX * 0.02;
133
+ if (form.spread > 0.02) {
134
+ const gx = p.gx ?? 0.5;
135
+ const gy = p.gy ?? 0.5;
136
+ const tx = ((gx + env.frameN * 0.00004) % 1) * W;
137
+ const ty = gy * H;
138
+ p.vx += (tx - p.x) * 0.0006 * form.spread;
139
+ p.vy += (ty - p.y) * 0.0006 * form.spread;
140
+ if (D > 0)
141
+ p.vz += ((p.gz ?? 0.5) * D - pz) * 0.0006 * form.spread;
142
+ }
143
+ if (conv) {
144
+ const cdx = conv.cx - p.x;
145
+ const cdy = conv.cy - p.y;
146
+ const cdz = -pz; // the sink core sits on the z = 0 plane
147
+ const cd = Math.hypot(cdx, cdy, cdz) || 1;
148
+ p.vx += (cdx / cd) * form.conv * 0.06;
149
+ p.vy += (cdy / cd) * form.conv * 0.06;
150
+ p.vz += (cdz / cd) * form.conv * 0.06;
151
+ }
152
+ // DOM body forces — the page's elements move the field (§4).
153
+ if (hasBodies) {
154
+ // per-particle screen factors (workover v0.3): one distance per screen body, computed
155
+ // once and reused across every body's pass below.
156
+ if (screens) {
157
+ for (let i = 0; i < screens.length; i++) {
158
+ const s = screens[i];
159
+ const sdx = s.cx - p.x;
160
+ const sdy = s.cy - p.y;
161
+ screenFall[i] = screenFactor(Math.sqrt(sdx * sdx + sdy * sdy), s.range, s.strength, s.screenMin ?? 0);
162
+ }
163
+ }
164
+ // first-class mass (§21.3): an additive force's Δv is scaled by 1/m as it applies
165
+ // (see applyForce); kinematic forces set velocity outright and are left unscaled.
166
+ const inv = p.m !== 1 && p.m > 0 ? 1 / p.m : 1;
167
+ for (const b of bodies) {
168
+ if (!b.vis || b.tokens.length === 0)
169
+ continue;
170
+ // shaped sources (§ Stage C): reference the nearest point on the element's box, not
171
+ // its centre, so matter shells the shape. Clamp is inlined (no allocation in the hot
172
+ // loop); inside the box dx=dy=0 → no directional pull, the right no-op.
173
+ let dx;
174
+ let dy;
175
+ if (b.shaped) {
176
+ const lx = b.cx - b.hw;
177
+ const rx = b.cx + b.hw;
178
+ const ty = b.cy - b.hh;
179
+ const by = b.cy + b.hh;
180
+ const nx = p.x < lx ? lx : p.x > rx ? rx : p.x;
181
+ const ny = p.y < ty ? ty : p.y > by ? by : p.y;
182
+ dx = nx - p.x;
183
+ dy = ny - p.y;
184
+ }
185
+ else {
186
+ dx = b.cx - p.x;
187
+ dy = b.cy - p.y;
188
+ }
189
+ // optional z lane (z-axis.md): bodies live on the z = 0 plane, so the z leg of
190
+ // the particle→body vector is just −p.z — exactly 0 in a flat field. Matter
191
+ // that drifts into the volume is pulled back toward the plane by the same
192
+ // falloffs that pull it across it.
193
+ const dz = -p.z;
194
+ const d2 = dx * dx + dy * dy + dz * dz;
195
+ // range cull: a ranged body can't reach past ~1.6× its range (the largest
196
+ // on-state multiplier, tether's 1.575×). Skip the sqrt, the modifier pass,
197
+ // and every apply for matter beyond it. range 0 = global → never culled.
198
+ if (b.range > 0 && d2 >= b.range * b.range * 2.56)
199
+ continue;
200
+ const d = Math.sqrt(d2);
201
+ // density sampling for two-way feedback (engine bookkeeping, ungated, §8) — and the
202
+ // thermodynamic sample (workover v0.3 §"Metrics"), same window, same cadence.
203
+ if (b.feedback && d < b.range * 0.5) {
204
+ b.count += 1 - d / (b.range * 0.5);
205
+ const th = (b.thermo ??= { n: 0, sx: 0, sy: 0, ss: 0, ss2: 0, sh: 0 });
206
+ const s2 = p.vx * p.vx + p.vy * p.vy;
207
+ th.n++;
208
+ th.sx += p.vx;
209
+ th.sy += p.vy;
210
+ th.ss += Math.sqrt(s2);
211
+ th.ss2 += s2;
212
+ th.sh += p.heat;
213
+ }
214
+ if (b.when && !passes(conditions, b, p, env))
215
+ continue;
216
+ env.dx = dx;
217
+ env.dy = dy;
218
+ env.dz = dz;
219
+ env.dist = d < 1 ? 1 : d;
220
+ // modifier pass (§20.3, formalized by the workover v0.3 modifier contract): the body's
221
+ // OWN modifiers evaluate in the contract order `spotlight → screen → resonate`
222
+ // (cls.modifiers is pre-sorted), then any custom modify() hooks on its other tokens
223
+ // (dynamic discovery — unchanged behavior for registry-extended forces). spotlight
224
+ // gates siblings, resonate scales their strength; `screen` contributes through the
225
+ // cross-body factor below (a screen body never attenuates its own siblings). Gates OR
226
+ // and strength factors multiply, so the composed value is order-independent — the
227
+ // order is the *contract* (pinned for future modifiers where it will matter).
228
+ const cls = classified(b);
229
+ let sMul = 1;
230
+ let gated = false;
231
+ let hasModifier = false;
232
+ for (const tok of cls.modifiers) {
233
+ const mod = forces[tok]?.modify;
234
+ if (!mod)
235
+ continue;
236
+ hasModifier = true;
237
+ const m = mod(b, p, env);
238
+ if (m.strength != null)
239
+ sMul *= m.strength;
240
+ if (m.gate)
241
+ gated = true;
242
+ }
243
+ for (const tok of cls.forces) {
244
+ const mod = forces[tok]?.modify;
245
+ if (!mod)
246
+ continue;
247
+ hasModifier = true;
248
+ const m = mod(b, p, env);
249
+ if (m.strength != null)
250
+ sMul *= m.strength;
251
+ if (m.gate)
252
+ gated = true;
253
+ }
254
+ if (gated)
255
+ continue; // spotlight cone excludes this particle
256
+ // `screen` (workover v0.3): OTHER bodies' quiet zones damp this body's force on this
257
+ // particle. Factors were computed once per particle above; a screen never damps itself.
258
+ let screenMul = 1;
259
+ if (screens) {
260
+ for (let i = 0; i < screens.length; i++) {
261
+ if (screens[i] !== b)
262
+ screenMul *= screenFall[i];
263
+ }
264
+ }
265
+ // conserved-attention multiplier (§2.4): a page-level effective strength,
266
+ // 1 = neutral (the default, so the live field is untouched until opted in).
267
+ const attn = b.attn ?? 1;
268
+ // the composed effective-strength multiplier: resonate's S(t) × the attention
269
+ // budget × the screen attenuation. 1 ⇒ the untouched fast path.
270
+ const mul = sMul * attn * screenMul;
271
+ if (!hasModifier && mul === 1) {
272
+ for (const tok of b.tokens) {
273
+ const f = forces[tok];
274
+ if (f)
275
+ applyForce(f, b, p, env, inv);
276
+ }
277
+ }
278
+ else if (!hasModifier) {
279
+ const origS = b.strength;
280
+ b.strength = origS * mul;
281
+ for (const tok of b.tokens) {
282
+ const f = forces[tok];
283
+ if (f)
284
+ applyForce(f, b, p, env, inv);
285
+ }
286
+ b.strength = origS;
287
+ }
288
+ else {
289
+ const origS = b.strength;
290
+ b.strength = origS * mul;
291
+ for (const tok of b.tokens) {
292
+ const f = forces[tok];
293
+ if (f && !f.modify)
294
+ applyForce(f, b, p, env, inv);
295
+ }
296
+ b.strength = origS;
297
+ }
298
+ }
299
+ }
300
+ // global safety cap (§20.10): no token or composite may drive a free particle past
301
+ // c (the unit system's "speed of light"). The natural primitives self-clamp; this
302
+ // enforces it for *every* force. A non-finite velocity slips the `> c²` test — the
303
+ // conformance safety sweep is what catches a NaN-producing force.
304
+ const cap = env.c;
305
+ const sp2 = p.vx * p.vx + p.vy * p.vy + p.vz * p.vz;
306
+ if (sp2 > cap * cap) {
307
+ const k = cap / Math.sqrt(sp2);
308
+ p.vx *= k;
309
+ p.vy *= k;
310
+ p.vz *= k;
311
+ }
312
+ // integrate, then damp (§2.2). The z lane integrates identically — inert at 0.
313
+ p.x += p.vx * dt;
314
+ p.y += p.vy * dt;
315
+ p.z += p.vz * dt;
316
+ p.vx *= FRICTION;
317
+ p.vy *= FRICTION;
318
+ p.vz *= FRICTION;
319
+ // wander (after damping, so it stays lively): a periodic brownian jitter
320
+ // every 40 frames, plus a smooth curl-noise eddy (§7).
321
+ if (env.frameN % 40 === 0 && form.wander > 0) {
322
+ const wsc = 0.05 * form.wander;
323
+ p.vx += ((env.rng ?? Math.random)() - 0.5) * wsc;
324
+ p.vy += ((env.rng ?? Math.random)() - 0.5) * wsc;
325
+ // the brownian kick gains a z leg in a volume — through the same injectable rng (#371)
326
+ if (D > 0)
327
+ p.vz += ((env.rng ?? Math.random)() - 0.5) * wsc;
328
+ }
329
+ if (form.wander > 0.05) {
330
+ const cn = (Math.sin(p.x * 0.0032 + env.t * 0.12) + Math.cos(p.y * 0.0034 - env.t * 0.15)) *
331
+ Math.PI;
332
+ p.vx += Math.cos(cn) * 0.013 * form.wander;
333
+ p.vy += Math.sin(cn) * 0.013 * form.wander;
334
+ }
335
+ p.heat *= HEAT_DECAY;
336
+ // mortal matter ages (the class-[S] sink): spawned particles carry a finite `age`
337
+ // and despawn at ≤ 0, so a continuous source stays budgeted. Immortal base-field
338
+ // matter (age undefined) is untouched — the conserved field is unchanged.
339
+ if (p.age != null) {
340
+ p.age -= dt;
341
+ if (p.age <= 0)
342
+ (dead ??= []).push(p);
343
+ }
344
+ // toroidal wrap at the edges (z wraps only in a depth > 0 volume).
345
+ if (p.x < -EDGE)
346
+ p.x = W + EDGE;
347
+ else if (p.x > W + EDGE)
348
+ p.x = -EDGE;
349
+ if (p.y < -EDGE)
350
+ p.y = H + EDGE;
351
+ else if (p.y > H + EDGE)
352
+ p.y = -EDGE;
353
+ if (D > 0) {
354
+ if (p.z < -EDGE)
355
+ p.z = D + EDGE;
356
+ else if (p.z > D + EDGE)
357
+ p.z = -EDGE;
358
+ }
359
+ }
360
+ // class-[S] sources (§20.1): a body-level pass *after* the per-particle loop, so a
361
+ // source emits matter once per frame (not once per existing particle) via env.spawn.
362
+ if (hasBodies) {
363
+ for (const b of bodies) {
364
+ if (!b.vis || b.tokens.length === 0)
365
+ continue;
366
+ for (const tok of b.tokens)
367
+ forces[tok]?.source?.(b, env);
368
+ }
369
+ }
370
+ // remove expired mortal matter (swap-remove is O(1); order is not significant).
371
+ if (dead)
372
+ for (const p of dead)
373
+ store.remove(p);
374
+ }
375
+ //# sourceMappingURL=integrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrator.js","sourceRoot":"","sources":["../../src/core/integrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /** Small, dependency-free math helpers. */
2
+ export type RGB = [number, number, number];
3
+ export declare const clamp: (v: number, lo: number, hi: number) => number;
4
+ export declare const lerp: (a: number, b: number, t: number) => number;
5
+ /** distance between two points. */
6
+ export declare const dist: (ax: number, ay: number, bx: number, by: number) => number;
7
+ /** parse `#rrggbb` (or `#rgb`) → `[r, g, b]`, falling back to a cool blue. */
8
+ export declare function hexToRgb(hex: string): RGB;
9
+ /** The resting (cool) and energized (warm) ends of the free-particle ramp (§20.8). */
10
+ export declare const COOL: RGB;
11
+ export declare const WARM: RGB;
12
+ /**
13
+ * Free-particle color: cool centre → warm edge by `rs` (= normalized dist²),
14
+ * then blended toward the travelling `accent` by `heat` (§20.8 / the prototype).
15
+ */
16
+ export declare function particleRGB(rs: number, heat: number, accent: RGB): RGB;
17
+ /** `[r, g, b]` → `#rrggbb`. */
18
+ export declare function rgbToHex([r, g, b]: RGB): string;
19
+ /** Lerp two hex colors by `t` ∈ [0,1] — conserved pigment mixing (§20.8). */
20
+ export declare function mixHex(a: string, b: string, t: number): string;
21
+ /** Sample a color ramp at `frac` ∈ [0,1] — the accent journey (§9). */
22
+ export declare function sampleStops(stops: readonly RGB[], frac: number): RGB;
23
+ /**
24
+ * The `screen` attenuation factor (workover v0.3 §"`screen` modifier") — pure:
25
+ *
26
+ * falloff = max(0, 1 − d/range)²
27
+ * screenFactor = clamp(1 − S·falloff, min, 1)
28
+ *
29
+ * A body carrying the `screen` token damps OTHER bodies' forces on matter within its
30
+ * range by this factor (applied in the integrator's force pass). Smooth at the edge
31
+ * (falloff → 0 as d → range; no hard cliff); `min` clamps the floor (`data-screen-min`,
32
+ * default 0 = full cancellation at the core is allowed); a non-positive range is inert
33
+ * (returns 1 — screens are always local, never global), which also guarantees no NaN
34
+ * at zero range.
35
+ */
36
+ export declare function screenFactor(d: number, range: number, strength: number, min?: number): number;
37
+ //# sourceMappingURL=math.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../../src/core/math.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAE3C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE3C,eAAO,MAAM,KAAK,GAAI,GAAG,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,MAAM,KAAG,MAC3B,CAAC;AAEhC,eAAO,MAAM,IAAI,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,KAAG,MAAyB,CAAC;AAEjF,mCAAmC;AACnC,eAAO,MAAM,IAAI,GAAI,IAAI,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,MAAM,KAAG,MACxC,CAAC;AAE/B,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAMzC;AAED,sFAAsF;AACtF,eAAO,MAAM,IAAI,EAAE,GAAqB,CAAC;AACzC,eAAO,MAAM,IAAI,EAAE,GAAoB,CAAC;AAExC;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,GAAG,CAQtE;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,MAAM,CAG/C;AAED,6EAA6E;AAC7E,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAK9D;AAED,uEAAuE;AACvE,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,GAAG,CASpE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAI,GAAG,MAAM,CAMxF"}
@@ -0,0 +1,77 @@
1
+ /** Small, dependency-free math helpers. */
2
+ export const clamp = (v, lo, hi) => v < lo ? lo : v > hi ? hi : v;
3
+ export const lerp = (a, b, t) => a + (b - a) * t;
4
+ /** distance between two points. */
5
+ export const dist = (ax, ay, bx, by) => Math.hypot(ax - bx, ay - by);
6
+ /** parse `#rrggbb` (or `#rgb`) → `[r, g, b]`, falling back to a cool blue. */
7
+ export function hexToRgb(hex) {
8
+ const h = hex.replace('#', '');
9
+ const x = h.length === 3 ? h.replace(/./g, (c) => c + c) : h;
10
+ const n = Number.parseInt(x.slice(0, 6), 16);
11
+ if (Number.isNaN(n))
12
+ return [77, 163, 255];
13
+ return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
14
+ }
15
+ /** The resting (cool) and energized (warm) ends of the free-particle ramp (§20.8). */
16
+ export const COOL = [200, 224, 255];
17
+ export const WARM = [255, 122, 69];
18
+ /**
19
+ * Free-particle color: cool centre → warm edge by `rs` (= normalized dist²),
20
+ * then blended toward the travelling `accent` by `heat` (§20.8 / the prototype).
21
+ */
22
+ export function particleRGB(rs, heat, accent) {
23
+ let r = COOL[0] + (WARM[0] - COOL[0]) * rs;
24
+ let g = COOL[1] + (WARM[1] - COOL[1]) * rs;
25
+ let b = COOL[2] + (WARM[2] - COOL[2]) * rs;
26
+ r += (accent[0] - r) * heat;
27
+ g += (accent[1] - g) * heat;
28
+ b += (accent[2] - b) * heat;
29
+ return [r, g, b];
30
+ }
31
+ /** `[r, g, b]` → `#rrggbb`. */
32
+ export function rgbToHex([r, g, b]) {
33
+ const h = (v) => clamp(Math.round(v), 0, 255).toString(16).padStart(2, '0');
34
+ return `#${h(r)}${h(g)}${h(b)}`;
35
+ }
36
+ /** Lerp two hex colors by `t` ∈ [0,1] — conserved pigment mixing (§20.8). */
37
+ export function mixHex(a, b, t) {
38
+ const [ar, ag, ab] = hexToRgb(a);
39
+ const [br, bg, bb] = hexToRgb(b);
40
+ const k = t < 0 ? 0 : t > 1 ? 1 : t;
41
+ return rgbToHex([ar + (br - ar) * k, ag + (bg - ag) * k, ab + (bb - ab) * k]);
42
+ }
43
+ /** Sample a color ramp at `frac` ∈ [0,1] — the accent journey (§9). */
44
+ export function sampleStops(stops, frac) {
45
+ if (stops.length === 0)
46
+ return [77, 163, 255];
47
+ if (stops.length === 1)
48
+ return stops[0];
49
+ const f = clamp(frac, 0, 1) * (stops.length - 1);
50
+ const i = Math.min(stops.length - 2, Math.floor(f));
51
+ const t = f - i;
52
+ const a = stops[i];
53
+ const b = stops[i + 1];
54
+ return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];
55
+ }
56
+ /**
57
+ * The `screen` attenuation factor (workover v0.3 §"`screen` modifier") — pure:
58
+ *
59
+ * falloff = max(0, 1 − d/range)²
60
+ * screenFactor = clamp(1 − S·falloff, min, 1)
61
+ *
62
+ * A body carrying the `screen` token damps OTHER bodies' forces on matter within its
63
+ * range by this factor (applied in the integrator's force pass). Smooth at the edge
64
+ * (falloff → 0 as d → range; no hard cliff); `min` clamps the floor (`data-screen-min`,
65
+ * default 0 = full cancellation at the core is allowed); a non-positive range is inert
66
+ * (returns 1 — screens are always local, never global), which also guarantees no NaN
67
+ * at zero range.
68
+ */
69
+ export function screenFactor(d, range, strength, min = 0) {
70
+ if (!(range > 0))
71
+ return 1;
72
+ const fall = Math.max(0, 1 - d / range);
73
+ const factor = 1 - strength * fall * fall;
74
+ const floor = Math.min(Math.max(min, 0), 1);
75
+ return factor < floor ? floor : factor > 1 ? 1 : factor;
76
+ }
77
+ //# sourceMappingURL=math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"math.js","sourceRoot":"","sources":["../../src/core/math.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Micro-reactions (§23) — the energy removed at an interaction is rendered as a
3
+ * reaction (sparks/flash). "Energy isn't lost — it's spent on spectacle." (§23.1)
4
+ */
5
+ import type { Vec2 } from './types.ts';
6
+ /** Kinetic energy removed at an interaction: ½·m·(|v_before|² − |v_after|²) (§23.2). */
7
+ export declare function energyDelta(m: number, vBefore: number, vAfter: number): number;
8
+ /** Reaction intensity from removed energy: clamp(k·ΔE, 0, iMax) (§23.2). */
9
+ export declare function reactionIntensity(dE: number, k?: number, iMax?: number): number;
10
+ /** Spark count for a reaction of a given power (§23.3, the wall exemplar). */
11
+ export declare function sparkCount(power: number, rand?: () => number): number;
12
+ /**
13
+ * The recoil impulse on the *other* agent in a transfer — equal-and-opposite,
14
+ * split by its mass: Δv = −Δp / m (§23.5). Used by `collide`/mover reactions
15
+ * (Phase 6). A heavier agent barely budges.
16
+ */
17
+ export declare function recoilImpulse(dpx: number, dpy: number, mOther: number): Vec2;
18
+ /**
19
+ * A discrete radial burst impulse (§11) — the velocity kick and heat a one-shot
20
+ * `field.burst(x, y)` imparts to matter at offset `(dx, dy[, dz])` from the blast,
21
+ * falling off linearly to nothing at radius `r`; outside `r` it's inert. `dz` is the
22
+ * optional z lane (z-axis.md) — omit it (or pass 0) for the flat-field impulse, which
23
+ * is bit-identical to the 2D form. Pure: the field's `burst` glue applies this per
24
+ * particle and tears nearby bound matter loose.
25
+ */
26
+ export declare function burstImpulse(dx: number, dy: number, r: number, power?: number, dz?: number): {
27
+ vx: number;
28
+ vy: number;
29
+ vz: number;
30
+ heat: number;
31
+ };
32
+ //# sourceMappingURL=reactions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactions.d.ts","sourceRoot":"","sources":["../../src/core/reactions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,wFAAwF;AACxF,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,SAAI,EAAE,IAAI,SAAM,GAAG,MAAM,CAGvE;AAED,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,MAAoB,GAAG,MAAM,CAElF;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAK5E;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,CAAC,EAAE,MAAM,EACT,KAAK,SAAI,EACT,EAAE,SAAI,GACL;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAMtD"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Micro-reactions (§23) — the energy removed at an interaction is rendered as a
3
+ * reaction (sparks/flash). "Energy isn't lost — it's spent on spectacle." (§23.1)
4
+ */
5
+ /** Kinetic energy removed at an interaction: ½·m·(|v_before|² − |v_after|²) (§23.2). */
6
+ export function energyDelta(m, vBefore, vAfter) {
7
+ return 0.5 * m * (vBefore * vBefore - vAfter * vAfter);
8
+ }
9
+ /** Reaction intensity from removed energy: clamp(k·ΔE, 0, iMax) (§23.2). */
10
+ export function reactionIntensity(dE, k = 1, iMax = 2.4) {
11
+ const i = k * dE;
12
+ return i < 0 ? 0 : i > iMax ? iMax : i;
13
+ }
14
+ /** Spark count for a reaction of a given power (§23.3, the wall exemplar). */
15
+ export function sparkCount(power, rand = Math.random) {
16
+ return 3 + Math.floor(rand() * (power > 0 ? power : 1) * 3);
17
+ }
18
+ /**
19
+ * The recoil impulse on the *other* agent in a transfer — equal-and-opposite,
20
+ * split by its mass: Δv = −Δp / m (§23.5). Used by `collide`/mover reactions
21
+ * (Phase 6). A heavier agent barely budges.
22
+ */
23
+ export function recoilImpulse(dpx, dpy, mOther) {
24
+ const m = mOther > 0 ? mOther : 1;
25
+ // `+ 0` normalizes a signed-zero result (−0 → 0) so equal-and-opposite
26
+ // impulses compare cleanly (deepStrictEqual treats −0 and 0 as distinct).
27
+ return { x: -dpx / m + 0, y: -dpy / m + 0 };
28
+ }
29
+ /**
30
+ * A discrete radial burst impulse (§11) — the velocity kick and heat a one-shot
31
+ * `field.burst(x, y)` imparts to matter at offset `(dx, dy[, dz])` from the blast,
32
+ * falling off linearly to nothing at radius `r`; outside `r` it's inert. `dz` is the
33
+ * optional z lane (z-axis.md) — omit it (or pass 0) for the flat-field impulse, which
34
+ * is bit-identical to the 2D form. Pure: the field's `burst` glue applies this per
35
+ * particle and tears nearby bound matter loose.
36
+ */
37
+ export function burstImpulse(dx, dy, r, power = 6, dz = 0) {
38
+ const d = Math.hypot(dx, dy, dz) || 1;
39
+ if (d >= r)
40
+ return { vx: 0, vy: 0, vz: 0, heat: 0 };
41
+ const falloff = 1 - d / r;
42
+ const f = falloff * power;
43
+ return { vx: (dx / d) * f, vy: (dy / d) * f, vz: (dz / d) * f, heat: falloff * 0.9 };
44
+ }
45
+ //# sourceMappingURL=reactions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactions.js","sourceRoot":"","sources":["../../src/core/reactions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,wFAAwF;AACxF,MAAM,UAAU,WAAW,CAAC,CAAS,EAAE,OAAe,EAAE,MAAc;IACpE,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC;AACzD,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,iBAAiB,CAAC,EAAU,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,GAAG;IAC7D,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IACjB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,OAAqB,IAAI,CAAC,MAAM;IACxE,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,GAAW,EAAE,MAAc;IACpE,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,uEAAuE;IACvE,0EAA0E;IAC1E,OAAO,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;AAC9C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,EAAU,EACV,EAAU,EACV,CAAS,EACT,KAAK,GAAG,CAAC,EACT,EAAE,GAAG,CAAC;IAEN,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACpD,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,CAAC,GAAG,OAAO,GAAG,KAAK,CAAC;IAC1B,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,GAAG,GAAG,EAAE,CAAC;AACvF,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The force + condition registry (§4). The engine owns the loop; forces and
3
+ * conditions register here. Built-in conditions (§5) are seeded automatically.
4
+ */
5
+ import type { Condition, ConditionRegistry, Force, ForceRegistry } from './types.ts';
6
+ export interface Registry {
7
+ readonly forces: ForceRegistry;
8
+ readonly conditions: ConditionRegistry;
9
+ force(f: Force): void;
10
+ condition(id: string, fn: Condition): void;
11
+ }
12
+ export declare function createRegistry(): Registry;
13
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGrF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI,CAAC;CAC5C;AAED,wBAAgB,cAAc,IAAI,QAAQ,CAazC"}