- TypeScript 89.7%
- CSS 7.8%
- HTML 1.1%
- JavaScript 1%
- Dockerfile 0.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
The 3D-redesign work lived only in the working tree. This captures the new scene-state/panel-host/scene modules, the rewritten HUD, and the e2e specs updated to match, so the whole project can be re-published cleanly to the remote. Co-Authored-By: Yani <[email protected]> |
||
| .github/workflows | ||
| public | ||
| src | ||
| tests | ||
| .dockerignore | ||
| .gitignore | ||
| docker-compose.yml | ||
| Dockerfile | ||
| index.html | ||
| nginx.conf | ||
| package-lock.json | ||
| package.json | ||
| PLAN.md | ||
| playwright.config.ts | ||
| README.md | ||
| tsconfig.json | ||
| vite.config.ts | ||
Alley Cat Empire 🐈⬛
A zero-cost, cat-themed idle tycoon game for mobile. Plain TypeScript + Vite + Canvas, no backend, no ads, no in-app purchases. Your save lives in your browser; play offline.
Persona: Yani — a chain-smoking alley cat building a neon empire, one dumpster at a time.
Run (dev)
npm install
npm run dev # vite dev server (mobile viewport via Playwright)
Test
npm run typecheck # tsc --noEmit (the real gate)
npm test # vitest unit tests
npm run e2e # Playwright (mobile-chromium) end-to-end
npm run balance # greedy-bot balance simulation (CI gate on economy)
Full gate: npm run typecheck && npm test && npm run e2e
Build & deploy
npm run build # → dist/ (PWA: manifest + service worker + svg icon + .nojekyll)
npm run preview # serve the built PWA locally
Upload dist/ to any static host (GitHub Pages, Netlify, Cloudflare Pages, a
subfolder — base: './' makes it host-path agnostic). It is installable and
works offline once loaded.
Zero-cost GitHub Pages: push to main and the included .github/workflows/ci.yml
runs the full gate (typecheck + unit + e2e + build) and deploys dist/ to GitHub
Pages automatically. Enable Settings → Pages → Source: GitHub Actions on the repo.
public/.nojekyll is copied into dist/ so GitHub Pages serves it unmodified.
Features
- Tap to earn catnip; buy buildings (dumpster → … → empire tower) that produce
catnip passively via
globalMult. - Upgrades with explicit
multmultipliers; achievements each grant +1% global mult. - Offline earnings: claim capped + decayed catnip on return (welcome-back modal). The cap is a player setting (default 8h, 1–24h) in Settings.
- Nine Lives (prestige): burn a life for Karma (
floor(sqrt(lifetime/1e6))), resets the run but keeps Karma + achievements. Karma adds +10% per point. - Audio: synthesized WebAudio blips (no asset files), mutable.
- Settings: mute, reduced-motion, offline cap, save export (download) / import (file).
- Canvas ambience: drifting fireflies + neon pulse (respects reduced-motion).
- PWA: installable, offline-first service worker.
Architecture
src/
core/ engine, economy, state, save (versioned, migrates)
content/ buildings, upgrades, achievements (data-driven)
ui/ hud (event-delegated), ambience (canvas)
audio/ sfx (WebAudio synth)
platform/ storage (localStorage wrapper + MemoryStorage for tests)
sim/ balance.ts (headless greedy-bot economy check)
public/ manifest.webmanifest, sw.js, icon.svg
tests/ unit/ (vitest) + e2e/ (playwright, mobile-chromium)
Deterministic and testable headless: Engine + MockClock + MemoryStorage run
the whole game in Node, which is what the unit/balance/sim suites exercise.
Save format
Versioned JSON in localStorage (alley-cat-empire/save). Export/import round-trips
through public/. Malformed imports are rejected (importSave returns null), and a
good import is always merged over a fresh base so missing fields are safe.