@reicek/neataptic-ts 0.1.21 → 0.1.22

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 (223) hide show
  1. package/.github/agents/boundary-mapper.agent.md +29 -0
  2. package/.github/agents/docs-scout.agent.md +29 -0
  3. package/.github/agents/plan-scout.agent.md +29 -0
  4. package/.github/agents/solid-split.agent.md +138 -0
  5. package/.github/copilot-instructions.md +103 -0
  6. package/package.json +6 -3
  7. package/plans/ES2023 migration +13 -8
  8. package/plans/Evolution_Training_Interoperability_Contracts.md +1 -1
  9. package/plans/Interactive_Examples_and_Learning_Path.md +10 -2
  10. package/plans/Memory_Optimization.md +3 -3
  11. package/plans/README.md +63 -0
  12. package/plans/Roadmap.md +15 -3
  13. package/plans/asciiMaze_SOLID_split.done.md +130 -0
  14. package/plans/flappy_bird_SOLID_split.done.md +67 -0
  15. package/scripts/assets/theme.css +221 -34
  16. package/scripts/copy-examples.mjs +9 -5
  17. package/scripts/export-onnx.mjs +3 -3
  18. package/scripts/generate-bench-tables.mjs +10 -10
  19. package/scripts/generate-bench-tables.ts +10 -10
  20. package/scripts/generate-docs.ts +1415 -449
  21. package/scripts/render-docs-html.ts +15 -8
  22. package/src/README.md +101 -223
  23. package/src/architecture/README.md +57 -185
  24. package/src/architecture/layer/README.md +38 -38
  25. package/src/architecture/network/README.md +33 -31
  26. package/src/architecture/network/activate/README.md +77 -77
  27. package/src/architecture/network/connect/README.md +15 -13
  28. package/src/architecture/network/deterministic/README.md +7 -7
  29. package/src/architecture/network/evolve/README.md +44 -44
  30. package/src/architecture/network/gating/README.md +20 -20
  31. package/src/architecture/network/genetic/README.md +51 -51
  32. package/src/architecture/network/mutate/README.md +97 -97
  33. package/src/architecture/network/onnx/README.md +264 -264
  34. package/src/architecture/network/prune/README.md +39 -39
  35. package/src/architecture/network/remove/README.md +26 -26
  36. package/src/architecture/network/serialize/README.md +56 -56
  37. package/src/architecture/network/slab/README.md +61 -61
  38. package/src/architecture/network/standalone/README.md +24 -24
  39. package/src/architecture/network/stats/README.md +9 -9
  40. package/src/architecture/network/topology/README.md +46 -46
  41. package/src/architecture/network/training/README.md +21 -21
  42. package/src/methods/README.md +9 -87
  43. package/src/multithreading/README.md +8 -77
  44. package/src/multithreading/workers/README.md +2 -2
  45. package/src/multithreading/workers/browser/README.md +0 -6
  46. package/src/multithreading/workers/node/README.md +0 -3
  47. package/src/neat/README.md +562 -568
  48. package/src/utils/README.md +18 -18
  49. package/test/examples/asciiMaze/README.md +59 -59
  50. package/test/examples/asciiMaze/asciiMaze.e2e.test.ts +14 -9
  51. package/test/examples/asciiMaze/browser-entry/README.md +196 -0
  52. package/test/examples/asciiMaze/browser-entry/browser-entry.abort.services.ts +95 -0
  53. package/test/examples/asciiMaze/browser-entry/browser-entry.constants.ts +23 -0
  54. package/test/examples/asciiMaze/browser-entry/browser-entry.curriculum.services.ts +115 -0
  55. package/test/examples/asciiMaze/browser-entry/browser-entry.globals.services.ts +106 -0
  56. package/test/examples/asciiMaze/browser-entry/browser-entry.host.services.ts +157 -0
  57. package/test/examples/asciiMaze/browser-entry/browser-entry.services.ts +14 -0
  58. package/test/examples/asciiMaze/browser-entry/browser-entry.ts +129 -0
  59. package/test/examples/asciiMaze/browser-entry/browser-entry.types.ts +120 -0
  60. package/test/examples/asciiMaze/browser-entry/browser-entry.utils.ts +98 -0
  61. package/test/examples/asciiMaze/browser-entry.ts +10 -576
  62. package/test/examples/asciiMaze/dashboardManager/README.md +276 -0
  63. package/test/examples/asciiMaze/dashboardManager/archive/README.md +16 -0
  64. package/test/examples/asciiMaze/dashboardManager/archive/dashboardManager.archive.services.ts +267 -0
  65. package/test/examples/asciiMaze/dashboardManager/dashboardManager.constants.ts +35 -0
  66. package/test/examples/asciiMaze/dashboardManager/dashboardManager.services.ts +103 -0
  67. package/test/examples/asciiMaze/dashboardManager/dashboardManager.ts +181 -0
  68. package/test/examples/asciiMaze/dashboardManager/dashboardManager.types.ts +267 -0
  69. package/test/examples/asciiMaze/dashboardManager/dashboardManager.utils.ts +254 -0
  70. package/test/examples/asciiMaze/dashboardManager/live/README.md +14 -0
  71. package/test/examples/asciiMaze/dashboardManager/live/dashboardManager.live.services.ts +264 -0
  72. package/test/examples/asciiMaze/dashboardManager/telemetry/README.md +47 -0
  73. package/test/examples/asciiMaze/dashboardManager/telemetry/dashboardManager.telemetry.services.ts +513 -0
  74. package/test/examples/asciiMaze/dashboardManager.ts +13 -2335
  75. package/test/examples/asciiMaze/evolutionEngine/README.md +1058 -0
  76. package/test/examples/asciiMaze/evolutionEngine/curriculumPhase.ts +90 -0
  77. package/test/examples/asciiMaze/evolutionEngine/engineState.constants.ts +36 -0
  78. package/test/examples/asciiMaze/evolutionEngine/engineState.ts +58 -513
  79. package/test/examples/asciiMaze/evolutionEngine/engineState.types.ts +212 -0
  80. package/test/examples/asciiMaze/evolutionEngine/engineState.utils.ts +301 -0
  81. package/test/examples/asciiMaze/evolutionEngine/evolutionEngine.types.ts +445 -0
  82. package/test/examples/asciiMaze/evolutionEngine/evolutionLoop.ts +81 -50
  83. package/test/examples/asciiMaze/evolutionEngine/optionsAndSetup.ts +2 -4
  84. package/test/examples/asciiMaze/evolutionEngine/populationDynamics.ts +17 -33
  85. package/test/examples/asciiMaze/evolutionEngine/populationPruning.ts +1 -1
  86. package/test/examples/asciiMaze/evolutionEngine/rngAndTiming.ts +1 -2
  87. package/test/examples/asciiMaze/evolutionEngine/sampling.ts +1 -1
  88. package/test/examples/asciiMaze/evolutionEngine/scratchPools.ts +2 -5
  89. package/test/examples/asciiMaze/evolutionEngine/setupHelpers.ts +30 -37
  90. package/test/examples/asciiMaze/evolutionEngine/telemetryMetrics.ts +16 -58
  91. package/test/examples/asciiMaze/evolutionEngine/trainingWarmStart.ts +2 -2
  92. package/test/examples/asciiMaze/evolutionEngine.ts +55 -55
  93. package/test/examples/asciiMaze/fitness.ts +2 -2
  94. package/test/examples/asciiMaze/fitness.types.ts +65 -0
  95. package/test/examples/asciiMaze/interfaces.ts +64 -1352
  96. package/test/examples/asciiMaze/mazeMovement/README.md +356 -0
  97. package/test/examples/asciiMaze/mazeMovement/finalization/README.md +49 -0
  98. package/test/examples/asciiMaze/mazeMovement/finalization/mazeMovement.finalization.ts +138 -0
  99. package/test/examples/asciiMaze/mazeMovement/mazeMovement.constants.ts +101 -0
  100. package/test/examples/asciiMaze/mazeMovement/mazeMovement.services.ts +230 -0
  101. package/test/examples/asciiMaze/mazeMovement/mazeMovement.ts +299 -0
  102. package/test/examples/asciiMaze/mazeMovement/mazeMovement.types.ts +185 -0
  103. package/test/examples/asciiMaze/mazeMovement/mazeMovement.utils.ts +153 -0
  104. package/test/examples/asciiMaze/mazeMovement/policy/README.md +91 -0
  105. package/test/examples/asciiMaze/mazeMovement/policy/mazeMovement.policy.ts +467 -0
  106. package/test/examples/asciiMaze/mazeMovement/runtime/README.md +95 -0
  107. package/test/examples/asciiMaze/mazeMovement/runtime/mazeMovement.runtime.ts +354 -0
  108. package/test/examples/asciiMaze/mazeMovement/shaping/README.md +124 -0
  109. package/test/examples/asciiMaze/mazeMovement/shaping/mazeMovement.shaping.ts +459 -0
  110. package/test/examples/asciiMaze/mazeMovement.ts +12 -2978
  111. package/test/examples/flappy_bird/Trace-20260309T191949.json +24124 -0
  112. package/test/examples/flappy_bird/browser-entry/README.md +1129 -0
  113. package/test/examples/flappy_bird/browser-entry/browser-entry.host.utils.ts +4 -324
  114. package/test/examples/flappy_bird/browser-entry/browser-entry.network-view.utils.ts +6 -399
  115. package/test/examples/flappy_bird/browser-entry/browser-entry.playback.utils.ts +1 -717
  116. package/test/examples/flappy_bird/browser-entry/browser-entry.spawn.utils.ts +11 -31
  117. package/test/examples/flappy_bird/browser-entry/browser-entry.visualization.utils.ts +15 -893
  118. package/test/examples/flappy_bird/browser-entry/host/README.md +307 -0
  119. package/test/examples/flappy_bird/browser-entry/host/host.resize.service.ts +1 -295
  120. package/test/examples/flappy_bird/browser-entry/host/host.ts +562 -6
  121. package/test/examples/flappy_bird/browser-entry/host/resize/README.md +274 -0
  122. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.constants.ts +31 -0
  123. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.services.ts +360 -0
  124. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.ts +117 -0
  125. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.types.ts +63 -0
  126. package/test/examples/flappy_bird/browser-entry/host/resize/host.resize.service.utils.ts +250 -0
  127. package/test/examples/flappy_bird/browser-entry/network-view/README.md +399 -0
  128. package/test/examples/flappy_bird/browser-entry/network-view/network-view.topology.utils.ts +255 -0
  129. package/test/examples/flappy_bird/browser-entry/network-view/network-view.ts +802 -7
  130. package/test/examples/flappy_bird/browser-entry/playback/README.md +684 -0
  131. package/test/examples/flappy_bird/browser-entry/playback/background/README.md +277 -0
  132. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/README.md +770 -0
  133. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.cache.services.ts +178 -0
  134. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.constants.ts +107 -0
  135. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.geometry.utils.ts +518 -0
  136. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.math.utils.ts +117 -0
  137. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.pulse.utils.ts +233 -0
  138. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.services.ts +211 -0
  139. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.ts +48 -0
  140. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.types.ts +212 -0
  141. package/test/examples/flappy_bird/browser-entry/playback/background/ground-grid/playback.background.ground-grid.utils.ts +81 -0
  142. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.cache.services.ts +96 -0
  143. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.constants.ts +62 -0
  144. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.services.ts +244 -0
  145. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.ts +53 -0
  146. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.types.ts +68 -0
  147. package/test/examples/flappy_bird/browser-entry/playback/background/playback.background.utils.ts +100 -0
  148. package/test/examples/flappy_bird/browser-entry/playback/frame-render/README.md +310 -0
  149. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.service.ts +92 -0
  150. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.services.ts +272 -0
  151. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types.ts +39 -0
  152. package/test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.utils.ts +493 -0
  153. package/test/examples/flappy_bird/browser-entry/playback/playback.constants.ts +1 -1
  154. package/test/examples/flappy_bird/browser-entry/playback/playback.frame-render.service.ts +4 -0
  155. package/test/examples/flappy_bird/browser-entry/playback/playback.snapshot.utils.ts +44 -0
  156. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.service.ts +39 -122
  157. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.services.ts +272 -0
  158. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.types.ts +62 -0
  159. package/test/examples/flappy_bird/browser-entry/playback/playback.starfield.utils.ts +11 -4
  160. package/test/examples/flappy_bird/browser-entry/playback/playback.ts +409 -8
  161. package/test/examples/flappy_bird/browser-entry/playback/playback.types.ts +4 -12
  162. package/test/examples/flappy_bird/browser-entry/runtime/README.md +235 -0
  163. package/test/examples/flappy_bird/browser-entry/runtime/runtime.evolution-launch.service.ts +45 -0
  164. package/test/examples/flappy_bird/browser-entry/runtime/runtime.lifecycle.service.ts +81 -0
  165. package/test/examples/flappy_bird/browser-entry/runtime/runtime.startup.service.ts +74 -0
  166. package/test/examples/flappy_bird/browser-entry/runtime/runtime.ts +31 -121
  167. package/test/examples/flappy_bird/browser-entry/runtime/runtime.types.ts +36 -0
  168. package/test/examples/flappy_bird/browser-entry/visualization/README.md +557 -0
  169. package/test/examples/flappy_bird/browser-entry/visualization/visualization.constants.ts +110 -0
  170. package/test/examples/flappy_bird/browser-entry/visualization/visualization.draw.service.ts +957 -19
  171. package/test/examples/flappy_bird/browser-entry/visualization/visualization.legend.utils.ts +138 -3
  172. package/test/examples/flappy_bird/browser-entry/visualization/visualization.topology.utils.ts +3 -27
  173. package/test/examples/flappy_bird/browser-entry/visualization/visualization.ts +1 -23
  174. package/test/examples/flappy_bird/browser-entry/worker-channel/README.md +156 -0
  175. package/test/examples/flappy_bird/constants/README.md +1179 -0
  176. package/test/examples/flappy_bird/constants/constants.network-view.ts +24 -0
  177. package/test/examples/flappy_bird/constants/constants.palette.ts +7 -0
  178. package/test/examples/flappy_bird/constants/constants.starfield.ts +78 -3
  179. package/test/examples/flappy_bird/environment/README.md +143 -0
  180. package/test/examples/flappy_bird/environment/environment.observation.utils.ts +1 -19
  181. package/test/examples/flappy_bird/environment/environment.step.service.ts +3 -66
  182. package/test/examples/flappy_bird/evaluation/README.md +130 -0
  183. package/test/examples/flappy_bird/evaluation/evaluation.fitness.utils.ts +1 -1
  184. package/test/examples/flappy_bird/evaluation/evaluation.rollout.service.ts +5 -375
  185. package/test/examples/flappy_bird/evaluation/rollout/README.md +291 -0
  186. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.constants.ts +30 -0
  187. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.service.ts +58 -0
  188. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.services.ts +310 -0
  189. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.types.ts +56 -0
  190. package/test/examples/flappy_bird/evaluation/rollout/evaluation.rollout.utils.ts +368 -0
  191. package/test/examples/flappy_bird/flappy-evolution-worker/README.md +618 -0
  192. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.playback.service.ts +7 -7
  193. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.frame.service.ts +364 -0
  194. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.types.ts +14 -0
  195. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.simulation.utils.ts +4 -201
  196. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.ts +184 -345
  197. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.warm-start.service.ts +291 -0
  198. package/test/examples/flappy_bird/flappy.simulation.shared.utils.ts +5 -0
  199. package/test/examples/flappy_bird/simulation-shared/README.md +417 -0
  200. package/test/examples/flappy_bird/simulation-shared/observation/README.md +183 -0
  201. package/test/examples/flappy_bird/simulation-shared/observation/observation.features.utils.ts +301 -0
  202. package/test/examples/flappy_bird/simulation-shared/observation/observation.ts +9 -0
  203. package/test/examples/flappy_bird/simulation-shared/observation/observation.vector.utils.ts +59 -0
  204. package/test/examples/flappy_bird/simulation-shared/simulation-shared.observation.utils.ts +5 -403
  205. package/test/examples/flappy_bird/simulation-shared/simulation-shared.spawn.utils.ts +20 -6
  206. package/test/examples/flappy_bird/{evaluation/evaluation.statistics.utils.ts → simulation-shared/simulation-shared.statistics.utils.ts} +23 -8
  207. package/test/examples/flappy_bird/trainer/README.md +563 -0
  208. package/test/examples/flappy_bird/trainer/evaluation/README.md +199 -0
  209. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.constants.ts +9 -0
  210. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.services.ts +73 -0
  211. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.ts +165 -0
  212. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.types.ts +25 -0
  213. package/test/examples/flappy_bird/trainer/evaluation/trainer.evaluation.service.utils.ts +161 -0
  214. package/test/examples/flappy_bird/trainer/trainer.evaluation.service.ts +13 -0
  215. package/test/examples/flappy_bird/trainer/trainer.report.service.services.ts +181 -0
  216. package/test/examples/flappy_bird/trainer/trainer.report.service.ts +126 -0
  217. package/test/examples/flappy_bird/trainer/trainer.selection.utils.ts +89 -0
  218. package/test/examples/flappy_bird/trainer/trainer.ts +11 -553
  219. package/test/examples/flappy_bird/browser-entry/browser-entry.utils.ts +0 -12
  220. package/test/examples/flappy_bird/environment/environment.ts +0 -7
  221. package/test/examples/flappy_bird/evaluation/evaluation.ts +0 -7
  222. package/test/examples/flappy_bird/simulation-shared/simulation-shared.ts +0 -15
  223. package/test/examples/flappy_bird/trainer/trainer.statistics.utils.ts +0 -78
@@ -1,5 +1,64 @@
1
- import type { PlaybackFrameStats } from '../browser-entry.types';
2
- import { animatePopulationEpisodeInternal } from '../browser-entry.playback.utils';
1
+ import {
2
+ resolveAliveBirdCount,
3
+ resolveLeaderPipesPassed,
4
+ } from '../browser-entry.observation.utils';
5
+ import type {
6
+ PlaybackFrameStats,
7
+ PopulationRenderState,
8
+ TrailState,
9
+ } from '../browser-entry.types';
10
+ import {
11
+ resolveVisibleWorldHeightPx,
12
+ resolveVisibleWorldWidthPx,
13
+ } from '../browser-entry.viewport.utils';
14
+ import { requestWorkerPlaybackStep } from '../worker-channel/worker-channel';
15
+ import { FLAPPY_EMULATION_SPEED_MULTIPLIER } from '../../constants/constants';
16
+ import {
17
+ renderPopulationFrame,
18
+ updateTrailState,
19
+ } from './frame-render/playback.frame-render.service';
20
+ import { nextAnimationFrame } from './playback.loop.service';
21
+ import {
22
+ applyPlaybackSnapshot,
23
+ resolveLeaderFramesSurvived,
24
+ } from './playback.snapshot.utils';
25
+ import {
26
+ resolvePlaybackCompletionSummary,
27
+ resolvePlaybackFrameStats,
28
+ resolvePlaybackStepRequest,
29
+ } from './playback.worker-channel.utils';
30
+
31
+ type PlaybackMutableSummary = PlaybackEpisodeSummary & {
32
+ latestLeaderPipesPassed: number;
33
+ latestLeaderFramesSurvived: number;
34
+ };
35
+
36
+ type PlaybackLoopState = {
37
+ simulationFrameBudget: number;
38
+ finished: boolean;
39
+ summary: PlaybackMutableSummary;
40
+ };
41
+
42
+ type PlaybackSessionContext = {
43
+ renderState: PopulationRenderState;
44
+ trailState: TrailState;
45
+ loopState: PlaybackLoopState;
46
+ };
47
+
48
+ type PlaybackIterationContext = {
49
+ canvas: HTMLCanvasElement;
50
+ context: CanvasRenderingContext2D;
51
+ evolutionWorker: Worker;
52
+ onFrameStats: (stats: PlaybackFrameStats) => void;
53
+ sessionContext: PlaybackSessionContext;
54
+ };
55
+
56
+ export type PlaybackEpisodeSummary = {
57
+ averagePipesPassed: number;
58
+ p90FramesSurvived: number;
59
+ winnerPipesPassed: number;
60
+ winnerFramesSurvived: number;
61
+ };
3
62
 
4
63
  /**
5
64
  * Public playback entry point used by browser runtime orchestration.
@@ -15,12 +74,7 @@ export async function animatePopulationEpisode(
15
74
  context: CanvasRenderingContext2D,
16
75
  evolutionWorker: Worker,
17
76
  onFrameStats: (stats: PlaybackFrameStats) => void,
18
- ): Promise<{
19
- averagePipesPassed: number;
20
- p90FramesSurvived: number;
21
- winnerPipesPassed: number;
22
- winnerFramesSurvived: number;
23
- }> {
77
+ ): Promise<PlaybackEpisodeSummary> {
24
78
  return animatePopulationEpisodeInternal(
25
79
  canvas,
26
80
  context,
@@ -28,3 +82,350 @@ export async function animatePopulationEpisode(
28
82
  onFrameStats,
29
83
  );
30
84
  }
85
+
86
+ /**
87
+ * Internal playback orchestration entry retained for compatibility re-exports.
88
+ *
89
+ * @param canvas - Target playback canvas.
90
+ * @param context - Canvas 2D context.
91
+ * @param evolutionWorker - Worker owning playback simulation state.
92
+ * @param onFrameStats - Callback receiving per-frame playback telemetry.
93
+ * @returns Aggregate playback summary for the current episode.
94
+ */
95
+ export async function animatePopulationEpisodeInternal(
96
+ canvas: HTMLCanvasElement,
97
+ context: CanvasRenderingContext2D,
98
+ evolutionWorker: Worker,
99
+ onFrameStats: (stats: PlaybackFrameStats) => void,
100
+ ): Promise<PlaybackEpisodeSummary> {
101
+ // Step 1: Initialize worker playback state and local render mirrors.
102
+ const sessionContext = initializePlaybackSessionContext(
103
+ canvas,
104
+ evolutionWorker,
105
+ );
106
+
107
+ // Step 2: Run playback iterations until the worker reports completion.
108
+ await runPlaybackLoop({
109
+ canvas,
110
+ context,
111
+ evolutionWorker,
112
+ onFrameStats,
113
+ sessionContext,
114
+ });
115
+
116
+ // Step 3: Render the final settled frame for the completed episode.
117
+ renderPopulationFrame(
118
+ context,
119
+ sessionContext.renderState,
120
+ sessionContext.trailState,
121
+ );
122
+
123
+ // Step 4: Fold the mutable loop summary into the public return shape.
124
+ return resolvePlaybackEpisodeSummary(sessionContext.loopState.summary);
125
+ }
126
+
127
+ /**
128
+ * Initializes worker playback and local state mirrors for one episode.
129
+ *
130
+ * @param canvas - Target playback canvas.
131
+ * @param evolutionWorker - Worker owning playback simulation state.
132
+ * @returns Session context shared across the playback loop.
133
+ */
134
+ function initializePlaybackSessionContext(
135
+ canvas: HTMLCanvasElement,
136
+ evolutionWorker: Worker,
137
+ ): PlaybackSessionContext {
138
+ // Step 1: Resolve the current viewport dimensions.
139
+ const viewportDimensions = resolvePlaybackViewportDimensions(canvas);
140
+
141
+ // Step 2: Start playback in the worker using the current viewport.
142
+ evolutionWorker.postMessage({
143
+ type: 'start-playback',
144
+ payload: viewportDimensions,
145
+ });
146
+
147
+ // Step 3: Build local render, trail, and loop state mirrors.
148
+ return {
149
+ renderState: createInitialRenderState(viewportDimensions),
150
+ trailState: createInitialTrailState(),
151
+ loopState: createInitialPlaybackLoopState(),
152
+ };
153
+ }
154
+
155
+ /**
156
+ * Runs playback iterations until the worker reports that the episode is done.
157
+ *
158
+ * @param iterationContext - Shared loop dependencies and mutable playback state.
159
+ * @returns Nothing.
160
+ */
161
+ async function runPlaybackLoop(
162
+ iterationContext: PlaybackIterationContext,
163
+ ): Promise<void> {
164
+ // Step 1: Continue iterating until the mutable loop state reports completion.
165
+ while (!iterationContext.sessionContext.loopState.finished) {
166
+ await runPlaybackIteration(iterationContext);
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Executes one playback iteration from viewport sync through render pacing.
172
+ *
173
+ * @param iterationContext - Shared loop dependencies and mutable playback state.
174
+ * @returns Nothing.
175
+ */
176
+ async function runPlaybackIteration(
177
+ iterationContext: PlaybackIterationContext,
178
+ ): Promise<void> {
179
+ // Step 1: Sync viewport size and request the next worker playback step.
180
+ syncPlaybackViewportDimensions(
181
+ iterationContext.canvas,
182
+ iterationContext.sessionContext.renderState,
183
+ );
184
+ const playbackStepPayload =
185
+ await requestPlaybackStepPayload(iterationContext);
186
+
187
+ // Step 2: Fold the worker snapshot into local render and trail state.
188
+ applyPlaybackStepSnapshot(
189
+ iterationContext.sessionContext,
190
+ playbackStepPayload.snapshot,
191
+ );
192
+
193
+ // Step 3: Resolve telemetry metrics and emit the frame stats callback.
194
+ emitPlaybackFrameStats(iterationContext, playbackStepPayload);
195
+
196
+ // Step 4: Update loop completion state when the worker marks playback done.
197
+ updatePlaybackLoopCompletion(
198
+ iterationContext.sessionContext.loopState,
199
+ playbackStepPayload,
200
+ );
201
+
202
+ // Step 5: Render the frame and yield to the browser when playback continues.
203
+ renderPopulationFrame(
204
+ iterationContext.context,
205
+ iterationContext.sessionContext.renderState,
206
+ iterationContext.sessionContext.trailState,
207
+ );
208
+ if (!iterationContext.sessionContext.loopState.finished) {
209
+ await nextAnimationFrame();
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Resolves the current visible playback viewport dimensions from the canvas.
215
+ *
216
+ * @param canvas - Target playback canvas.
217
+ * @returns Visible world width and height in pixels.
218
+ */
219
+ function resolvePlaybackViewportDimensions(canvas: HTMLCanvasElement): {
220
+ visibleWorldWidthPx: number;
221
+ visibleWorldHeightPx: number;
222
+ } {
223
+ // Step 1: Read the current world-space viewport dimensions.
224
+ return {
225
+ visibleWorldWidthPx: resolveVisibleWorldWidthPx(canvas),
226
+ visibleWorldHeightPx: resolveVisibleWorldHeightPx(canvas),
227
+ };
228
+ }
229
+
230
+ /**
231
+ * Creates the initial render state used before the first worker snapshot.
232
+ *
233
+ * @param viewportDimensions - Current visible world dimensions.
234
+ * @returns Initialized population render state.
235
+ */
236
+ function createInitialRenderState(viewportDimensions: {
237
+ visibleWorldWidthPx: number;
238
+ visibleWorldHeightPx: number;
239
+ }): PopulationRenderState {
240
+ // Step 1: Seed render fields with viewport dimensions and empty entities.
241
+ return {
242
+ frameIndex: 0,
243
+ visibleWorldWidthPx: viewportDimensions.visibleWorldWidthPx,
244
+ visibleWorldHeightPx: viewportDimensions.visibleWorldHeightPx,
245
+ nextPipeId: 0,
246
+ lastSpawnedPipeGapPx: 0,
247
+ lastSpawnedPipeGapCenterYPx: 0,
248
+ lastSpawnedPipeSpawnIntervalFrames: 0,
249
+ framesUntilNextPipeSpawn: 0,
250
+ pipes: [],
251
+ birds: [],
252
+ };
253
+ }
254
+
255
+ /**
256
+ * Creates the initial trail state used before any snapshots have been applied.
257
+ *
258
+ * @returns Empty trail state for all birds.
259
+ */
260
+ function createInitialTrailState(): TrailState {
261
+ // Step 1: Initialize the trail cache as empty arrays.
262
+ return {
263
+ birdTrailsY: [],
264
+ };
265
+ }
266
+
267
+ /**
268
+ * Creates the mutable loop state used while processing playback steps.
269
+ *
270
+ * @returns Initialized loop state and aggregate summary values.
271
+ */
272
+ function createInitialPlaybackLoopState(): PlaybackLoopState {
273
+ // Step 1: Initialize frame-budget and completion tracking.
274
+ return {
275
+ simulationFrameBudget: 0,
276
+ finished: false,
277
+ summary: {
278
+ averagePipesPassed: 0,
279
+ p90FramesSurvived: 0,
280
+ winnerPipesPassed: 0,
281
+ winnerFramesSurvived: 0,
282
+ latestLeaderPipesPassed: 0,
283
+ latestLeaderFramesSurvived: 0,
284
+ },
285
+ };
286
+ }
287
+
288
+ /**
289
+ * Synchronizes the render state viewport fields with the current canvas size.
290
+ *
291
+ * @param canvas - Target playback canvas.
292
+ * @param renderState - Mutable render state updated in place.
293
+ * @returns Nothing.
294
+ */
295
+ function syncPlaybackViewportDimensions(
296
+ canvas: HTMLCanvasElement,
297
+ renderState: PopulationRenderState,
298
+ ): void {
299
+ // Step 1: Resolve current viewport dimensions from the canvas.
300
+ const viewportDimensions = resolvePlaybackViewportDimensions(canvas);
301
+
302
+ // Step 2: Store the current viewport dimensions on the mutable render state.
303
+ renderState.visibleWorldWidthPx = viewportDimensions.visibleWorldWidthPx;
304
+ renderState.visibleWorldHeightPx = viewportDimensions.visibleWorldHeightPx;
305
+ }
306
+
307
+ /**
308
+ * Requests one playback step batch from the evolution worker.
309
+ *
310
+ * @param iterationContext - Shared loop dependencies and mutable playback state.
311
+ * @returns Worker playback step payload for the current iteration.
312
+ */
313
+ async function requestPlaybackStepPayload(
314
+ iterationContext: PlaybackIterationContext,
315
+ ) {
316
+ // Step 1: Resolve the worker request from the current loop budget and viewport.
317
+ const { renderState, loopState } = iterationContext.sessionContext;
318
+ const { simulationFrameBudgetRemainder, playbackStepRequest } =
319
+ resolvePlaybackStepRequest({
320
+ simulationFrameBudget: loopState.simulationFrameBudget,
321
+ visibleWorldWidthPx: renderState.visibleWorldWidthPx,
322
+ visibleWorldHeightPx: renderState.visibleWorldHeightPx,
323
+ emulationSpeedMultiplier: FLAPPY_EMULATION_SPEED_MULTIPLIER,
324
+ });
325
+ loopState.simulationFrameBudget = simulationFrameBudgetRemainder;
326
+
327
+ // Step 2: Request the next playback step from the worker.
328
+ return requestWorkerPlaybackStep(
329
+ iterationContext.evolutionWorker,
330
+ playbackStepRequest,
331
+ );
332
+ }
333
+
334
+ /**
335
+ * Applies the latest worker snapshot to render state and trail caches.
336
+ *
337
+ * @param sessionContext - Shared mutable playback session state.
338
+ * @param snapshot - Worker snapshot for the current playback batch.
339
+ * @returns Nothing.
340
+ */
341
+ function applyPlaybackStepSnapshot(
342
+ sessionContext: PlaybackSessionContext,
343
+ snapshot: Parameters<typeof applyPlaybackSnapshot>[1],
344
+ ): void {
345
+ // Step 1: Fold the worker snapshot into the mutable render state.
346
+ applyPlaybackSnapshot(sessionContext.renderState, snapshot);
347
+
348
+ // Step 2: Refresh the bird trail cache from the updated render state.
349
+ updateTrailState(sessionContext.trailState, sessionContext.renderState);
350
+ }
351
+
352
+ /**
353
+ * Resolves leader telemetry and emits the public frame-stats callback.
354
+ *
355
+ * @param iterationContext - Shared loop dependencies and mutable playback state.
356
+ * @param playbackStepPayload - Worker playback result for the current iteration.
357
+ * @returns Nothing.
358
+ */
359
+ function emitPlaybackFrameStats(
360
+ iterationContext: PlaybackIterationContext,
361
+ playbackStepPayload: Awaited<ReturnType<typeof requestWorkerPlaybackStep>>,
362
+ ): void {
363
+ // Step 1: Resolve leader metrics from the updated render state.
364
+ const { renderState, loopState } = iterationContext.sessionContext;
365
+ const leaderPipesPassed = resolveLeaderPipesPassed(renderState.birds);
366
+ const leaderFramesSurvived = resolveLeaderFramesSurvived(renderState);
367
+ loopState.summary.latestLeaderPipesPassed = leaderPipesPassed;
368
+ loopState.summary.latestLeaderFramesSurvived = leaderFramesSurvived;
369
+
370
+ // Step 2: Emit frame telemetry for HUD and runtime consumers.
371
+ iterationContext.onFrameStats(
372
+ resolvePlaybackFrameStats(
373
+ playbackStepPayload,
374
+ renderState.frameIndex,
375
+ resolveAliveBirdCount(renderState.birds),
376
+ leaderPipesPassed,
377
+ leaderFramesSurvived,
378
+ ),
379
+ );
380
+ }
381
+
382
+ /**
383
+ * Updates the loop summary when the worker reports playback completion.
384
+ *
385
+ * @param loopState - Mutable playback loop state.
386
+ * @param playbackStepPayload - Worker playback result for the current iteration.
387
+ * @returns Nothing.
388
+ */
389
+ function updatePlaybackLoopCompletion(
390
+ loopState: PlaybackLoopState,
391
+ playbackStepPayload: Awaited<ReturnType<typeof requestWorkerPlaybackStep>>,
392
+ ): void {
393
+ // Step 1: Skip summary folding until the worker marks playback complete.
394
+ if (!playbackStepPayload.done) {
395
+ return;
396
+ }
397
+
398
+ // Step 2: Fold the final aggregate summary into the mutable loop state.
399
+ const playbackCompletionSummary = resolvePlaybackCompletionSummary(
400
+ playbackStepPayload,
401
+ loopState.summary.latestLeaderPipesPassed,
402
+ loopState.summary.latestLeaderFramesSurvived,
403
+ );
404
+ loopState.finished = true;
405
+ loopState.summary.averagePipesPassed =
406
+ playbackCompletionSummary.averagePipesPassed;
407
+ loopState.summary.p90FramesSurvived =
408
+ playbackCompletionSummary.p90FramesSurvived;
409
+ loopState.summary.winnerPipesPassed =
410
+ playbackCompletionSummary.winnerPipesPassed;
411
+ loopState.summary.winnerFramesSurvived =
412
+ playbackCompletionSummary.winnerFramesSurvived;
413
+ }
414
+
415
+ /**
416
+ * Folds the mutable loop summary into the public playback summary shape.
417
+ *
418
+ * @param summary - Mutable loop summary accumulated during playback.
419
+ * @returns Public playback episode summary.
420
+ */
421
+ function resolvePlaybackEpisodeSummary(
422
+ summary: PlaybackMutableSummary,
423
+ ): PlaybackEpisodeSummary {
424
+ // Step 1: Return only the public aggregate fields.
425
+ return {
426
+ averagePipesPassed: summary.averagePipesPassed,
427
+ p90FramesSurvived: summary.p90FramesSurvived,
428
+ winnerPipesPassed: summary.winnerPipesPassed,
429
+ winnerFramesSurvived: summary.winnerFramesSurvived,
430
+ };
431
+ }
@@ -1,15 +1,7 @@
1
- /**
2
- * Shared type contract for starfield tile rendering layers.
3
- *
4
- * A tile is pre-rendered and repeated horizontally to draw efficient
5
- * parallax backgrounds during playback.
6
- */
7
- export type StarTile = {
8
- image: CanvasImageSource;
9
- tileWidthPx: number;
10
- tileHeightPx: number;
11
- scrollRatio: number;
12
- };
1
+ export type {
2
+ PlaybackStarfieldLayerSpec,
3
+ StarTile,
4
+ } from './playback.starfield.types';
13
5
 
14
6
  /**
15
7
  * Axis-aligned visible world bounds used for edge-aware trail fading.
@@ -0,0 +1,235 @@
1
+ # browser-entry/runtime
2
+
3
+ ## browser-entry/runtime/runtime.types.ts
4
+
5
+ ### RuntimeContainerTarget
6
+
7
+ Container argument accepted by the browser runtime start function.
8
+
9
+ ### RuntimeGlobalWindow
10
+
11
+ Browser `window` extension shape used for global runtime wiring.
12
+
13
+ ### RuntimeHostViewContext
14
+
15
+ Browser host view handles used by the runtime entry orchestration.
16
+
17
+ ### RuntimeMutableLifecycleState
18
+
19
+ Mutable lifecycle state used to coordinate stop semantics and completion.
20
+
21
+ ### RuntimeRunHandle
22
+
23
+ Public run handle returned by the browser runtime entrypoint.
24
+
25
+ ### RuntimeStartConfig
26
+
27
+ Static runtime configuration resolved before the browser loop starts.
28
+
29
+ ### RuntimeStartContext
30
+
31
+ Shared runtime startup dependencies created before evolution begins.
32
+
33
+ ## browser-entry/runtime/runtime.ts
34
+
35
+ ### RuntimeRunHandle
36
+
37
+ Public run handle returned by the browser runtime entrypoint.
38
+
39
+ ### start
40
+
41
+ `(container: import("test/examples/flappy_bird/browser-entry/runtime/runtime.types").RuntimeContainerTarget) => Promise<import("test/examples/flappy_bird/browser-entry/browser-entry.runtime.types").FlappyBirdRunHandle>`
42
+
43
+ ## browser-entry/runtime/runtime.errors.ts
44
+
45
+ ### resolveRequiredRuntimeHostElement
46
+
47
+ `(container: import("test/examples/flappy_bird/browser-entry/runtime/runtime.types").RuntimeContainerTarget) => HTMLElement`
48
+
49
+ Resolves and validates the browser runtime host element.
50
+
51
+ Parameters:
52
+
53
+ - `container` - - Element id or HTMLElement provided to runtime start.
54
+
55
+ Returns: Resolved host element.
56
+
57
+ ### resolveRuntimeHudErrorStatus
58
+
59
+ `(error: unknown) => string`
60
+
61
+ Formats unknown runtime failures into a stable HUD status string.
62
+
63
+ Parameters:
64
+
65
+ - `error` - - Unknown runtime exception value.
66
+
67
+ Returns: Normalized status string for HUD output.
68
+
69
+ ### RuntimeContainerNotFoundError
70
+
71
+ Error raised when the browser runtime host container cannot be resolved.
72
+
73
+ ## browser-entry/runtime/runtime.startup.service.ts
74
+
75
+ ### createRuntimeStartConfig
76
+
77
+ `() => import("test/examples/flappy_bird/browser-entry/runtime/runtime.types").RuntimeStartConfig`
78
+
79
+ Resolves the static runtime configuration used during browser startup.
80
+
81
+ Returns: Runtime configuration derived from shared constants.
82
+
83
+ ### createRuntimeStartContext
84
+
85
+ `(container: import("test/examples/flappy_bird/browser-entry/runtime/runtime.types").RuntimeContainerTarget) => import("test/examples/flappy_bird/browser-entry/runtime/runtime.types").RuntimeStartContext`
86
+
87
+ Creates the shared runtime startup dependencies used by the entry orchestration.
88
+
89
+ Parameters:
90
+
91
+ - `container` - - Element id or HTMLElement to host the demo.
92
+
93
+ Returns: Shared runtime start context for setup and loop launch.
94
+
95
+ ### initializeRuntimeHud
96
+
97
+ `(runtimeStartContext: import("test/examples/flappy_bird/browser-entry/runtime/runtime.types").RuntimeStartContext) => void`
98
+
99
+ Paints the initial runtime HUD values before the evolution loop starts.
100
+
101
+ Parameters:
102
+
103
+ - `runtimeStartContext` - - Shared runtime start context.
104
+
105
+ Returns: Nothing.
106
+
107
+ ## browser-entry/runtime/runtime.lifecycle.service.ts
108
+
109
+ ### createRuntimeLifecycleState
110
+
111
+ `() => import("test/examples/flappy_bird/browser-entry/runtime/runtime.types").RuntimeMutableLifecycleState`
112
+
113
+ Creates mutable lifecycle state for stop semantics and completion signaling.
114
+
115
+ Returns: Mutable lifecycle state used by the run handle.
116
+
117
+ ### createRuntimeRunHandle
118
+
119
+ `(runtimeStartContext: import("test/examples/flappy_bird/browser-entry/runtime/runtime.types").RuntimeStartContext, runtimeLifecycleState: import("test/examples/flappy_bird/browser-entry/runtime/runtime.types").RuntimeMutableLifecycleState) => import("test/examples/flappy_bird/browser-entry/browser-entry.runtime.types").FlappyBirdRunHandle`
120
+
121
+ Builds the public run handle and binds it to runtime teardown behavior.
122
+
123
+ Parameters:
124
+
125
+ - `runtimeStartContext` - - Shared runtime start context.
126
+ - `runtimeLifecycleState` - - Mutable lifecycle state for stop semantics.
127
+
128
+ Returns: Public run handle exposed to callers.
129
+
130
+ ## browser-entry/runtime/runtime.telemetry.service.ts
131
+
132
+ ### createRuntimeTelemetryState
133
+
134
+ `() => import("test/examples/flappy_bird/browser-entry/runtime/runtime.telemetry.service").RuntimeTelemetryState`
135
+
136
+ Creates telemetry state and attaches optional minor-GC observer.
137
+
138
+ Returns: Initialized telemetry state.
139
+
140
+ ### disconnectRuntimeTelemetry
141
+
142
+ `(telemetryState: import("test/examples/flappy_bird/browser-entry/runtime/runtime.telemetry.service").RuntimeTelemetryState) => void`
143
+
144
+ Disconnects runtime telemetry observers.
145
+
146
+ Parameters:
147
+
148
+ - `telemetryState` - - Runtime telemetry state.
149
+
150
+ Returns: Nothing.
151
+
152
+ ### resolveInitialRuntimeTelemetryHudValues
153
+
154
+ `() => { telemetryHeader: string; telemetryActivationsPerFrame: string; telemetrySimulationStepsPerRaf: string; telemetryHudUpdatesPerSecond: string; telemetryMinorGcPerMinute: string; }`
155
+
156
+ Resolves default telemetry HUD values used before first playback updates.
157
+
158
+ Returns: Initial telemetry field values.
159
+
160
+ ### resolveRuntimeTelemetryHudValues
161
+
162
+ `(frameStats: import("test/examples/flappy_bird/browser-entry/browser-entry.worker.types").PlaybackFrameStats, telemetryState: import("test/examples/flappy_bird/browser-entry/runtime/runtime.telemetry.service").RuntimeTelemetryState) => { telemetryActivationsPerFrame: string; telemetrySimulationStepsPerRaf: string; telemetryHudUpdatesPerSecond: string; telemetryMinorGcPerMinute: string; }`
163
+
164
+ Resolves per-frame telemetry HUD values and updates rolling windows.
165
+
166
+ Parameters:
167
+
168
+ - `frameStats` - - Playback frame stats for the current frame.
169
+ - `telemetryState` - - Runtime telemetry mutable state.
170
+
171
+ Returns: Formatted telemetry HUD values for this frame.
172
+
173
+ ### RuntimeTelemetryState
174
+
175
+ Runtime telemetry mutable state used for rolling HUD metrics.
176
+
177
+ ## browser-entry/runtime/runtime.evolution-loop.service.ts
178
+
179
+ ### runRuntimeEvolutionLoop
180
+
181
+ `(options: import("test/examples/flappy_bird/browser-entry/runtime/runtime.evolution-loop.service").RuntimeEvolutionLoopOptions) => Promise<void>`
182
+
183
+ Runs generation orchestration and playback until a stop signal is observed.
184
+
185
+ Parameters:
186
+
187
+ - `options` - - Runtime evolution dependencies and mutable state accessors.
188
+
189
+ Returns: Nothing.
190
+
191
+ ### RuntimeEvolutionLoopOptions
192
+
193
+ Dependencies required to run the browser runtime evolution loop.
194
+
195
+ ## browser-entry/runtime/runtime.browser-globals.service.ts
196
+
197
+ ### installRuntimeBrowserGlobals
198
+
199
+ `(startRuntime: import("test/examples/flappy_bird/browser-entry/runtime/runtime.browser-globals.service").RuntimeStartFunction) => void`
200
+
201
+ Publishes browser globals for demo auto-start and host-driven control.
202
+
203
+ This keeps parity with the asciiMaze entry style:
204
+
205
+ - `window.flappyBird.start(...)` for explicit invocation,
206
+ - `window.flappyBirdStart(...)` for compatibility,
207
+ - one guarded auto-start for standalone HTML usage.
208
+
209
+ Parameters:
210
+
211
+ - `startRuntime` - - Runtime entry function.
212
+
213
+ Returns: Nothing.
214
+
215
+ ### RuntimeStartFunction
216
+
217
+ `(container: import("test/examples/flappy_bird/browser-entry/runtime/runtime.types").RuntimeContainerTarget | undefined) => Promise<import("test/examples/flappy_bird/browser-entry/browser-entry.runtime.types").FlappyBirdRunHandle>`
218
+
219
+ Runtime start function signature used by browser-global wiring.
220
+
221
+ ## browser-entry/runtime/runtime.evolution-launch.service.ts
222
+
223
+ ### launchRuntimeEvolution
224
+
225
+ `(runtimeStartContext: import("test/examples/flappy_bird/browser-entry/runtime/runtime.types").RuntimeStartContext, runtimeLifecycleState: import("test/examples/flappy_bird/browser-entry/runtime/runtime.types").RuntimeMutableLifecycleState, stop: () => void) => void`
226
+
227
+ Starts the runtime evolution loop and routes unexpected failures to the HUD.
228
+
229
+ Parameters:
230
+
231
+ - `runtimeStartContext` - - Shared runtime start context.
232
+ - `runtimeLifecycleState` - - Mutable lifecycle state used for stop checks.
233
+ - `stop` - - Idempotent stop function bound to the current runtime handle.
234
+
235
+ Returns: Nothing.