CHANGELOG, tornado showcase shot, capture script update
@@ -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
|
||||
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 168 KiB |
|
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 202 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 183 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 227 KiB |
|
Before Width: | Height: | Size: 326 KiB After Width: | Height: | Size: 366 KiB |
|
Before Width: | Height: | Size: 235 KiB After Width: | Height: | Size: 266 KiB |
|
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 258 KiB |
|
After Width: | Height: | Size: 365 KiB |
@@ -523,8 +523,7 @@ export class UI {
|
||||
<button class="btn" id="mImport">📂 Import Save</button>
|
||||
</div>
|
||||
<h3>Save slots</h3>
|
||||
<div id="slots"></div>
|
||||
<h3>Settings</h3>
|
||||
<div id="slots"></div> <h3>Settings</h3>
|
||||
<div class="settings">
|
||||
<label><input type="checkbox" id="setSound" ${this.settings.sound ? 'checked' : ''}> Sound effects</label>
|
||||
<label><input type="checkbox" id="setShadow" ${this.settings.shadows ? 'checked' : ''}> Shadows (pretty, costs FPS)</label>
|
||||
|
||||
@@ -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 };
|
||||
|
||||