diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..7fc0086 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,31 @@ +# Changelog + +All notable changes to PolyCity are documented here. + +## 1.0.0 — initial public release + +### Gameplay +- Procedurally generated island maps with rivers, beaches and forests +- RCI zoning with demand-driven development and a three-tier density ladder +- City-wide power grid (coal / solar / wind, coastal wind bonus) with + farthest-first brownouts +- Land value model (services, pollution, waterfront, leisure) driving upgrades +- Service buildings: police, fire, hospital, school, park, plaza, stadium +- Pollution-driven fires that spread unless covered by fire stations +- Tornado disasters that flatten streets into rubble (toggleable) +- Budget with live tax slider, itemized income/upkeep ledger +- Happiness, RCI demand bars, milestones up to Megalopolis, quest onboarding +- Traffic agents flowing along the road network +- Day/night cycle with lit windows at night + +### Systems +- Autosave plus 3 manual slots, JSON export/import +- PWA: installable, offline play via service worker +- Adaptive render resolution for weak GPUs; optional shadows +- Touch controls: one-finger paint, two-finger orbit/zoom + +### Quality +- 45-assertion engine test suite (pure Node) +- 40-year economy soak test (11 assertions) +- Headless browser end-to-end smoke test +- GitHub Pages workflow + Netlify config for one-click publishing diff --git a/shots/01-boot.png b/shots/01-boot.png index 938e59a..bfe744a 100644 Binary files a/shots/01-boot.png and b/shots/01-boot.png differ diff --git a/shots/02-built.png b/shots/02-built.png index ec51669..85339e7 100644 Binary files a/shots/02-built.png and b/shots/02-built.png differ diff --git a/shots/03-grown.png b/shots/03-grown.png index 78a9e46..4e2a3a9 100644 Binary files a/shots/03-grown.png and b/shots/03-grown.png differ diff --git a/shots/08-budget.png b/shots/08-budget.png index c1ad570..ad9f5b9 100644 Binary files a/shots/08-budget.png and b/shots/08-budget.png differ diff --git a/shots/08-menu.png b/shots/08-menu.png index 9eb9f76..f8e6789 100644 Binary files a/shots/08-menu.png and b/shots/08-menu.png differ diff --git a/shots/08-stats.png b/shots/08-stats.png index e89b263..94d0d62 100644 Binary files a/shots/08-stats.png and b/shots/08-stats.png differ diff --git a/shots/09-final.png b/shots/09-final.png index 43c8e88..9e66105 100644 Binary files a/shots/09-final.png and b/shots/09-final.png differ diff --git a/shots/scene-boot.png b/shots/scene-boot.png index 7cd79f4..cce57ca 100644 Binary files a/shots/scene-boot.png and b/shots/scene-boot.png differ diff --git a/shots/scene-day.png b/shots/scene-day.png index b657869..273935b 100644 Binary files a/shots/scene-day.png and b/shots/scene-day.png differ diff --git a/shots/scene-dusk.png b/shots/scene-dusk.png index 34c5a41..402163a 100644 Binary files a/shots/scene-dusk.png and b/shots/scene-dusk.png differ diff --git a/shots/scene-night.png b/shots/scene-night.png index 179de36..15782ad 100644 Binary files a/shots/scene-night.png and b/shots/scene-night.png differ diff --git a/shots/scene-tornado.png b/shots/scene-tornado.png new file mode 100644 index 0000000..5019f50 Binary files /dev/null and b/shots/scene-tornado.png differ diff --git a/src/ui/ui.js b/src/ui/ui.js index 08335bb..fce7ef0 100644 --- a/src/ui/ui.js +++ b/src/ui/ui.js @@ -523,8 +523,7 @@ export class UI {

Save slots

-
-

Settings

+

Settings

diff --git a/tests/capture.mjs b/tests/capture.mjs index 886ea6c..2185b9c 100644 --- a/tests/capture.mjs +++ b/tests/capture.mjs @@ -85,6 +85,16 @@ await page.evaluate(() => { window.POLYCITY._parts.renderer.timeOfDay = 0.75; }) await page.waitForTimeout(300); await snap('scene-night.png'); +// tornado aftermath +await page.evaluate(() => { + const c = window.POLYCITY.city; + window.POLYCITY._parts.renderer.timeOfDay = 0.30; + c.notify = () => {}; // keep the frame clean + c.spawnTornado(); c.spawnTornado(); +}); +await page.waitForTimeout(500); +await snap('scene-tornado.png'); + const stats = await page.evaluate(() => { const c = window.POLYCITY.city; return { pop: c.stats.pop, dev: [...c.grid.level].filter(v => v > 0).length, happy: c.stats.happiness };