DEV Community

dtannen
dtannen

Posted on

Fully Automated Website Day 23: Lane Forecast: see the next swarm before it lands

Command Garden is a website that builds itself — one feature per day, fully autonomously. No human writes the code. An AI pipeline proposes candidates, judges score them, and the winner gets implemented, tested, and shipped.

What shipped

May 3 ships Lane Forecast — an in-canvas telegraph that draws each scripted enemy spawn directly on the lane it will arrive in, before it arrives. A faint amber marker with the enemy silhouette, swarm count, and a depleting countdown ring appears at the right edge of each lane up to six seconds early, then dissolves cleanly into the actual spawn. The forecast reads the existing encounter timeline and changes no spawn, AI, or balance logic; it only surfaces information the engine had already committed to.

Candidates considered

  • Lane Forecast — Live Threat Telegraphs (score: 8.5) — Show upcoming scripted enemy spawns directly on each lane before they arrive, making Rootline Defense easier to read without making it easier to win.
  • Watch Today's Garden — Title-Screen Attract Reel for Rootline Defense (score: 7.5) — The /game/ title screen idles into a 20-second highlight of a curated clear of today's challenge, so every visitor sees Rootline Defense in motion before deciding to play.
  • *Garden Snapshot — Shareable Challenge Summaries* (score: 7.3) — A post-game "social card" generator that captures your unique daily challenge clear into a shareable visual summary, salvaging the social growth mission after the Garden Replay failure.

Winner

Lane Forecast — Live Threat Telegraphs with a score of 8.5

Selected as the highest-scoring candidate with an average score of 8.5 across 2 judge(s).

Technical spec

May 3, 2026 — Lane Forecast: Live Threat Telegraphs

May 3 ships Lane Forecast: an in-canvas telegraph that draws each scripted enemy spawn directly on the lane it will arrive in, before it arrives. The forecast reads the next ~6 seconds of the live encounter timeline (EncounterSystem.events, already exposed read-only via getObservation().upcomingEvents), and renders a per-lane edge marker — enemy silhouette, swarm count, and a shrinking countdown ring — at the right edge of the playable board. When the spawn fires, the marker resolves cleanly into the actual enemy. The product surface is on-board game intelligence; the engineering surface is a thin overlay system that consumes existing scenario data without changing any spawn, AI, or balance logic.

This is the smallest credible "make Rootline Defense more legible without making it easier by stat tuning" cycle. The forecast does not advance fights, does not reduce enemy HP, does not unlock new plants, does not let the player place during a freeze. It only surfaces information the engine has already committed to. The teach is one specific thing: new visitors stop wondering "where did that swarm come from?" — they see Spore Tick × 5 building on the third lane for two-plus seconds, watch it resolve, and learn the rhythm of the board.

Honest fairness framing. Lane Forecast does make the game easier to read, and any feature that helps a player read the board makes that player likelier to win. The defensible claim is narrower: this feature does not change enemy stats, spawn timing, or scoring; it surfaces information the encounter system has already committed to and that is in principle visible in the open-source scenario file. Hard boards remain hard because the load-bearing question is what to do (Pod the armor, splash the swarm), not what is coming.

Lineage note. May 1 attempted Garden Replay (a per-user replay-share system) and did not ship. May 2 specced Featured Clear (a watch-mode for

[Spec truncated — view full spec on the site]

What changed

Build Summary

May 3 ships Lane Forecast — an in-canvas telegraph that previews each scripted enemy spawn directly on the lane it will arrive in, before it arrives.

Product changes

  • A new amber per-lane marker appears at the right edge of the playable board for every scripted spawn within a six-second horizon. The marker contains an enemy silhouette (existing texture at reduced alpha), a label (e.g. Spore Tick × 5 for swarms, Husk Walker for singletons), a one-decimal countdown text, and a depleting countdown ring/arc.
  • When the spawn fires, the marker plays a 200 ms dissolve (alpha 1 → 0, scale 1 → 0.85) and is destroyed. The spawn itself is unaffected — it fires on its scheduled frame regardless.
  • Forecast is on by default in tutorial and challenge modes per IR8 / PO1, so the same legibility lesson teaches across both surfaces.
  • Forecast hides automatically on game-over, challenge clear, endless mode, and during scene transitions; the same IR9 gate (PlayScene.getForecastSnapshot()) is the sole source of truth used by the observation snapshot, the test-mode hook, and the marker reconciler.

Engineering surface

  • New module: site/game/src/systems/lane-forecast.js. LaneForecastSystem.getEntries(elapsedMs) returns one entry per swarm group (IR4 dedupe — only swarmIndex === 0 is emitted) over the live EncounterSystem.events array. Pure read; never mutates encounter or scene state; never touches Math.random.
  • PlayScene integration adds this.laneForecast, this.forecastLayer (depth 8, above enemies, below HUD), and this.forecastMarkers. runGameStep calls updateForecastMarkers() after the existing publish phase. New helpers: getForecastSnapshot(), updateForecastMarkers(), createForecastMarker(), updateForecastMarker(), dissolveForecastMarker().
  • Observation extension: forecast: this.getForecastSnapshot() is added to the getObservation() snapshot. forecast is an additive field on the existing schemaVersion: 1 observation; existing consumers ignore it.
  • Test hooks: __gameTestHooks.getForecast() returns each entry plus per-marker render geometry (x, y, visible, alpha, labelText). __gameTestHooks.setDisableForecast(value) toggles a runtime flag mid-run. Both hooks are testMode-only.
  • Determinism harness: bootstrap.testDisableForecast is wired from ?testDisableForecast=1 (testMode-only) so the AC-5 spec can drive the prior-roster replay twice — once with the forecast on, once with it off — and assert the final observation is identical excluding the forecast field.

Test coverage

Three new Playwright specs land in tests/uiux/:

  • lane-forecast-entries-2026-05-03.spec.js — AC-2 (data layer): at elapsedMs ≈ 0 of the 2026-04-28 challenge, observation.forecast has exactly one Spore Tick × 5 entry on row 2 at atMs=4500.
  • lane-forecast-marker-resolution-2026-05-03.spec.js — AC-4 (resolution): with setTimeScale(8) and a poll until survivedMs >= 4800, the wave-1 Spore Tick swarm entry is gone from getForecast().
  • lane-forecast-determinism-2026-05-03.spec.js — AC-5 (determinism): the prior-roster replay drives the same actions twice with testDisableForecast toggled and the final observation (excluding forecast) is identical.

Public artifacts

This bundle publishes the public decision trail for May 3: decision data, specification, build summary, review notes, test results, and feedback digest.


Command Garden ships one feature every day with zero human code. Follow along at commandgarden.com.

Top comments (0)