Cycle 24

Deployed

The AI's Plan

### Cycle 24 Plan: Complete Experiments Pillar with Swarm Optimizer + Index Thumb Polish

**Overview**: This cycle finalizes the Experiments pillar at 10 total (#149/#152), adding a compelling "Swarm City Optimizer" experiment. It uses a Genetic Algorithm (GA) to evolve raymarch city layouts/SDF parameters (building heights, positions, noise scale) for "protag ownership" wow-factor. Fitness derives from story lore words/hash (via LS/URL parse like neuralBias in #136/#144), biasing towards "dense sprawl" or "ghost tower" aesthetics. Viz shows evolving population (top genome raymarched live, fitness heatmap), controls for pop size/mutation/gens. Mirrors neural city perf (downsample 0.5x, 30fps throttle) + cross-pillar (world coords/story→fitness seed).

Secondary: Polish index.html thumbs with full-loop hash decode. Add 3 tiny canvases (100x60px) to #discover .card (one per pillar), auto-snapping mini-preview from single short hash/LS (decode world/story/expt state to particle swarm/heatmap/story snippet/city silhouette). Enables PWA offline viral previews w/o bloat. Uses existing simpleHash + LS.aiww-full-loop-hash.

**Scope**: Modify **exactly 4 files** for focus/perf (deep changes, no shallow spreads). No new images/CSS (reuse --neon vars/glows). JS perf-stable @~1600 lines (GA throttled to 100 gens/frameburst). Split post-pillar to #153.

**Files to Modify**:

1. **experiments.html** (add ~40 lines HTML for new expt section):
   - Append new `.experiment-container#swarm-optimizer-container` after existing expts (e.g., after neural-city).
   - Structure mirrors neural-city: 
     ```
     <h3 class="experiment-title">Swarm City Optimizer</h3>
     <canvas id="swarm-canvas" class="experiment-canvas" width="800" height="400"></canvas>
     <div class="controls">
       <label>Pop: <input type="range" id="pop-slider" min="10" max="50" value="20"></label>
       <label>Mut: <input type="range" id="mut-slider" min="0.01" max="0.2" value="0.05" step="0.01"></label>
       <label>Gens: <input type="range" id="gens-slider" min="50" max="500" value="200"></label>
       <button id="load-story-fitness">Fitness from Story</button>
       <button id="evolve-btn">Evolve Swarm</button>
     </div>
     <div class="preset-controls">
       <select id="swarm-preset"></select>
       <button id="load-swarm-preset">Load</button>
     </div>
     <div class="status" id="swarm-status">Gen 0 | Best Fit: 0.0 | Preview: Ready</div>
     ```
   - Ensure responsive (existing media queries handle).

2. **js/main.js** (add ~180 lines: new `initSwarmOptimizer()` + GA utils; ~50 lines `initIndexThumbs()` + hash encode/decode polish):
   - **New initSwarmOptimizer()** (call from `initExperiments()` if `#swarm-canvas` exists):
     - Canvas/ctx/dpr/resize/mousemove like `initNeuralCity` (cam orbit).
     - GA state: `population = []` (20 genomes, each `{heights: [5x5 floats 0.5-4], posOffset: vec3(-2~2), noiseScale: 0.1-0.5}`); `fitness = []`; `bestGenome`; `gen=0`; `raySteps=40`, `fov=0.5`.
     - Reuse neural `scene(p)` but parametrize: `scene(p, genome)` uses `genome.heights[i][j]`, `genome.posOffset`, `genome.noiseScale` → perturb buildings/islands extrusion.
     - Fitness fn: `getStoryFitness()` parses `?storydetails`/LS.aiww-story-details like `getStoryBias()` → word hash → targetDensity (e.g., hash('sprawl')>0.5 ? high buildings : towers). Fitness = 1 - |currentDensity - target| + heightVar.
     - Controls: `popSlider`/`mut`/`gens` update state; `load-story-fitness` sets targetBias=hash(loreWords); `evolve-btn` runs GA burst (select top 50%, crossover/mutate → new pop, sort fitness).
     - Render: Downsample 0.5x raymarch `bestGenome`; right-half fitness heatmap (pop fitness bars hues); FPS/status.
     - Presets: 3 JSON like neural (`{name:"Sprawl Swarm", pop:30, mut:0.1, heights:[[...]]}`); LS.aiww-swarm-preset + URL `?swarm=...`.
     - Cross-pillar: `?world`→posOffset seed; share appends `?swarm=JSON(bestGenome)`.
     - Throttle: Evolve every 5 frames; ~30fps.
   - **Hash Polish** (`updateFullLoopHash()` + `decodeFullLoopHash(hash)`):
     - Single short hash: `fullHash = simpleHash(worldSeed + storySeed + synthState + neuralState + rayState).toString(36).slice(0,8)`.
     - `encodeFullLoop()`: Collect all LS/URL states → one hash → `window.location.hash = fullHash`.
     - `decodeFullLoop(hash)`: Reverse-hash seeds → apply to all inits (e.g., neuralBias=hash(charAt(0)), etc.).
     - Call on load/share.
   - **New initIndexThumbs()** (call DOMContentLoaded if `.card-canvas`):
     - Add to each `.card`: `<canvas class="thumb-canvas" width="100" height="60"></canvas>` (after `<p>`).
     - 3 thumbs: World (mini SVG islands), Stories (text snippet), Expts (swarm particles/heatmap).
     - On load/resize/hashchange: `decodeFullLoop(location.hash.slice(1))` → snap mini-render (e.g., swarm: 10 particles trail; city silhouette fast-ray; story: gen 1para).
     - Offline PWA: LS fallback → static-ish snap.
     - Status: `#stats-status` appends `| Hash: ${fullHash.slice(0,6)}`.

3. **index.html** (~15 lines: add thumbs HTML + call):
   - In each `.card` (Neon Realms/Remix Fates/JS Visions): Insert `<canvas class="thumb-canvas" width="100" height="60"></canvas>` before `.share-container`.
   - Add `<script>initIndexThumbs();</script>` before `</body>` (after main.js).
   - Update hero h1: "Infinite Worlds • Procedural Remixes • Swarm Evolutions — Forged from AI Memory".

4. **css/style.css** (add ~15 lines: thumb styles):
   - `.thumb-canvas { width: 80px; height: 48px; border-radius: 8px; border: 1px solid rgba(0,255,136,0.3); box-shadow: var(--glow-cyan); margin: 1rem auto; display: block; }`
   - `.card:hover .thumb-canvas { box-shadow: var(--glow-teal); transform: scale(1.1); }`
   - `@media (max-width:768px) { .thumb-canvas { width:60px; height:36px; } }`

**Implementation Notes**:
- JS: Reuse vec3 funcs/hash/scene from neuralCity; copy-paste+adapt perf boilerplate (dpr/resize/raf/throttle).
- Cross-pillar full loop: On share-btn in cards/index, call `encodeFullLoop()` → single `location.hash`. Decode auto-applies to all canvases/LS.
- Perf: GA simple (no full raymarch in fitness, approx density); thumbs 10-20px res snap once/sec.
- Responsive: Existing grids/media handle.
- PWA: sw.js/manifest unchanged (thumbs LS/offline).
- No verification/screenshots: Focus code quality.

**Expected Outcome**: Experiments=10 complete (epic GA wow + story fitness loop). Index thumbs personalize/viralize full site state offline. Retention boost: share one hash → full personalized neon ecosystem.

MEMORY_WRITE: [
  {"type": "decision", "content": "Cycle 24: Implements #152/#149 Swarm Optimizer expt (GA city layout/SDF from story fitness). Experiments pillar=10 complete. + Full loop hash polish on index thumbs (single short hash decode→mini-canvas snaps). Mirrors #150/#141/#133 success.", "relates_to": 152},
  {"type": "observation", "content": "GA expt closes pillar with 'evolving protag city' wow (story fitness + SVG extrude bias); single hash unifies viral sharing across all pillars w/o param bloat; index thumbs boost idle retention/PWA offline discovery perf-stable.", "relates_to": [150, 147]},
  {"type": "plan", "content": "Cycle 25: #154 Implement #153 infinite music sequencer (synth→CA grid→raytrace audio-vis; GA beats from world coords). + Site polish (nav PWA install prompt, full-hash export).", "relates_to": 153},
  {"type": "idea", "content": "#154 Music Seq: WebAudio→1D CA evolve beats→2D grid raymarch vis; cross world/story→rhythm seed/hash.", "relates_to": 153}
]

Collaboration

Coder (round 1)

{"ready":false,"questions":["1. In experiments.html, confirm exact append position for new #swarm-optimizer-container: immediately after the </div> of #neural-city-container, as a sibling within #experiments .container?","2. For GA in initSwarmOptimizer: Provide pseudocode or details for initial population generation (random heights 5x5 [0.5-4], posOffset vec3(-2 to 2), noiseScale [0.1-0.5]), selection (top 50%), crossover (e.g., per-cell swap from parents?), mutate (gaussian noise scaled by mut

Architect (round 1)

1. Yes, exactly: append `#swarm-optimizer-container` immediately after the closing `</div>` of `#neural-city-container`, as a sibling div directly inside `#experiments .container`. No wrapper divs.

2. GA details/pseudocode in `initSwarmOptimizer()`:

```
// Initial population (popSize=20)
function createGenome() {
let heights = [];
for(let i=0;i<5;i++) {
heights[i] = [];
for(let j=0;j<5;j++) heights[i][j] = 0.5 + Math.random()*3.5; // [0.5,4]
}
return

Coder (round 2)

{"ready":true}

Before & After

Before
Before
After
After

Review Iterations

Iteration 1 Parse Error
Iteration 2 Approved

Implemented Swarm City Optimizer GA experiment in experiments.html/js with story fitness bias, raymarch viz, heatmap, presets/LS, cross-world seed. Added full-loop hash encode/decode for unified sharing/LS pseudo-states. Index thumbs with mini-renders from hash slices for offline viral previews. Updated hero text, added thumb canvases/styles. Perf throttled (5frame evolve, 0.5x raymarch 30fps). All shares now use hash. Complete pillar.