Skip to content

Repository files navigation

Food vs Pests

A lane-defence game in the spirit of Plants vs Zombies, with one twist: you play the food. You place edible defenders on a kitchen countertop and hold off waves of pests.

Solo project. Design, code, UI specification and balance by Daniil Muratov, 2026.

The design comes first

The game is built from a written design document, and the document is the source of truth: when the game changes, the document changes with it.

Document What is in it
docs/design-pack/SPEC.md The full UI specification: layout, states, sizes, behaviour
docs/design-pack/01-battle-hud.md Battle HUD
docs/design-pack/02-level-select.md Level select
docs/design-pack/03-shop.md Shop
docs/design-pack/04-almanac.md Almanac
docs/design-pack/05-loadout.md Loadout
docs/design-pack/09-tokens.md Design tokens: colour, type, spacing
docs/adr/0001-design-pack-is-canon.md Why the design pack, not the code, is canon

A few decisions the document records, as examples of how the design is argued rather than asserted:

  • The board is described in lanes and depth, not rows and columns. 5 lanes, 16 cells of depth. The same board and the same balance then work in landscape and in portrait, and the engine rebuilds the layout when the screen shape changes.
  • The mousetrap clears the whole lane, not one pest. It used to snap shut on the single pest that touched it. A lane is rarely lost to one pest, it is lost to the ones walking through the gap behind it, so the safety net now drives the length of its lane. Three rules come with that: a burrowed pest is missed, nothing killed by the trap pays a coin, and nothing killed by the trap leaves a brood.
  • Nothing is paid for losing. The trap fires because the lane was already lost, so it earns nothing.

Tech

TypeScript, Phaser 3, Vite, Vitest, Capacitor for the Android build.

  • src/core/ — simulation: grid, waves, economy, combat. No rendering, no Phaser.
  • src/view/ — Phaser scenes, sprite manifest, procedural placeholders for missing art.
  • src/data/ — content and level data.
  • test/ — 24 test files covering board, economy and combat rules.

Keeping the simulation free of the renderer is what makes the rules testable: the balance tests run in Node, without a browser and without Phaser.

Running it

npm install
npm run dev      # http://localhost:5173
npm test         # Vitest
npm run build    # type-check and production bundle
npm run android  # build, sync and open the Capacitor Android project

Art is loaded from public/assets/sprites/. If a sheet is missing, BootScene draws a procedural placeholder of the same size and frame count and logs what it could not find, so the game always runs.

Status

Playable vertical slice: the battle screen, the economy, the wave loop and the loss condition all work. Screens outside the slice (shop, almanac, loadout) are specified in the design pack and not yet implemented.

About

Lane-defence game where you play the food. TypeScript + Phaser 3, design-doc-driven, solo project.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages