@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,180 @@
1
+ import {
2
+ FLAPPY_BIRD_BODY_GLOW_BLUR_PX,
3
+ FLAPPY_BIRD_CHAMPION_EXTRA_GLOW_BLUR_PX,
4
+ FLAPPY_BIRD_RADIUS_PX,
5
+ FLAPPY_BIRD_X_PX,
6
+ FLAPPY_NON_CHAMPION_BODY_GLOW_BLUR_PX,
7
+ FLAPPY_PIPE_OUTLINE_CYAN_GLOW_BLUR_PX,
8
+ FLAPPY_PIPE_OUTLINE_GLOW_ALPHA,
9
+ FLAPPY_PIPE_OUTLINE_GLOW_STROKE_WIDTH_PX,
10
+ FLAPPY_PIPE_OUTLINE_STROKE_WIDTH_PX,
11
+ } from '../../../constants/constants';
12
+ import { resolveBirdRenderStyle } from '../playback.render.utils';
13
+ import type { PlaybackBirdGeometry } from './playback.frame-render.types';
14
+
15
+ /**
16
+ * Detailed bird-painting helpers for playback frames.
17
+ *
18
+ * The bird renderer keeps the body intentionally simple and geometric: a neon
19
+ * square with optional champion glow passes. That makes the population readable
20
+ * at a glance even when many birds overlap.
21
+ */
22
+
23
+ /**
24
+ * Draws one active bird body and champion-only highlight passes.
25
+ *
26
+ * The champion receives an extra additive-outline treatment so viewers can spot
27
+ * the leading bird quickly during playback.
28
+ *
29
+ * @param context - Canvas 2D drawing context.
30
+ * @param birdYPx - Bird vertical position in world pixels.
31
+ * @param birdIndex - Index of the bird being rendered.
32
+ * @param championBirdIndex - Champion index for the current frame.
33
+ * @returns Nothing.
34
+ */
35
+ export function renderPlaybackBird(
36
+ context: CanvasRenderingContext2D,
37
+ birdYPx: number,
38
+ birdIndex: number,
39
+ championBirdIndex: number,
40
+ ): void {
41
+ const birdGeometry = resolvePlaybackBirdGeometry(birdYPx);
42
+ const birdRenderStyle = resolveBirdRenderStyle(birdIndex, championBirdIndex);
43
+
44
+ drawChampionPlaybackBirdGlow(context, birdGeometry, birdRenderStyle);
45
+ drawPlaybackBirdBody(context, birdGeometry, birdRenderStyle);
46
+ }
47
+
48
+ /**
49
+ * Resolves the fixed bird geometry used by all body rendering passes.
50
+ *
51
+ * Geometry is snapped to integer pixels so the square body stays crisp instead
52
+ * of blurring across subpixel boundaries.
53
+ *
54
+ * @param birdYPx - Bird vertical position in world pixels.
55
+ * @returns Pixel-aligned square geometry for the bird body.
56
+ */
57
+ export function resolvePlaybackBirdGeometry(
58
+ birdYPx: number,
59
+ ): PlaybackBirdGeometry {
60
+ const birdSideLengthPx = Math.max(1, Math.round(FLAPPY_BIRD_RADIUS_PX * 2));
61
+
62
+ return {
63
+ birdSideLengthPx,
64
+ birdLeftPx: Math.round(FLAPPY_BIRD_X_PX - FLAPPY_BIRD_RADIUS_PX),
65
+ birdTopPx: Math.round(birdYPx - FLAPPY_BIRD_RADIUS_PX),
66
+ };
67
+ }
68
+
69
+ /**
70
+ * Draws the square bird body with its base neon glow.
71
+ *
72
+ * This is the standard body pass shared by champion and non-champion birds.
73
+ *
74
+ * @param context - Canvas 2D drawing context.
75
+ * @param birdGeometry - Pixel-aligned bird geometry.
76
+ * @param birdRenderStyle - Resolved bird style payload.
77
+ * @returns Nothing.
78
+ */
79
+ export function drawPlaybackBirdBody(
80
+ context: CanvasRenderingContext2D,
81
+ birdGeometry: PlaybackBirdGeometry,
82
+ birdRenderStyle: ReturnType<typeof resolveBirdRenderStyle>,
83
+ ): void {
84
+ context.globalAlpha = birdRenderStyle.birdOpacity;
85
+ context.fillStyle = birdRenderStyle.birdRenderColor;
86
+ context.shadowColor = birdRenderStyle.birdRenderColor;
87
+ context.shadowBlur = resolvePlaybackBirdBodyGlowBlur(birdRenderStyle);
88
+ context.fillRect(
89
+ birdGeometry.birdLeftPx,
90
+ birdGeometry.birdTopPx,
91
+ birdGeometry.birdSideLengthPx,
92
+ birdGeometry.birdSideLengthPx,
93
+ );
94
+ }
95
+
96
+ /**
97
+ * Draws the champion bird using the same two-pass additive outline glow method as pipes.
98
+ *
99
+ * Reusing the pipe-style glow language helps the whole playback scene feel like
100
+ * one visual system instead of unrelated rendering effects.
101
+ *
102
+ * @param context - Canvas 2D drawing context.
103
+ * @param birdGeometry - Pixel-aligned bird geometry.
104
+ * @param birdRenderStyle - Resolved bird style payload.
105
+ * @returns Nothing.
106
+ */
107
+ export function drawChampionPlaybackBirdGlow(
108
+ context: CanvasRenderingContext2D,
109
+ birdGeometry: PlaybackBirdGeometry,
110
+ birdRenderStyle: ReturnType<typeof resolveBirdRenderStyle>,
111
+ ): void {
112
+ if (!birdRenderStyle.isChampionBird) {
113
+ return;
114
+ }
115
+
116
+ const previousCompositeOperation = context.globalCompositeOperation;
117
+ const previousGlobalAlpha = context.globalAlpha;
118
+ const previousStrokeStyle = context.strokeStyle;
119
+ const previousShadowColor = context.shadowColor;
120
+ const previousShadowBlur = context.shadowBlur;
121
+ const previousLineWidth = context.lineWidth;
122
+ const previousShadowOffsetX = context.shadowOffsetX;
123
+ const previousShadowOffsetY = context.shadowOffsetY;
124
+
125
+ context.globalCompositeOperation = 'lighter';
126
+ context.strokeStyle = birdRenderStyle.birdRenderColor;
127
+ context.globalAlpha = FLAPPY_PIPE_OUTLINE_GLOW_ALPHA;
128
+ context.shadowColor = birdRenderStyle.birdRenderColor;
129
+ context.shadowBlur = FLAPPY_PIPE_OUTLINE_CYAN_GLOW_BLUR_PX;
130
+ context.shadowOffsetX = 0;
131
+ context.shadowOffsetY = 0;
132
+ context.lineWidth = FLAPPY_PIPE_OUTLINE_GLOW_STROKE_WIDTH_PX;
133
+ context.strokeRect(
134
+ birdGeometry.birdLeftPx,
135
+ birdGeometry.birdTopPx,
136
+ birdGeometry.birdSideLengthPx,
137
+ birdGeometry.birdSideLengthPx,
138
+ );
139
+
140
+ context.globalAlpha = 1;
141
+ context.shadowBlur = 0;
142
+ context.shadowColor = 'transparent';
143
+ context.lineWidth = FLAPPY_PIPE_OUTLINE_STROKE_WIDTH_PX;
144
+ context.strokeRect(
145
+ birdGeometry.birdLeftPx,
146
+ birdGeometry.birdTopPx,
147
+ birdGeometry.birdSideLengthPx,
148
+ birdGeometry.birdSideLengthPx,
149
+ );
150
+
151
+ context.globalCompositeOperation = previousCompositeOperation;
152
+ context.globalAlpha = previousGlobalAlpha;
153
+ context.strokeStyle = previousStrokeStyle;
154
+ context.shadowColor = previousShadowColor;
155
+ context.shadowBlur = previousShadowBlur;
156
+ context.lineWidth = previousLineWidth;
157
+ context.shadowOffsetX = previousShadowOffsetX;
158
+ context.shadowOffsetY = previousShadowOffsetY;
159
+ }
160
+
161
+ /**
162
+ * Resolves the body glow blur for one bird render pass.
163
+ *
164
+ * Champion birds receive a slightly stronger body glow than the rest of the
165
+ * population.
166
+ *
167
+ * @param birdRenderStyle - Resolved bird style payload.
168
+ * @returns Blur radius used behind the square bird body.
169
+ */
170
+ export function resolvePlaybackBirdBodyGlowBlur(
171
+ birdRenderStyle: ReturnType<typeof resolveBirdRenderStyle>,
172
+ ): number {
173
+ if (!birdRenderStyle.isChampionBird) {
174
+ return FLAPPY_NON_CHAMPION_BODY_GLOW_BLUR_PX;
175
+ }
176
+
177
+ return (
178
+ FLAPPY_BIRD_BODY_GLOW_BLUR_PX + FLAPPY_BIRD_CHAMPION_EXTRA_GLOW_BLUR_PX
179
+ );
180
+ }
@@ -0,0 +1,77 @@
1
+ import type { PlaybackFrameSceneContext } from './playback.frame-render.types';
2
+
3
+ /**
4
+ * Canvas-state helpers for playback frame rendering.
5
+ *
6
+ * These functions isolate the mutable canvas setup and teardown needed for one
7
+ * frame so the orchestration layer can read as declarative world rendering.
8
+ */
9
+
10
+ /**
11
+ * Resets the target canvas and base paint state before frame drawing begins.
12
+ *
13
+ * This establishes a predictable baseline before world-space transforms and glow
14
+ * effects are applied.
15
+ *
16
+ * @param context - Canvas 2D drawing context.
17
+ * @returns Nothing.
18
+ */
19
+ export function preparePlaybackFrameCanvas(
20
+ context: CanvasRenderingContext2D,
21
+ ): void {
22
+ // Step 1: Reset base paint state to a predictable source-over draw pass.
23
+ context.globalAlpha = 1;
24
+ context.globalCompositeOperation = 'source-over';
25
+ context.shadowBlur = 0;
26
+ context.shadowColor = 'transparent';
27
+ context.shadowOffsetX = 0;
28
+ context.shadowOffsetY = 0;
29
+
30
+ // Step 2: Clear the full backing canvas before drawing the next frame.
31
+ context.clearRect(0, 0, context.canvas.width, context.canvas.height);
32
+ }
33
+
34
+ /**
35
+ * Applies the viewport transform used for world-space frame rendering.
36
+ *
37
+ * After this transform, draw calls can work in simulation coordinates instead of
38
+ * raw canvas pixel coordinates.
39
+ *
40
+ * @param context - Canvas 2D drawing context.
41
+ * @param sceneContext - Shared scene geometry for the frame.
42
+ * @returns Nothing.
43
+ */
44
+ export function beginPlaybackFrameViewportTransform(
45
+ context: CanvasRenderingContext2D,
46
+ sceneContext: PlaybackFrameSceneContext,
47
+ ): void {
48
+ // Step 1: Save the caller state before applying viewport-space transforms.
49
+ context.save();
50
+
51
+ // Step 2: Translate and scale into the current world viewport.
52
+ context.translate(
53
+ sceneContext.viewport.offsetXPx,
54
+ sceneContext.viewport.offsetYPx,
55
+ );
56
+ context.scale(sceneContext.viewport.scale, sceneContext.viewport.scale);
57
+ context.translate(-sceneContext.cameraLeftPx, 0);
58
+ }
59
+
60
+ /**
61
+ * Restores the caller canvas state after viewport-space frame drawing.
62
+ *
63
+ * This ensures later canvas users do not inherit playback-specific transform or
64
+ * alpha state.
65
+ *
66
+ * @param context - Canvas 2D drawing context.
67
+ * @returns Nothing.
68
+ */
69
+ export function finalizePlaybackFrameCanvas(
70
+ context: CanvasRenderingContext2D,
71
+ ): void {
72
+ // Step 1: Reset global alpha before restoring the caller transform state.
73
+ context.globalAlpha = 1;
74
+
75
+ // Step 2: Restore the caller state saved before viewport transforms.
76
+ context.restore();
77
+ }
@@ -0,0 +1,167 @@
1
+ import {
2
+ FLAPPY_BIRD_RADIUS_PX,
3
+ FLAPPY_BIRD_X_PX,
4
+ FLAPPY_PIPE_WIDTH_PX,
5
+ } from '../../../constants/constants';
6
+ import type {
7
+ PopulationRenderState,
8
+ TrailState,
9
+ } from '../../browser-entry.types';
10
+ import { resolvePlaybackGroundGridPipeConnectionProfile } from '../background/ground-grid/playback.background.ground-grid.math.utils';
11
+ import { renderPlaybackBackground } from '../background/playback.background';
12
+ import { drawPipeNeonOutline } from '../playback.render.service';
13
+ import type {
14
+ PlaybackBirdRenderer,
15
+ PlaybackFrameSceneContext,
16
+ PlaybackTrailRenderer,
17
+ PlaybackTrailStyleResolver,
18
+ } from './playback.frame-render.types';
19
+
20
+ /**
21
+ * Entity-layer rendering helpers for playback frames.
22
+ *
23
+ * These services paint the world-space contents of a frame once the scene and
24
+ * canvas transforms have already been resolved.
25
+ */
26
+
27
+ /**
28
+ * Draws the split playback background for the current world viewport.
29
+ *
30
+ * Background painting is delegated to the dedicated background subsystem so this
31
+ * layer can stay focused on frame composition order.
32
+ *
33
+ * @param context - Canvas 2D drawing context.
34
+ * @param renderState - Mutable simulation state snapshot.
35
+ * @param sceneContext - Shared scene geometry for the frame.
36
+ * @returns Nothing.
37
+ */
38
+ export function renderPlaybackFrameBackground(
39
+ context: CanvasRenderingContext2D,
40
+ renderState: PopulationRenderState,
41
+ sceneContext: PlaybackFrameSceneContext,
42
+ ): void {
43
+ // Step 1: Render the world-space background behind all gameplay entities.
44
+ renderPlaybackBackground(context, {
45
+ viewportLeftXPx: sceneContext.cameraLeftPx,
46
+ visibleWorldWidthPx: sceneContext.visibleWorldWidthPx,
47
+ visibleWorldHeightPx: sceneContext.visibleWorldHeightPx,
48
+ frameIndex: renderState.frameIndex,
49
+ scrollBasePx: renderState.cumulativePipeTravelPx,
50
+ });
51
+ }
52
+
53
+ /**
54
+ * Draws all visible pipe segments and their neon outlines for the frame.
55
+ *
56
+ * Pipes are rendered as upper and lower segments connected to the projected
57
+ * floor profile used by the background grid.
58
+ *
59
+ * @param context - Canvas 2D drawing context.
60
+ * @param renderState - Mutable simulation state snapshot.
61
+ * @param sceneContext - Shared scene geometry for the frame.
62
+ * @returns Nothing.
63
+ */
64
+ export function renderPlaybackFramePipes(
65
+ context: CanvasRenderingContext2D,
66
+ renderState: PopulationRenderState,
67
+ sceneContext: PlaybackFrameSceneContext,
68
+ ): void {
69
+ // Step 1: Resolve the lifted lower-pipe floor from the shared grid projection.
70
+ const pipeConnectionProfile = resolvePlaybackGroundGridPipeConnectionProfile(
71
+ sceneContext.visibleWorldHeightPx,
72
+ );
73
+
74
+ // Step 2: Render each pipe pair against the projected floor height.
75
+ for (const pipe of renderState.pipes) {
76
+ const gapHalfPx = pipe.gapSizePx * 0.5;
77
+ const gapTopPx = pipe.gapCenterYPx - gapHalfPx;
78
+ const gapBottomPx = pipe.gapCenterYPx + gapHalfPx;
79
+
80
+ drawPipeNeonOutline(context, pipe.xPx, 0, FLAPPY_PIPE_WIDTH_PX, gapTopPx);
81
+
82
+ drawPipeNeonOutline(
83
+ context,
84
+ pipe.xPx,
85
+ gapBottomPx,
86
+ FLAPPY_PIPE_WIDTH_PX,
87
+ pipeConnectionProfile.pipeFloorYPx - gapBottomPx,
88
+ );
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Draws all active birds for the current frame.
94
+ *
95
+ * Only live birds are painted so the playback frame reflects the active
96
+ * population rather than leaving ghost bodies behind.
97
+ *
98
+ * @param context - Canvas 2D drawing context.
99
+ * @param renderState - Mutable simulation state snapshot.
100
+ * @param sceneContext - Shared scene geometry for the frame.
101
+ * @param renderBird - Bird body renderer owned by the detailed utility layer.
102
+ * @returns Nothing.
103
+ */
104
+ export function renderPlaybackFrameBirds(
105
+ context: CanvasRenderingContext2D,
106
+ renderState: PopulationRenderState,
107
+ sceneContext: PlaybackFrameSceneContext,
108
+ renderBird: PlaybackBirdRenderer,
109
+ ): void {
110
+ // Step 1: Render only currently active birds.
111
+ renderState.birds.forEach((bird, birdIndex) => {
112
+ if (bird.done) {
113
+ return;
114
+ }
115
+
116
+ renderBird(context, bird.yPx, birdIndex, sceneContext.championBirdIndex);
117
+ });
118
+ }
119
+
120
+ /**
121
+ * Draws stepped trails for all active birds in the frame.
122
+ *
123
+ * In practice the trail cache usually contains only the champion trail, but the
124
+ * renderer stays generic and asks the trail-style policy how each active bird
125
+ * should be painted.
126
+ *
127
+ * @param context - Canvas 2D drawing context.
128
+ * @param renderState - Mutable simulation state snapshot.
129
+ * @param trailState - Leader trail render cache.
130
+ * @param sceneContext - Shared scene geometry for the frame.
131
+ * @param resolveTrailStyle - Trail style resolver owned by the detailed utility layer.
132
+ * @param renderTrail - Trail segment renderer owned by the detailed utility layer.
133
+ * @returns Nothing.
134
+ */
135
+ export function renderPlaybackFrameTrails(
136
+ context: CanvasRenderingContext2D,
137
+ renderState: PopulationRenderState,
138
+ trailState: TrailState,
139
+ sceneContext: PlaybackFrameSceneContext,
140
+ resolveTrailStyle: PlaybackTrailStyleResolver,
141
+ renderTrail: PlaybackTrailRenderer,
142
+ ): void {
143
+ // Step 1: Render only trails for active birds with available trail data.
144
+ renderState.birds.forEach((bird, birdIndex) => {
145
+ if (bird.done) {
146
+ return;
147
+ }
148
+
149
+ const birdTrailPoints = trailState.birdTrailsY[birdIndex];
150
+ if (!birdTrailPoints || birdTrailPoints.length === 0) {
151
+ return;
152
+ }
153
+
154
+ const { baseOpacity, trailColor } = resolveTrailStyle(
155
+ birdIndex,
156
+ sceneContext.championBirdIndex,
157
+ );
158
+ renderTrail(
159
+ context,
160
+ birdTrailPoints,
161
+ trailColor,
162
+ FLAPPY_BIRD_X_PX - FLAPPY_BIRD_RADIUS_PX,
163
+ baseOpacity,
164
+ sceneContext.edgeBounds,
165
+ );
166
+ });
167
+ }
@@ -0,0 +1,57 @@
1
+ import {
2
+ FLAPPY_BIRD_VIEWPORT_X_RATIO,
3
+ FLAPPY_BIRD_X_PX,
4
+ } from '../../../constants/constants';
5
+ import type { PopulationRenderState } from '../../browser-entry.types';
6
+ import { resolveWorldViewport } from '../../browser-entry.viewport.utils';
7
+ import { resolveChampionBirdIndex } from '../playback.render.utils';
8
+ import type { PlaybackFrameSceneContext } from './playback.frame-render.types';
9
+
10
+ /**
11
+ * Scene-resolution helpers for playback frame rendering.
12
+ *
13
+ * Before anything can be painted, the renderer needs a camera-relative view of
14
+ * the world: viewport scale, visible bounds, camera origin, and which bird is
15
+ * currently the champion.
16
+ */
17
+
18
+ /**
19
+ * Resolves the shared scene contract used by one frame render pass.
20
+ *
21
+ * The camera is anchored so the focal bird region stays at a readable screen
22
+ * position while the world scrolls beneath it.
23
+ *
24
+ * @param context - Canvas 2D drawing context.
25
+ * @param renderState - Mutable simulation state snapshot.
26
+ * @returns Viewport, camera, and edge-bounds state for the frame.
27
+ */
28
+ export function resolvePlaybackFrameSceneContext(
29
+ context: CanvasRenderingContext2D,
30
+ renderState: PopulationRenderState,
31
+ ): PlaybackFrameSceneContext {
32
+ // Step 1: Resolve viewport scaling and visible world bounds.
33
+ const viewport = resolveWorldViewport(context.canvas);
34
+ const visibleWorldWidthPx = Math.max(1, renderState.visibleWorldWidthPx);
35
+ const visibleWorldHeightPx = Math.max(1, renderState.visibleWorldHeightPx);
36
+
37
+ // Step 2: Resolve camera position and champion index for this frame.
38
+ const desiredBirdScreenXPx =
39
+ visibleWorldWidthPx * FLAPPY_BIRD_VIEWPORT_X_RATIO;
40
+ const cameraLeftPx = FLAPPY_BIRD_X_PX - desiredBirdScreenXPx;
41
+ const championBirdIndex = resolveChampionBirdIndex(renderState);
42
+
43
+ // Step 3: Return the shared frame scene context.
44
+ return {
45
+ viewport,
46
+ visibleWorldWidthPx,
47
+ visibleWorldHeightPx,
48
+ cameraLeftPx,
49
+ championBirdIndex,
50
+ edgeBounds: {
51
+ leftXPx: cameraLeftPx,
52
+ rightXPx: cameraLeftPx + visibleWorldWidthPx,
53
+ topYPx: 0,
54
+ bottomYPx: visibleWorldHeightPx,
55
+ },
56
+ };
57
+ }
@@ -0,0 +1,176 @@
1
+ import type {
2
+ PopulationRenderState,
3
+ TrailState,
4
+ } from '../../../../../../test/examples/flappy_bird/browser-entry/browser-entry.types';
5
+ import { updateTrailState } from '../../../../../../test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.service';
6
+ import { renderPlaybackFrameBirds } from '../../../../../../test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.services';
7
+ import { renderPlaybackBird } from '../../../../../../test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.utils';
8
+ import { FLAPPY_CHAMPION_TRAIL_MAX_POINTS } from '../../../../../../test/examples/flappy_bird/constants/constants.birds';
9
+
10
+ describe('updateTrailState', () => {
11
+ it('retains a trail for the current champion only', () => {
12
+ const renderState = createRenderState({
13
+ birds: [
14
+ createBird({ pipesPassed: 1, framesSurvived: 10 }),
15
+ createBird({ pipesPassed: 3, framesSurvived: 20 }),
16
+ ],
17
+ });
18
+ const trailState: TrailState = {
19
+ birdTrailsY: [[{ frameIndex: 4, yPx: 10 }], []],
20
+ };
21
+
22
+ updateTrailState(trailState, renderState);
23
+
24
+ expect(trailState.birdTrailsY.map((birdTrail) => birdTrail.length)).toEqual(
25
+ [0, 1],
26
+ );
27
+ });
28
+
29
+ it('clears trail history for eliminated birds', () => {
30
+ const renderState = createRenderState({
31
+ birds: [createBird({ done: true, pipesPassed: 5, framesSurvived: 30 })],
32
+ });
33
+ const trailState: TrailState = {
34
+ birdTrailsY: [[{ frameIndex: 7, yPx: 24 }]],
35
+ };
36
+
37
+ updateTrailState(trailState, renderState);
38
+
39
+ expect(trailState.birdTrailsY[0].length).toBe(0);
40
+ });
41
+
42
+ it('caps champion trail history to the short champion limit', () => {
43
+ const renderState = createRenderState({
44
+ frameIndex: FLAPPY_CHAMPION_TRAIL_MAX_POINTS + 5,
45
+ birds: [createBird({ pipesPassed: 2, framesSurvived: 12 })],
46
+ });
47
+ const trailState: TrailState = {
48
+ birdTrailsY: [
49
+ Array.from(
50
+ { length: FLAPPY_CHAMPION_TRAIL_MAX_POINTS },
51
+ (_, frameIndex) => ({
52
+ frameIndex,
53
+ yPx: frameIndex,
54
+ }),
55
+ ),
56
+ ],
57
+ };
58
+
59
+ updateTrailState(trailState, renderState);
60
+
61
+ expect(trailState.birdTrailsY[0].length).toBe(
62
+ FLAPPY_CHAMPION_TRAIL_MAX_POINTS,
63
+ );
64
+ });
65
+
66
+ it('keeps rendering all active birds while trails stay champion-only', () => {
67
+ const renderBird = jest.fn();
68
+ const renderState = createRenderState({
69
+ birds: [
70
+ createBird({ pipesPassed: 1, framesSurvived: 10 }),
71
+ createBird({ pipesPassed: 3, framesSurvived: 20 }),
72
+ createBird({ done: true, pipesPassed: 0, framesSurvived: 5 }),
73
+ ],
74
+ });
75
+
76
+ renderPlaybackFrameBirds(
77
+ {} as CanvasRenderingContext2D,
78
+ renderState,
79
+ createSceneContext(),
80
+ renderBird,
81
+ );
82
+
83
+ expect(renderBird.mock.calls.map(([, , birdIndex]) => birdIndex)).toEqual([
84
+ 0, 1,
85
+ ]);
86
+ });
87
+
88
+ it('renders non-champion birds without champion highlight passes', () => {
89
+ const drawingContext = createMockDrawingContext();
90
+
91
+ renderPlaybackBird(drawingContext, 40, 0, 1);
92
+
93
+ expect(drawingContext.strokeRect).not.toHaveBeenCalled();
94
+ });
95
+
96
+ it('keeps champion highlight passes for the current leader', () => {
97
+ const drawingContext = createMockDrawingContext();
98
+
99
+ renderPlaybackBird(drawingContext, 40, 1, 1);
100
+
101
+ expect(drawingContext.strokeRect).toHaveBeenCalledTimes(2);
102
+ });
103
+ });
104
+
105
+ function createRenderState(overrides?: {
106
+ frameIndex?: number;
107
+ birds?: PopulationRenderState['birds'];
108
+ }): PopulationRenderState {
109
+ return {
110
+ frameIndex: overrides?.frameIndex ?? 8,
111
+ cumulativePipeTravelPx: 0,
112
+ visibleWorldWidthPx: 640,
113
+ visibleWorldHeightPx: 480,
114
+ nextPipeId: 0,
115
+ lastSpawnedPipeGapPx: 0,
116
+ lastSpawnedPipeGapCenterYPx: 0,
117
+ lastSpawnedPipeSpawnIntervalFrames: 0,
118
+ framesUntilNextPipeSpawn: 0,
119
+ pipes: [],
120
+ birds: overrides?.birds ?? [],
121
+ };
122
+ }
123
+
124
+ function createBird(overrides?: {
125
+ yPx?: number;
126
+ pipesPassed?: number;
127
+ framesSurvived?: number;
128
+ done?: boolean;
129
+ }): PopulationRenderState['birds'][number] {
130
+ return {
131
+ yPx: overrides?.yPx ?? 32,
132
+ pipesPassed: overrides?.pipesPassed ?? 0,
133
+ framesSurvived: overrides?.framesSurvived ?? 0,
134
+ done: overrides?.done ?? false,
135
+ };
136
+ }
137
+
138
+ function createSceneContext() {
139
+ return {
140
+ viewport: {
141
+ offsetXPx: 0,
142
+ offsetYPx: 0,
143
+ scale: 1,
144
+ },
145
+ visibleWorldWidthPx: 640,
146
+ visibleWorldHeightPx: 480,
147
+ cameraLeftPx: 0,
148
+ championBirdIndex: 1,
149
+ edgeBounds: {
150
+ leftXPx: 0,
151
+ rightXPx: 640,
152
+ topYPx: 0,
153
+ bottomYPx: 480,
154
+ },
155
+ };
156
+ }
157
+
158
+ function createMockDrawingContext(): CanvasRenderingContext2D {
159
+ return {
160
+ fillRect: jest.fn(),
161
+ strokeRect: jest.fn(),
162
+ beginPath: jest.fn(),
163
+ moveTo: jest.fn(),
164
+ lineTo: jest.fn(),
165
+ stroke: jest.fn(),
166
+ globalAlpha: 1,
167
+ globalCompositeOperation: 'source-over',
168
+ fillStyle: '#000000',
169
+ strokeStyle: '#000000',
170
+ shadowColor: 'transparent',
171
+ shadowBlur: 0,
172
+ shadowOffsetX: 0,
173
+ shadowOffsetY: 0,
174
+ lineWidth: 1,
175
+ } as unknown as CanvasRenderingContext2D;
176
+ }