@reicek/neataptic-ts 0.1.26 → 0.1.27

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 (123) hide show
  1. package/.github/agents/boundary-mapper.agent.md +13 -8
  2. package/.github/agents/docs-scout.agent.md +14 -9
  3. package/.github/agents/plan-scout.agent.md +11 -6
  4. package/.github/agents/solid-split.agent.md +33 -17
  5. package/.github/copilot-instructions.md +100 -88
  6. package/.github/skills/educational-docs/SKILL.md +90 -40
  7. package/.github/skills/educational-docs/assets/mermaid-diagram-playbook.md +141 -141
  8. package/.github/skills/educational-docs/assets/visual-style-guide.md +1 -1
  9. package/.github/skills/plan-alignment/SKILL.md +1 -1
  10. package/.github/skills/solid-split/SKILL.md +54 -35
  11. package/.github/skills/solid-split/assets/docs-checklist.md +1 -1
  12. package/.github/skills/solid-split/assets/split-plan-template.md +41 -12
  13. package/.github/skills/solid-split/assets/split-workflow-checklist.md +4 -1
  14. package/.github/skills/test-fix-workflow/SKILL.md +12 -7
  15. package/.github/skills/trace-analyzer-extension/SKILL.md +1 -1
  16. package/.github/skills/trace-analyzer-extension/assets/extension-checklist.md +1 -1
  17. package/.github/skills/trace-analyzer-extension/references/analyzer-extension-workflow.md +1 -1
  18. package/.github/skills/trace-audit-reporting/SKILL.md +1 -1
  19. package/.github/skills/trace-audit-reporting/assets/performance-report-template.md +1 -1
  20. package/.github/skills/trace-audit-reporting/references/trace-analysis-workflow.md +1 -1
  21. package/.github/skills/tracker-handoff/SKILL.md +53 -5
  22. package/package.json +1 -1
  23. package/plans/Flappy_Bird_Folder_Documentation_Pass.logs.md +42 -0
  24. package/plans/Flappy_Bird_Folder_Documentation_Pass.md +22 -104
  25. package/plans/README.md +6 -2
  26. package/plans/Roadmap.md +35 -31
  27. package/plans/analyze-trace-solid-split.logs.md +35 -0
  28. package/plans/analyze-trace-solid-split.plans.md +21 -52
  29. package/plans/architecture-solid-split.logs.md +44 -0
  30. package/plans/architecture-solid-split.plans.md +20 -653
  31. package/plans/asciiMaze-typescript-repair.logs.md +35 -0
  32. package/plans/asciiMaze-typescript-repair.plans.md +30 -36
  33. package/plans/generate-docs-solid-split.logs.md +36 -0
  34. package/plans/generate-docs-solid-split.plans.md +21 -73
  35. package/plans/methods-docs.logs.md +37 -0
  36. package/plans/methods-docs.plans.md +22 -183
  37. package/plans/methods-solid-split.logs.md +41 -0
  38. package/plans/methods-solid-split.plans.md +23 -65
  39. package/plans/neat-docs.logs.md +38 -0
  40. package/plans/neat-docs.plans.md +21 -63
  41. package/plans/neat-test-surface-repair.logs.md +38 -0
  42. package/plans/neat-test-surface-repair.plans.md +24 -24
  43. package/plans/readme-first-section-pass.logs.md +63 -0
  44. package/plans/readme-first-section-pass.plans.md +42 -0
  45. package/plans/render-docs-html-solid-split.logs.md +36 -0
  46. package/plans/render-docs-html-solid-split.plans.md +20 -54
  47. package/plans/src-no-explicit-any-cleanup.logs.md +39 -0
  48. package/plans/src-no-explicit-any-cleanup.plans.md +23 -161
  49. package/plans/utils-docs.logs.md +37 -0
  50. package/plans/utils-docs.plans.md +20 -35
  51. package/src/README.md +88 -22
  52. package/src/architecture/README.md +94 -17
  53. package/src/architecture/activationArrayPool/README.md +53 -0
  54. package/src/architecture/activationArrayPool/activationArrayPool.ts +53 -0
  55. package/src/architecture/layer/README.md +94 -5
  56. package/src/architecture/layer/layer.ts +94 -5
  57. package/src/architecture/network/README.md +85 -14
  58. package/src/architecture/network/activate/README.md +301 -213
  59. package/src/architecture/network/activate/docs.order.json +9 -0
  60. package/src/architecture/network/activate/network.activate.utils.ts +90 -0
  61. package/src/architecture/network/connect/README.md +80 -3
  62. package/src/architecture/network/connect/docs.order.json +9 -0
  63. package/src/architecture/network/connect/network.connect.utils.ts +79 -0
  64. package/src/architecture/network/deterministic/README.md +96 -12
  65. package/src/architecture/network/deterministic/docs.order.json +10 -0
  66. package/src/architecture/network/deterministic/network.deterministic.utils.ts +90 -0
  67. package/src/architecture/network/evolve/README.md +286 -228
  68. package/src/architecture/network/evolve/docs.order.json +11 -0
  69. package/src/architecture/network/evolve/network.evolve.utils.ts +59 -0
  70. package/src/architecture/network/gating/README.md +58 -16
  71. package/src/architecture/network/gating/docs.order.json +9 -0
  72. package/src/architecture/network/gating/network.gating.utils.ts +43 -0
  73. package/src/architecture/network/genetic/README.md +75 -36
  74. package/src/architecture/network/genetic/docs.order.json +10 -0
  75. package/src/architecture/network/genetic/network.genetic.utils.ts +53 -17
  76. package/src/architecture/network/network.ts +91 -46
  77. package/src/architecture/network/standalone/README.md +309 -285
  78. package/src/architecture/network/standalone/docs.order.json +13 -0
  79. package/src/architecture/network/standalone/network.standalone.utils.ts +51 -28
  80. package/src/architecture/network.ts +94 -17
  81. package/src/architecture/nodePool/README.md +53 -0
  82. package/src/architecture/nodePool/nodePool.ts +53 -0
  83. package/src/methods/README.md +80 -34
  84. package/src/methods/methods.ts +80 -34
  85. package/src/methods/mutation/README.md +39 -93
  86. package/src/methods/mutation/mutation.ts +58 -0
  87. package/src/multithreading/README.md +114 -14
  88. package/src/multithreading/docs.order.json +5 -0
  89. package/src/multithreading/multi.ts +103 -7
  90. package/src/multithreading/types.ts +6 -1
  91. package/src/multithreading/workers/README.md +72 -2
  92. package/src/multithreading/workers/browser/README.md +39 -0
  93. package/src/multithreading/workers/browser/testworker.ts +40 -0
  94. package/src/multithreading/workers/node/README.md +50 -11
  95. package/src/multithreading/workers/node/docs.order.json +4 -0
  96. package/src/multithreading/workers/node/testworker.ts +43 -3
  97. package/src/multithreading/workers/workers.ts +36 -1
  98. package/src/neat/README.md +230 -152
  99. package/src/neat/adaptive/core/README.md +99 -42
  100. package/src/neat/adaptive/core/adaptive.core.ts +71 -14
  101. package/src/neat/adaptive/core/docs.order.json +8 -0
  102. package/src/neat/docs.order.json +9 -0
  103. package/src/neat/lineage/README.md +118 -16
  104. package/src/neat/lineage/lineage.ts +115 -13
  105. package/src/neat/neat.defaults.constants.ts +91 -13
  106. package/src/neat.ts +86 -20
  107. package/src/utils/README.md +71 -21
  108. package/src/utils/memory.ts +69 -19
  109. package/test/examples/asciiMaze/browser-entry/README.md +81 -8
  110. package/test/examples/asciiMaze/browser-entry/browser-entry.ts +81 -8
  111. package/test/examples/asciiMaze/dashboardManager/README.md +68 -4
  112. package/test/examples/asciiMaze/dashboardManager/dashboardManager.ts +68 -4
  113. package/test/examples/asciiMaze/evolutionEngine/README.md +1259 -1174
  114. package/test/examples/asciiMaze/evolutionEngine/docs.order.json +10 -0
  115. package/test/examples/asciiMaze/evolutionEngine/evolutionEngine.types.ts +87 -0
  116. package/test/examples/asciiMaze/mazeMovement/README.md +81 -4
  117. package/test/examples/asciiMaze/mazeMovement/mazeMovement.ts +81 -4
  118. package/test/examples/flappy_bird/browser-entry/README.md +64 -21
  119. package/test/examples/flappy_bird/browser-entry/browser-entry.ts +64 -21
  120. package/test/examples/flappy_bird/flappy-evolution-worker/README.md +98 -10
  121. package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.ts +98 -10
  122. package/test/examples/flappy_bird/simulation-shared/README.md +88 -4
  123. package/test/examples/flappy_bird/simulation-shared/simulation-shared.types.ts +88 -4
@@ -0,0 +1,10 @@
1
+ {
2
+ "introFile": "evolutionEngine.types.ts",
3
+ "fileOrder": [
4
+ "evolutionEngine.types.ts",
5
+ "engineState.types.ts",
6
+ "evolutionLoop.ts",
7
+ "evolutionEngine.services.ts",
8
+ "sampling.ts"
9
+ ]
10
+ }
@@ -1,3 +1,90 @@
1
+ /**
2
+ * Population-level runtime contracts for the ASCII Maze evolution engine.
3
+ *
4
+ * This folder is where one maze, one fitness story, and one NEAT controller
5
+ * turn into a repeatable training program. The public `EvolutionEngine` facade
6
+ * uses these contracts to normalize options, coordinate host callbacks, keep
7
+ * deterministic state reproducible, and decide when a curriculum phase has
8
+ * produced a winner worth carrying forward.
9
+ *
10
+ * The important distinction is scale. `mazeMovement/` explains one agent run.
11
+ * `fitness.ts` explains how that run is scored. `dashboardManager/` explains
12
+ * how progress is shown to a human. `evolutionEngine/` explains how many runs
13
+ * across many generations become one population-level search loop with stop
14
+ * reasons, telemetry, warm starts, and phase outcomes that the next maze can
15
+ * reuse.
16
+ *
17
+ * This file is the right chapter opening because it names the public nouns of
18
+ * that loop before the reader hits pooled scratch buffers or hot-path helpers.
19
+ * It answers four questions quickly: what a caller can configure, what a host
20
+ * may observe or interrupt, what result the engine returns, and which shared
21
+ * runtime contexts keep the hot path allocation-light.
22
+ *
23
+ * A useful mental model is to treat the engine as a control tower rather than
24
+ * the aircraft itself. The engine does not move the agent through one maze cell
25
+ * at a time. It schedules phases, batches generations, preserves deterministic
26
+ * state, and hands structured outcomes back to browser or terminal hosts.
27
+ *
28
+ * Read the chapter in three passes. Start here for the public contracts and the
29
+ * meaning of a run result. Continue to `engineState.types.ts` when you want the
30
+ * shared scratch and toggle state that keeps the loop cheap. Finish with
31
+ * `evolutionLoop.ts`, `evolutionEngine.services.ts`, and `sampling.ts` when you
32
+ * want the actual orchestration and telemetry mechanics.
33
+ *
34
+ * ```mermaid
35
+ * flowchart LR
36
+ * classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
37
+ * classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
38
+ *
39
+ * Caller["Caller or host"]:::base --> Options["IRunMazeEvolutionOptions\nrun inputs"]:::base
40
+ * Options --> Engine["EvolutionEngine facade\npopulation-level control"]:::accent
41
+ * Engine --> Loop["generation loop\nevaluate mutate telemetry"]:::base
42
+ * Loop --> Result["MazeEvolutionRunResult\nbest network + exit reason"]:::base
43
+ * Result --> Phase["MazeEvolutionCurriculumPhaseOutcome\ncarry winner forward"]:::base
44
+ * Engine --> Host["EvolutionHostAdapter\npause and stop hooks"]:::base
45
+ * ```
46
+ *
47
+ * ```mermaid
48
+ * flowchart TD
49
+ * classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
50
+ * classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
51
+ *
52
+ * EngineFolder["evolutionEngine/"]:::accent --> Contracts["evolutionEngine.types.ts\npublic run contracts"]:::base
53
+ * EngineFolder --> Scratch["engineState.types.ts\nshared scratch and toggles"]:::base
54
+ * EngineFolder --> Loop["evolutionLoop.ts\nmain generation orchestration"]:::base
55
+ * EngineFolder --> Services["evolutionEngine.services.ts\nand helpers"]:::base
56
+ * EngineFolder --> Sampling["sampling.ts\nand telemetry support"]:::base
57
+ * ```
58
+ *
59
+ * For background reading on the staged difficulty idea behind the browser and
60
+ * curriculum-style runs, see Wikipedia contributors,
61
+ * [Curriculum learning](https://en.wikipedia.org/wiki/Curriculum_learning),
62
+ * which captures the broader teaching idea of solving easier tasks before
63
+ * harder ones.
64
+ *
65
+ * Example: describe the host adapter and reporting hooks the engine may call.
66
+ *
67
+ * ```ts
68
+ * const hostAdapter: EvolutionHostAdapter = {
69
+ * isPauseRequested: () => window.asciiMazePaused === true,
70
+ * handleStop: ({ reason, completedGenerations }) => {
71
+ * console.log(reason, completedGenerations);
72
+ * },
73
+ * };
74
+ * ```
75
+ *
76
+ * Example: sketch one engine run configuration before execution begins.
77
+ *
78
+ * ```ts
79
+ * const runOptions: IRunMazeEvolutionOptions = {
80
+ * mazeConfig: { maze },
81
+ * agentSimConfig: { maxSteps: 160 },
82
+ * evolutionAlgorithmConfig: { popSize: 120, deterministic: true },
83
+ * reportingConfig: { dashboardManager, logEvery: 5 },
84
+ * };
85
+ * ```
86
+ */
87
+
1
88
  import type Network from '../../../../src/architecture/network';
2
89
  import type { FitnessEvaluatorFn } from '../fitness.types';
3
90
  import type {
@@ -1,10 +1,87 @@
1
1
  # mazeMovement
2
2
 
3
- Public MazeMovement facade for the dedicated mazeMovement module boundary.
3
+ Episode-simulation boundary for one maze-controlled agent.
4
+
5
+ This folder is where a policy stops being abstract logits and starts paying
6
+ for local decisions. One run moves through perception, direction selection,
7
+ collision-aware movement, shaping, and finalization until the agent reaches
8
+ the exit or exhausts its step budget.
9
+
10
+ The boundary exists because single-episode logic needs both honesty and
11
+ inspectability. If movement rules, reward shaping, and stop conditions were
12
+ scattered across fitness or evolution helpers, it would be much harder to
13
+ tell whether poor results came from weak policy, thin observations, harsh
14
+ shaping, or simple runtime edge cases.
15
+
16
+ Read the folder as four cooperating shelves. `runtime/` builds perception,
17
+ visit bookkeeping, and low-level state transitions. `policy/` converts raw
18
+ outputs into concrete directional choices and exploration nudges. `shaping/`
19
+ applies the score semantics that make sparse-goal navigation learnable.
20
+ `finalization/` folds the finished path into one result the engine and
21
+ fitness layers can compare.
22
+
23
+ The public class stays class-based on purpose. Existing imports remain
24
+ stable, but the real teaching value is now inside the split helpers. The
25
+ facade tells the reader what the episode boundary promises; the subfolders
26
+ explain how that promise is kept.
27
+
28
+ Read this chapter in three passes. Start with `simulateAgent(...)` when you
29
+ want the whole episode loop. Continue to `selectDirection(...)` and
30
+ `moveAgent(...)` when you want the policy-to-action seam. Finish in the
31
+ runtime, policy, shaping, and finalization folders when you need the exact
32
+ bookkeeping or reward logic behind one run.
33
+
34
+ ```mermaid
35
+ flowchart LR
36
+ classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
37
+ classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
38
+
39
+ Vision["vision and visit state"]:::base --> Policy["direction selection\nand exploration nudges"]:::accent
40
+ Policy --> Move["collision-aware movement"]:::base
41
+ Move --> Shaping["progress and penalty shaping"]:::base
42
+ Shaping --> Finalize["episode result\nfitness path progress"]:::base
43
+ ```
44
+
45
+ ```mermaid
46
+ flowchart TD
47
+ classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
48
+ classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
49
+
50
+ MazeMovement["mazeMovement/"]:::accent --> Facade["mazeMovement.ts\npublic episode facade"]:::base
51
+ MazeMovement --> Runtime["runtime/\nvision and state"]:::base
52
+ MazeMovement --> Policy["policy/\naction choice"]:::base
53
+ MazeMovement --> Shaping["shaping/\nreward and penalties"]:::base
54
+ MazeMovement --> Finalization["finalization/\nresult folding"]:::base
55
+ ```
4
56
 
5
- The folder now owns runtime helpers, policy helpers, shaping helpers, and
6
- finalization logic. This file keeps the user-facing API in one place while
7
- the implementation stays split into focused helpers.
57
+ For background on why direction selection talks about probabilities and
58
+ entropy instead of only the raw logits, see Wikipedia contributors,
59
+ [Softmax function](https://en.wikipedia.org/wiki/Softmax_function), which is
60
+ the probability transform used by the action-diagnostics helper layer.
61
+
62
+ Example: inspect the direction choice implied by one network output vector.
63
+
64
+ ```ts
65
+ const directionStats = MazeMovement.selectDirection([0.4, 1.2, -0.3, 0.1]);
66
+
67
+ console.log(directionStats.selectedDirection);
68
+ console.log(directionStats.entropy);
69
+ ```
70
+
71
+ Example: simulate one complete maze episode for a candidate network.
72
+
73
+ ```ts
74
+ const result = MazeMovement.simulateAgent(
75
+ network,
76
+ encodedMaze,
77
+ startPos,
78
+ exitPos,
79
+ distanceMap,
80
+ 160,
81
+ );
82
+
83
+ console.log(result.fitness, result.reachedExit);
84
+ ```
8
85
 
9
86
  ## mazeMovement/mazeMovement.types.ts
10
87
 
@@ -1,9 +1,86 @@
1
1
  /**
2
- * Public MazeMovement facade for the dedicated mazeMovement module boundary.
2
+ * Episode-simulation boundary for one maze-controlled agent.
3
3
  *
4
- * The folder now owns runtime helpers, policy helpers, shaping helpers, and
5
- * finalization logic. This file keeps the user-facing API in one place while
6
- * the implementation stays split into focused helpers.
4
+ * This folder is where a policy stops being abstract logits and starts paying
5
+ * for local decisions. One run moves through perception, direction selection,
6
+ * collision-aware movement, shaping, and finalization until the agent reaches
7
+ * the exit or exhausts its step budget.
8
+ *
9
+ * The boundary exists because single-episode logic needs both honesty and
10
+ * inspectability. If movement rules, reward shaping, and stop conditions were
11
+ * scattered across fitness or evolution helpers, it would be much harder to
12
+ * tell whether poor results came from weak policy, thin observations, harsh
13
+ * shaping, or simple runtime edge cases.
14
+ *
15
+ * Read the folder as four cooperating shelves. `runtime/` builds perception,
16
+ * visit bookkeeping, and low-level state transitions. `policy/` converts raw
17
+ * outputs into concrete directional choices and exploration nudges. `shaping/`
18
+ * applies the score semantics that make sparse-goal navigation learnable.
19
+ * `finalization/` folds the finished path into one result the engine and
20
+ * fitness layers can compare.
21
+ *
22
+ * The public class stays class-based on purpose. Existing imports remain
23
+ * stable, but the real teaching value is now inside the split helpers. The
24
+ * facade tells the reader what the episode boundary promises; the subfolders
25
+ * explain how that promise is kept.
26
+ *
27
+ * Read this chapter in three passes. Start with `simulateAgent(...)` when you
28
+ * want the whole episode loop. Continue to `selectDirection(...)` and
29
+ * `moveAgent(...)` when you want the policy-to-action seam. Finish in the
30
+ * runtime, policy, shaping, and finalization folders when you need the exact
31
+ * bookkeeping or reward logic behind one run.
32
+ *
33
+ * ```mermaid
34
+ * flowchart LR
35
+ * classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
36
+ * classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
37
+ *
38
+ * Vision["vision and visit state"]:::base --> Policy["direction selection\nand exploration nudges"]:::accent
39
+ * Policy --> Move["collision-aware movement"]:::base
40
+ * Move --> Shaping["progress and penalty shaping"]:::base
41
+ * Shaping --> Finalize["episode result\nfitness path progress"]:::base
42
+ * ```
43
+ *
44
+ * ```mermaid
45
+ * flowchart TD
46
+ * classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
47
+ * classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
48
+ *
49
+ * MazeMovement["mazeMovement/"]:::accent --> Facade["mazeMovement.ts\npublic episode facade"]:::base
50
+ * MazeMovement --> Runtime["runtime/\nvision and state"]:::base
51
+ * MazeMovement --> Policy["policy/\naction choice"]:::base
52
+ * MazeMovement --> Shaping["shaping/\nreward and penalties"]:::base
53
+ * MazeMovement --> Finalization["finalization/\nresult folding"]:::base
54
+ * ```
55
+ *
56
+ * For background on why direction selection talks about probabilities and
57
+ * entropy instead of only the raw logits, see Wikipedia contributors,
58
+ * [Softmax function](https://en.wikipedia.org/wiki/Softmax_function), which is
59
+ * the probability transform used by the action-diagnostics helper layer.
60
+ *
61
+ * Example: inspect the direction choice implied by one network output vector.
62
+ *
63
+ * ```ts
64
+ * const directionStats = MazeMovement.selectDirection([0.4, 1.2, -0.3, 0.1]);
65
+ *
66
+ * console.log(directionStats.selectedDirection);
67
+ * console.log(directionStats.entropy);
68
+ * ```
69
+ *
70
+ * Example: simulate one complete maze episode for a candidate network.
71
+ *
72
+ * ```ts
73
+ * const result = MazeMovement.simulateAgent(
74
+ * network,
75
+ * encodedMaze,
76
+ * startPos,
77
+ * exitPos,
78
+ * distanceMap,
79
+ * 160,
80
+ * );
81
+ *
82
+ * console.log(result.fitness, result.reachedExit);
83
+ * ```
7
84
  */
8
85
 
9
86
  import type { INetwork } from '../interfaces';
@@ -1,37 +1,80 @@
1
1
  # browser-entry
2
2
 
3
- Browser demo public entry for the Flappy Bird example.
3
+ Browser teaching surface and lifecycle facade for the Flappy Bird example.
4
+
5
+ This folder is where worker-owned evolution meets human-friendly inspection.
6
+ The browser side owns DOM setup, HUD updates, playback rendering, and network
7
+ visualization. The worker side owns the hot-path simulation and packed frame
8
+ production. `browser-entry/` exists so those responsibilities stay honest
9
+ instead of drifting into one blurry runtime.
10
+
11
+ That split is the main reason this file stays intentionally small. The public
12
+ `start(...)` surface should feel simple to call even though the surrounding
13
+ system is not simple at all. A caller gets one run handle, while the folder
14
+ behind it fans out into runtime bootstrap, host layout, worker messaging,
15
+ playback rendering, and inspection views.
16
+
17
+ Read this boundary as the browser-side answer to one practical question:
18
+ how do you make an evolved controller visible and interactive without moving
19
+ simulation authority back onto the main thread? The answer is a stable entry
20
+ facade plus a strict authority split between browser presentation and worker
21
+ execution.
22
+
23
+ `index.html` is only the local shell that loads the published bundle and then
24
+ reaches this same start boundary through globals. If you want the real
25
+ host/runtime seam, start here rather than with the static shell.
26
+
27
+ Read the folder in three passes. Start with this file for the public
28
+ lifecycle contract. Continue into `runtime/` and `worker-channel/` for the
29
+ bootstrap and protocol story. Finish with `host/`, `playback/`,
30
+ `network-view/`, and `visualization/` for the teaching surface the browser
31
+ renders around the worker-owned simulation.
4
32
 
5
- This boundary is the hand-off point between library consumers and the demo's
6
- browser runtime. Calling `start` boots the canvas UI, worker channel, HUD,
7
- and playback loop without exposing all of that internal orchestration as part
8
- of the public API.
33
+ ```mermaid
34
+ flowchart LR
35
+ classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
36
+ classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
9
37
 
10
- In other words, this file is intentionally tiny because it acts like a clean
11
- facade over a much larger interactive system.
38
+ Start["start()"]:::accent --> Runtime["runtime/\nbootstrap orchestration"]:::base
39
+ Runtime --> Host["host/\nDOM and canvas shell"]:::base
40
+ Runtime --> Channel["worker-channel/\nworker protocol"]:::base
41
+ Channel --> Playback["playback/\npopulation rendering"]:::base
42
+ Runtime --> Network["network-view + visualization/\nnetwork inspection"]:::base
43
+ ```
12
44
 
13
- Educational note:
14
- `index.html` is only the local browser shell that loads the published bundle
15
- and then exposes this same start boundary through browser globals. Read this
16
- file when you want the real host/runtime seam instead of the static shell.
45
+ ```mermaid
46
+ flowchart TD
47
+ classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
48
+ classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
49
+
50
+ Browser["Main thread browser host"]:::accent --> Ui["canvas HUD and network view"]:::base
51
+ Browser --> Handle["FlappyBirdRunHandle\nstop isRunning done"]:::base
52
+ Browser --> Protocol["worker-channel\nmessage transport"]:::base
53
+ Protocol --> Worker["worker-owned evolution\nand packed playback frames"]:::base
54
+ ```
55
+
56
+ For background on why the boundary keeps simulation authority off the main
57
+ thread, see MDN,
58
+ [Using Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers),
59
+ which captures the browser execution model this example leans on.
60
+
61
+ Example: start the demo and stop it from embedding code later.
17
62
 
18
- Minimal browser start example:
19
63
  ```ts
20
64
  import { start } from './browser-entry/browser-entry';
21
65
 
22
66
  const handle = await start('flappy-bird-output');
23
- // Later: handle.stop();
67
+ setTimeout(() => handle.stop(), 10_000);
24
68
  await handle.done;
25
69
  ```
26
70
 
27
- Startup path:
28
- ```mermaid
29
- flowchart LR
30
- Start["start()"] --> Runtime["runtime/\nbootstrap orchestration"]
31
- Runtime --> Host["host/\nDOM and canvas shell"]
32
- Runtime --> Channel["worker-channel/\nworker protocol"]
33
- Channel --> Playback["playback/\npopulation rendering"]
34
- Runtime --> Network["network-view + visualization/\nnetwork inspection"]
71
+ Example: watch the lifecycle handle while the browser host is running.
72
+
73
+ ```ts
74
+ const handle = await start('flappy-bird-output');
75
+
76
+ console.log(handle.isRunning());
77
+ await handle.done;
35
78
  ```
36
79
 
37
80
  ## browser-entry/browser-entry.ts
@@ -1,36 +1,79 @@
1
1
  /**
2
- * Browser demo public entry for the Flappy Bird example.
2
+ * Browser teaching surface and lifecycle facade for the Flappy Bird example.
3
3
  *
4
- * This boundary is the hand-off point between library consumers and the demo's
5
- * browser runtime. Calling `start` boots the canvas UI, worker channel, HUD,
6
- * and playback loop without exposing all of that internal orchestration as part
7
- * of the public API.
4
+ * This folder is where worker-owned evolution meets human-friendly inspection.
5
+ * The browser side owns DOM setup, HUD updates, playback rendering, and network
6
+ * visualization. The worker side owns the hot-path simulation and packed frame
7
+ * production. `browser-entry/` exists so those responsibilities stay honest
8
+ * instead of drifting into one blurry runtime.
8
9
  *
9
- * In other words, this file is intentionally tiny because it acts like a clean
10
- * facade over a much larger interactive system.
10
+ * That split is the main reason this file stays intentionally small. The public
11
+ * `start(...)` surface should feel simple to call even though the surrounding
12
+ * system is not simple at all. A caller gets one run handle, while the folder
13
+ * behind it fans out into runtime bootstrap, host layout, worker messaging,
14
+ * playback rendering, and inspection views.
11
15
  *
12
- * Educational note:
13
- * `index.html` is only the local browser shell that loads the published bundle
14
- * and then exposes this same start boundary through browser globals. Read this
15
- * file when you want the real host/runtime seam instead of the static shell.
16
+ * Read this boundary as the browser-side answer to one practical question:
17
+ * how do you make an evolved controller visible and interactive without moving
18
+ * simulation authority back onto the main thread? The answer is a stable entry
19
+ * facade plus a strict authority split between browser presentation and worker
20
+ * execution.
21
+ *
22
+ * `index.html` is only the local shell that loads the published bundle and then
23
+ * reaches this same start boundary through globals. If you want the real
24
+ * host/runtime seam, start here rather than with the static shell.
25
+ *
26
+ * Read the folder in three passes. Start with this file for the public
27
+ * lifecycle contract. Continue into `runtime/` and `worker-channel/` for the
28
+ * bootstrap and protocol story. Finish with `host/`, `playback/`,
29
+ * `network-view/`, and `visualization/` for the teaching surface the browser
30
+ * renders around the worker-owned simulation.
31
+ *
32
+ * ```mermaid
33
+ * flowchart LR
34
+ * classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
35
+ * classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
36
+ *
37
+ * Start["start()"]:::accent --> Runtime["runtime/\nbootstrap orchestration"]:::base
38
+ * Runtime --> Host["host/\nDOM and canvas shell"]:::base
39
+ * Runtime --> Channel["worker-channel/\nworker protocol"]:::base
40
+ * Channel --> Playback["playback/\npopulation rendering"]:::base
41
+ * Runtime --> Network["network-view + visualization/\nnetwork inspection"]:::base
42
+ * ```
43
+ *
44
+ * ```mermaid
45
+ * flowchart TD
46
+ * classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
47
+ * classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
48
+ *
49
+ * Browser["Main thread browser host"]:::accent --> Ui["canvas HUD and network view"]:::base
50
+ * Browser --> Handle["FlappyBirdRunHandle\nstop isRunning done"]:::base
51
+ * Browser --> Protocol["worker-channel\nmessage transport"]:::base
52
+ * Protocol --> Worker["worker-owned evolution\nand packed playback frames"]:::base
53
+ * ```
54
+ *
55
+ * For background on why the boundary keeps simulation authority off the main
56
+ * thread, see MDN,
57
+ * [Using Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers),
58
+ * which captures the browser execution model this example leans on.
59
+ *
60
+ * Example: start the demo and stop it from embedding code later.
16
61
  *
17
- * Minimal browser start example:
18
62
  * ```ts
19
63
  * import { start } from './browser-entry/browser-entry';
20
64
  *
21
65
  * const handle = await start('flappy-bird-output');
22
- * // Later: handle.stop();
66
+ * setTimeout(() => handle.stop(), 10_000);
23
67
  * await handle.done;
24
68
  * ```
25
69
  *
26
- * Startup path:
27
- * ```mermaid
28
- * flowchart LR
29
- * Start["start()"] --> Runtime["runtime/\nbootstrap orchestration"]
30
- * Runtime --> Host["host/\nDOM and canvas shell"]
31
- * Runtime --> Channel["worker-channel/\nworker protocol"]
32
- * Channel --> Playback["playback/\npopulation rendering"]
33
- * Runtime --> Network["network-view + visualization/\nnetwork inspection"]
70
+ * Example: watch the lifecycle handle while the browser host is running.
71
+ *
72
+ * ```ts
73
+ * const handle = await start('flappy-bird-output');
74
+ *
75
+ * console.log(handle.isRunning());
76
+ * await handle.done;
34
77
  * ```
35
78
  */
36
79
  export { start } from './runtime/runtime';
@@ -7,16 +7,104 @@ explanation, HUD rendering, and network inspection, while the worker owns the
7
7
  hot path: evolving generations, materializing playback state, advancing the
8
8
  simulation, and packaging compact snapshots back to the host.
9
9
 
10
- Read this file as the worker chapter's public spine. It is not the place for
11
- low-level simulation math or message-shape detail. Instead it shows how the
12
- worker turns a small typed protocol into one long-lived deterministic runtime.
13
-
14
- Protocol flow at a glance:
15
- 1. `init` seeds deterministic worker state and creates the NEAT runtime.
16
- 2. `request-generation` evolves one generation and posts a summary message.
17
- 3. `start-playback` materializes worker-local simulation state.
18
- 4. `request-playback-step` advances playback and streams packed snapshots.
19
- 5. `stop` marks the worker as cooperatively stopped.
10
+ That separation is doing two jobs at once. It protects the browser from
11
+ heavy simulation work, and it turns responsibility into something a reader
12
+ can see directly because every cross-thread handoff must become an explicit
13
+ typed message.
14
+
15
+ Read this folder as the protocol chapter between the browser host and the
16
+ deterministic runtime that actually evolves and replays the flock. The
17
+ important design question is not merely "how do Web Workers run code?" It is
18
+ "which side should own each piece of truth when evolution, playback, and
19
+ inspection all need the same population?"
20
+
21
+ In this example, the answer is deliberate:
22
+
23
+ - the host owns controls, HUD state, and network visualization,
24
+ - the worker owns generation requests, playback stepping, and winner
25
+ selection,
26
+ - packed snapshots are the narrow bridge between those two worlds.
27
+
28
+ ## What This Folder Is Trying To Teach
29
+
30
+ The worker chapter is organized around four reader questions:
31
+
32
+ 1. How does the browser request evolution work without becoming the
33
+ simulation authority?
34
+ 2. How does one evolved population become a replayable playback session?
35
+ 3. Why are snapshots packed into typed arrays instead of posted as nested
36
+ render objects?
37
+ 4. Where should you read next when the protocol is clear but one runtime step
38
+ still feels opaque?
39
+
40
+ ## Core Worker Map
41
+
42
+ ```mermaid
43
+ flowchart LR
44
+ Host["browser-entry/\nhost UI and controls"] --> Protocol["protocol service\nlegal message transitions"]
45
+ Protocol --> Runtime["runtime service\nworker-local NEAT controller"]
46
+ Runtime --> Evolution["evolution service\nadvance one generation"]
47
+ Runtime --> Playback["playback service\nmaterialize and step population"]
48
+ Playback --> Snapshot["snapshot utils\npacked typed-array transport"]
49
+ Snapshot --> Host
50
+
51
+ WarmStart["warm-start service\ngeneration zero bootstrap"] -.-> Evolution
52
+ Types["worker types\nmessage and DTO contracts"] -.-> Protocol
53
+
54
+ classDef boundary fill:#001522,stroke:#0fb5ff,color:#9fdcff,stroke-width:2px;
55
+ classDef runtime fill:#03111f,stroke:#00e5ff,color:#d8f6ff,stroke-width:2px;
56
+ classDef highlight fill:#2a1029,stroke:#ff4a8d,color:#ffd7e8,stroke-width:3px;
57
+
58
+ class Host,Protocol,Types boundary;
59
+ class Runtime,Evolution,Playback,Snapshot runtime;
60
+ class Snapshot highlight;
61
+ ```
62
+
63
+ Read the diagram left to right. The host is allowed to request work, but it
64
+ never takes ownership of the worker's mutable simulation state. The worker
65
+ can then optimize for determinism and throughput while the browser optimizes
66
+ for explanation.
67
+
68
+ ## Choose Your Route
69
+
70
+ - Start with `flappy-evolution-worker.ts` if you want the high-level message
71
+ lifecycle.
72
+ - Read `flappy-evolution-worker.protocol.service.ts` next if you want the
73
+ legal sequencing rules.
74
+ - Read `flappy-evolution-worker.runtime.service.ts` if you want the worker's
75
+ NEAT runtime setup.
76
+ - Read `flappy-evolution-worker.playback.service.ts` and
77
+ `flappy-evolution-worker.simulation.frame.service.ts` if you want the hot
78
+ playback path.
79
+ - Read `flappy-evolution-worker.snapshot.utils.ts` if you want the typed-array
80
+ transport story.
81
+
82
+ Minimal host-side sketch:
83
+
84
+ ```ts
85
+ worker.postMessage({
86
+ type: 'init',
87
+ payload: { populationSize: 50, elitismCount: 10, rngSeed: 12345 },
88
+ });
89
+ worker.postMessage({ type: 'request-generation' });
90
+ worker.postMessage({
91
+ type: 'start-playback',
92
+ payload: { visibleWorldWidthPx: 1280, visibleWorldHeightPx: 720 },
93
+ });
94
+ worker.postMessage({
95
+ type: 'request-playback-step',
96
+ payload: {
97
+ requestId: 1,
98
+ simulationSteps: 2,
99
+ visibleWorldWidthPx: 1280,
100
+ visibleWorldHeightPx: 720,
101
+ },
102
+ });
103
+ ```
104
+
105
+ If you want background reading before the symbol shelf, the MDN Web Workers
106
+ guide is the fastest practical reference for why this example pushes both
107
+ evolution and playback off the main thread.
20
108
 
21
109
  ## flappy-evolution-worker/flappy-evolution-worker.ts
22
110