CB ◈ CITYBUILDER
SOFTWARE…ENGINE…
DEVELOPER REFERENCE · SOFTWARE v2.8

Project Documentation

The game design, simulation architecture, data provenance, reproducibility, technical stack and development history in one place.

v0.7 infrastructure model (engine 0.3.3)

City services are a versioned Python module (citybuilder/engine/services.py) layered over the frozen v0.3.2 lifecycle model. Power and water derive from utility cells; transit accessibility comes from transit cells. Coverage is a synthetic district-grid score, not actual network geography.

Owner-funded annual maintenance reduces asset wear and can improve network coverage; unfunded assets deteriorate. Maintenance priority and manual repairs are replay-validated game actions. Only new v0.3.3 games receive this state; older JSON saves preserve original rules and checksums.

Project Documentation is intentionally excluded from all main menus. Its direct route remains /documentation.html.

Purpose and scope

CityBuilder is a modular, browser-playable city-building and economic strategy game. Players start with the same city and compare different choices involving private and public ownership, taxation, services, regulation, construction and infrastructure.

Each new game begins with three identical parallel universes—capitalism, socialism and a mixed economy. They use the same simulation rules, with policies and player actions providing different inputs. Outcomes are not assigned by ideology labels.

Model disclaimer: This is a playable educational simulation with hand-tuned coefficients, not an empirically calibrated city forecasting, property valuation, or political-science model.

Application architecture

Server: Ubuntu, Nginx, Python 3, FastAPI/Uvicorn and optional MariaDB. Client: HTML, CSS, vanilla JavaScript, and canvas drawings. Real-city reference tiles come from OpenStreetMap on the user's browser.

ModuleResponsibilities
citybuilder/engine/Deterministic economy, city building, versioned rules, neighborhoods and the v0.3.2 construction lifecycle and v0.3.3 service networks.
citybuilder/persistence/JSON canonicalization, checksums, action-history replay and state validation.
citybuilder/api.pyNew games, action execution, metadata, import and optional MariaDB saves.
frontend/City maps, graphs, timeline, comparisons, documentation and help pages.
database/Optional MariaDB storage, not required for local JSON exports.

The Python game engine is authoritative. The browser does not calculate economic outcomes.

Economic model and assumptions

Players adjust effective taxation, public ownership, regulation, trade openness, welfare, education, healthcare, and infrastructure spending. The engine combines these inputs with city conditions and reproducibly seeded events.

It tracks GDP, population, happiness, poverty, unemployment, inequality, treasury, debt, housing affordability, civic services and other metrics. Newer engine versions add housing markets, land values, zoning, neighborhood condition, and a financed project pipeline.

Actual historical populations are used for the established-city starting profiles. Other starting financial figures, project-cell maps, land prices, condition scores, construction timing and economic coefficients are illustrative.

Do not treat a simulation result as a prediction that one economic system will outperform another in a real city. Preset choices are policy input bundles, not guaranteed outcomes.

Construction lifecycle (engine 0.3.2)

  1. Choose a permitted building and a synthetic 12×10 planning cell. Existing occupancy and zoning determine eligibility.
  2. Choose public or private funding. The approved project reserves the full simulated cost, including a modelled material/finance premium.
  3. Work lasts one to several simulated years. Regulations and trade openness affect cost and risk; seeded delays can extend the timetable.
  4. Housing capacity or civic-service benefits appear only after completion. If a project is abandoned, a limited salvage amount is returned—not the full original investment.
  5. Automatic opportunities also enter the same project pipeline. Historical JSON checkpoints include their status for review.

For replay compatibility, older engine 0.3.1 and earlier saves retain their immediate-build rules. v0.3.2 applies only to newly created games.

City profiles and map accuracy

New York City, Miami, Los Angeles and fictional Harborview offer established and greenfield starting choices. The “Real geography” tab uses real reference map tiles and approximate neighborhood marker locations. The interactive GRID is a simulated 12×10 project board—not legally mapped lots, real zoning lines, or real building inventories.

Construction, land values, ownership, conditions and development progression are game variables even while displayed over a real street map.

Parallel Universes and history

The experiment starts with identical city states and shared random seed. Universes evolve independently as decisions and policies change. The comparison uses matched saved-year checkpoints to avoid comparing different years.

The timeline supports historical review; earlier years are read-only. “Create branch” copies an actual checkpoint into a new future so users can test alternative decisions without rewriting past events.

Save file design and integrity

Local exports are versioned .citybuilder.json files. Files contain a city scenario, engine version, deterministic seed, action history, universe states, annual checkpoints and a SHA-256 integrity checksum. Imports validate the checksum and replay actions under their recorded engine rules.

The save format remains version 1 across supported releases. Old engines remain available so that historic saves reproduce original results; we do not silently recompute history with newer models.

Local SHA-256 checksums catch corruption or casual edits; a motivated player can recompute a checksum. Verified competitive scores require authoritative server replay and signatures with keys held server-side.

Installation and operations

Typical installation: /var/www/CITYBUILDER; systemd service citybuilder.service; Python API on 127.0.0.1:8848; Nginx frontend on port 8088. MariaDB is optional.

sudo systemctl status citybuilder --no-pager curl -fsS http://127.0.0.1:8848/api/v1/health curl -I http://127.0.0.1:8088/

Keep the prototype on a trusted LAN unless authentication, HTTPS and rate limiting have been configured. Update installers back up modified files and run tests before completion. This docs page is static and public to anyone who can reach the game.

Version history

SoftwareMajor addition
v0.1–v0.2.1Original city economy, policy themes, real-city scenarios, recalibrated economic response.
v0.3AReal geographic explorer and simulated planning GRID.
v0.3B / engine 0.3.0Construction economy, zoning, property values and markets.
v0.3C / engine 0.3.1Living neighborhoods and funded rehabilitation.
v0.4Keyboard timeline, read-only history and matched-year side-by-side comparisons.
v0.5Recorded-checkpoint visual city evolution.
v0.6 / engine 0.3.2Multi-year funded construction pipeline plus Project Documentation and How to Play pages.
v0.7 / engine 0.3.3Electricity, water and transit service networks; maintenance priorities and repairs.
v0.8 / engine 0.3.4Aggregate households, migration, housing support and default-off legacy Cloud.
v0.9 / engine 0.3.5Aggregate tenure, rental/ownership decisions, job transitions and funded mobility programs.
v1.0 / engine 0.3.5Scenario Lab and internal consistency diagnostics.
v1.1 / engine 0.3.5Version badge reliability with API fallback.
v1.2 / engine 0.3.6Optional Chaos Factor, ongoing crime, funded preparedness and scheduled crisis challenges.

The current release is software v1.2 / engine v0.3.6. The two badges at the top show the installed software release and the live current engine version. Existing saves may still use older engines.

Known limitations and roadmap

Not yet implemented: empirically calibrated real-world disaster/crime rates, real GIS parcel/zoning datasets, calibrated municipal finance, citizens at the individual level, real estate transactions, construction supply chains, officially verified leaderboards, online multiplayer, and full offline Python-free gameplay.

Planned development: more realistic emergency reconstruction, improved calibration and tuning tools; realistic housing and transport interactions; richer project financing; comparative policy explanations and accessible tutorial scenarios.

v0.9 — Citizen Decision Engine (0.3.5)

Modular engine citybuilder/engine/decisions.py extends the frozen 0.3.4 citizens.py annual step. It aggregates tenure choices, buying versus renting, local household moves, job switches and cohort-specific migration flows. Inputs are simulated household income, home prices, rent burden, unemployment, satisfaction, market vacancy and funded mobility programs. It never reads the economic system label, never creates individual resident records and never claims empirically calibrated outcomes.

The mobility_program action accepts one of none, training, homebuyer, balanced, validating actions on the Python API and charging at most 0%, 0.15%, 0.20% or 0.32% of city GDP per year from available treasury funds. Training has a bounded marginal employment effect. Ownership shares respond gradually to affordability and financed support; counted transactions do not create new housing units. Aggregate migration totals remain consistent with v0.3.4 migration. Results enter annual history and are stored in the versioned, hashed JSON checkpoints.

Current software is v1.2, engine is 0.3.6. Engines 0.1.0–0.3.4 remain unchanged for deterministic import/replay. Cloud save stays off by default; /documentation.html remains accessible only by direct URL, not linked from the player menu.

v0.8 — Citizens & Migration

Engine 0.3.4 adds aggregate income cohorts, job participation, annual migration, rent burden, satisfaction, and paid rent assistance. Its inputs are synthetic economic variables; this is not a population forecast or personal-data collection. Existing saves replay under their original engine.

Cloud save is removed from the main interface and disabled by default in the Python API. Database credentials alone no longer activate the old Cloud endpoints. The optional legacy MariaDB vault contains readable JSON and has no account system; do not expose it to public networks. Local JSON save, SHA-256 and replay validation are unchanged.

v1.2 — Chaos Factor & Crime (engine 0.3.6)

Python module citybuilder/engine/chaos.py extends the immutable 0.3.5 tick. When enabled, exogenous events are drawn from a random sequence keyed only by shared seed, city, year and enabled event types—never by economic-system label. All universes receive the same incident and nominal severity at the same year. Recovery cost depends on funded preparedness and local economic conditions.

Disasters default OFF. Crime is a separate ON-by-default synthetic citywide aggregate score, influenced by employment, housing affordability, poverty, services and funded public-safety policy. No individual or demographic criminal profiling and no actual neighborhood crime rates are used.

The chaos_config command applies globally to all universes; chaos_schedule inserts a future, reproducible fictional challenge; chaos_policy chooses one universe's paid safety/preparedness budget. All commands and the resulting states are versioned and SHA-256 replay-checked. Previous engines 0.1.0–0.3.5 remain unchanged.

Event frequencies are **illustrative, not forecasts or observed hazard rates**. Terrorism is represented only as a rare abstract security disruption without operational details.

Software v1.3 — Crisis comparison

The modular frontend/crisis-compare.js reads actual snapshot.universes[id].checkpoints[year].state.chaos.events_year values. A shared incident key includes simulated year, hazard type, severity and scheduled/random origin. No projections or hazards are computed in JavaScript.

Incident-specific damage and lost GDP remain separate from the citywide, cumulative recovery backlog and all repairs since the incident. Missing checkpoints are explicitly labeled. The independent Python engine stays v0.3.6; local JSON schemas and replay hashes are unchanged.

Roadmap & feedback subsystem — Software v1.4

/goals.html displays the versioned /roadmap.json project plan. The roadmap is not part of the deterministic economic model; updating it never changes game outcomes or historical saves.

/feedback.html connects to /api/v1/feedback/config, /submit and /status. Data is stored separately in /var/lib/citybuilder/feedback/feedback.sqlite3 with WAL mode and restrictive file permissions. No public ticket listing or admin HTTP endpoint exists. Administrators review submissions using the local citybuilder-feedback command over SSH.

Submissions are rate-limited per source (stored as a keyed HMAC rather than a raw IP), bounded in length, and never displayed as trusted HTML. Users receive a high-entropy secret receipt code; only its SHA-256 digest is stored. The status endpoint requires that receipt code. No email addresses are collected. The installation adds a locked-down systemd writable directory and explicit feedback opt-in, without changing MariaDB, Nginx or engine v0.3.6.

Public Internet deployment still requires HTTPS, a reverse-proxy rate limit, backups, monitoring and operator moderation. This is a prototype, not a turnkey public forum.

Software v1.0: Scenario Lab & Model Audit

The Python audit module at citybuilder/audit/lab.py performs independent bounded counterfactual simulation trials using the frozen engine 0.3.6. The transport entrypoint is POST /api/v1/audit/run with validated scenario ID, 5/10/25-year horizon, 1–5 trials, seed, and one predefined policy-sensitivity lever. A single-flight semaphore prevents concurrent audits; the endpoint never receives a player game save or writes to MariaDB.

Checks include identical initial conditions, replay repeatability, ideology-label neutrality under identical policy vectors, numeric ranges and fiscal stress warnings. Sensitivity compares one policy intervention with a matching baseline seed. Outputs include parameter disclosure, per-preset annual series, end-year mean/min/max, warnings, and JSON export.

Methodology limitation: No historical data calibration, exogenous shock distribution validation, statistical confidence intervals, external benchmark, or real-world causal identification is performed. Engine 0.3.6 remains unchanged so existing JSON hash-chain replay is compatible; this is a diagnostic software release, not a new economic engine or a forecast.

Scenario Lab appears on the player navigation. This technical Project Documentation remains direct-access only at /documentation.html.

Software v1.5 — Versioned economic calibration

New games run Python engine 0.3.7 via engine/calibration.py, preserving engine 0.3.6 and older for exact JSON replay. Changes include bounded inflation, modeled real and nominal wage indexes, financing costs, and investment incentives. They are synthetic economic relationships; no claim of historical predictive calibration is made.

The POST /api/v1/calibration/run endpoint runs bounded, read-only before/after trials on the same seeds. BLS 2025 metro unemployment references and the Federal Reserve's national 2% PCE objective are accompanied by provenance, geography and limits. No external calls or game mutation occurs during calibration runs.

Historical Backtesting is a proposed v2.2 milestone. It will use sourced observations, comparable geography/units, documented data revisions, missing-value handling and separate actual vs counterfactual histories.

v1.6 / engine 0.3.8 — Municipal finance model

citybuilder/engine/finance.py wraps frozen engine 0.3.7, separating explicit bond debt from legacy general debt to prevent double-counted interest. Cash and debt increase equally at bond issuance. Coupons are annual expenses; redemptions are financing flows. The annual ledger reconciles treasury movement. All coefficients and ratings are synthetic, and historic save hashes remain unchanged.

v1.7 / engine 0.3.9 — Schematic district model

citybuilder/engine/districts.py wraps frozen finance engine 0.3.8; four 6×5 quadrants aggregate existing grid housing, zoning, jobs, utility coverage and land values. District planning action charges $3M and can guide one additional fully funded automatic construction project each year. District investments draw from the actual treasury and depreciate. No official GIS parcel or census tract boundaries are implied. Earlier game version replays are untouched.

Climate resilience · v1.8

New-engine cities can fund coastal protection, seismic retrofits, wildfire defense and emergency response centers in four simulated planning quadrants. A municipal risk pool receives actual treasury transfers and can pay recovery liabilities only from its funded balance. The external crisis schedule remains the same across universes. All values are synthetic game estimates, not local engineering or insurance advice.

Public opinion & governance · v1.9

Each new city has fictional approval, trust and civil-liberty scores. Funded justice, transparency and participation programs have separate costs. Four-year civic confidence elections are optional and do not force economic systems or political parties to change. Historical years remain read-only. These are synthetic educational scores, not a forecast or an evaluation of any real community.

Software v2.0 — Scenario Workshop and Best City Contest

The non-executable Scenario Workshop creates declarative JSON challenge packs, containing only a known base city, random seed, title, description, objective and horizon. Player files do not define new code, true city geography, laws or engine coefficients. The workshop's validated scenario packages do not alter economic results or previous saves.

The contest portal at /contest.html uses citybuilder/contests/ and a private SQLite database in /var/lib/citybuilder/contests/, distinct from SQLite feedback, MariaDB and player JSON saves. New contests must be created locally with published rules, frozen seed and target year, and explicit administrator opt-in. Submissions are size- and rate-limited and must pass complete deterministic replay validation. Scoring uses a documented fixed multi-dimensional formula, not uploaded scores. Only operator-approved entries become visible in the leaderboard.

Competitive integrity limitation: SHA-256 and deterministic replay do not establish the player's identity or prevent scripted optimal-play searches. Scores are provisional until a staff member checks eligibility and terms. The app has no prize payout, contact, or identity-verification mechanism. Prize contest rules, applicable legal requirements, fraud response, eligibility and payment must be handled by the organizer separately.

Cloud game saves are still disabled; the optional contest database is separately enabled by an explicit environment flag. Existing economic engine 0.4.1 and all earlier game-save replay are unchanged.

Software v2.2 / Engine 0.4.2 — City Manager & Teaching Mode

citybuilder/engine/manager.py implements deterministic, explainable, budget-aware recommendations and an optional one-intervention-per-year automatic manager. It extends but does not alter archived engine 0.4.1. Interventions and explanations are in validated JSON checkpoints; user-approved suggestions are explicit replayed actions. Cautious and balanced profiles preserve immediate minimum cash reserves. No tax, bond, ideology, electoral or Chaos changes are made automatically. Built-in lessons cover housing, budgets and services. No external LLM calls or personal data are involved.

Use the engine's 0.4.1 start option for v2.0 prize contests pinned to that engine. Official contests still require published rules, server replay, organizer moderation and manual prize review; local checksums alone cannot prevent deliberate cheating. See docs/AI_MANAGER_V21.md for detailed rules and limitations.

Historical Lab v2.2 (separate from save files)

Python modules citybuilder.history.data and citybuilder.history.backtest serve sourced U.S. Census 2010/2020 city-proper counts and 2025 estimates and perform read-only synthetic counterfactual runs using the frozen engine v0.4.2. Endpoints: GET /api/v1/history/starter?city_id=miami and POST /api/v1/history/run. Runs are bounded to 25 years, 180 observations and a 160 KB request body, share the audit CPU slot, and persist no data. The exported citybuilder-historical-report is not a ranked citybuilder-save. Incoming rows must contain metric, units, city/metro scope, observation date, series type, source title, link, data vintage and price basis. Comparisons refuse non-city geometry and mismatched monetary price bases. Baseline population is observed; most city assets and policies remain synthetic game assumptions. Existing save formats, hashes, competition validation and database schemas are unchanged.

Interface Modes — Software 2.2.1

On the main gameplay screen, ui-mode.js and ui-mode.css expose Simple (default for new browser visitors) and Advanced views by selectively hiding presentation panels using data-ui-level="advanced". The preference is stored in browser localStorage under citybuilder-ui-mode and never in a save payload. The Python engine, engine version 0.4.2, contests, and replay validation are unchanged.

v2.8 Historical Methodology

New Python modules citybuilder.history.normalization and citybuilder.history.revisions provide bounded, non-persistent previews. Housing and rent may be converted using fixed BLS CPI-U national all-items annual averages (2000–2024). The 2025 index is incomplete and therefore excluded from conversions. CPI-U is not a GDP deflator; GDP and debt are left untouched. All derived records retain their original source, add method notes, and export as separate JSON. Revision comparisons report value, scope, price basis and vintage changes without selecting a preferred source. The simulation remains engine 0.4.2; SHA-256 saves and contests are unaffected.

Historical Lab — Software v2.8

The geography-method checker keeps metropolitan and city-proper statistics separate. The source catalog preserves original records and source vintages. Retrospective accuracy reports show error per indicator rather than a single politically weighted winning score. Use Historical Lab; these methods do not alter saved city games.