A browser arena defense on a 6×6 grid, drawn up on paper first — ten plant and terrain types, six player classes, one lawn to lose.

Wall off every adjacent tile and a unit has nowhere legal to step. It doesn't die, doesn't reroute, doesn't time out — it just stops, and the round can never end.
getNextMove got a fallback: zero valid moves triggers a scan of adjacent tiles and removes one non-boulder plant to force a path open, logged so it's visible.
clearSpawnTile runs before every spawn. Trees, honey locust and boulders get cleared off the landing tile so nothing ever materialises inside a wall.
PLANT_CAPS.trees = [3, 0] — the zero increment means it never grows with the round. Honey locust and regular trees share the cap.
Every duration doubled. Humans 0.35→0.7s, runners 0.4→0.8s, grass 2.5→5s, roses 1.4→2.8s. The board stopped feeling frantic.
The original background sat at #060e0c — near-black with a green cast that read as sickly rather than lush. Every surface value shifted warmer and brighter, and the text came up with it.
Small numbers, big difference. The shop icons also needed work — Rose Vines, Mushroom and Mint all use animation strips, so the shop clips to the first frame via overflow hidden plus a full-width image trick rather than maintaining separate static art.
DOM grid with CSS transitions. Sprite strips animate by stepping background-position, not by swapping images.
Three-column: board centre, shop left, log right. CSS-driven filters on the event log so you can mute spawn spam.
Enemy stats and plant caps both scale per round from a single table, so difficulty is one place to tune.
A Cloudflare Quick Tunnel launcher — no account needed, Ctrl+C to stop. Hand someone a URL and they're playing.
Also known as Arm A Garden. Same game, two names, depending on how much the joke is landing that day.
The design existed as pen on paper before any of it existed as code — arena dimensions, plant table, class stats, movement rules. Digitising it into a formal spec came before the first line of JavaScript.
A 6×6 grid. Small enough that every tile placement is a real decision and a bad wall can strand you.
Plants and terrain in one table, each with its own effect — offensive, blocking, slowing, or purely structural.
Each with HP, speed and an ability. The player is a piece on the board, not a disembodied cursor.
Written before implementation, which is why the pathfinding edge cases were findable rather than mysterious.
Damage tracked per plant and scaled exponentially, so a plant that survives contributes more the longer it holds.
Frost recalculates per step rather than per turn, which is the only way slow reads correctly against variable enemy speeds.
Flags added to stop the same effect applying twice in one resolution — the stacking bug that made frost look like an instant kill.
Adjacency-triggered combinations, which is where most of the balance work went and where most of the bugs lived.