PolyCity v1.0 — full-featured 3D city-builder (Three.js + Vite)
- Procedural island maps, RCI zoning, demand-driven growth - City-wide power grid with brownouts; wind coastal bonus - Land value, upgrades, services, pollution, fires & fire spread - Budget/taxes, happiness, milestones, quest onboarding - Traffic agents, day/night cycle, adaptive render scale - Saves: autosave + 3 slots + JSON export/import - PWA (offline), GitHub Pages/Netlify deploy configs - Tests: 40-assertion engine suite + headless E2E
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
# 🏙️ PolyCity — 3D City Builder
|
||||
|
||||
**PolyCity** is a full-featured, free, open-source city-building simulation that runs
|
||||
entirely in your browser. Zone districts, wire up power, keep citizens happy, fight
|
||||
fires, balance the budget — and grow a tiny island outpost into a glittering megalopolis.
|
||||
|
||||
Built with **Three.js + Vite**, zero runtime dependencies beyond the engine,
|
||||
procedural graphics (no asset downloads), and a simulation modeled on the classics.
|
||||
|
||||

|
||||
|
||||
## ✨ Features
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| 🗺️ **Procedural islands** | Every new map is unique — winding rivers, beaches, forests |
|
||||
| 🏘️ **RCI zoning** | Residential / commercial / industrial with demand-driven growth |
|
||||
| ⚡ **Power grid** | Coal, solar & wind plants; brownouts when demand exceeds supply; wind turbines get +50 % on the coast |
|
||||
| 📈 **Land value & upgrades** | Parks, plazas, services and waterfronts raise land value; buildings grow through 3 density tiers |
|
||||
| 🚓 **City services** | Police, fire stations, hospitals and schools shape happiness and value |
|
||||
| 🔥 **Disasters** | Pollution-driven fires spread, burn buildings to rubble and are contained by fire coverage |
|
||||
| 💰 **Budget & taxes** | Live tax slider, itemized income/upkeep ledger, debt warnings |
|
||||
| 🚗 **Traffic** | Animated cars flow along your road network |
|
||||
| 🌗 **Day/night cycle** | Windows light up as the sun sets |
|
||||
| 🎯 **Goals & milestones** | From *Outpost* to *Megalopolis*, with an onboarding quest list |
|
||||
| 💾 **Saves** | Autosave, 3 manual slots, JSON export/import |
|
||||
| 📱 **Touch support** | Paint with one finger, pinch-zoom, two-finger rotate |
|
||||
| 🔌 **PWA** | Installable, offline-capable via service worker |
|
||||
|
||||
## 🎮 Controls
|
||||
|
||||
| Action | Input |
|
||||
|---|---|
|
||||
| Use tool / paint | **Left-drag** or one finger |
|
||||
| Orbit camera | **Right-drag** or two fingers |
|
||||
| Pan | **Middle-drag**, or `WASD` / arrow keys (`Shift` = faster) |
|
||||
| Zoom | Mouse wheel / pinch |
|
||||
| Pause · speed | `Space` · `1` `2` `3` |
|
||||
| Tools | `Q` inspect · `B` bulldoze · `R` road · `Z/X/C` zones |
|
||||
| Close / cancel | `Esc` · Help: `H` |
|
||||
|
||||
### How to play in 30 seconds
|
||||
1. Drag an **L-shaped road** from the coast inland.
|
||||
2. Paint **homes** beside it, then some **shops** and **industry**.
|
||||
3. Drop a **coal plant** anywhere — power is a city-wide grid.
|
||||
4. Press ▶▶ and watch the neighborhood fill in.
|
||||
5. Add police/fire/parks to push land value past the upgrade thresholds.
|
||||
|
||||
## 🚀 Run it locally
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
pnpm dev # dev server → http://localhost:5173
|
||||
```
|
||||
|
||||
## 📦 Production build
|
||||
|
||||
```bash
|
||||
pnpm build # outputs static site to dist/
|
||||
pnpm preview # serve dist/ locally
|
||||
```
|
||||
|
||||
The build is fully static and relative-path based — drop `dist/` on any host.
|
||||
|
||||
## 🌍 Publish it
|
||||
|
||||
**GitHub Pages** — this repo ships `.github/workflows/deploy.yml`; push to `main`
|
||||
and enable Pages (*Settings → Pages → Source: GitHub Actions*).
|
||||
|
||||
**Netlify / Vercel / Cloudflare Pages** — import the repo, build command
|
||||
`pnpm build`, publish directory `dist`. A ready-made [`netlify.toml`](netlify.toml)
|
||||
is included.
|
||||
|
||||
**itch.io** — zip the contents of `dist/` (keep `index.html` at the zip root),
|
||||
upload as an HTML5 game, check *sharedarraybuffer is not needed* and any
|
||||
resolution; the game auto-fits.
|
||||
|
||||
## 🧪 Tests
|
||||
|
||||
```bash
|
||||
node tests/engine.mjs # 40-assertion simulation suite (pure Node)
|
||||
node tests/smoke.mjs # headless-browser end-to-end run
|
||||
node tests/capture.mjs # renders promo screenshots into shots/
|
||||
```
|
||||
|
||||
## 🛠️ Tech notes
|
||||
|
||||
- One shared `MeshStandardMaterial` + instanced meshes draw the entire city in a
|
||||
handful of draw calls; geometry is merged & vertex-colored at load time.
|
||||
- Simulation runs on typed arrays (64×64 tiles) with monthly ticks decoupled
|
||||
from rendering; speeds pause / 1× / 2× / 3×.
|
||||
- Adaptive resolution keeps frame times sane on weak GPUs.
|
||||
- All audio is synthesized WebAudio — no assets, no tracking, no network calls.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE) — build, remix, ship it. 🏗️
|
||||
Reference in New Issue
Block a user