6 KiB
Botanica
An illustrated greenhouse game built on the existing Plant Laboratory. Register with a username and password, grow and collect deterministic SVG plants, sell specimens, expand your glasshouses and fund real genetic crosses. Quests, research and opt-in workers support gradual, offline progress. The game uses simplified fictional genetics.
Run
Keep .env local and preserve HOST_PORT=8155, PUBLIC_DOMAIN=http://localhost. Copy .env.example if the file is missing.
npm ci
docker compose config --quiet
docker compose up --build -d
docker compose ps
curl -fsS http://localhost:8155/health
Open http://localhost:8155. Only the web entrypoint is published. It binds to all host interfaces by default so the configured Cloudflare tunnel can reach http://192.168.1.197:8155; set HOST_BIND=127.0.0.1 in the deployment environment for loopback-only access. API and PostgreSQL stay on the Compose network. The one-shot bootstrap service applies transaction-locked, tracked migrations, then seeds the sandbox owner/catalog and 100 deterministic demo plants. Repeat runs do not duplicate or overwrite plants. A named volume retains your collection across docker compose down / up. Do not use down -v unless intentionally deleting all saved data.
Explore
-
/: greenhouse home, seed inventory, growing slots, server timers and harvest. -
/shop,/quests,/research: server-priced upgrades, twelve one-time goals and three research unlocks. -
/workers: hire and configure gardeners/breeders, opt-in safe auto-sale and bounded offline reports. -
/settings: account, logout and reduced motion. One-use password recovery codes are shown once at signup. -
/examples: the original sandbox records, preserved separately and read-only. -
/lab: complete diploid allele editor, phenotype and rarity explanations, stage/cosmetic seed controls, manual mutation preview, image exports and save designed founder. -
/breed: saved parent pickers, compatibility, server-authoritative breeding, saved child, lineage and journal. Failed requests retry with the same idempotency key. -
/gallery: persisted collection with search, trait filters, sorting and 24-item pagination. The keyboard-accessible specimen inspector includes genotype, ancestry, birth records and JSON/SVG/PNG exports. -
/plants/:id: directly linkable plant detail and ancestry navigation. -
/studies: M2 systematic 12-variation atlas and 100-seed renderer proof. -
/about: compatibility alias for account/settings.
Advanced Lab studies are preserved outside the game economy: they cannot be sold or used as game parents. Manual golden-vein previews affect image exports only. Saving from the editor creates a new founder without those preview mutations. Bred mutations and rarity outcomes are recorded once on the server. Collection frequency is shown separately from the trait-derived rarity tier.
Checks and development
npm run typecheck
npm run test
npm run build
npm run test:integration
docker compose -f compose.test.yaml down
The regular test command builds pure package dependencies, runs domain/API tests and checks original SVG source synchronization. Integration cases are skipped unless TEST_DATABASE_URL is provided. test:integration builds a separate botanica-checks stack with a fresh tmpfs PostgreSQL database, no published ports and no access to the application's saved data. It tests clean migrations, idempotent 100-plant seed, persistence, concurrency, rollback, ownership, filter/search/sort and pagination, plus account recovery, monetary integrity, paid breeding and bounded worker catch-up. Game tests use an additional isolated schema. Cleanup removes only the temporary test stack.
npm run dev starts Vite (5173) and API (3000); provide a reachable PostgreSQL DATABASE_URL in the host environment. Compose intentionally does not publish its database. Prefer Compose for the complete runtime.
Root npm run db:migrate / npm run db:seed use TypeScript tooling with an explicit DATABASE_URL. Against Compose:
docker compose run --rm bootstrap node dist/migrate.js
docker compose run --rm bootstrap node dist/seed.js
Production images run as non-root and contain compiled code. nginx handles SPA routes and proxies /api/ and /health; relative browser URLs keep private container hostnames out of clients. PUBLIC_BASE_URL derives localhost plus the exposed port, or just the HTTPS origin behind a production reverse proxy. .env is ignored by both Git and Docker build contexts.
Browser acceptance and artwork
scripts/verify-m3.cjs and scripts/verify-m4.cjs exercise the real application with Playwright/Chrome and write screenshots, exports and measurements to artifacts/. Provide a Playwright package through PLAYWRIGHT_MODULE and optionally a browser binary through BROWSER_EXECUTABLE. Those historical scripts target the pre-account sandbox. scripts/verify-game.cjs exercises the current account/game UI and preserves labeled QA records without saving passwords or sessions to artifacts. Browser checks intentionally retain their labeled founder/offspring as evidence of persistence. M0/M2 artifacts document earlier gates; their historical scripts target their respective earlier UI.
The pure renderer composes 15 original handcrafted SVG primitives, six palettes and deterministic layout. npm run assets:write regenerates primitive sources from typed path definitions; tests reject source drift. Artwork provenance documents CC0 assets. No runtime image services, remote fonts, trackers or paid APIs are used.
See API examples, deployment, progress and future roadmap.
Accounts use Argon2id, hashed cookie sessions, CSRF protection, ownership-scoped queries and bounded in-process auth throttling. The configured public origin is https://botanica.p20.dev; set PUBLIC_ORIGINS explicitly for any additional hostnames. Read game implementation notes for migration, economy and worker semantics.