@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,58 @@
1
+ /**
2
+ * Rollout orchestration module.
3
+ *
4
+ * This file will host the internal rollout orchestration entry while the
5
+ * public evaluation-level service remains a stable compatibility facade.
6
+ */
7
+ import {
8
+ createRolloutEpisodeRuntimeState,
9
+ finalizeRolloutEpisodeState,
10
+ resolveRolloutEpisodeContext,
11
+ runRolloutEpisodeLoop,
12
+ } from './evaluation.rollout.services';
13
+ import { composeRolloutEpisodeResult } from './evaluation.rollout.utils';
14
+ import type {
15
+ FlappyEpisodeResult,
16
+ FlappyNetworkLike,
17
+ FlappyRolloutOptions,
18
+ } from '../evaluation.types';
19
+
20
+ /**
21
+ * Roll out an episode and return details.
22
+ *
23
+ * @param network - Genome/network to evaluate.
24
+ * @param rolloutOptions - Optional rollout controls.
25
+ * @returns Episode result details.
26
+ */
27
+ export function rolloutEpisode(
28
+ network: FlappyNetworkLike,
29
+ rolloutOptions: FlappyRolloutOptions = {},
30
+ ): FlappyEpisodeResult {
31
+ // Step 1: Resolve rollout configuration and initialize mutable runtime state.
32
+ const rolloutEpisodeContext = resolveRolloutEpisodeContext(
33
+ network,
34
+ rolloutOptions,
35
+ );
36
+ const rolloutEpisodeRuntimeState = createRolloutEpisodeRuntimeState(
37
+ rolloutEpisodeContext,
38
+ );
39
+
40
+ // Step 2: Simulate frames until the episode terminates or the frame budget is exhausted.
41
+ runRolloutEpisodeLoop(
42
+ network,
43
+ rolloutEpisodeContext,
44
+ rolloutEpisodeRuntimeState,
45
+ );
46
+
47
+ // Step 3: Apply timeout termination when the loop exhausted the frame budget.
48
+ finalizeRolloutEpisodeState(
49
+ rolloutEpisodeContext,
50
+ rolloutEpisodeRuntimeState,
51
+ );
52
+
53
+ // Step 4: Compose the episode result from the final state and accumulated fitness channels.
54
+ return composeRolloutEpisodeResult(
55
+ rolloutEpisodeContext,
56
+ rolloutEpisodeRuntimeState,
57
+ );
58
+ }
@@ -0,0 +1,310 @@
1
+ /**
2
+ * Rollout runtime services.
3
+ *
4
+ * This file will host context resolution, runtime initialization, frame loop,
5
+ * and early-termination behavior for rollout execution.
6
+ */
7
+ import {
8
+ FLAPPY_CONTROL_SUBSTEPS_PER_FRAME,
9
+ FLAPPY_MAX_FRAMES_PER_EPISODE,
10
+ } from '../../constants/constants';
11
+ import {
12
+ FLAPPY_EVALUATION_DEFAULT_DIFFICULTY_SCALE,
13
+ FLAPPY_EVALUATION_DEFAULT_EARLY_TERMINATION_CONSECUTIVE_FRAMES,
14
+ FLAPPY_EVALUATION_DEFAULT_EARLY_TERMINATION_GRACE_FRAMES,
15
+ } from '../evaluation.constants';
16
+ import {
17
+ createInitialFlappyState,
18
+ getFlappyObservationFeatures,
19
+ stepFlappyStateWithControlSubsteps,
20
+ type FlappyObservationFeatures,
21
+ } from '../../flappyEnvironment.ts';
22
+ import {
23
+ clampValue,
24
+ commitSharedObservationMemoryStep,
25
+ createSharedObservationMemoryState,
26
+ resolveFlapDecision,
27
+ resolveTemporalObservationVector,
28
+ } from '../../flappy.simulation.shared.utils';
29
+ import { createXorshift32 } from '../../rng';
30
+ import { mixGenomeEvaluationSeed } from '../evaluation.seed.utils';
31
+ import {
32
+ FLAPPY_ROLLOUT_DEFAULT_GENOME_ID,
33
+ FLAPPY_ROLLOUT_DONE_REASON_COLLISION,
34
+ FLAPPY_ROLLOUT_DONE_REASON_TIMEOUT,
35
+ FLAPPY_ROLLOUT_MIN_EARLY_TERMINATION_CONSECUTIVE_FRAMES,
36
+ FLAPPY_ROLLOUT_MIN_EARLY_TERMINATION_GRACE_FRAMES,
37
+ FLAPPY_ROLLOUT_MIN_MAX_FRAMES,
38
+ FLAPPY_ROLLOUT_ZERO_FITNESS,
39
+ } from './evaluation.rollout.constants';
40
+ import type {
41
+ RolloutEpisodeContext,
42
+ RolloutEpisodeRuntimeState,
43
+ } from './evaluation.rollout.types';
44
+ import type {
45
+ FlappyNetworkLike,
46
+ FlappyRolloutOptions,
47
+ } from '../evaluation.types';
48
+ import {
49
+ computeDenseShapingReward,
50
+ isBirdLikelyUnrecoverable,
51
+ } from './evaluation.rollout.utils';
52
+
53
+ /**
54
+ * Resolves normalized rollout configuration from user options.
55
+ *
56
+ * @param network - Genome/network to evaluate.
57
+ * @param rolloutOptions - Optional rollout controls.
58
+ * @returns Normalized rollout configuration.
59
+ */
60
+ export function resolveRolloutEpisodeContext(
61
+ network: FlappyNetworkLike,
62
+ rolloutOptions: FlappyRolloutOptions,
63
+ ): RolloutEpisodeContext {
64
+ // Step 1: Resolve the deterministic evaluation seed from the explicit option or genome id.
65
+ const genomeId = network._id ?? FLAPPY_ROLLOUT_DEFAULT_GENOME_ID;
66
+ const seed = rolloutOptions.seed ?? mixGenomeEvaluationSeed(genomeId);
67
+
68
+ // Step 2: Normalize the rollout scalar options into safe ranges.
69
+ return {
70
+ seed,
71
+ difficultyScale: clampValue(
72
+ rolloutOptions.difficultyScale ??
73
+ FLAPPY_EVALUATION_DEFAULT_DIFFICULTY_SCALE,
74
+ FLAPPY_ROLLOUT_ZERO_FITNESS,
75
+ FLAPPY_ROLLOUT_MIN_MAX_FRAMES,
76
+ ),
77
+ maxFramesPerEpisode: Math.max(
78
+ FLAPPY_ROLLOUT_MIN_MAX_FRAMES,
79
+ Math.min(
80
+ FLAPPY_MAX_FRAMES_PER_EPISODE,
81
+ Math.trunc(rolloutOptions.maxFrames ?? FLAPPY_MAX_FRAMES_PER_EPISODE),
82
+ ),
83
+ ),
84
+ earlyTerminationGraceFrames: Math.max(
85
+ FLAPPY_ROLLOUT_MIN_EARLY_TERMINATION_GRACE_FRAMES,
86
+ Math.trunc(
87
+ rolloutOptions.earlyTerminationGraceFrames ??
88
+ FLAPPY_EVALUATION_DEFAULT_EARLY_TERMINATION_GRACE_FRAMES,
89
+ ),
90
+ ),
91
+ earlyTerminationConsecutiveFrames: Math.max(
92
+ FLAPPY_ROLLOUT_MIN_EARLY_TERMINATION_CONSECUTIVE_FRAMES,
93
+ Math.trunc(
94
+ rolloutOptions.earlyTerminationConsecutiveFrames ??
95
+ FLAPPY_EVALUATION_DEFAULT_EARLY_TERMINATION_CONSECUTIVE_FRAMES,
96
+ ),
97
+ ),
98
+ enableEarlyTermination: rolloutOptions.enableEarlyTermination === true,
99
+ normalizeFitness: rolloutOptions.normalizeFitness === true,
100
+ pipeProgressTarget: rolloutOptions.pipeProgressTarget,
101
+ };
102
+ }
103
+
104
+ /**
105
+ * Creates mutable runtime state for one rollout episode.
106
+ *
107
+ * @param rolloutEpisodeContext - Normalized rollout configuration.
108
+ * @returns Mutable runtime state.
109
+ */
110
+ export function createRolloutEpisodeRuntimeState(
111
+ rolloutEpisodeContext: RolloutEpisodeContext,
112
+ ): RolloutEpisodeRuntimeState {
113
+ // Step 1: Create the seeded RNG and initial game state.
114
+ const rng = createXorshift32(rolloutEpisodeContext.seed);
115
+ const state = createInitialFlappyState(rng);
116
+
117
+ // Step 2: Create the temporal observation memory used by the network controller.
118
+ return {
119
+ rng,
120
+ state,
121
+ observationMemoryState: createSharedObservationMemoryState(),
122
+ denseShapingFitness: FLAPPY_ROLLOUT_ZERO_FITNESS,
123
+ unrecoverableFrameCount: FLAPPY_ROLLOUT_ZERO_FITNESS,
124
+ };
125
+ }
126
+
127
+ /**
128
+ * Runs the main rollout loop until termination or frame-budget exhaustion.
129
+ *
130
+ * @param network - Genome/network to evaluate.
131
+ * @param rolloutEpisodeContext - Normalized rollout configuration.
132
+ * @param rolloutEpisodeRuntimeState - Mutable runtime state.
133
+ * @returns Nothing.
134
+ */
135
+ export function runRolloutEpisodeLoop(
136
+ network: FlappyNetworkLike,
137
+ rolloutEpisodeContext: RolloutEpisodeContext,
138
+ rolloutEpisodeRuntimeState: RolloutEpisodeRuntimeState,
139
+ ): void {
140
+ // Step 1: Continue stepping while the episode remains active and within the frame cap.
141
+ while (
142
+ !rolloutEpisodeRuntimeState.state.done &&
143
+ rolloutEpisodeRuntimeState.state.frameIndex <
144
+ rolloutEpisodeContext.maxFramesPerEpisode
145
+ ) {
146
+ runRolloutEpisodeFrame(
147
+ network,
148
+ rolloutEpisodeContext,
149
+ rolloutEpisodeRuntimeState,
150
+ );
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Finalizes episode state after the main rollout loop exits.
156
+ *
157
+ * @param rolloutEpisodeContext - Normalized rollout configuration.
158
+ * @param rolloutEpisodeRuntimeState - Mutable runtime state.
159
+ * @returns Nothing.
160
+ */
161
+ export function finalizeRolloutEpisodeState(
162
+ rolloutEpisodeContext: RolloutEpisodeContext,
163
+ rolloutEpisodeRuntimeState: RolloutEpisodeRuntimeState,
164
+ ): void {
165
+ // Step 1: Leave the state unchanged when the episode already finished naturally.
166
+ if (
167
+ rolloutEpisodeRuntimeState.state.done ||
168
+ rolloutEpisodeRuntimeState.state.frameIndex <
169
+ rolloutEpisodeContext.maxFramesPerEpisode
170
+ ) {
171
+ return;
172
+ }
173
+
174
+ // Step 2: Mark a clean timeout when the frame budget was exhausted.
175
+ rolloutEpisodeRuntimeState.state.done = true;
176
+ rolloutEpisodeRuntimeState.state.doneReason =
177
+ FLAPPY_ROLLOUT_DONE_REASON_TIMEOUT;
178
+ }
179
+
180
+ /**
181
+ * Runs one rollout frame including control, shaping, and early termination.
182
+ *
183
+ * @param network - Genome/network to evaluate.
184
+ * @param rolloutEpisodeContext - Normalized rollout configuration.
185
+ * @param rolloutEpisodeRuntimeState - Mutable runtime state.
186
+ * @returns Nothing.
187
+ */
188
+ function runRolloutEpisodeFrame(
189
+ network: FlappyNetworkLike,
190
+ rolloutEpisodeContext: RolloutEpisodeContext,
191
+ rolloutEpisodeRuntimeState: RolloutEpisodeRuntimeState,
192
+ ): void {
193
+ // Step 1: Capture the pre-step observation used by dense shaping.
194
+ const previousObservationFeatures = getFlappyObservationFeatures(
195
+ rolloutEpisodeRuntimeState.state,
196
+ rolloutEpisodeContext.difficultyScale,
197
+ );
198
+
199
+ // Step 2: Advance the environment using network-driven flap control.
200
+ stepFlappyStateWithControlSubsteps(
201
+ rolloutEpisodeRuntimeState.state,
202
+ rolloutEpisodeRuntimeState.rng,
203
+ () =>
204
+ resolveRolloutFrameFlapDecision(
205
+ network,
206
+ rolloutEpisodeContext,
207
+ rolloutEpisodeRuntimeState,
208
+ ),
209
+ rolloutEpisodeContext.difficultyScale,
210
+ FLAPPY_CONTROL_SUBSTEPS_PER_FRAME,
211
+ );
212
+
213
+ // Step 3: Update dense shaping from the pre-step and post-step observations.
214
+ const currentObservationFeatures = getFlappyObservationFeatures(
215
+ rolloutEpisodeRuntimeState.state,
216
+ rolloutEpisodeContext.difficultyScale,
217
+ );
218
+ rolloutEpisodeRuntimeState.denseShapingFitness += computeDenseShapingReward(
219
+ previousObservationFeatures,
220
+ currentObservationFeatures,
221
+ );
222
+
223
+ // Step 4: Apply the optional early-termination heuristic when enabled.
224
+ applyRolloutEarlyTerminationIfNeeded(
225
+ rolloutEpisodeContext,
226
+ rolloutEpisodeRuntimeState,
227
+ currentObservationFeatures,
228
+ );
229
+ }
230
+
231
+ /**
232
+ * Resolves the flap decision for one control substep and commits memory state.
233
+ *
234
+ * @param network - Genome/network to evaluate.
235
+ * @param rolloutEpisodeContext - Normalized rollout configuration.
236
+ * @param rolloutEpisodeRuntimeState - Mutable runtime state.
237
+ * @returns Whether the bird should flap.
238
+ */
239
+ function resolveRolloutFrameFlapDecision(
240
+ network: FlappyNetworkLike,
241
+ rolloutEpisodeContext: RolloutEpisodeContext,
242
+ rolloutEpisodeRuntimeState: RolloutEpisodeRuntimeState,
243
+ ): boolean {
244
+ // Step 1: Resolve the current observation features from the mutable game state.
245
+ const observationFeatures = getFlappyObservationFeatures(
246
+ rolloutEpisodeRuntimeState.state,
247
+ rolloutEpisodeContext.difficultyScale,
248
+ );
249
+
250
+ // Step 2: Build the temporal observation vector and query the network outputs.
251
+ const observation = resolveTemporalObservationVector(
252
+ observationFeatures,
253
+ rolloutEpisodeRuntimeState.observationMemoryState,
254
+ );
255
+ const outputs = network.activate(observation);
256
+ const shouldFlap = resolveFlapDecision(outputs);
257
+
258
+ // Step 3: Commit the observation and control decision to temporal memory.
259
+ commitSharedObservationMemoryStep(
260
+ rolloutEpisodeRuntimeState.observationMemoryState,
261
+ observationFeatures,
262
+ shouldFlap,
263
+ );
264
+ return shouldFlap;
265
+ }
266
+
267
+ /**
268
+ * Applies the optional early-termination heuristic for unrecoverable starts.
269
+ *
270
+ * @param rolloutEpisodeContext - Normalized rollout configuration.
271
+ * @param rolloutEpisodeRuntimeState - Mutable runtime state.
272
+ * @param currentObservationFeatures - Post-step observation features.
273
+ * @returns Nothing.
274
+ */
275
+ function applyRolloutEarlyTerminationIfNeeded(
276
+ rolloutEpisodeContext: RolloutEpisodeContext,
277
+ rolloutEpisodeRuntimeState: RolloutEpisodeRuntimeState,
278
+ currentObservationFeatures: FlappyObservationFeatures,
279
+ ): void {
280
+ // Step 1: Exit immediately when early termination is disabled.
281
+ if (!rolloutEpisodeContext.enableEarlyTermination) {
282
+ return;
283
+ }
284
+
285
+ // Step 2: Track consecutive unrecoverable frames only during the warmup phase.
286
+ const earlyTerminationEligible =
287
+ rolloutEpisodeRuntimeState.state.pipesPassed ===
288
+ FLAPPY_ROLLOUT_ZERO_FITNESS &&
289
+ rolloutEpisodeRuntimeState.state.frameIndex >=
290
+ rolloutEpisodeContext.earlyTerminationGraceFrames;
291
+ const birdLikelyUnrecoverable = isBirdLikelyUnrecoverable(
292
+ currentObservationFeatures,
293
+ );
294
+ rolloutEpisodeRuntimeState.unrecoverableFrameCount =
295
+ earlyTerminationEligible && birdLikelyUnrecoverable
296
+ ? rolloutEpisodeRuntimeState.unrecoverableFrameCount + 1
297
+ : FLAPPY_ROLLOUT_ZERO_FITNESS;
298
+
299
+ // Step 3: Stop the episode once the unrecoverable streak reaches the configured threshold.
300
+ if (
301
+ rolloutEpisodeRuntimeState.unrecoverableFrameCount <
302
+ rolloutEpisodeContext.earlyTerminationConsecutiveFrames
303
+ ) {
304
+ return;
305
+ }
306
+
307
+ rolloutEpisodeRuntimeState.state.done = true;
308
+ rolloutEpisodeRuntimeState.state.doneReason =
309
+ FLAPPY_ROLLOUT_DONE_REASON_COLLISION;
310
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Rollout-internal type contracts.
3
+ *
4
+ * This file will host runtime-only rollout types that should not widen the
5
+ * public evaluation-level API surface.
6
+ */
7
+ import { createSharedObservationMemoryState } from '../../flappy.simulation.shared.utils';
8
+ import { createXorshift32 } from '../../rng';
9
+ import type { FlappyGameState } from '../../flappyEnvironment.ts';
10
+
11
+ /**
12
+ * Immutable rollout options normalized into execution-safe ranges.
13
+ */
14
+ export type RolloutEpisodeContext = {
15
+ seed: number;
16
+ difficultyScale: number;
17
+ maxFramesPerEpisode: number;
18
+ earlyTerminationGraceFrames: number;
19
+ earlyTerminationConsecutiveFrames: number;
20
+ enableEarlyTermination: boolean;
21
+ normalizeFitness: boolean;
22
+ pipeProgressTarget: number | undefined;
23
+ };
24
+
25
+ /**
26
+ * Mutable runtime state accumulated while one rollout episode executes.
27
+ */
28
+ export type RolloutEpisodeRuntimeState = {
29
+ rng: ReturnType<typeof createXorshift32>;
30
+ state: FlappyGameState;
31
+ observationMemoryState: ReturnType<typeof createSharedObservationMemoryState>;
32
+ denseShapingFitness: number;
33
+ unrecoverableFrameCount: number;
34
+ };
35
+
36
+ /**
37
+ * Fitness-channel breakdown used to compose the public episode result.
38
+ */
39
+ export type RolloutFitnessBreakdown = {
40
+ survivalFitness: number;
41
+ pipePassFitness: number;
42
+ denseShapingFitness: number;
43
+ terminalShapingFitness: number;
44
+ };
45
+
46
+ /**
47
+ * Per-frame dense shaping channels resolved from consecutive observations.
48
+ */
49
+ export type DenseShapingRewardComponents = {
50
+ nextGapAlignmentReward: number;
51
+ approachProgressReward: number;
52
+ centeringProgressReward: number;
53
+ clearanceReward: number;
54
+ secondGapAlignmentReward: number;
55
+ velocityStabilityReward: number;
56
+ };