- Small functions — one responsibility, fits on screen
- Small structs — group only what belongs together
- Comment every exported function, type, and non-obvious block
- Follow standard Go conventions (gofmt, golint)
- Write unit tests for every function with logic
- Table-driven tests preferred
- Use interfaces and mocks to isolate dependencies (especially NanoRPC and DB)
- Prefer clarity over cleverness
- No premature abstractions — solve the problem in front of you
- Keep dependencies minimal
- Each directory owns one concern — game logic, HTTP handling, DB, templates, and static assets must never bleed into each other's directories
- Behaviours (game rules, RPC calls, DB queries) live in
internal/; presentation (HTML, CSS, JS) lives ininternal/templates/andweb/static/ - Each game or feature gets its own subdirectory — do not mix concerns from different games in shared files unless it is genuinely shared logic
- Pages and routes for a game belong to that game's handler and template directory, not a sibling game's
internal/games/— shared faucet game logic (packagegames)internal/games/farm/— Nano Faucet Multiplayer Farm game logic (packagefarm)internal/handler/— HTTP handlers for all gamesinternal/db/— PostgreSQL layer; migrations ininternal/db/migrations/internal/nano/— Nano RPC, wallet derivation, block signinginternal/templates/faucet_game/— HTML templates for the faucet shooter gameinternal/templates/faucet_multiplayer_farm_templates/— HTML templates for the Farmweb/static/— shared static assets;web/static/faucet_multiplayer_farm_static/for Farm assets
Custom AI persona prompts live in .claude/skills/<name>/SKILL.md:
/storyteller— expert narrative craft, world-building, Farm dialogue/gamedev— expert game developer (math, physics, multiplayer, Farm systems)/webdev— expert web developer (HTML/CSS/JS, Go net/http, security, performance)