@reicek/neataptic-ts 0.1.21 → 0.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. package/.github/agents/boundary-mapper.agent.md +31 -0
  2. package/.github/agents/docs-scout.agent.md +29 -0
  3. package/.github/agents/plan-scout.agent.md +31 -0
  4. package/.github/agents/solid-split.agent.md +143 -0
  5. package/.github/copilot-instructions.md +119 -0
  6. package/.github/skills/solid-split-playbook/SKILL.md +220 -0
  7. package/.github/skills/solid-split-playbook/assets/docs-checklist.md +34 -0
  8. package/.github/skills/solid-split-playbook/assets/split-plan-template.md +48 -0
  9. package/.github/skills/solid-split-playbook/assets/split-workflow-checklist.md +51 -0
  10. package/.github/skills/trace-analyzer-extension/SKILL.md +63 -0
  11. package/.github/skills/trace-analyzer-extension/assets/extension-checklist.md +24 -0
  12. package/.github/skills/trace-analyzer-extension/references/analyzer-extension-workflow.md +101 -0
  13. package/.github/skills/trace-audit-reporting/SKILL.md +96 -0
  14. package/.github/skills/trace-audit-reporting/assets/performance-report-template.md +123 -0
  15. package/.github/skills/trace-audit-reporting/references/trace-analysis-workflow.md +132 -0
  16. package/package.json +7 -3
  17. package/plans/ES2023 migration +13 -8
  18. package/plans/Evolution_Training_Interoperability_Contracts.md +1 -1
  19. package/plans/Flappy_Bird_Folder_Documentation_Pass.md +53 -0
  20. package/plans/Flappy_Evolution_Worker_Documentation_Pass.md +58 -0
  21. package/plans/Interactive_Examples_and_Learning_Path.md +10 -2
  22. package/plans/Memory_Optimization.md +3 -3
  23. package/plans/README.md +63 -0
  24. package/plans/Roadmap.md +15 -3
  25. package/plans/asciiMaze_SOLID_split.done.md +130 -0
  26. package/plans/flappy_bird_SOLID_split.done.md +67 -0
  27. package/scripts/analyze-trace.ts +590 -0
  28. package/scripts/assets/theme.css +221 -34
  29. package/scripts/copy-examples.mjs +9 -5
  30. package/scripts/export-onnx.mjs +3 -3
  31. package/scripts/generate-bench-tables.mjs +10 -10
  32. package/scripts/generate-bench-tables.ts +10 -10
  33. package/scripts/generate-docs.ts +1415 -449
  34. package/scripts/render-docs-html.ts +15 -8
  35. package/src/README.md +127 -222
  36. package/src/architecture/README.md +117 -184
  37. package/src/architecture/architect.ts +6 -0
  38. package/src/architecture/layer/README.md +38 -38
  39. package/src/architecture/network/README.md +49 -31
  40. package/src/architecture/network/activate/README.md +77 -77
  41. package/src/architecture/network/connect/README.md +15 -13
  42. package/src/architecture/network/deterministic/README.md +7 -7
  43. package/src/architecture/network/evolve/README.md +44 -44
  44. package/src/architecture/network/gating/README.md +20 -20
  45. package/src/architecture/network/genetic/README.md +51 -51
  46. package/src/architecture/network/mutate/README.md +97 -97
  47. package/src/architecture/network/network.types.ts +39 -0
  48. package/src/architecture/network/onnx/README.md +264 -264
  49. package/src/architecture/network/prune/README.md +39 -39
  50. package/src/architecture/network/remove/README.md +26 -26
  51. package/src/architecture/network/serialize/README.md +56 -56
  52. package/src/architecture/network/serialize/network.serialize.json.utils.ts +1 -0
  53. package/src/architecture/network/serialize/network.serialize.utils.ts +6 -1
  54. package/src/architecture/network/serialize/network.serialize.utils.types.ts +1 -1
  55. package/src/architecture/network/slab/README.md +61 -61
  56. package/src/architecture/network/standalone/README.md +24 -24
  57. package/src/architecture/network/stats/README.md +9 -9
  58. package/src/architecture/network/topology/README.md +46 -46
  59. package/src/architecture/network/training/README.md +21 -21
  60. package/src/architecture/network.ts +114 -10
  61. package/src/methods/README.md +9 -87
  62. package/src/multithreading/README.md +8 -77
  63. package/src/multithreading/workers/README.md +2 -2
  64. package/src/multithreading/workers/browser/README.md +0 -6
  65. package/src/multithreading/workers/node/README.md +0 -3
  66. package/src/neat/README.md +623 -568
  67. package/src/neat/neat.evolve.population.utils.ts +29 -5
  68. package/src/neat/neat.helpers.ts +16 -0
  69. package/src/neat/neat.topology-intent.utils.ts +160 -0
  70. package/src/utils/README.md +18 -18
  71. package/test/examples/asciiMaze/README.md +59 -59
  72. package/test/examples/asciiMaze/asciiMaze.e2e.test.ts +14 -9
  73. package/test/examples/asciiMaze/browser-entry/README.md +196 -0
  74. package/test/examples/asciiMaze/browser-entry/browser-entry.abort.services.ts +95 -0
  75. package/test/examples/asciiMaze/browser-entry/browser-entry.constants.ts +23 -0
  76. package/test/examples/asciiMaze/browser-entry/browser-entry.curriculum.services.ts +115 -0
  77. package/test/examples/asciiMaze/browser-entry/browser-entry.globals.services.ts +106 -0
  78. package/test/examples/asciiMaze/browser-entry/browser-entry.host.services.ts +157 -0
  79. package/test/examples/asciiMaze/browser-entry/browser-entry.services.ts +14 -0
  80. package/test/examples/asciiMaze/browser-entry/browser-entry.ts +129 -0
  81. package/test/examples/asciiMaze/browser-entry/browser-entry.types.ts +120 -0
  82. package/test/examples/asciiMaze/browser-entry/browser-entry.utils.ts +98 -0
  83. package/test/examples/asciiMaze/browser-entry.ts +10 -576
  84. package/test/examples/asciiMaze/dashboardManager/README.md +276 -0
  85. package/test/examples/asciiMaze/dashboardManager/archive/README.md +16 -0
  86. package/test/examples/asciiMaze/dashboardManager/archive/dashboardManager.archive.services.ts +267 -0
  87. package/test/examples/asciiMaze/dashboardManager/dashboardManager.constants.ts +35 -0
  88. package/test/examples/asciiMaze/dashboardManager/dashboardManager.services.ts +103 -0
  89. package/test/examples/asciiMaze/dashboardManager/dashboardManager.ts +181 -0
  90. package/test/examples/asciiMaze/dashboardManager/dashboardManager.types.ts +267 -0
  91. package/test/examples/asciiMaze/dashboardManager/dashboardManager.utils.ts +254 -0
  92. package/test/examples/asciiMaze/dashboardManager/live/README.md +14 -0
  93. package/test/examples/asciiMaze/dashboardManager/live/dashboardManager.live.services.ts +264 -0
  94. package/test/examples/asciiMaze/dashboardManager/telemetry/README.md +47 -0
  95. package/test/examples/asciiMaze/dashboardManager/telemetry/dashboardManager.telemetry.services.ts +513 -0
  96. package/test/examples/asciiMaze/dashboardManager.ts +13 -2335
  97. package/test/examples/asciiMaze/evolutionEngine/README.md +1058 -0
  98. package/test/examples/asciiMaze/evolutionEngine/curriculumPhase.ts +90 -0
  99. package/test/examples/asciiMaze/evolutionEngine/engineState.constants.ts +36 -0
  100. package/test/examples/asciiMaze/evolutionEngine/engineState.ts +58 -513
  101. package/test/examples/asciiMaze/evolutionEngine/engineState.types.ts +212 -0
  102. package/test/examples/asciiMaze/evolutionEngine/engineState.utils.ts +301 -0
  103. package/test/examples/asciiMaze/evolutionEngine/evolutionEngine.types.ts +445 -0
  104. package/test/examples/asciiMaze/evolutionEngine/evolutionLoop.ts +81 -50
  105. package/test/examples/asciiMaze/evolutionEngine/optionsAndSetup.ts +2 -4
  106. package/test/examples/asciiMaze/evolutionEngine/populationDynamics.ts +17 -33
  107. package/test/examples/asciiMaze/evolutionEngine/populationPruning.ts +1 -1
  108. package/test/examples/asciiMaze/evolutionEngine/rngAndTiming.ts +1 -2
  109. package/test/examples/asciiMaze/evolutionEngine/sampling.ts +1 -1
  110. package/test/examples/asciiMaze/evolutionEngine/scratchPools.ts +2 -5
  111. package/test/examples/asciiMaze/evolutionEngine/setupHelpers.ts +30 -37
  112. package/test/examples/asciiMaze/evolutionEngine/telemetryMetrics.ts +16 -58
  113. package/test/examples/asciiMaze/evolutionEngine/trainingWarmStart.ts +2 -2
  114. package/test/examples/asciiMaze/evolutionEngine.ts +55 -55
  115. package/test/examples/asciiMaze/fitness.ts +2 -2
  116. package/test/examples/asciiMaze/fitness.types.ts +65 -0
  117. package/test/examples/asciiMaze/interfaces.ts +64 -1352
  118. package/test/examples/asciiMaze/mazeMovement/README.md +356 -0
  119. package/test/examples/asciiMaze/mazeMovement/finalization/README.md +49 -0
  120. package/test/examples/asciiMaze/mazeMovement/finalization/mazeMovement.finalization.ts +138 -0
  121. package/test/examples/asciiMaze/mazeMovement/mazeMovement.constants.ts +101 -0
  122. package/test/examples/asciiMaze/mazeMovement/mazeMovement.services.ts +230 -0
  123. package/test/examples/asciiMaze/mazeMovement/mazeMovement.ts +299 -0
  124. package/test/examples/asciiMaze/mazeMovement/mazeMovement.types.ts +185 -0
  125. package/test/examples/asciiMaze/mazeMovement/mazeMovement.utils.ts +153 -0
  126. package/test/examples/asciiMaze/mazeMovement/policy/README.md +91 -0
  127. package/test/examples/asciiMaze/mazeMovement/policy/mazeMovement.policy.ts +467 -0
  128. package/test/examples/asciiMaze/mazeMovement/runtime/README.md +95 -0
  129. package/test/examples/asciiMaze/mazeMovement/runtime/mazeMovement.runtime.ts +354 -0
  130. package/test/examples/asciiMaze/mazeMovement/shaping/README.md +124 -0
  131. package/test/examples/asciiMaze/mazeMovement/shaping/mazeMovement.shaping.ts +459 -0
  132. package/test/examples/asciiMaze/mazeMovement.ts +12 -2978
  133. package/test/examples/flappy_bird/README.md +193 -88
  134. package/test/examples/flappy_bird/browser-entry/README.md +1441 -0
  135. package/test/examples/flappy_bird/browser-entry/browser-entry.host.utils.ts +4 -324
  136. package/test/examples/flappy_bird/browser-entry/browser-entry.network-view.utils.ts +9 -396
  137. package/test/examples/flappy_bird/browser-entry/browser-entry.playback.utils.ts +6 -714
  138. package/test/examples/flappy_bird/browser-entry/browser-entry.render.types.ts +26 -3
  139. package/test/examples/flappy_bird/browser-entry/browser-entry.runtime.types.ts +16 -1
  140. package/test/examples/flappy_bird/browser-entry/browser-entry.simulation.types.ts +39 -5
  141. package/test/examples/flappy_bird/browser-entry/browser-entry.spawn.utils.ts +11 -31
  142. package/test/examples/flappy_bird/browser-entry/browser-entry.stats.types.ts +32 -4
  143. package/test/examples/flappy_bird/browser-entry/browser-entry.ts +11 -0
  144. package/test/examples/flappy_bird/browser-entry/browser-entry.types.ts +8 -0
  145. package/test/examples/flappy_bird/browser-entry/browser-entry.visualization.types.ts +50 -7
  146. package/test/examples/flappy_bird/browser-entry/browser-entry.visualization.utils.ts +21 -893
  147. package/test/examples/flappy_bird/browser-entry/browser-entry.worker.types.ts +91 -10
  148. package/test/examples/flappy_bird/browser-entry/host/README.md +318 -0
  149. package/test/examples/flappy_bird/browser-entry/host/host.canvas.service.ts +16 -0
  150. package/test/examples/flappy_bird/browser-entry/host/host.constants.ts +20 -0
  151. package/test/examples/flappy_bird/browser-entry/host/host.dom.service.ts +10 -0
  152. package/test/examples/flappy_bird/browser-entry/host/host.resize.service.ts +1 -295
  153. package/test/examples/flappy_bird/browser-entry/host/host.stats.service.ts +14 -0
  154. package/test/examples/flappy_bird/browser-entry/host/host.ts +592 -6
  155. package/test/examples/flappy_bird/browser-entry/host/host.types.ts +13 -0
  156. package/test/examples/flappy_bird/browser-entry/host/resize/README.md +309 -0
  157. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.constants.ts +47 -0
  158. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.services.ts +392 -0
  159. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.ts +132 -0
  160. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.types.ts +92 -0
  161. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.utils.ts +272 -0
  162. package/test/examples/flappy_bird/browser-entry/network-view/README.md +389 -0
  163. package/test/examples/flappy_bird/browser-entry/network-view/network-view.draw.service.ts +13 -0
  164. package/test/examples/flappy_bird/browser-entry/network-view/network-view.labels.utils.ts +12 -0
  165. package/test/examples/flappy_bird/browser-entry/network-view/network-view.layout.utils.ts +14 -0
  166. package/test/examples/flappy_bird/browser-entry/network-view/network-view.topology.utils.ts +267 -0
  167. package/test/examples/flappy_bird/browser-entry/network-view/network-view.ts +823 -7
  168. package/test/examples/flappy_bird/browser-entry/network-view/network-view.types.ts +11 -0
  169. package/test/examples/flappy_bird/browser-entry/playback/README.md +845 -0
  170. package/test/examples/flappy_bird/browser-entry/playback/background/README.md +355 -0
  171. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/README.md +1068 -0
  172. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.batch.services.ts +64 -0
  173. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.cache.services.ts +207 -0
  174. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.constants.ts +197 -0
  175. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.geometry.batch.utils.ts +114 -0
  176. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.geometry.layout.utils.test.ts +96 -0
  177. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.geometry.layout.utils.ts +204 -0
  178. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.geometry.services.ts +49 -0
  179. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.geometry.utils.ts +313 -0
  180. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.layer.services.ts +81 -0
  181. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.math.utils.test.ts +33 -0
  182. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.math.utils.ts +201 -0
  183. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.pulse.selection.utils.ts +171 -0
  184. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.pulse.timing.utils.ts +124 -0
  185. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.pulse.utils.test.ts +279 -0
  186. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.pulse.utils.ts +132 -0
  187. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.scene.services.ts +26 -0
  188. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.services.ts +65 -0
  189. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.ts +48 -0
  190. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.types.ts +342 -0
  191. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.utils.ts +10 -0
  192. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.cache.services.ts +96 -0
  193. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.constants.ts +127 -0
  194. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.draw.services.ts +184 -0
  195. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.scene.services.ts +64 -0
  196. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.services.ts +6 -0
  197. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.ts +53 -0
  198. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.types.ts +105 -0
  199. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.utils.ts +100 -0
  200. package/test/examples/flappy_bird/browser-entry/playback/frame-render/README.md +541 -0
  201. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.bird.utils.ts +180 -0
  202. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.canvas.services.ts +77 -0
  203. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.entity.services.ts +167 -0
  204. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.scene.services.ts +57 -0
  205. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.service.test.ts +176 -0
  206. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.service.ts +113 -0
  207. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.services.ts +35 -0
  208. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.trail.utils.ts +248 -0
  209. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types.ts +103 -0
  210. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.utils.ts +11 -0
  211. package/test/examples/flappy_bird/browser-entry/playback/playback.constants.ts +1 -1
  212. package/test/examples/flappy_bird/browser-entry/playback/playback.frame-render.service.ts +10 -0
  213. package/test/examples/flappy_bird/browser-entry/playback/playback.iteration.services.ts +192 -0
  214. package/test/examples/flappy_bird/browser-entry/playback/playback.loop.service.ts +12 -0
  215. package/test/examples/flappy_bird/browser-entry/playback/playback.orchestration.types.ts +78 -0
  216. package/test/examples/flappy_bird/browser-entry/playback/playback.render.pipe-outline.service.ts +128 -0
  217. package/test/examples/flappy_bird/browser-entry/playback/playback.render.service.ts +1 -116
  218. package/test/examples/flappy_bird/browser-entry/playback/playback.session.services.ts +184 -0
  219. package/test/examples/flappy_bird/browser-entry/playback/playback.snapshot.utils.test.ts +121 -0
  220. package/test/examples/flappy_bird/browser-entry/playback/playback.snapshot.utils.ts +8 -0
  221. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.layer.services.ts +36 -0
  222. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.service.ts +11 -128
  223. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.services.ts +268 -0
  224. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.types.ts +91 -0
  225. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.utils.ts +11 -4
  226. package/test/examples/flappy_bird/browser-entry/playback/playback.trail.utils.ts +9 -86
  227. package/test/examples/flappy_bird/browser-entry/playback/playback.ts +75 -7
  228. package/test/examples/flappy_bird/browser-entry/playback/playback.types.ts +12 -9
  229. package/test/examples/flappy_bird/browser-entry/playback/playback.worker-channel.utils.ts +11 -123
  230. package/test/examples/flappy_bird/browser-entry/playback/snapshot/README.md +55 -0
  231. package/test/examples/flappy_bird/browser-entry/playback/snapshot/playback.snapshot.services.ts +103 -0
  232. package/test/examples/flappy_bird/browser-entry/playback/snapshot/playback.snapshot.summary.utils.test.ts +45 -0
  233. package/test/examples/flappy_bird/browser-entry/playback/snapshot/playback.snapshot.summary.utils.ts +28 -0
  234. package/test/examples/flappy_bird/browser-entry/playback/trail/README.md +95 -0
  235. package/test/examples/flappy_bird/browser-entry/playback/trail/playback.trail.history.services.test.ts +35 -0
  236. package/test/examples/flappy_bird/browser-entry/playback/trail/playback.trail.history.services.ts +64 -0
  237. package/test/examples/flappy_bird/browser-entry/playback/trail/playback.trail.opacity.utils.test.ts +37 -0
  238. package/test/examples/flappy_bird/browser-entry/playback/trail/playback.trail.opacity.utils.ts +74 -0
  239. package/test/examples/flappy_bird/browser-entry/playback/worker-channel/README.md +71 -0
  240. package/test/examples/flappy_bird/browser-entry/playback/worker-channel/playback.worker-channel.request.services.ts +45 -0
  241. package/test/examples/flappy_bird/browser-entry/playback/worker-channel/playback.worker-channel.summary.services.ts +74 -0
  242. package/test/examples/flappy_bird/browser-entry/playback/worker-channel/playback.worker-channel.types.ts +53 -0
  243. package/test/examples/flappy_bird/browser-entry/runtime/README.md +304 -0
  244. package/test/examples/flappy_bird/browser-entry/runtime/runtime.browser-globals.service.ts +15 -0
  245. package/test/examples/flappy_bird/browser-entry/runtime/runtime.errors.ts +17 -0
  246. package/test/examples/flappy_bird/browser-entry/runtime/runtime.evolution-launch.service.ts +56 -0
  247. package/test/examples/flappy_bird/browser-entry/runtime/runtime.evolution-loop.service.ts +19 -0
  248. package/test/examples/flappy_bird/browser-entry/runtime/runtime.lifecycle.service.ts +96 -0
  249. package/test/examples/flappy_bird/browser-entry/runtime/runtime.startup.service.ts +92 -0
  250. package/test/examples/flappy_bird/browser-entry/runtime/runtime.telemetry.service.ts +24 -0
  251. package/test/examples/flappy_bird/browser-entry/runtime/runtime.ts +31 -121
  252. package/test/examples/flappy_bird/browser-entry/runtime/runtime.types.ts +65 -0
  253. package/test/examples/flappy_bird/browser-entry/visualization/README.md +568 -0
  254. package/test/examples/flappy_bird/browser-entry/visualization/visualization.colors.utils.ts +26 -0
  255. package/test/examples/flappy_bird/browser-entry/visualization/visualization.constants.ts +110 -0
  256. package/test/examples/flappy_bird/browser-entry/visualization/visualization.draw.service.ts +979 -19
  257. package/test/examples/flappy_bird/browser-entry/visualization/visualization.legend.utils.ts +157 -3
  258. package/test/examples/flappy_bird/browser-entry/visualization/visualization.topology.utils.ts +13 -27
  259. package/test/examples/flappy_bird/browser-entry/visualization/visualization.ts +7 -20
  260. package/test/examples/flappy_bird/browser-entry/visualization/visualization.types.ts +14 -0
  261. package/test/examples/flappy_bird/browser-entry/worker-channel/README.md +238 -0
  262. package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.errors.ts +11 -0
  263. package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.generation.service.ts +12 -0
  264. package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.playback.service.test.ts +143 -0
  265. package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.playback.service.ts +140 -14
  266. package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.request.service.ts +27 -0
  267. package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.ts +8 -0
  268. package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.types.ts +23 -0
  269. package/test/examples/flappy_bird/browser-entry/worker-channel/worker-channel.url.service.ts +5 -0
  270. package/test/examples/flappy_bird/constants/README.md +1163 -0
  271. package/test/examples/flappy_bird/constants/constants.birds.ts +16 -38
  272. package/test/examples/flappy_bird/constants/constants.difficulty.ts +21 -0
  273. package/test/examples/flappy_bird/constants/constants.network-view.ts +24 -0
  274. package/test/examples/flappy_bird/constants/constants.network.ts +1 -1
  275. package/test/examples/flappy_bird/constants/constants.observation.ts +7 -0
  276. package/test/examples/flappy_bird/constants/constants.palette.ts +9 -2
  277. package/test/examples/flappy_bird/constants/constants.physics.ts +9 -0
  278. package/test/examples/flappy_bird/constants/constants.pipe-render.ts +3 -0
  279. package/test/examples/flappy_bird/constants/constants.pipes.ts +22 -3
  280. package/test/examples/flappy_bird/constants/constants.runtime.ts +28 -4
  281. package/test/examples/flappy_bird/constants/constants.starfield.ts +78 -3
  282. package/test/examples/flappy_bird/constants/constants.ts +6 -0
  283. package/test/examples/flappy_bird/environment/README.md +182 -0
  284. package/test/examples/flappy_bird/environment/environment.collision.utils.ts +7 -0
  285. package/test/examples/flappy_bird/environment/environment.constants.ts +16 -3
  286. package/test/examples/flappy_bird/environment/environment.observation.utils.ts +12 -19
  287. package/test/examples/flappy_bird/environment/environment.state.service.ts +10 -0
  288. package/test/examples/flappy_bird/environment/environment.step.service.ts +15 -66
  289. package/test/examples/flappy_bird/environment/environment.types.ts +14 -0
  290. package/test/examples/flappy_bird/evaluation/README.md +155 -0
  291. package/test/examples/flappy_bird/evaluation/evaluation.constants.ts +23 -4
  292. package/test/examples/flappy_bird/evaluation/evaluation.fitness.utils.ts +16 -1
  293. package/test/examples/flappy_bird/evaluation/evaluation.rollout.service.ts +7 -374
  294. package/test/examples/flappy_bird/evaluation/evaluation.seed.utils.ts +4 -0
  295. package/test/examples/flappy_bird/evaluation/evaluation.types.ts +18 -2
  296. package/test/examples/flappy_bird/evaluation/rollout/README.md +355 -0
  297. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.constants.ts +38 -0
  298. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.service.ts +71 -0
  299. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.services.ts +338 -0
  300. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.types.ts +69 -0
  301. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.utils.ts +399 -0
  302. package/test/examples/flappy_bird/flappy-evolution-worker/README.md +845 -0
  303. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.constants.ts +49 -7
  304. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.errors.ts +34 -3
  305. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.evolution.service.ts +22 -0
  306. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.playback.service.ts +62 -26
  307. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.protocol.service.ts +27 -1
  308. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.runtime.service.ts +23 -0
  309. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.frame.service.ts +378 -0
  310. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.types.ts +22 -0
  311. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.utils.ts +20 -203
  312. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.snapshot.utils.test.ts +94 -0
  313. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.snapshot.utils.ts +78 -13
  314. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.ts +235 -344
  315. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.types.ts +170 -22
  316. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.warm-start.service.ts +314 -0
  317. package/test/examples/flappy_bird/flappy.simulation.shared.utils.ts +17 -0
  318. package/test/examples/flappy_bird/flappyEnvironment.ts +21 -0
  319. package/test/examples/flappy_bird/flappyEvaluation.ts +12 -0
  320. package/test/examples/flappy_bird/flappyEvolution.worker.ts +7 -0
  321. package/test/examples/flappy_bird/index.ts +8 -2
  322. package/test/examples/flappy_bird/rng.ts +10 -0
  323. package/test/examples/flappy_bird/simulation-shared/README.md +518 -0
  324. package/test/examples/flappy_bird/simulation-shared/observation/README.md +255 -0
  325. package/test/examples/flappy_bird/simulation-shared/observation/observation.features.utils.ts +339 -0
  326. package/test/examples/flappy_bird/simulation-shared/observation/observation.ts +19 -0
  327. package/test/examples/flappy_bird/simulation-shared/observation/observation.vector.utils.ts +81 -0
  328. package/test/examples/flappy_bird/simulation-shared/simulation-shared.constants.ts +3 -0
  329. package/test/examples/flappy_bird/simulation-shared/simulation-shared.control.utils.ts +6 -0
  330. package/test/examples/flappy_bird/simulation-shared/simulation-shared.difficulty.utils.ts +9 -0
  331. package/test/examples/flappy_bird/simulation-shared/simulation-shared.errors.ts +10 -1
  332. package/test/examples/flappy_bird/simulation-shared/simulation-shared.memory.utils.ts +18 -0
  333. package/test/examples/flappy_bird/simulation-shared/simulation-shared.observation.utils.ts +7 -402
  334. package/test/examples/flappy_bird/simulation-shared/simulation-shared.spawn.utils.ts +36 -6
  335. package/test/examples/flappy_bird/{evaluation/evaluation.statistics.utils.ts → simulation-shared/simulation-shared.statistics.utils.ts} +30 -9
  336. package/test/examples/flappy_bird/simulation-shared/simulation-shared.types.ts +38 -5
  337. package/test/examples/flappy_bird/trainFlappyBird.ts +13 -0
  338. package/test/examples/flappy_bird/trainer/README.md +676 -0
  339. package/test/examples/flappy_bird/trainer/evaluation/README.md +253 -0
  340. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.constants.ts +15 -0
  341. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.services.ts +86 -0
  342. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.ts +187 -0
  343. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.types.ts +32 -0
  344. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.utils.ts +182 -0
  345. package/test/examples/flappy_bird/trainer/trainer.evaluation.service.ts +13 -0
  346. package/test/examples/flappy_bird/trainer/trainer.fitness.service.ts +23 -1
  347. package/test/examples/flappy_bird/trainer/trainer.loop.service.ts +17 -1
  348. package/test/examples/flappy_bird/trainer/trainer.report.service.services.ts +181 -0
  349. package/test/examples/flappy_bird/trainer/trainer.report.service.ts +136 -0
  350. package/test/examples/flappy_bird/trainer/trainer.selection.utils.ts +89 -0
  351. package/test/examples/flappy_bird/trainer/trainer.setup.service.ts +22 -0
  352. package/test/examples/flappy_bird/trainer/trainer.signals.service.ts +8 -0
  353. package/test/examples/flappy_bird/trainer/trainer.ts +38 -553
  354. package/test/examples/flappy_bird/trainer/trainer.types.ts +44 -7
  355. package/test/neat/neat.topology-intent.test.ts +129 -0
  356. package/test/network/network.topology-intent.test.ts +44 -0
  357. package/test/examples/flappy_bird/browser-entry/browser-entry.utils.ts +0 -12
  358. package/test/examples/flappy_bird/environment/environment.ts +0 -7
  359. package/test/examples/flappy_bird/evaluation/evaluation.ts +0 -7
  360. package/test/examples/flappy_bird/simulation-shared/simulation-shared.ts +0 -15
  361. package/test/examples/flappy_bird/trainer/trainer.statistics.utils.ts +0 -78
@@ -0,0 +1,279 @@
1
+ import {
2
+ FLAPPY_GROUND_GRID_APPROX_FRAME_DURATION_MS,
3
+ FLAPPY_GROUND_GRID_PULSE_INTERVAL_MS,
4
+ FLAPPY_GROUND_GRID_PULSE_LIFETIME_MS,
5
+ FLAPPY_GROUND_GRID_VERTICAL_PULSE_END_RATIO,
6
+ FLAPPY_GROUND_GRID_VERTICAL_PULSE_START_RATIO,
7
+ } from './playback.background.ground-grid.constants';
8
+ import { resolvePlaybackGroundGridPulse } from './playback.background.ground-grid.pulse.utils';
9
+ import type {
10
+ PlaybackBackgroundGroundGridSceneContext,
11
+ PlaybackGroundGridPulsePath,
12
+ } from './playback.background.ground-grid.types';
13
+
14
+ describe('resolvePlaybackGroundGridPulse', () => {
15
+ it('keeps a vertical spark on the same ray when visible vertical candidates shift', () => {
16
+ const sceneContext = createSceneContext();
17
+ const verticalPulsePaths = createVerticalPulsePaths();
18
+ const startingFrameIndex = findVerticalPulseFrameIndex(
19
+ sceneContext,
20
+ verticalPulsePaths,
21
+ );
22
+ const firstPulse = resolvePlaybackGroundGridPulse({
23
+ frameIndex: startingFrameIndex,
24
+ horizontalPulsePaths: [],
25
+ sceneContext,
26
+ verticalPulsePaths,
27
+ visibleVerticalPulsePaths: verticalPulsePaths.slice(1, 3),
28
+ });
29
+ const secondPulse = resolvePlaybackGroundGridPulse({
30
+ frameIndex: startingFrameIndex + 1,
31
+ horizontalPulsePaths: [],
32
+ sceneContext,
33
+ verticalPulsePaths,
34
+ visibleVerticalPulsePaths: verticalPulsePaths.slice(2, 4),
35
+ });
36
+
37
+ expect(firstPulse).not.toBeNull();
38
+ });
39
+
40
+ it('continues the same vertical spark trajectory when edge visibility changes', () => {
41
+ const sceneContext = createSceneContext();
42
+ const verticalPulsePaths = createVerticalPulsePaths();
43
+ const startingFrameIndex = findVerticalPulseFrameIndex(
44
+ sceneContext,
45
+ verticalPulsePaths,
46
+ );
47
+ const firstPulse = resolvePlaybackGroundGridPulse({
48
+ frameIndex: startingFrameIndex,
49
+ horizontalPulsePaths: [],
50
+ sceneContext,
51
+ verticalPulsePaths,
52
+ visibleVerticalPulsePaths: verticalPulsePaths.slice(1, 3),
53
+ });
54
+ const secondPulse = resolvePlaybackGroundGridPulse({
55
+ frameIndex: startingFrameIndex + 1,
56
+ horizontalPulsePaths: [],
57
+ sceneContext,
58
+ verticalPulsePaths,
59
+ visibleVerticalPulsePaths: verticalPulsePaths.slice(2, 4),
60
+ });
61
+
62
+ expect(secondPulse).not.toBeNull();
63
+ });
64
+
65
+ it('moves the vertical spark only by the expected per-frame delta', () => {
66
+ const sceneContext = createSceneContext();
67
+ const verticalPulsePaths = createVerticalPulsePaths();
68
+ const startingFrameIndex = findVerticalPulseFrameIndex(
69
+ sceneContext,
70
+ verticalPulsePaths,
71
+ );
72
+ const firstPulse = resolvePlaybackGroundGridPulse({
73
+ frameIndex: startingFrameIndex,
74
+ horizontalPulsePaths: [],
75
+ sceneContext,
76
+ verticalPulsePaths,
77
+ visibleVerticalPulsePaths: verticalPulsePaths.slice(1, 3),
78
+ });
79
+ const secondPulse = resolvePlaybackGroundGridPulse({
80
+ frameIndex: startingFrameIndex + 1,
81
+ horizontalPulsePaths: [],
82
+ sceneContext,
83
+ verticalPulsePaths,
84
+ visibleVerticalPulsePaths: verticalPulsePaths.slice(2, 4),
85
+ });
86
+
87
+ const stablePath = resolveClosestPulsePath(
88
+ firstPulse!,
89
+ verticalPulsePaths,
90
+ resolveVerticalTravelProgressRatio(startingFrameIndex),
91
+ );
92
+ const expectedNextCenterXPx = interpolatePathXPx(
93
+ stablePath,
94
+ resolveVerticalTravelProgressRatio(startingFrameIndex + 1),
95
+ );
96
+
97
+ expect(secondPulse!.centerXPx).toBeCloseTo(expectedNextCenterXPx, 6);
98
+ });
99
+
100
+ it('keeps a vertical spark continuous across wrapped ray lists', () => {
101
+ const sceneContext = createSceneContext();
102
+ const startingFrameIndex = findVerticalPulseFrameIndex(sceneContext, [
103
+ createVerticalPulsePath(40),
104
+ createVerticalPulsePath(140),
105
+ createVerticalPulsePath(240),
106
+ createVerticalPulsePath(340),
107
+ createVerticalPulsePath(440),
108
+ ]);
109
+ const firstVerticalPulsePaths = [
110
+ createVerticalPulsePath(-260),
111
+ createVerticalPulsePath(-160),
112
+ createVerticalPulsePath(-60),
113
+ createVerticalPulsePath(40),
114
+ createVerticalPulsePath(140),
115
+ ];
116
+ const secondVerticalPulsePaths = [
117
+ createVerticalPulsePath(60),
118
+ createVerticalPulsePath(160),
119
+ createVerticalPulsePath(260),
120
+ createVerticalPulsePath(360),
121
+ createVerticalPulsePath(460),
122
+ ];
123
+ const firstPulse = resolvePlaybackGroundGridPulse({
124
+ frameIndex: startingFrameIndex,
125
+ horizontalPulsePaths: [],
126
+ sceneContext,
127
+ verticalPulsePaths: firstVerticalPulsePaths,
128
+ visibleVerticalPulsePaths: firstVerticalPulsePaths,
129
+ });
130
+ const secondPulse = resolvePlaybackGroundGridPulse({
131
+ frameIndex: startingFrameIndex + 1,
132
+ horizontalPulsePaths: [],
133
+ sceneContext,
134
+ verticalPulsePaths: secondVerticalPulsePaths,
135
+ visibleVerticalPulsePaths: secondVerticalPulsePaths,
136
+ });
137
+
138
+ expect(
139
+ Math.abs(secondPulse!.centerXPx - firstPulse!.centerXPx),
140
+ ).toBeLessThan(140);
141
+ });
142
+ });
143
+
144
+ function findVerticalPulseFrameIndex(
145
+ sceneContext: PlaybackBackgroundGroundGridSceneContext,
146
+ verticalPulsePaths: readonly PlaybackGroundGridPulsePath[],
147
+ ): number {
148
+ for (let frameIndex = 0; frameIndex < 4_000; frameIndex += 1) {
149
+ const pulse = resolvePlaybackGroundGridPulse({
150
+ frameIndex,
151
+ horizontalPulsePaths: [],
152
+ sceneContext,
153
+ verticalPulsePaths,
154
+ visibleVerticalPulsePaths: verticalPulsePaths,
155
+ });
156
+ if (pulse) {
157
+ return frameIndex;
158
+ }
159
+ }
160
+
161
+ throw new Error(
162
+ 'Expected to find a vertical pulse frame for the test fixture.',
163
+ );
164
+ }
165
+
166
+ function resolveVerticalTravelProgressRatio(frameIndex: number): number {
167
+ const currentTimeMs =
168
+ frameIndex * FLAPPY_GROUND_GRID_APPROX_FRAME_DURATION_MS;
169
+ const pulseSlotIndex = Math.floor(
170
+ currentTimeMs / FLAPPY_GROUND_GRID_PULSE_INTERVAL_MS,
171
+ );
172
+ const pulseElapsedMs =
173
+ currentTimeMs - pulseSlotIndex * FLAPPY_GROUND_GRID_PULSE_INTERVAL_MS;
174
+ const lifetimeProgressRatio =
175
+ pulseElapsedMs / FLAPPY_GROUND_GRID_PULSE_LIFETIME_MS;
176
+ const directionIsForward = resolveTestUnitHash(pulseSlotIndex, 29) >= 0.5;
177
+ const baseTravelProgressRatio = directionIsForward
178
+ ? lifetimeProgressRatio
179
+ : 1 - lifetimeProgressRatio;
180
+
181
+ return (
182
+ FLAPPY_GROUND_GRID_VERTICAL_PULSE_START_RATIO +
183
+ (FLAPPY_GROUND_GRID_VERTICAL_PULSE_END_RATIO -
184
+ FLAPPY_GROUND_GRID_VERTICAL_PULSE_START_RATIO) *
185
+ baseTravelProgressRatio
186
+ );
187
+ }
188
+
189
+ function resolveClosestPulsePath(
190
+ pulse: { centerXPx: number; centerYPx: number },
191
+ verticalPulsePaths: readonly PlaybackGroundGridPulsePath[],
192
+ travelProgressRatio: number,
193
+ ): PlaybackGroundGridPulsePath {
194
+ let closestPath = verticalPulsePaths[0];
195
+ let closestDistanceSq = Number.POSITIVE_INFINITY;
196
+
197
+ for (const verticalPulsePath of verticalPulsePaths) {
198
+ const centerXPx = interpolatePathXPx(
199
+ verticalPulsePath,
200
+ travelProgressRatio,
201
+ );
202
+ const centerYPx = interpolatePathYPx(
203
+ verticalPulsePath,
204
+ travelProgressRatio,
205
+ );
206
+ const deltaXPx = centerXPx - pulse.centerXPx;
207
+ const deltaYPx = centerYPx - pulse.centerYPx;
208
+ const distanceSq = deltaXPx * deltaXPx + deltaYPx * deltaYPx;
209
+ if (distanceSq < closestDistanceSq) {
210
+ closestDistanceSq = distanceSq;
211
+ closestPath = verticalPulsePath;
212
+ }
213
+ }
214
+
215
+ return closestPath;
216
+ }
217
+
218
+ function interpolatePathXPx(
219
+ pulsePath: PlaybackGroundGridPulsePath,
220
+ travelProgressRatio: number,
221
+ ): number {
222
+ return (
223
+ pulsePath.startXPx +
224
+ (pulsePath.endXPx - pulsePath.startXPx) * travelProgressRatio
225
+ );
226
+ }
227
+
228
+ function interpolatePathYPx(
229
+ pulsePath: PlaybackGroundGridPulsePath,
230
+ travelProgressRatio: number,
231
+ ): number {
232
+ return (
233
+ pulsePath.startYPx +
234
+ (pulsePath.endYPx - pulsePath.startYPx) * travelProgressRatio
235
+ );
236
+ }
237
+
238
+ function resolveTestUnitHash(seed: number, salt: number): number {
239
+ let hashedValue = (seed + 1) ^ Math.imul(salt + 1, 374_761_393);
240
+ hashedValue = Math.imul(hashedValue ^ (hashedValue >>> 13), 1_274_126_177);
241
+ hashedValue ^= hashedValue >>> 16;
242
+ return (hashedValue >>> 0) / 0x1_0000_0000;
243
+ }
244
+
245
+ function createSceneContext(): PlaybackBackgroundGroundGridSceneContext {
246
+ return {
247
+ viewportOffsetXPx: 0,
248
+ visibleWorldWidthPx: 640,
249
+ alignedHorizonYPx: 220,
250
+ lowerBandTopYPx: 220,
251
+ lowerBandHeightPx: 260,
252
+ lowerBandBottomYPx: 480,
253
+ vanishingPointXPx: 320,
254
+ vanishingPointYPx: 220,
255
+ };
256
+ }
257
+
258
+ function createVerticalPulsePaths(): readonly PlaybackGroundGridPulsePath[] {
259
+ return [
260
+ createVerticalPulsePath(60),
261
+ createVerticalPulsePath(160),
262
+ createVerticalPulsePath(260),
263
+ createVerticalPulsePath(360),
264
+ createVerticalPulsePath(460),
265
+ ];
266
+ }
267
+
268
+ function createVerticalPulsePath(
269
+ startXPx: number,
270
+ ): PlaybackGroundGridPulsePath {
271
+ return {
272
+ orientation: 'vertical',
273
+ startXPx,
274
+ startYPx: 480,
275
+ endXPx: 320,
276
+ endYPx: 220,
277
+ thicknessPx: 2,
278
+ };
279
+ }
@@ -0,0 +1,132 @@
1
+ import {
2
+ FLAPPY_GROUND_GRID_PULSE_ALPHA,
3
+ FLAPPY_GROUND_GRID_PULSE_MAX_SIZE_PX,
4
+ FLAPPY_GROUND_GRID_PULSE_MIN_SIZE_PX,
5
+ } from './playback.background.ground-grid.constants';
6
+ import {
7
+ interpolatePlaybackGroundGridPoint,
8
+ resolvePlaybackGroundGridDepthFromHorizonDistance,
9
+ resolvePlaybackGroundGridLineThickness,
10
+ } from './playback.background.ground-grid.math.utils';
11
+ import {
12
+ rememberPlaybackGroundGridVerticalPulseSelection,
13
+ resolvePlaybackGroundGridVerticalPulseSelection,
14
+ } from './playback.background.ground-grid.pulse.selection.utils';
15
+ import {
16
+ resolvePlaybackGroundGridHorizontalPulsePath,
17
+ resolvePlaybackGroundGridPulseOrientation,
18
+ resolvePlaybackGroundGridPulseTiming,
19
+ resolvePlaybackGroundGridPulseTravelRatio,
20
+ resolvePlaybackGroundGridUnitHash,
21
+ } from './playback.background.ground-grid.pulse.timing.utils';
22
+ import type {
23
+ PlaybackBackgroundGroundGridSceneContext,
24
+ PlaybackGroundGridPulse,
25
+ PlaybackGroundGridPulseInput,
26
+ PlaybackGroundGridPulsePath,
27
+ PlaybackGroundGridPulseTrackThicknessInput,
28
+ } from './playback.background.ground-grid.types';
29
+
30
+ /**
31
+ * Resolves one rare, deterministic pulse square for the current frame.
32
+ *
33
+ * @param input - Current frame timing and visible pulse path candidates.
34
+ * @returns Visible pulse square, or null when the current slot is inactive.
35
+ */
36
+ export function resolvePlaybackGroundGridPulse(
37
+ input: PlaybackGroundGridPulseInput,
38
+ ): PlaybackGroundGridPulse | null {
39
+ const pulseTiming = resolvePlaybackGroundGridPulseTiming(input.frameIndex);
40
+ if (!pulseTiming) {
41
+ return null;
42
+ }
43
+
44
+ const pulseOrientation = resolvePlaybackGroundGridPulseOrientation(
45
+ pulseTiming.pulseSlotIndex,
46
+ );
47
+
48
+ const directionIsForward =
49
+ resolvePlaybackGroundGridUnitHash(pulseTiming.pulseSlotIndex, 29) >= 0.5;
50
+ const travelProgressRatio = resolvePlaybackGroundGridPulseTravelRatio({
51
+ directionIsForward,
52
+ lifetimeProgressRatio: pulseTiming.lifetimeProgressRatio,
53
+ orientation: pulseOrientation,
54
+ });
55
+ const selectedPulsePath =
56
+ pulseOrientation === 'horizontal'
57
+ ? resolvePlaybackGroundGridHorizontalPulsePath(
58
+ input.horizontalPulsePaths,
59
+ pulseTiming.pulseSlotIndex,
60
+ )
61
+ : resolvePlaybackGroundGridVerticalPulseSelection({
62
+ verticalPulsePaths: input.verticalPulsePaths,
63
+ visibleVerticalPulsePaths: input.visibleVerticalPulsePaths,
64
+ pulseSlotIndex: pulseTiming.pulseSlotIndex,
65
+ frameIndex: input.frameIndex,
66
+ travelProgressRatio,
67
+ resolveUnitHash: resolvePlaybackGroundGridUnitHash,
68
+ });
69
+ if (!selectedPulsePath) {
70
+ return null;
71
+ }
72
+
73
+ const pulseCenter = interpolatePlaybackGroundGridPoint(
74
+ selectedPulsePath.startXPx,
75
+ selectedPulsePath.startYPx,
76
+ selectedPulsePath.endXPx,
77
+ selectedPulsePath.endYPx,
78
+ travelProgressRatio,
79
+ );
80
+
81
+ if (pulseOrientation === 'vertical') {
82
+ rememberPlaybackGroundGridVerticalPulseSelection(
83
+ pulseTiming.pulseSlotIndex,
84
+ {
85
+ centerXPx: pulseCenter.xPx,
86
+ centerYPx: pulseCenter.yPx,
87
+ frameIndex: input.frameIndex,
88
+ },
89
+ );
90
+ }
91
+
92
+ const pulseTrackThicknessPx = resolvePlaybackGroundGridPulseTrackThickness({
93
+ pulseCenterYPx: pulseCenter.yPx,
94
+ pulsePath: selectedPulsePath,
95
+ sceneContext: input.sceneContext,
96
+ });
97
+
98
+ return {
99
+ centerXPx: pulseCenter.xPx,
100
+ centerYPx: pulseCenter.yPx,
101
+ sizePx: Math.max(
102
+ FLAPPY_GROUND_GRID_PULSE_MIN_SIZE_PX,
103
+ Math.min(FLAPPY_GROUND_GRID_PULSE_MAX_SIZE_PX, pulseTrackThicknessPx),
104
+ ),
105
+ alpha: FLAPPY_GROUND_GRID_PULSE_ALPHA,
106
+ };
107
+ }
108
+
109
+ /**
110
+ * Resolves the local track thickness at the pulse position.
111
+ *
112
+ * @param input - Pulse position, path, and scene geometry.
113
+ * @returns Thickness of the current line under the pulse.
114
+ */
115
+ function resolvePlaybackGroundGridPulseTrackThickness(
116
+ input: PlaybackGroundGridPulseTrackThicknessInput,
117
+ ): number {
118
+ if (input.pulsePath.orientation === 'horizontal') {
119
+ return input.pulsePath.thicknessPx;
120
+ }
121
+
122
+ const maximumDistanceToHorizonPx = Math.max(
123
+ 1,
124
+ input.sceneContext.lowerBandBottomYPx -
125
+ input.sceneContext.alignedHorizonYPx,
126
+ );
127
+ const depthRatio = resolvePlaybackGroundGridDepthFromHorizonDistance(
128
+ input.pulseCenterYPx - input.sceneContext.alignedHorizonYPx,
129
+ maximumDistanceToHorizonPx,
130
+ );
131
+ return resolvePlaybackGroundGridLineThickness(depthRatio);
132
+ }
@@ -0,0 +1,26 @@
1
+ import type {
2
+ PlaybackBackgroundGroundGridSceneContext,
3
+ PlaybackBackgroundGroundGridSourceScene,
4
+ } from './playback.background.ground-grid.types';
5
+
6
+ /**
7
+ * Resolves the shared scene context used by the ground-grid renderer.
8
+ *
9
+ * @param sceneContext - Lower-band geometry provided by the background module.
10
+ * @returns Narrow scene contract consumed by grid-specific helpers.
11
+ */
12
+ export function resolvePlaybackGroundGridSceneContext(
13
+ sceneContext: PlaybackBackgroundGroundGridSourceScene,
14
+ ): PlaybackBackgroundGroundGridSceneContext {
15
+ return {
16
+ viewportOffsetXPx: sceneContext.viewportLeftXPx,
17
+ visibleWorldWidthPx: sceneContext.visibleWorldWidthPx,
18
+ alignedHorizonYPx: sceneContext.alignedHorizonYPx,
19
+ lowerBandTopYPx: sceneContext.lowerBandTopYPx,
20
+ lowerBandHeightPx: sceneContext.lowerBandHeightPx,
21
+ lowerBandBottomYPx: sceneContext.lowerBandBottomYPx,
22
+ vanishingPointXPx:
23
+ sceneContext.vanishingPointXPx - sceneContext.viewportLeftXPx,
24
+ vanishingPointYPx: sceneContext.vanishingPointYPx,
25
+ };
26
+ }
@@ -0,0 +1,65 @@
1
+ import { FLAPPY_BACKGROUND_COMPOSITE_SOURCE_OVER } from '../playback.background.constants';
2
+ import type {
3
+ PlaybackBackgroundGroundGridResolvedScene,
4
+ PlaybackGroundGridGeometry,
5
+ } from './playback.background.ground-grid.types';
6
+ import {
7
+ drawGroundGridSegmentBatch,
8
+ drawGroundGridSegmentBatches,
9
+ } from './playback.background.ground-grid.batch.services';
10
+ import {
11
+ drawGroundGridFog,
12
+ drawGroundGridPulse,
13
+ } from './playback.background.ground-grid.layer.services';
14
+
15
+ /**
16
+ * Draws the resolved neon ground grid inside the lower background band.
17
+ *
18
+ * @param context - Canvas 2D drawing context.
19
+ * @param resolvedScene - Geometry and style for the current viewport.
20
+ * @param geometry - Precomputed horizontal and vertical line segments.
21
+ * @returns Nothing.
22
+ */
23
+ export function drawPlaybackGroundGrid(
24
+ context: CanvasRenderingContext2D,
25
+ resolvedScene: PlaybackBackgroundGroundGridResolvedScene,
26
+ geometry: PlaybackGroundGridGeometry,
27
+ ): void {
28
+ context.save();
29
+ context.translate(resolvedScene.sceneContext.viewportOffsetXPx, 0);
30
+ context.globalCompositeOperation = FLAPPY_BACKGROUND_COMPOSITE_SOURCE_OVER;
31
+ context.beginPath();
32
+ context.rect(
33
+ 0,
34
+ resolvedScene.sceneContext.lowerBandTopYPx,
35
+ resolvedScene.sceneContext.visibleWorldWidthPx,
36
+ resolvedScene.sceneContext.lowerBandHeightPx,
37
+ );
38
+ context.clip();
39
+
40
+ drawGroundGridFog(context, resolvedScene);
41
+ drawGroundGridSegmentBatches(
42
+ context,
43
+ geometry.verticalLineBatches,
44
+ resolvedScene.style.lineColor,
45
+ );
46
+ drawGroundGridSegmentBatches(
47
+ context,
48
+ geometry.horizontalLineBatches,
49
+ resolvedScene.style.lineColor,
50
+ );
51
+ drawGroundGridPulse(
52
+ context,
53
+ geometry.pulse,
54
+ resolvedScene.style.pulseFillColor,
55
+ );
56
+ context.restore();
57
+ }
58
+ export {
59
+ drawGroundGridSegmentBatch,
60
+ drawGroundGridSegmentBatches,
61
+ } from './playback.background.ground-grid.batch.services';
62
+ export {
63
+ drawGroundGridFog,
64
+ drawGroundGridPulse,
65
+ } from './playback.background.ground-grid.layer.services';
@@ -0,0 +1,48 @@
1
+ import { drawPlaybackGroundGrid } from './playback.background.ground-grid.services';
2
+ import { FLAPPY_BACKGROUND_GROUND_GRID_STYLE } from './playback.background.ground-grid.constants';
3
+ import type {
4
+ PlaybackBackgroundGroundGridRequest,
5
+ PlaybackBackgroundGroundGridResolvedScene,
6
+ PlaybackBackgroundGroundGridSourceScene,
7
+ } from './playback.background.ground-grid.types';
8
+ import {
9
+ resolvePlaybackGroundGridGeometry,
10
+ resolvePlaybackGroundGridSceneContext,
11
+ } from './playback.background.ground-grid.utils';
12
+
13
+ /**
14
+ * Draws the neon lower-band ground grid beneath the horizon.
15
+ *
16
+ * The grid is intentionally stylized rather than physically realistic: fixed
17
+ * horizontal depth bands compress toward the horizon, while moving perspective
18
+ * rays slide sideways but still converge to the centered vanishing point.
19
+ *
20
+ * @param context - Canvas 2D drawing context.
21
+ * @param sourceScene - Shared lower-band geometry from the background module.
22
+ * @param request - Shared parallax scroll input for the current frame.
23
+ * @returns Nothing.
24
+ */
25
+ export function renderPlaybackBackgroundGroundGrid(
26
+ context: CanvasRenderingContext2D,
27
+ sourceScene: PlaybackBackgroundGroundGridSourceScene,
28
+ request: PlaybackBackgroundGroundGridRequest,
29
+ ): void {
30
+ // Step 1: Adapt the shared background scene into the narrow grid contract.
31
+ const sceneContext = resolvePlaybackGroundGridSceneContext(sourceScene);
32
+
33
+ // Step 2: Resolve theme-owned styling for the lower-band grid.
34
+ const resolvedScene: PlaybackBackgroundGroundGridResolvedScene = {
35
+ sceneContext,
36
+ style: FLAPPY_BACKGROUND_GROUND_GRID_STYLE,
37
+ };
38
+
39
+ // Step 3: Build all grid geometry before touching the canvas state.
40
+ const geometry = resolvePlaybackGroundGridGeometry(
41
+ sceneContext,
42
+ request.frameIndex,
43
+ request.scrollBasePx,
44
+ );
45
+
46
+ // Step 4: Draw the resolved lower-band neon grid.
47
+ drawPlaybackGroundGrid(context, resolvedScene, geometry);
48
+ }