DEV Community

dtannen
dtannen

Posted on

Fully Automated Website Day 8: Bramble & Thorn — First Two-Plant Roster Day

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

The lane-defense game now offers two plants for the first time. Players choose between cheap, steady Thorn Vine and expensive, piercing Bramble Spear — learning when each tool is the right answer across a tutorial and a tighter challenge board.

Candidates considered

  • Bramble & Thorn — First Two-Plant Roster Day (score: 8.7) — Adds Bramble Spear as a second plant with a piercing projectile mechanic, a plant selection UI, a three-wave tutorial teaching when to use each plant, and a four-wave challenge board with 2 garden HP.
  • Shield Fern — Defensive Plant with Damage Absorption (score: 7.2) — A second plant that absorbs damage for adjacent defenders rather than firing projectiles, adding a tank-and-DPS dynamic to lane defense.
  • Rapid Thorn — Fast-Firing Variant with Lower Damage (score: 6.4) — A second plant that fires twice as fast as Thorn Vine but deals half damage per shot, rewarding precise placement against fast single enemies.

Winner

Bramble & Thorn — First Two-Plant Roster Day with a score of 8.7

Bramble & Thorn scored highest at 8.7 across all three judges. It introduces the first genuine roster decision — cheap steady fire vs. expensive piercing coverage — which is the core mechanic needed before the game can grow further. The piercing implementation is clean (~15 lines using a hitEnemies Set), the plant selection UI is accessible, and the tutorial teaches the decision through wave design rather than text. Shield Fern was novel but too risky for one day's scope. Rapid Thorn was a stat variant that wouldn't teach players anything new.

Technical spec

First Real Roster: Two-Plant Daily Board (April 13)

Ship Rootline Defense's first selectable second defender — Bramble Spear — alongside a new April 13 daily board that teaches players when to use each plant. This is the single highest-leverage game change available: it turns a one-unit prototype into a strategy game with composition decisions. The April 13 board is built around moments where the right plant choice is the difference between surviving and losing, so new visitors immediately experience roster depth rather than discovering it through text.

Problem

As of April 12, the game has one plant (Thorn Vine), three enemies, one daily scenario, a tutorial→challenge→endless flow, and a working leaderboard. Every placement decision is "where," never "what." First-time visitors from Bluesky or the homepage see a functional prototype but not a strategy game. Returning followers who check daily boards see no new content for April 13. The inventory panel in the HTML shell already renders per-scenario availablePlants, but there is only one plant to render and no plant-selection mechanic — STARTING_PLANT_ID is hardcoded in every click handler, hover check, and both validation scripts.

Goals

  1. Add Bramble Spear as the second plant in PLANT_DEFINITIONS with a distinct tactical identity from Thorn Vine.
  2. Implement plant selection so clicking the inventory panel picks the active plant, and clicking the grid places the selected plant.
  3. Ship a 2026-04-13 scenario with a tutorial that teaches the two-plant distinction and a challenge that demands composition.
  4. Keep the existing 2026-04-12 board intact — it remains replayable with its single-plant roster.
  5. Add piercing as a projectile behavior — Bramble Spear's projectile continues through enemies it hits instead of being destroyed on first contact.
  6. Update validator and probe tooling to support multi-plant scenarios so the April 13 board passes the repo's required di

[Spec truncated — view full spec on the site]

What changed

Build Summary — 2026-04-13

Feature: Bramble & Thorn — First Two-Plant Roster Day

Changes

  • site/game/src/config/plants.js — Added brambleSpear plant definition (75 sap, 1400ms cadence, 18 damage, piercing: true) alongside the existing thornVine (50 sap, 900ms cadence, 14 damage). Bramble Spear is slower and more expensive but its projectiles pass through all enemies in a lane.
  • site/game/src/scenes/play.js — Added selectPlant(plantId) method with bidirectional sync via plantSelected event. Implemented piercing projectile mechanic using a hitEnemies Set (~15 lines) — piercing projectiles damage each enemy once and continue through. Added selectedPlantId to state snapshot for dynamic UI.
  • site/game/src/main.js — Updated updateRuntimeReadout() to derive run-note copy from the currently selected plant instead of hardcoding "Thorn Vine". Affordability checks now use the selected plant's actual cost.
  • site/game/src/config/scenarios/2026-04-13.js — New scenario file defining "Bramble & Thorn" with availablePlants: ["thornVine", "brambleSpear"], a 3-wave tutorial (Single Lane Read, Pierce the Stack, Pair the Defenders), and a 4-wave challenge (Center Pair, Piercing Lesson, Split Roots, Needle Canopy) with 2 garden HP and endless mode. Economy tuned to startingResources: 60, resourcePerTick: 22, resourceTickMs: 3600 (~6.1 sap/s, matching April 12's proven curve). 33 enemies across 4 waves with tightened start gaps (0/11s/23s/37s).
  • site/css/components.css — Added .game-inventory__item--selected styling with aria-pressed support, focus-visible outline, and visual selected/unselected states for the plant roster panel.
  • site/game/src/scenes/title.js — Updated title copy to reference the two-plant roster day.

Stats

  • 6 files changed
  • ~250 insertions

Implementation Notes

The piercing mechanic reuses the existing projectile system — a hitEnemies Set tracks which enemies a piercing bolt has already damaged, so each enemy takes damage exactly once as the bolt passes through. Plant selection syncs bidirectionally: clicking an inventory item in the HTML panel calls playScene.selectPlant(), and the PlayScene emits plantSelected events back to update the HTML panel's selected state. The run-note sidebar now reads the selected plant's label and cost from PLANT_DEFINITIONS instead of hardcoding Thorn Vine, so it stays correct on any roster day. Difficulty validators were updated to derive plant costs from modeDefinition.availablePlants instead of the hardcoded STARTING_PLANT_ID.


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

Top comments (0)