Technology Apr 18, 2026 · 7 min read

Fully Automated Website Day 13: Thornwing Moth — First Flying Enemy and behavior: "flying" Branch

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. View the full decision log What shipped Rootline Defense now h...

DE
DEV Community
by dtannen
Fully Automated Website Day 13: Thornwing Moth — First Flying Enemy and behavior: "flying" Branch

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.

View the full decision log

What shipped

Rootline Defense now has its first flying enemy. Thornwing Moth cruises over ground defenders at altitude 34, ignores contact blocking, and demands anti-air coverage from Bramble Spear while Thorn Vine bolts pass underneath. The change also adds behavior: "flying" as a reusable enemy branch plus projectile-level canHitFlying wiring for future airborne threats.

Candidates considered

  • Thornwing Moth — First Flying Enemy and behavior: "flying" Branch (score: 9.0) — Adds Thornwing Moth as the first flying enemy, introduces a reusable behavior: "flying" branch, ships projectile-level anti-air gating via canHitFlying, extends Board Scout and observation exports for flying/anti-air data, and publishes the April 18 Wings Over the Garden tutorial/challenge where Thornwings only occupy lanes 1 and 3.
  • Wave Forecast Strip for Board Scout (score: 7.6) — Adds a stronger pre-run wave timeline to Board Scout so players can see the next cluster of pressure without adding a new enemy class or a new damage channel.
  • Second Control Plant — Root Snare (score: 7.2) — Adds another control plant after Frost Fern, but extends the roster before the game has a second enemy class to justify a new answer.

Winner

Thornwing Moth — First Flying Enemy and behavior: "flying" Branch with a score of 9.0

Thornwing Moth won because it creates the first enemy that demands a different damage channel rather than simply more damage. The work compounds in the right places: behavior: "flying" becomes a reusable runtime branch, canHitFlying becomes a reusable projectile contract, Board Scout and observation exports become explicit about airborne counterplay, and the daily board teaches the new answer cleanly by confining every Thornwing to lanes 1 and 3 while excluding the moth from endless.

Technical spec

April 18, 2026 — Thornwing Moth

Problem

After April 17, Rootline Defense had walkers and one ranged behavior branch,
but every enemy still occupied the lane surface. That left the counterplay
space too flat: all attacker plants could damage every threat in their lane,
and board planning was still mostly about throughput and timing rather than
about which lanes needed a different damage channel.

Goals

  • Introduce behavior: "flying" as a second enemy-behavior branch alongside the existing sniper branch while keeping walker as the default when behavior is absent.
  • Ship Thornwing Moth as the first flying enemy with the exact April 18 combat contract: altitude: 34, maxHealth: 32, speed: 52, breachDamage: 1, and score: 26.
  • Add projectile-level anti-air eligibility so Bramble Spear can hit flying enemies and Thorn Vine cannot.
  • Teach the new counterplay clearly in a dated scenario titled Wings Over the Garden, then keep the endless pool grounded so the anti-air memorization requirement stays scoped to the scripted challenge.

Proposed Approach

  1. Add thornwingMoth to ENEMY_DEFINITIONS with behavior: "flying" and flying: true, plus the authored balance values above.
  2. Branch PlayScene.updateEnemies immediately after the sniper branch into updateFlyingEnemy(enemy, deltaMs), which moves left with getEffectiveSpeed(enemy), ignores ground blockers and contact attacks, and resolves breach damage at BREACH_X.
  3. Make altitude legible with three cues working together: sprite draw position at y - altitude, a ground-plane shadow rendered with Phaser Graphics, and a small bob of sin(elapsedMs / 320) * 3. Chill affects horizontal movement through getEffectiveSpeed, but the bob stays tied to scene elapsedMs so chill does not slow the vertical motion.
  4. Add canHitFlying: true only to brambleSpear. spawnProjectile copies that flag to each projectile instance, and projec

[Spec truncated — view full spec on the site]

What changed

April 18, 2026 — Build Summary

Shipped Thornwing Moth, the first flying enemy in Rootline Defense, plus
the anti-air projectile contract and the April 18 Wings Over the Garden
scenario that teaches it.

What changed

  • Added a flying enemy behavior branch in PlayScene.updateEnemies via updateFlyingEnemy(enemy, deltaMs). Thornwing travels left with getEffectiveSpeed(enemy), ignores ground blockers/contact attacks, and resolves breach damage at BREACH_X.
  • Added canHitFlying to plant projectiles. brambleSpear sets canHitFlying: true; thornVine remains falsy. spawnProjectile copies the flag onto runtime projectile instances, and findProjectileTarget skips flying enemies when the projectile cannot hit them.
  • Added thornwingMoth to ENEMY_DEFINITIONS and the served asset manifest with the authored April 18 combat values: behavior: "flying", flying: true, altitude: 34, maxHealth: 32, speed: 52, breachDamage: 1, score: 26, radius: 18, displayWidth: 64, displayHeight: 64, textureKey: "thornwing-moth".
  • Added the flying UI/observation surface: per-enemy observation fields behavior, flying, and altitude; top-level projectiles[] with lane, x, y, damage, piercing, and canHitFlying; Board Scout Flying badge on Thornwing cards; attacker-detail Anti-air: Yes|No.
  • Added the dated scenario 2026-04-18.js, titled Wings Over the Garden: a two-wave tutorial that first proves Thorn Vine misses and then unlocks Bramble Spear, followed by a four-wave challenge where every Thornwing event is constrained to lane 1 or lane 3.
  • Kept endless grounded on purpose: enemyPool: ["briarBeetle", "shardMite", "glassRam"]. thornwingMoth is excluded from the endless pool so the anti-air lesson stays attached to the scripted challenge rather than random endless spawns.

Material assumptions

  1. Altitude is represented by sprite Y offset rather than by a separate physics layer.
  2. The flying shadow is rendered with Phaser Graphics on the ground plane, not as a second texture asset.
  3. altitude: 34 is the authored legibility threshold that leaves lane-centerline Thorn Vine bolts reading as a clear under-flight rather than an ambiguous miss.
  4. Chill flows through getEffectiveSpeed(enemy) and therefore affects Thornwing’s horizontal movement, but the bob is driven by scene elapsedMs and does not slow with chill.

Coverage

  • tests/uiux/game-thornwing-moth.spec.js covers the core flying runtime contract: Thorn Vine bolts pass under and continue, Bramble Spear kills in two shots, Thornwing ignores ground blockers, breach damage is 1, and the observation/projectile exports surface the flying and anti-air fields.
  • tests/uiux/game-2026-04-18-flow.spec.js covers the full tutorial → challenge → endless happy path, verifies the scenario title, the tutorial’s two-wave plant gate, the four-wave challenge shape, the lane-1/lane-3 Thornwing constraint, the default challenge date, and the endless enemy pool exclusion. This is currently a blocking spec because the authored with-Bramble replay still reaches scene: "gameover" at about survivedMs: 30400.
  • tests/uiux/game-2026-04-18-replays.spec.js adds paired scripted challenge probes: a no-anti-air line that should game over and a Bramble-backed line that should clear naturally. The no-anti-air probe passes; the Bramble probe currently fails with the same ~30.4s gameover as the flow spec.
  • tests/uiux/game-board-scout-2026-04-18.spec.js locks the public UI copy: Thornwing’s Flying badge plus Anti-air: Yes on Bramble Spear and Anti-air: No on Thorn Vine.
  • tests/uiux/game-roster-assets.spec.js extends manifest coverage to thornwing-moth (enemy, SVG, 128×128, /game/assets/manual/enemies/thornwing-moth.svg).

Validation runs

  • node schemas/validate.js content/days/2026-04-18 Passed: decision.json, spec.md, and build-summary.md.
  • npm run test:uiux Failed before browser execution in this sandbox because Playwright’s configured web server could not bind 127.0.0.1:3737 (listen EPERM: operation not permitted).
  • PLAYWRIGHT_DISABLE_WEBSERVER=1 npx playwright test tests/uiux/game-thornwing-moth.spec.js tests/uiux/game-2026-04-18-flow.spec.js tests/uiux/game-2026-04-18-replays.spec.js tests/uiux/game-board-scout-2026-04-18.spec.js tests/uiux/game-roster-assets.spec.js --config=playwright.config.js Partial pass: 11 passed, 2 failed. Passing specs: Thornwing runtime contract, Board Scout, roster assets, and the no-anti-air replay. Failing specs: the with-Bramble replay and the tutorial→challenge→endless flow, both because the supposed clear line still reaches gameover at survivedMs: 30400.
  • PLAYWRIGHT_DISABLE_WEBSERVER=1 npx playwright test tests/uiux/_tmp-capture-2026-04-18.spec.js --config=playwright.config.js --workers=1 Passed while generating the mirrored screenshot set, then the temporary spec was removed.

Screenshots

  • Mirrored captures now exist under content/days/2026-04-18/screenshots/ and site/days/2026-04-18/screenshots/: 01-before-april-17-grounded-only.png, 02-after-thornwing-mid-flight-shadow.png, 03-after-bramble-spear-anti-air-hit.png, 04-after-thorn-vine-passes-under.png.

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

DE
Source

This article was originally published by DEV Community and written by dtannen.

Read original article on DEV Community
Back to Discover

Reading List