@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
@@ -0,0 +1,100 @@
1
+ import {
2
+ FLAPPY_BACKGROUND_HORIZON_STYLE,
3
+ FLAPPY_BACKGROUND_HORIZON_HALF_THICKNESS_MULTIPLIER,
4
+ FLAPPY_BACKGROUND_HORIZON_LINE_THICKNESS_PX,
5
+ FLAPPY_BACKGROUND_MIN_VIEWPORT_DIMENSION_PX,
6
+ FLAPPY_BACKGROUND_ODD_STROKE_ALIGNMENT_OFFSET_PX,
7
+ FLAPPY_BACKGROUND_ODD_STROKE_DIVISOR,
8
+ FLAPPY_BACKGROUND_SKY_HEIGHT_RATIO,
9
+ } from './playback.background.constants';
10
+ import type {
11
+ PlaybackBackgroundLayout,
12
+ PlaybackHorizonStyle,
13
+ } from './playback.background.types';
14
+
15
+ /**
16
+ * Resolves the vertical split between the starfield sky and the future ground.
17
+ *
18
+ * @param visibleWorldHeightPx - Current visible world height in pixels.
19
+ * @returns Stable scene layout for the current frame.
20
+ */
21
+ export function resolvePlaybackBackgroundLayout(
22
+ visibleWorldHeightPx: number,
23
+ ): PlaybackBackgroundLayout {
24
+ // Step 1: Clamp the viewport height so follow-up math stays render-safe.
25
+ const safeVisibleWorldHeightPx =
26
+ resolveSafeBackgroundDimension(visibleWorldHeightPx);
27
+
28
+ // Step 2: Reserve the top segment for the current starfield parallax.
29
+ const skyHeightPx = Math.max(
30
+ FLAPPY_BACKGROUND_MIN_VIEWPORT_DIMENSION_PX,
31
+ Math.round(safeVisibleWorldHeightPx * FLAPPY_BACKGROUND_SKY_HEIGHT_RATIO),
32
+ );
33
+ const horizonThicknessPx = FLAPPY_BACKGROUND_HORIZON_LINE_THICKNESS_PX;
34
+ const lowerBandTopYPx = skyHeightPx;
35
+ const lowerBandBottomYPx = safeVisibleWorldHeightPx;
36
+ const lowerBandHeightPx = Math.max(
37
+ FLAPPY_BACKGROUND_MIN_VIEWPORT_DIMENSION_PX,
38
+ lowerBandBottomYPx - lowerBandTopYPx,
39
+ );
40
+ const horizonYPx = Math.max(
41
+ 0,
42
+ lowerBandTopYPx -
43
+ horizonThicknessPx * FLAPPY_BACKGROUND_HORIZON_HALF_THICKNESS_MULTIPLIER,
44
+ );
45
+
46
+ // Step 3: Return an explicit layout object so render code stays declarative.
47
+ return {
48
+ skyHeightPx,
49
+ lowerBandTopYPx,
50
+ lowerBandHeightPx,
51
+ lowerBandBottomYPx,
52
+ horizonYPx,
53
+ horizonThicknessPx,
54
+ };
55
+ }
56
+
57
+ /**
58
+ * Resolves the neon paint settings for the horizon divider.
59
+ *
60
+ * @returns Reusable draw style for both the glow and crisp line passes.
61
+ */
62
+ export function resolvePlaybackHorizonStyle(): PlaybackHorizonStyle {
63
+ // Step 1: Reuse one frozen style object so horizon drawing stays allocation-free.
64
+ return FLAPPY_BACKGROUND_HORIZON_STYLE;
65
+ }
66
+
67
+ /**
68
+ * Resolves pixel-snapped horizon positioning for crisp canvas strokes.
69
+ *
70
+ * @param horizonYPx - Logical horizon centerline in pixels.
71
+ * @param lineThicknessPx - Stroke thickness in pixels.
72
+ * @returns Pixel-snapped y-position for the stroke.
73
+ */
74
+ export function resolveAlignedHorizonYPx(
75
+ horizonYPx: number,
76
+ lineThicknessPx: number,
77
+ ): number {
78
+ // Step 1: Offset odd-width strokes onto half pixels for crisp rasterization.
79
+ const oddStrokeAlignmentOffsetPx =
80
+ lineThicknessPx % FLAPPY_BACKGROUND_ODD_STROKE_DIVISOR === 1
81
+ ? FLAPPY_BACKGROUND_ODD_STROKE_ALIGNMENT_OFFSET_PX
82
+ : 0;
83
+
84
+ // Step 2: Return the aligned horizon position.
85
+ return horizonYPx + oddStrokeAlignmentOffsetPx;
86
+ }
87
+
88
+ /**
89
+ * Clamps a background dimension into a render-safe positive integer.
90
+ *
91
+ * @param dimensionPx - Candidate viewport dimension in pixels.
92
+ * @returns Positive integer dimension suitable for canvas math.
93
+ */
94
+ export function resolveSafeBackgroundDimension(dimensionPx: number): number {
95
+ // Step 1: Round sub-pixel measurements and enforce a positive floor.
96
+ return Math.max(
97
+ FLAPPY_BACKGROUND_MIN_VIEWPORT_DIMENSION_PX,
98
+ Math.round(dimensionPx),
99
+ );
100
+ }
@@ -0,0 +1,310 @@
1
+ # browser-entry/playback/frame-render
2
+
3
+ ## browser-entry/playback/frame-render/playback.frame-render.types.ts
4
+
5
+ ### PlaybackBirdGeometry
6
+
7
+ Pixel-aligned square geometry used by bird paint helpers.
8
+
9
+ ### PlaybackFrameSceneContext
10
+
11
+ Local type contracts for playback frame rendering.
12
+
13
+ These types are extracted from the broader frame renderer so scene state,
14
+ bird geometry, and trail styling can evolve behind a dedicated module
15
+ boundary.
16
+
17
+ ### PlaybackTrailRenderStyle
18
+
19
+ Resolved opacity and color for one bird trail render pass.
20
+
21
+ ## browser-entry/playback/frame-render/playback.frame-render.service.ts
22
+
23
+ ### renderPopulationFrame
24
+
25
+ `(context: CanvasRenderingContext2D, renderState: import("test/examples/flappy_bird/browser-entry/browser-entry.simulation.types").PopulationRenderState, trailState: import("test/examples/flappy_bird/browser-entry/browser-entry.simulation.types").TrailState) => void`
26
+
27
+ Draws one simulation frame for the current population state.
28
+
29
+ Parameters:
30
+
31
+ - `context` - - Canvas 2D drawing context.
32
+ - `renderState` - - Mutable simulation state snapshot.
33
+ - `trailState` - - Leader trail render cache.
34
+
35
+ Returns: Nothing.
36
+
37
+ ### updateTrailState
38
+
39
+ `(trailState: import("test/examples/flappy_bird/browser-entry/browser-entry.simulation.types").TrailState, renderState: import("test/examples/flappy_bird/browser-entry/browser-entry.simulation.types").PopulationRenderState) => void`
40
+
41
+ Updates the trail cache from the latest frame snapshot.
42
+
43
+ Parameters:
44
+
45
+ - `trailState` - - Mutable trail state.
46
+ - `renderState` - - Current render state.
47
+
48
+ Returns: Nothing.
49
+
50
+ ## browser-entry/playback/frame-render/playback.frame-render.services.ts
51
+
52
+ ### beginPlaybackFrameViewportTransform
53
+
54
+ `(context: CanvasRenderingContext2D, sceneContext: import("test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types").PlaybackFrameSceneContext) => void`
55
+
56
+ Applies the viewport transform used for world-space frame rendering.
57
+
58
+ Parameters:
59
+
60
+ - `context` - - Canvas 2D drawing context.
61
+ - `sceneContext` - - Shared scene geometry for the frame.
62
+
63
+ Returns: Nothing.
64
+
65
+ ### finalizePlaybackFrameCanvas
66
+
67
+ `(context: CanvasRenderingContext2D) => void`
68
+
69
+ Restores the caller canvas state after viewport-space frame drawing.
70
+
71
+ Parameters:
72
+
73
+ - `context` - - Canvas 2D drawing context.
74
+
75
+ Returns: Nothing.
76
+
77
+ ### preparePlaybackFrameCanvas
78
+
79
+ `(context: CanvasRenderingContext2D) => void`
80
+
81
+ Resets the target canvas and base paint state before frame drawing begins.
82
+
83
+ Parameters:
84
+
85
+ - `context` - - Canvas 2D drawing context.
86
+
87
+ Returns: Nothing.
88
+
89
+ ### renderPlaybackFrameBackground
90
+
91
+ `(context: CanvasRenderingContext2D, renderState: import("test/examples/flappy_bird/browser-entry/browser-entry.simulation.types").PopulationRenderState, sceneContext: import("test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types").PlaybackFrameSceneContext) => void`
92
+
93
+ Draws the split playback background for the current world viewport.
94
+
95
+ Parameters:
96
+
97
+ - `context` - - Canvas 2D drawing context.
98
+ - `renderState` - - Mutable simulation state snapshot.
99
+ - `sceneContext` - - Shared scene geometry for the frame.
100
+
101
+ Returns: Nothing.
102
+
103
+ ### renderPlaybackFrameBirds
104
+
105
+ `(context: CanvasRenderingContext2D, renderState: import("test/examples/flappy_bird/browser-entry/browser-entry.simulation.types").PopulationRenderState, sceneContext: import("test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types").PlaybackFrameSceneContext, renderBird: PlaybackBirdRenderer) => void`
106
+
107
+ Draws all active birds for the current frame.
108
+
109
+ Parameters:
110
+
111
+ - `context` - - Canvas 2D drawing context.
112
+ - `renderState` - - Mutable simulation state snapshot.
113
+ - `sceneContext` - - Shared scene geometry for the frame.
114
+ - `renderBird` - - Bird body renderer owned by the detailed utility layer.
115
+
116
+ Returns: Nothing.
117
+
118
+ ### renderPlaybackFramePipes
119
+
120
+ `(context: CanvasRenderingContext2D, renderState: import("test/examples/flappy_bird/browser-entry/browser-entry.simulation.types").PopulationRenderState, sceneContext: import("test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types").PlaybackFrameSceneContext) => void`
121
+
122
+ Draws all visible pipe segments and their neon outlines for the frame.
123
+
124
+ Parameters:
125
+
126
+ - `context` - - Canvas 2D drawing context.
127
+ - `renderState` - - Mutable simulation state snapshot.
128
+ - `sceneContext` - - Shared scene geometry for the frame.
129
+
130
+ Returns: Nothing.
131
+
132
+ ### renderPlaybackFrameTrails
133
+
134
+ `(context: CanvasRenderingContext2D, renderState: import("test/examples/flappy_bird/browser-entry/browser-entry.simulation.types").PopulationRenderState, trailState: import("test/examples/flappy_bird/browser-entry/browser-entry.simulation.types").TrailState, sceneContext: import("test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types").PlaybackFrameSceneContext, resolveTrailStyle: PlaybackTrailStyleResolver, renderTrail: PlaybackTrailRenderer) => void`
135
+
136
+ Draws stepped trails for all active birds in the frame.
137
+
138
+ Parameters:
139
+
140
+ - `context` - - Canvas 2D drawing context.
141
+ - `renderState` - - Mutable simulation state snapshot.
142
+ - `trailState` - - Leader trail render cache.
143
+ - `sceneContext` - - Shared scene geometry for the frame.
144
+ - `resolveTrailStyle` - - Trail style resolver owned by the detailed utility layer.
145
+ - `renderTrail` - - Trail segment renderer owned by the detailed utility layer.
146
+
147
+ Returns: Nothing.
148
+
149
+ ### resolvePlaybackFrameSceneContext
150
+
151
+ `(context: CanvasRenderingContext2D, renderState: import("test/examples/flappy_bird/browser-entry/browser-entry.simulation.types").PopulationRenderState) => import("test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types").PlaybackFrameSceneContext`
152
+
153
+ Resolves the shared scene contract used by one frame render pass.
154
+
155
+ Parameters:
156
+
157
+ - `context` - - Canvas 2D drawing context.
158
+ - `renderState` - - Mutable simulation state snapshot.
159
+
160
+ Returns: Viewport, camera, and edge-bounds state for the frame.
161
+
162
+ ## browser-entry/playback/frame-render/playback.frame-render.utils.ts
163
+
164
+ ### drawPlaybackBirdBody
165
+
166
+ `(context: CanvasRenderingContext2D, birdGeometry: import("test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types").PlaybackBirdGeometry, birdRenderStyle: import("test/examples/flappy_bird/browser-entry/playback/playback.render.utils").PlaybackBirdRenderStyle) => void`
167
+
168
+ Draws the square bird body with its base neon glow.
169
+
170
+ Parameters:
171
+
172
+ - `context` - - Canvas 2D drawing context.
173
+ - `birdGeometry` - - Pixel-aligned bird geometry.
174
+ - `birdRenderStyle` - - Resolved bird style payload.
175
+
176
+ Returns: Nothing.
177
+
178
+ ### drawPlaybackBirdChampionAura
179
+
180
+ `(context: CanvasRenderingContext2D, birdGeometry: import("test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types").PlaybackBirdGeometry, birdRenderStyle: import("test/examples/flappy_bird/browser-entry/playback/playback.render.utils").PlaybackBirdRenderStyle) => void`
181
+
182
+ Draws the soft champion aura plate behind the bird body.
183
+
184
+ Parameters:
185
+
186
+ - `context` - - Canvas 2D drawing context.
187
+ - `birdGeometry` - - Pixel-aligned bird geometry.
188
+ - `birdRenderStyle` - - Resolved bird style payload.
189
+
190
+ Returns: Nothing.
191
+
192
+ ### drawPlaybackBirdChampionGlowPlate
193
+
194
+ `(context: CanvasRenderingContext2D, birdGeometry: import("test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types").PlaybackBirdGeometry, birdRenderStyle: import("test/examples/flappy_bird/browser-entry/playback/playback.render.utils").PlaybackBirdRenderStyle) => void`
195
+
196
+ Draws the champion-only red glow plate beneath the bird body.
197
+
198
+ Parameters:
199
+
200
+ - `context` - - Canvas 2D drawing context.
201
+ - `birdGeometry` - - Pixel-aligned bird geometry.
202
+ - `birdRenderStyle` - - Resolved bird style payload.
203
+
204
+ Returns: Nothing.
205
+
206
+ ### drawPlaybackBirdLeaderRing
207
+
208
+ `(context: CanvasRenderingContext2D, birdGeometry: import("test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types").PlaybackBirdGeometry, isChampionBird: boolean) => void`
209
+
210
+ Draws the leader ring around the champion bird.
211
+
212
+ Parameters:
213
+
214
+ - `context` - - Canvas 2D drawing context.
215
+ - `birdGeometry` - - Pixel-aligned bird geometry.
216
+ - `isChampionBird` - - Whether the current bird is the champion.
217
+
218
+ Returns: Nothing.
219
+
220
+ ### drawPlaybackBirdShine
221
+
222
+ `(context: CanvasRenderingContext2D, birdGeometry: import("test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types").PlaybackBirdGeometry, isChampionBird: boolean) => void`
223
+
224
+ Draws the reflective shine highlight for one bird body.
225
+
226
+ Parameters:
227
+
228
+ - `context` - - Canvas 2D drawing context.
229
+ - `birdGeometry` - - Pixel-aligned bird geometry.
230
+ - `isChampionBird` - - Whether the current bird is the champion.
231
+
232
+ Returns: Nothing.
233
+
234
+ ### drawTrail
235
+
236
+ `(context: CanvasRenderingContext2D, trailPoints: import("test/examples/flappy_bird/browser-entry/browser-entry.simulation.types").TrailPoint[], color: string, anchorX: number, baseOpacity: number, edgeBounds: import("test/examples/flappy_bird/browser-entry/playback/playback.types").PlaybackEdgeBounds) => void`
237
+
238
+ Draws the stepped trail history for one active bird.
239
+
240
+ Parameters:
241
+
242
+ - `context` - - Canvas 2D drawing context.
243
+ - `trailPoints` - - Cached per-frame trail points for one bird.
244
+ - `color` - - Stroke color for the trail.
245
+ - `anchorX` - - Bird anchor x-position in world space.
246
+ - `baseOpacity` - - Base opacity before edge and lifetime fading.
247
+ - `edgeBounds` - - Visible world bounds used for edge fading.
248
+
249
+ Returns: Nothing.
250
+
251
+ ### drawTrailSegmentWithEdgeFade
252
+
253
+ `(context: CanvasRenderingContext2D, startXPx: number, startYPx: number, endXPx: number, endYPx: number, baseOpacity: number, edgeBounds: import("test/examples/flappy_bird/browser-entry/playback/playback.types").PlaybackEdgeBounds, startFrameOffset: number, endFrameOffset: number, maximumTrailFrameOffset: number) => void`
254
+
255
+ Draws one trail segment with combined edge and lifetime fading.
256
+
257
+ Parameters:
258
+
259
+ - `context` - - Canvas 2D drawing context.
260
+ - `startXPx` - - Segment start x-position.
261
+ - `startYPx` - - Segment start y-position.
262
+ - `endXPx` - - Segment end x-position.
263
+ - `endYPx` - - Segment end y-position.
264
+ - `baseOpacity` - - Base opacity before fade factors.
265
+ - `edgeBounds` - - Visible world bounds used for edge fading.
266
+ - `startFrameOffset` - - Relative age of the segment start.
267
+ - `endFrameOffset` - - Relative age of the segment end.
268
+ - `maximumTrailFrameOffset` - - Oldest visible trail age.
269
+
270
+ Returns: Nothing.
271
+
272
+ ### renderPlaybackBird
273
+
274
+ `(context: CanvasRenderingContext2D, birdYPx: number, birdIndex: number, championBirdIndex: number) => void`
275
+
276
+ Draws one active bird body, glow, shine, and leader ring.
277
+
278
+ Parameters:
279
+
280
+ - `context` - - Canvas 2D drawing context.
281
+ - `birdYPx` - - Bird vertical position in world pixels.
282
+ - `birdIndex` - - Index of the bird being rendered.
283
+ - `championBirdIndex` - - Champion index for the current frame.
284
+
285
+ Returns: Nothing.
286
+
287
+ ### resolvePlaybackBirdGeometry
288
+
289
+ `(birdYPx: number) => import("test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types").PlaybackBirdGeometry`
290
+
291
+ Resolves the fixed bird geometry used by all body rendering passes.
292
+
293
+ Parameters:
294
+
295
+ - `birdYPx` - - Bird vertical position in world pixels.
296
+
297
+ Returns: Pixel-aligned square geometry for the bird body.
298
+
299
+ ### resolvePlaybackTrailStyle
300
+
301
+ `(birdIndex: number, championBirdIndex: number) => import("test/examples/flappy_bird/browser-entry/playback/frame-render/playback.frame-render.types").PlaybackTrailRenderStyle`
302
+
303
+ Resolves the trail style used for one bird's stepped trail.
304
+
305
+ Parameters:
306
+
307
+ - `birdIndex` - - Index of the bird being rendered.
308
+ - `championBirdIndex` - - Champion index for the current frame.
309
+
310
+ Returns: Base opacity and color for the bird trail.
@@ -0,0 +1,92 @@
1
+ import {
2
+ FLAPPY_BIRD_RADIUS_PX,
3
+ FLAPPY_BIRD_X_PX,
4
+ } from '../../../constants/constants';
5
+ import type {
6
+ PopulationRenderState,
7
+ TrailState,
8
+ } from '../../browser-entry.types';
9
+ import { pushTrailPoint } from '../playback.trail.utils';
10
+ import {
11
+ beginPlaybackFrameViewportTransform,
12
+ finalizePlaybackFrameCanvas,
13
+ preparePlaybackFrameCanvas,
14
+ renderPlaybackFrameBackground,
15
+ renderPlaybackFrameBirds,
16
+ renderPlaybackFramePipes,
17
+ renderPlaybackFrameTrails,
18
+ resolvePlaybackFrameSceneContext,
19
+ } from './playback.frame-render.services';
20
+ import {
21
+ drawTrail,
22
+ renderPlaybackBird,
23
+ resolvePlaybackTrailStyle,
24
+ } from './playback.frame-render.utils';
25
+
26
+ /**
27
+ * Draws one simulation frame for the current population state.
28
+ *
29
+ * @param context - Canvas 2D drawing context.
30
+ * @param renderState - Mutable simulation state snapshot.
31
+ * @param trailState - Leader trail render cache.
32
+ * @returns Nothing.
33
+ */
34
+ export function renderPopulationFrame(
35
+ context: CanvasRenderingContext2D,
36
+ renderState: PopulationRenderState,
37
+ trailState: TrailState,
38
+ ): void {
39
+ // Step 1: Resolve scene geometry and champion render state.
40
+ const sceneContext = resolvePlaybackFrameSceneContext(context, renderState);
41
+
42
+ // Step 2: Reset canvas state and enter the viewport transform.
43
+ preparePlaybackFrameCanvas(context);
44
+ beginPlaybackFrameViewportTransform(context, sceneContext);
45
+
46
+ // Step 3: Draw the split background, pipes, birds, and trails in order.
47
+ renderPlaybackFrameBackground(context, renderState, sceneContext);
48
+ renderPlaybackFramePipes(context, renderState, sceneContext);
49
+ renderPlaybackFrameBirds(
50
+ context,
51
+ renderState,
52
+ sceneContext,
53
+ renderPlaybackBird,
54
+ );
55
+ renderPlaybackFrameTrails(
56
+ context,
57
+ renderState,
58
+ trailState,
59
+ sceneContext,
60
+ resolvePlaybackTrailStyle,
61
+ drawTrail,
62
+ );
63
+
64
+ // Step 4: Restore the caller canvas state after viewport-space drawing.
65
+ finalizePlaybackFrameCanvas(context);
66
+ }
67
+
68
+ /**
69
+ * Updates the trail cache from the latest frame snapshot.
70
+ *
71
+ * @param trailState - Mutable trail state.
72
+ * @param renderState - Current render state.
73
+ * @returns Nothing.
74
+ */
75
+ export function updateTrailState(
76
+ trailState: TrailState,
77
+ renderState: PopulationRenderState,
78
+ ): void {
79
+ renderState.birds.forEach((bird, birdIndex) => {
80
+ if (!trailState.birdTrailsY[birdIndex]) {
81
+ trailState.birdTrailsY[birdIndex] = [];
82
+ }
83
+ const birdTrail = trailState.birdTrailsY[birdIndex];
84
+
85
+ if (bird.done) {
86
+ birdTrail.length = 0;
87
+ return;
88
+ }
89
+
90
+ pushTrailPoint(birdTrail, renderState.frameIndex, bird.yPx);
91
+ });
92
+ }