πŸ™οΈ Cities: Skylines II / the economy
← GameTrainers

Cities: Skylines II β€” the economy, and how to play it

The economic system, the twenty-milestone ladder, and how to decide what to do next. Everything is read out of the game's own assemblies and save files; where a figure is measured or assumed rather than read, it says so.

One city runs through this as the worked example β€” Beetham β€” because a model with no numbers in it cannot be checked. Every table can be regenerated, and every figure belongs to a stated snapshot, because the city has several of them and they are not interchangeable:

# run from cities_skylines2/. $SAVES is the game's own save folder:
#   %USERPROFILE%\AppData\LocalLow\Colossal Order\Cities Skylines II\Saves\<steam id>
python state/cs2.py "$SAVES/Beetham 4.cok" "$SAVES/Beetham 2.cok" draw       # Part I and Β§7's levers
python state/scenario_matrix.py "$SAVES/Beetham 4.cok" "$SAVES/Beetham 2.cok"   # Β§8's matrix
python state/cs2.py "$SAVES/Beetham 4.cok" "$SAVES/Beetham 2.cok" play <plan.json>  # Β§8: your own play
python state/cs2.py "$SAVES/Beetham 4.cok" brief                             # position and ranked moves

Each save is given as a path; the save folder is searched for you only when you name no save at all.

Part I and Β§7 are the Beetham 4 city β€” population 3,187, milestone 4, at simulation clock 2026-06 20:18, 180,000 drawn of a 700,000 ceiling. Where a passage needs a city whose industrial lots are full, it says Beetham 7 in the sentence or in the table's own title.

Every table says which snapshot produced it. The ranked building list and the rails quoted beside Β§8's scenarios are the Beetham 7 city: population 3,305, 230,000 drawn, so 470,000 of room, a 2,794-cell land bank, road at 2.91 a household. Every solved run β€” the matrix, the plays, the one-lever rows β€” is the Beetham 4 city against Beetham 2, where those same bounds read 520,000 of room and road at 3.85.

Two snapshots of one city are two cities as far as any of these figures are concerned, and the later one is not simply the better of the two. Beetham 7 against Beetham 3 spans 0.174 of a month where Beetham 4 against Beetham 2 spans 0.573, so the newer pair measures growth over a third of the evidence and reads high for it.

The second (older) save is not optional for either. Absorption and the job-slot replenishment rate are measured across a pair and cannot be read from one file.


The three questions, and where each is answered

"How much can I borrow?" β†’ Β§8. Size the draw to the plan it funds, and draw in the month the plan spends. A draw re-prices your whole balance (Β§3), so what the next 100,000 costs depends on what you already owe β€” and the matrix's financing pairs price the habit of borrowing early on a thin margin at up to half a million.

"What should I do next?" β†’ Β§8. Zone, and zone where the bars are open β€” low or high here; medium's bar is shut behind a glut of empty homes, and capacity painted into a shut bar stays land while its road bill arrives anyway (Β§7). If you zone less than about 130 households a month, this city runs out of borrowing room and can no longer cover its bills; above that, income catches up with upkeep on its own.

"Is this building worth it?" β†’ Β§7. Work out how much happiness it would have to deliver to pay for itself, then check whether anything can actually deliver that much. A 200,000 building costing 20,000 a month has to return +16.9 happiness here β€” more if its capital is borrowed. Eliminating crime completely returns at most +11.4; taking park coverage from zero to full returns up to +10. Neither is enough alone, both together clear it β€” and this city has done neither. Parks are the cheaper of the two and stop paying once coverage reaches 1.5, so they are also the shortest shopping list.


The five symbols used throughout

symbol what it is this city
D the monthly hole β€” upkeep minus income, before interest 126,180
L the credit ceiling: the most you are allowed to owe. Only a milestone raises it (Creditworthiness.m_Amount). 700,000
a how much of that ceiling you have actually borrowed 180,000
r the interest rate you pay per month, which climbs as a approaches L: rMin + dΒ·(a/L) 6.63%
g how fast income is growing, per month measured 48.40%

rMin is 2% a month, rMax is 20% a month, and d is the gap between them, 0.18.

How the parts fit, and where each table comes from

Several subjects appear more than once, in a fixed order, and each appearance does a different job:

Where a figure appears twice it is because it is the conclusion of one section and the input to another. The crime ceiling and the park term both work that way, and Β§7 puts them together explicitly rather than leaving the reader to.

Every table of numbers in this document is generated, bar one. Fourteen of them β€” Β§3's borrowing ladder and its split, Β§5's sector table, Β§6's milestone ladder, Β§7's tax yields, zoning, density and lever tables, Β§8's matrix and ledger, and the four search tables under Β§8's branching subsection β€” are spliced between markers by state/scenario_matrix.py --write and state/playout_tree.py --write, so regenerating IS updating the document and no two of them can quote different money for the same play. They used to be typed by hand, and they drifted: Β§7 and Β§8 disagreed about what zoning 300 a month leaves, and the tax-yield table was wrong in all eight of its figures while the prose beside it was right. The exception is Β§2's ledger, which is half a reading off the game's own on-screen panel and says so where it sits.

Prose figures are still written by hand; tests/test_document_figures.py checks every one that sits in a section owning a generated table β€” 132 of 263 β€” and prints the boundary rather than leaving it implied.


Part I β€” the machinery

1. Units, and the clock

The unit the game calls a "day" is the thing you see as a month. That is a naming collision in the code and every money figure depends on getting it right.

TimeSystem.kTicksPerDay is 262,144 ticks. TimeSettingsData.m_DaysPerYear is 12, so twelve units make a year and each unit advances the calendar by one month. There is no separate month tick: the hour and minute you see are the position inside one unit. A save reading 2026-06, 20:18 is 85% of the way through what the calendar calls June.

unit ticks what it is
tick 1 the simulation's smallest step
statistics sample 8,192 32 per unit β€” every money figure is sampled here
simulation "day" 262,144 = one calendar month
calendar year 3,145,728 twelve of the above

A sample holds the amount for that sample, so a monthly figure is 32Γ— the stored value. Verified against the in-game Economy panel: loan interest reads 372.8 per sample and the panel shows Β’11,931 β€” 372.8 Γ— 32 = 11,930.

Two things follow, and the second one is a trap.

The sample is the finest economic grain there is. "Per month" is not a convenient conversion of some underlying continuous figure β€” it is 32 real samples added up.

And a city crosses the calendar far faster than a play session suggests. This one went from founding to 3,300 citizens in 395,559 ticks, which is about 1.5 months of simulated time, over a few hours of play. So any rule of thumb phrased in months is phrased in a unit the entire run barely contains: "measure over at least half a month" sounds cautious and actually means "over a third of the whole game so far".

Every money figure in this document is per month.

2. Where money comes from and where it goes

Two revenue channels and fifteen ways to spend, both enumerations in the assembly, so neither is a matter of opinion.

Revenue is IncomeSource: four taxes β€” residential, commercial, industrial, office β€” plus service fees, trade and a subsidy. The taxes are the whole story, and they split in a way that decides Β§4: residential tax is levied on citizens' wages; the other three on company revenue.

Expenditure is ExpenseSource:

SubsidyResidential  LoanInterest      ImportElectricity   ImportWater
ExportSewage        ServiceUpkeep     SubsidyCommercial   SubsidyIndustrial
SubsidyOffice       ImportPolice      ImportAmbulance     ImportHearse
ImportFireEngine    ImportGarbage     MapTileUpkeep

Zoning is not on it. UpkeepPaymentJob charges a spawned building's upkeep to the renter's own resources and never touches PlayerMoney β€” zoned buildings fund themselves and pay tax on top. Roads do cost, folded into ServiceUpkeep.

Service upkeep scales with usage, not size: GetUpkeepWithUsageScale multiplies each building's m_Upkeep by its own ServiceUsage.m_Usage and adds each installed upgrade's entry. No area or geometry term appears anywhere in that path, so a larger drawn area does not raise maintenance.

There are two more things on the money side, both exact, both easy to miss.

CityServiceBudgetSystem computes m_FullCost after the usage scaling and then takes m_Cost = m_FullCost Γ— budget% / 100. So the budget sliders take a straight percentage off collected upkeep β€” 427,658 a month on this city, so each point off every slider saves 4,277. Nothing here works out what that cut costs you in service coverage, so you can price one side of the trade exactly and not the other.

Service upkeep is about 97% of all expenditure. Interest is small enough beside it to ignore, so a debt problem in this game is nearly always an upkeep problem.

The ledger

line per month, parsed in-game Economy panel
Taxes 258,443 Β’268,720
Service fees 50,938 Β’51,829
Revenue 309,380 Β’320,549
Service upkeep 435,561 Β’431,998
Loan interest 11,931 Β’11,931
Expenses 447,492 Β’443,929
Net βˆ’138,111 βˆ’Β’123,380

The small gaps are sampling noise β€” the parser reads one sample, the panel smooths. Loan interest is constant and matches exactly, which is what validates the read.

This is the one table in the document that is typed on purpose. Its right column is a reading taken off the game's own Economy panel by eye, which no tool can regenerate; generating the left column beside it would leave a table half self-updating and half not, and a reader with no way to tell which half is which. Both halves belong to the Beetham 4 snapshot and neither moves again.

3. How borrowing is priced

The rate is not fixed. It rises with how much of the ceiling you have drawn, and it re-prices the entire balance.

The rate slides in a straight line between a floor and a ceiling, according to how much of your credit limit you have used:

rate    = rMin + (rMax βˆ’ rMin) Γ— (what you owe Γ· your credit limit)
payment = what you owe Γ— rate          ← interest only, never principal

The two ends are EconomyParameterData.m_LoanMinMaxInterestRate β€” 2% and 20% β€” and your credit limit is Creditworthiness.m_Amount, the most the game will let you owe. Both are read out of the game's own files on every run rather than worked out from an observed loan. One loan gives you one equation with two unknowns, so any pair of endpoints that happens to fit it will survive every arithmetic check you can throw at it while still being wrong.

The rate applies to the whole balance, so drawing more money makes the money you already owe more expensive too. That is the only way this differs from ordinary borrowing, and it is what makes the quoted rate misleading.

Right now this city owes 180,000 of a 700,000 ceiling. The rate is 6.63% and the bill is 11,931 a month β€” and that is genuinely what it pays. Draw another 420,000 and the rate goes to 17.43%, but it goes to 17.43% on all 600,000, not just on the new money. The bill becomes 104,571.

So to price a draw, compare the whole bill before and after. Never multiply the new money by the quoted rate:

draw this much more new rate monthly bill the draw actually costs
β€” 6.63% 11,931 β€”
+90,000 8.94% 24,145 13.57%
+210,000 12.03% 46,911 16.66%
+420,000 17.43% 104,571 22.06%
+520,000 20.00% 140,000 24.63%

The last column is the one to judge a loan by, and it needs saying carefully, because it is not a rate you will ever see on screen.

What you pay every month is the quoted rate on everything you owe β€” 6.63% today, 17.43% after that big draw. That much is simple.

What a draw costs you is a different question, because taking new money does two things at once. It borrows the new money, and it raises the price of every guilder you already owed. Take the 420,000 row β€” the monthly bill goes from 11,931 to 104,571, up 92,640. That increase splits cleanly in two:

where the extra bill comes from per month
interest on the new 420,000, at the new 17.43% 73,200
the old 180,000 re-priced from 6.63% to 17.43% 19,440
the increase in your monthly bill 92,640

The second line is the one people miss. It is a new bill, every month, for money you borrowed long ago and have already spent. You get nothing for it.

Divide the whole 92,640 by the 420,000 you actually received and you get 22.06%. That is what the draw truly cost: the price of the new money, plus the price rise you inflicted on your old debt, spread over the money you took. It is the number to judge a loan by, and across the draws in the table above it runs from twice the rate the game shows you to nearly four times it.

For any other position, the cost of drawing Ξ” when you already owe a against a ceiling of L is

2% + 18% Γ— (2a + Ξ”) / L

The 2a is the whole story. Your existing debt is counted twice over: once because you are still paying interest on it, and again because the draw has just made that interest more expensive. New money is counted once. So the more you already owe, the more of the cost is punishment for what you owed before β€” and the second half of a credit ceiling costs far more than the first.

Which gives the practical rule: borrowing early is cheap and borrowing late is not. The same +90,000 costs 4.31% taken against no debt at all, against 13.57% taken from where this city sits now. The whole of that gap is the price rise you inflict on debt you are already carrying β€” so the less you owe, the less there is to re-price, and the more nearly the quoted rate is the true cost.

One building halves every figure above: the Central Bank. It is the only thing in the game that touches loan interest, and it applies a βˆ’0.5 multiplier to the rate β€” so the whole table above halves while it stands. On this city that takes the current 6.63% to 3.32% and the monthly bill from 11,931 to 5,966, and it takes the fully-drawn 20% ceiling down to 10%. The effect is rebuilt from the buildings standing each update, so it lasts exactly as long as the bank does.

The full list of what grants that and every other city-wide effect, with values, is reference/city_modifiers.md. Nothing else in the game reaches this section.

The solver does not carry it. City modifiers are read out of the save but no part of the loop consumes one, so every interest figure in Part II is the unmodified rate. That costs nothing here: the save's modifier buffer holds one non-zero entry, TaxiStartingFee +10, and LoanInterest is empty. On a city that has built the bank, halve every rate in this section by hand.

Debt never grows on its own, and never shrinks on its own either. The monthly payment is interest and only interest β€” not a penny of it comes off what you owe. So the balance sits exactly where you put it until you move it, and the only thing in the entire game that moves it is you dragging the loan slider. A deficit does not quietly turn into debt; it drains your cash, and then you decide whether to borrow. That is why borrowing is a decision in this document rather than a consequence.

And at zero cash you cannot repay at all. Repayment is capped at what your cash can cover, so a city with nothing in the bank cannot reduce its loan by any amount, however much it wants to. That is the real cost of running cash to the floor: not the missed purchases, but that you lose the ability to deleverage at the exact moment the rate is highest. This city sits at cash βˆ’39 and is already in that position.

4. The production loop

The sections above are not independent. They are one loop, and every quantity in the debt maths is downstream of education and happiness.

   SCHOOLS ─► education tier of each citizen
                β”‚
                β”œβ”€β–Ί JOB MATCHING     centre = 4Β·complexity + buildingLevel βˆ’ 1
                β”‚     └─► employed / under-employed / unemployed
                β”‚           └─► unemployment ─► m_UnemployedWellbeingPenalty ─┐
                β”‚                                                             β”‚
                β”œβ”€β–Ί DEMAND FACTORS   EducatedWorkforce +, UneducatedWorkforce βˆ’β”‚
                β”‚     └─► office & industrial demand                          β”‚
                β”‚           └─► companies spawn ─► job slots ─► TAX ─► income β”‚
                β”‚                                                             β”‚
                β”œβ”€β–Ί WORKER OUTPUT   base 2.0/3.5/6.0/8.5/11.0 by tier         β”‚
                β”‚     └─► production ─► profit ─► tax ─► income                β”‚
                β”œβ”€β–Ί m_EducationWellbeingMultiplier ──────────────────────────►│
                β”‚                                                             β–Ό
                └─► m_Tax{tier}Multiplier ─► how much tax costs         HAPPINESS
                                                                              β”‚
   POPULATION above its all-time peak ─────┐                                  β”‚
                                           β–Ό                                  β–Ό
                          XP/month = 1.5Β·newPeakPop     +      22.4Β·happiness
                                           β”‚        happiness also Γ— (0.75+h/200)
                                           β”‚        on EVERY worker's output
                                           β–Ό
                            MILESTONE ─► Creditworthiness += m_LoanLimit ─► L

Education touches everything

  1. Job matching. CalculateNumberOfWorkplaces fixes each company's education mix from complexity and building level. Citizens whose tier has no free slots are unemployed or under-employed regardless of how many jobs exist.
  2. Demand. EducatedWorkforce is a positive factor for both office (+40) and industrial (+180); UneducatedWorkforce is βˆ’180 on industrial. Educating people literally creates zoning demand.
  3. Happiness. m_EducationWellbeingMultiplier raises wellbeing directly, and the unemployment it prevents was dragging wellbeing down.
  4. The credit ceiling. Happiness pays 22.4 XP a month per point, and it is the only XP source that keeps paying once population stops growing. XP is what reaches the next milestone, and a milestone is what raises how much you can borrow β€” so educating the city is how you raise your borrowing ceiling.
  5. Tax tolerance, against you. The five per-tier multipliers run βˆ’0.4 / βˆ’1.0 / βˆ’2.0 / βˆ’4.0 / βˆ’5.0 (Uneducated β†’ Highly), applied as multiplier Γ— (residentialRate βˆ’ 10) wellbeing per citizen. A Highly educated citizen resents a tax point 12.5Γ— as hard as an Uneducated one, so educating the city shrinks its tax tolerance even as it grows everything else.

The counterweight: schools are service buildings, so they raise D, and the returns lag by however long a citizen takes to graduate.

Education and happiness multiply output directly

EconomyUtils.GetCompanyProductionPerDay:

production = ceil( output.m_Amount
                   Γ— buildingEfficiency Γ— sectorEfficiency Γ— GetWorkforce(employees)
                   Γ— 256 / neededWorkPerUnit )

GetWorkforce = Ξ£ over employees of GetWorkerWorkforce(citizen.Happiness, employee.m_Level)
GetWorkerWorkforce(happiness, level):
    base = (level == 0) ? 2.0 : 1.0 + 2.5 Γ— level
    return base Γ— (0.75 + happiness / 200)

with kCompanyUpdatesPerDay = 256 and all three sector efficiencies exactly 1.0. buildingEfficiency is the product of every entry in the building's Efficiency buffer, floored at 0.01 β€” it carries utility supply, sickness, missing staff, city modifiers and specialization, so all of those scale production too.

employee.m_Level is the job slot's level, not the citizen's education. FindJobSystem fills it from FreeWorkplaces.GetBestFor, which walks downward from the citizen's education until a free slot exists. A well-educated citizen in a level-0 slot contributes 2.0, not 8.5.

level of the job slot output per worker times what an Uneducated slot makes
Uneducated 2.0 1.0Γ—
Poorly educated 3.5 1.75Γ—
Educated 6.0 3.0Γ—
Well educated 8.5 4.25Γ—
Highly educated 11.0 5.5Γ—

Happiness is applied twice, multiplicatively. Once per worker inside GetWorkerWorkforce, and again building-wide: WorkProviderTickJob.UpdateNotificationAndEfficiency writes EfficiencyFactor.EmployeeHappiness as Ξ£ workforce(actual) Γ· Ξ£ workforce(50), which reduces to the same (0.75 + h/200) factor and lands in buildingEfficiency. So the effective multiplier is the square:

happiness output multiplier per worker multiplier on the building's total output
0 0.75Γ— 0.56Γ—
48 (this city) 0.99Γ— 0.98Γ—
50 1.00Γ— 1.00Γ—
90 (the highest reachable) 1.20Γ— 1.44Γ—

But the multiplier reaches about half your income and no more. TaxSystem's estimators read statistics 45/46/47 for commercial, industrial and office, which production drives; residential tax reads statistic 44, and GetHouseholdIncome builds that from GetWage(Worker.m_Level) plus benefits, with no happiness term anywhere. Service fees are charged on consumption. So of this city's 309,380 income, the output multiplier lands on 158,193 of company tax and leaves the rest untouched. Moving happiness 48 β†’ 90 is worth +74,230/month, and it costs no construction.

Wages are the counterweight and they do not keep up: m_Wage0…m_Wage4 read 1200 / 1500 / 2000 / 2500 / 3000, so output rises 5.5Γ— across the tiers while wages rise 2.5Γ—. The top tier delivers 2.2Γ— the output per guilder of wage.

Where this city's happiness went

CitizenHappinessSystem stores its own factor decomposition β€” 26 factors across 16 groups. The stored figures are health + wellbeing, and Citizen.GetHappiness() is (m_WellBeing + m_Health) / 2, so a factor's effect on happiness is half its stored total. Quote the stored figure as happiness and every consequence downstream is 2Γ— too big.

factor happiness factor happiness
Crime βˆ’11.35 Healthcare +6.97
TrafficPenalty βˆ’3.01 Apartment +4.21
NoisePollution βˆ’2.23 Consumption +1.41
Unemployment βˆ’0.64 Leisure +0.93
DeathPenalty βˆ’0.01 Education +0.92

Health runs 59.93 and wellbeing 34.46, so happiness is 47.2 against the save's recorded 48. Crime alone outweighs every other negative combined.

Happiness cannot reach 100. GetMaxHealth caps health by age: 100 under 2 years, 90 under 3, 80 under 6, then βˆ’10 a year, with AgingSystem putting the tier boundaries at 21 / 36 / 84 days against 12 days a year. On this city's age mix the average max health is 80, so the best reachable happiness is 90.

5. Demand, and what the game will let you build

What the residential bars are

Two numbers do two different jobs.

Household demand β€” one number, 61 on this city β€” is how many households want to move in. That is the demand for housing, and Β§8 is where it gets spent.

The three bars β€” 100 / 0 / 100 here β€” decide whether buildings actually get built, one bar per density. ZoneSpawnSystem puts a building on a zoned cell only while that density's bar is positive. If the bar is at zero, cells you zone for that density stay empty ground. The bars do not decide where arriving households live; households move into whatever empty homes exist.

Each bar starts from one count: how many homes of that density are standing empty. The game wants a reserve of them on hand β€” 5 low, 60 medium, 100 high (m_FreeResidentialRequirement) β€” and measures how far short of that you are:

term = 100 Γ— (reserve βˆ’ empty homes) / reserve

Low divides by 5, so each empty house moves the term 20 points:

empty low houses 0 1 2 3 4 5 6 7
term 100 80 60 40 20 0 βˆ’20 βˆ’40

Medium divides by 60 and high by 100, so one empty home moves them 1.7 points and 1 point. The same house does twenty times more to low than to high. On this city this term is the whole of what separates the two: +100 for low against βˆ’38 for medium.

The term is not the bar. The bar adds half the household demand and the other factors β€” happiness, tax, free workplaces, unemployment β€” and clamps at 100:

bar = clamp(household demand / 2 + term + other factors, 0, 100)

So the bar can still read 100 while the term has slid a long way down: the extras keep the sum above the 100 cap, and nothing moves on screen until the sum falls below it. Past the reserve it turns sharp, because a negative term also cancels the other factors β€” at this city's household demand of 61, six empty low houses put the bar at 10 and seven put it at 0.

Building medium does not clear low. Separate counts, separate reserves.

Low sits at 100 almost permanently. A low-density building holds exactly one household at every building level (measured: 188 buildings, 188 households, unchanged as they level up), so five families moving in take the reserve to zero. Arrivals empty it about as fast as construction refills it.

So a bar tells you whether zoning that density will produce buildings, and nothing else. It does not tell you how much to zone β€” that is household demand, in Β§8 β€” and a low bar at 100 is not evidence the city is short of housing. It reads 100 here while dozens of medium units stand empty.

A locked density shows no bar at all

UpdateResidentialDemandJob opens by building a bool3 over m_UnlockedZonePrefabs β€” the query is ZoneData with Exclude<Locked> β€” setting one component per GetZoneDensity of each unlocked residential zone, and closes with

m_BuildingDemand = math.select(int3.zero, m_BuildingDemand, unlocked)

So a density with no unlocked zone reports zero however much demand the factors add up to. This is not cosmetic: it is why the transcription disagreed with one save of eleven for two sessions. That save is the only one missing Residential LowRent β€” which is the High density residential zone, whatever its name says. ZoneData has no density field; GetZoneDensity decides it from ZonePropertiesData, so classifying by name gets LowRent wrong and returns nothing at all for Residential Mixed, which is Medium.

What this city can build

zone building bar, 0–100 what is holding it there
Residential low 100 at maximum
Residential high 100 at maximum
Commercial 47 local demand for goods, +183, and petrol, +54
Industrial 0 every commodity still has an empty lot standing
Office 0 same β€” one empty office lot, and no firm waiting for it

Wanting to exist and being allowed to build are two different things

This is the distinction the rest of the document leans on hardest, so it is worth getting straight once.

Each sector carries two numbers. Company demand is how badly firms want to operate β€” it moves with labour, tax and how much of the goods the city is buying. Building demand is whether the game will put up a new building, and it is the only one that gates zoning. Industrial company demand here reads 424 against a building demand of 0: the firms want to exist and the game will not build for them.

What separates the two is a single test, applied to each commodity separately, with no tax term and no labour term in it:

spare lots = empty properties βˆ’ firms with no premises
building demand = 0 if any lot is spare, otherwise 50

In plain terms: while an empty industrial lot is standing anywhere, the game will not build another one. Only once every lot is taken does the sector's company demand (industrialCompanyDemands[r]) start counting toward the building bar. So a sector reading zero is not a slow sector β€” it is a full one.

What empties those lots is the same company demand, reaching them through a different system. IndustrialSpawnSystem runs 2,048 times a simulation month, and on each pass it creates a firm for a commodity when a draw comes in below that commodity's company demand:

range = round(5000 Γ· log10(1 + population), held between 1 and 5)
spawn a firm for commodity r if random(0 … range) < industrialCompanyDemands[r]

range is 1,427 at this city's 3,187 citizens, so each point of a commodity's company demand is about one chance in 1,427 per pass, and a firm that spawns has no premises until IndustrialFindPropertySystem seats it in a free lot. At most one firm per commodity waits at a time β€” the pass skips a commodity that already has one β€” and each firm that arrives and settles costs the sector one vacancy for good.

So the two numbers are not independent after all. Company demand does not gate building; it is what consumes the vacancies that do. And the 424 above is summed across commodities: all of it is the nine raw materials β€” Grain, Vegetables, Oil, Ore, Coal, Stone, Livestock, Cotton and Fish, which are extracted rather than manufactured and take farm and mine lots. Across the eighteen manufactured commodities this city's company demand is 0 at the default 10% rate, so nothing is trying to take a factory lot at all, and its two spare ones stand. Β§7 prices what moving the rate does to that.

Industrial and office also share one gate rather than having one each. ZoneSpawnSystem adds the two building bars, halves the result with integer division, and asks whether that is above zero β€” so the two must sum to at least 2 before either will build. They share it because an office zone is, internally, an industrial zone.

Why educating further does not move the industrial bar

The two workforce numbers in the demand factors are one mechanism seen from either end. For each commodity the game computes a labour surplus β€” employable Γ— 0.85 βˆ’ free workplaces, summed over the top three education tiers for the educated term and the bottom two for the uneducated one β€” and clamps it to Β±10 at the default rates. This city has 203 idle Educated citizens and zero unemployed Uneducated, so the educated term sits on its +10 ceiling and the uneducated on its βˆ’10 floor, for every commodity, and they cancel exactly.

They cancel because both are pinned, not because the tiers happen to balance. Adding more educated citizens moves a term that is already at its limit, so it changes nothing. What does move it is putting uneducated labour into the city, or cutting the industrial rate below 10%. The rate reaches these two terms because the job branches on the sign of taxFactor: at or above 10% it is zero or negative and the surplus is simply clamped to Β±10, and below 10% it turns positive and the surplus goes through MapAndClaimWorkforceEffect instead, whose scales are βˆ’max(10 + taxFactor, 10) and +10/+15. Β§7 prices what that is worth.

One reading trap in the raw factors: LocalDemand βˆ’1 and EmptyBuildings βˆ’1 are not small negative remainders. βˆ’1 is what the game writes down when a factor is zero β€” a placeholder applied to four factors at the end of the pass.

The labour market does not clear, and the demand system cannot see it

Job slots carry a required education tier, set by CalculateNumberOfWorkplaces from complexity and building level. Unemployment is therefore not one number:

education level job slots at this level filled standing empty citizens at this level with no job
Uneducated 791 271 520 0
Poorly educated 963 840 123 76
Educated 569 569 0 203
Well educated 162 100 62 1
Highly educated 27 9 18 0

Every Educated slot is occupied and 203 Educated citizens have nowhere to go, while 520 Uneducated slots stand empty with nobody unemployed to fill them. FreeWorkplaces.GetBestFor walks downward, so the surplus tier does not queue β€” it takes a lower slot, and both its output and its wage are read from the slot. 482 citizens work below their education, costing 38,359 in company tax and 14,400 in residential tax β€” 52,760/month, invisible in every panel.

Two consequences, and the second is the one that bites.

Zoning does not clear it. A new building's slot mix comes from its complexity and level β€” properties of what spawns, not of what you need β€” so zoning into existing demand adds mostly the tiers already vacant.

The demand system cannot see the mismatch at all. The residential demand job reads free workplaces as an untiered count: FreeWorkplaces is the largest positive term holding residential demand up, and it is counting 724 vacancies of which 520 are slots the arrivals cannot take. The game invites more citizens on the strength of jobs that cannot absorb them.

The extractor case, which is the same trap with no way out

14 extractor companies hold 24 slots and fill 12 β€” 7 Uneducated and 5 Poorly educated β€” while the city has 0 unemployed Uneducated to draw on. Commuters cannot help: the spawn gate counts only tiers 2/3/4. ExtractorAISystem.GetArea sets m_MaxWorkers from painted area, so enlarging a farm makes the shortfall worse, and extractor building level is pinned at 1 permanently, fixing their education mix forever.

Sectors

sector companies tax paid/month tax per worker profit workers employed % of their job slots filled
Commercial 34 61,520 255.3 147,421 241 81%
Industrial 138 353,879 267.7 467,142 1,322 65%
Office 7 9,492 237.3 βˆ’10,942 40 73%
Extractor 14 2,201 183.4 1,871 12 50%

Every column is counted per company out of CompanyStatisticData β€” m_TaxPaid and m_Profit are already monthly totals β€” against the job slots WorkProvider declares and the staff its Employee buffer holds.

Per worker the sectors are within 15% of each other. Office pays little tax because there are only 7 office companies against 138 industrial ones, not because office yields poorly. What actually differs between sectors is who they employ and whether they turn a profit: office is the one running at a loss.

That loss is not why its building bar reads zero. officeBuildingDemand is decided by (m_FreeProperties[r] βˆ’ m_Propertyless[r] > 0) ? 0 : 50 per commodity, and this city holds one spare office lot with no firm waiting for it β€” there is no profitability term anywhere in that test.


Part II β€” the decision

6. The two countdowns, and the milestone ladder

First, the ceiling. The ceiling is Creditworthiness.m_Amount, the most total debt the game will let you carry β€” a borrowing limit and nothing else. It has no connection to your revenue, your income or your spending. It is L in every formula below, it reads 700,000 on this city, and the only thing that moves it is reaching a milestone: MilestoneSystem.NextMilestone does m_Amount += MilestoneData.m_LoanLimit, so it is a running total of the steps you have climbed. Every ratio in this section is measured against it.

There is no bankruptcy in this game. What kills a city is running out of borrowing room before income catches up with upkeep. When that happens you still owe the monthly shortfall, there is nothing left to borrow, and β€” because repayment is capped at what your cash can cover (Β§3) β€” at zero cash you cannot even pay the debt down. The city keeps existing but can no longer act on anything. This document calls that stalling, and it is the only way to lose.

Two countdowns run at once, and you survive if the second finishes first:

months of money left = (cash + borrowing room left) Γ· (monthly hole + interest)
months until rescue  = XP still needed Γ· XP earned per month

And then it runs again. Reaching a milestone does not end the race; it raises the ceiling, pays some cash, and starts the next countdown against a larger XP step. The ladder later in this section shows the steps growing faster than the ceilings do, so winning one round leaves you needing to win a harder one.

That is what makes this a rate rather than a target, and Β§7 has the row that shows it. Zone nothing and this city still reaches milestone 5, in month 4 β€” it was near enough that happiness alone, paying about 1,075 XP a month, carried it over the line. What it cannot do is reach the one after. With no housing being zoned its population never moves off 3,388, so the half of the XP formula that pays for new peaks contributes nothing at all, while milestone 6 asks for 7,700 more. The city spends its enlarged ceiling in two months and stalls in month 6 with that milestone still four months out.

So the countdown you have to keep winning is the next one, and the only thing that keeps winning it is population that is still climbing.

Divide the first through by the ceiling β€” writing f for the fraction of the ceiling you have already borrowed β€” and the ceiling itself drops out:

months of money left = (1 βˆ’ f) / ( D/L + rate(f)Β·f )        rate(f) = rMin + dΒ·f

rMin and d are the loan-rate floor and its spread β€” EconomyParameterData.m_LoanMinMaxInterestRate, 2% and 20%, so d is 18 points (Β§3).

That is why one table serves every milestone: how long you last depends on your monthly hole measured against your ceiling, and on how much of the ceiling you have already spent β€” not on the raw size of the ceiling.

The table below is that formula, evaluated. Its rows are D/L, the monthly hole divided by the borrowing ceiling β€” not by revenue. Its columns are f. Working one cell longhand, the 20% row at half borrowed:

rate(0.50) = rMin + d Γ— f     = 0.02 + 0.18 Γ— 0.50   = 11%
months     = (1 βˆ’ f) / (D/L + rate(f)Β·f)
           = (1 βˆ’ 0.50) / (0.20 + 0.11 Γ— 0.50)
           = 0.50 / 0.255                            = 2.0 months

Every cell is months until you run out of money:

D/L β€” monthly hole Γ· borrowing ceiling nothing borrowed, f=0 a quarter, f=0.25 half, f=0.5 three-quarters, f=0.75 95%, f=0.95
5% 20.0 11.3 4.8 1.5 0.2
10% 10.0 6.5 3.2 1.2 0.2
15% 6.7 4.5 2.4 0.9 0.2
20% 5.0 3.5 2.0 0.8 0.1
30% 3.3 2.4 1.4 0.6 0.1

Interest is charged on the whole balance, and the rate itself climbs as you borrow more, so the numbers fall away far faster than the borrowing rises. Read along the 10% row: going from a quarter borrowed to three-quarters borrowed spends five and a half of the six and a half months you had.

Every cell holds the deficit still, so read the table as a floor and not as a forecast. The hole does not stay where you left it: new residents pay tax, and a growing city closes part of it every month. What these numbers give you is how long you last if nothing improves β€” the worst case, and a real one. Β§8 scores the same moves with the deficit allowed to move and gets longer answers, sometimes several times longer.

Reaching a milestone moves you a long way inside this table, in both directions at once. It raises the ceiling, which shrinks your hole relative to it and moves you to a better row; and its cash reward pays debt down, which lowers the fraction borrowed and moves you to a better column. This city at milestone 4 owes 180,000 against a 700,000 ceiling β€” an 18.03% hole, a quarter borrowed, about 4 months off the table. Reaching milestone 5 lifts the ceiling to 1,100,000 and pays 125,000 in cash; put that cash against the debt and the position becomes an 11.47% hole at 5% borrowed, about 9 months, with the rate on the debt still held falling 6.63% β†’ 2.90%. The table does not change. Where you sit in it does.

Solvency comes down to one ratio β€” the monthly hole divided by the ceiling.

Borrow a to cover a hole of D and you are draining money two ways at once: the hole eats through the loan at D/a per month, and the interest costs rate(a). Your total drain is the sum, and it has a floor β€” borrow too little and D/a is brutal, borrow too much and rate(a) is. The best you can do is

min over a of [ D/a + rate(a) ]  =  rMin + 2√(d · D/L)

which is where the ceiling drops out: only the ratio D/L survives. Income has to grow at least that fast, because that is the slowest you can possibly bleed. (The 2 here is the ordinary minimum of x/a + ka β€” nothing to do with the rate curve's slope.)

A hole worth 10% of the ceiling demands 28.83% growth at every milestone alike; 5% demands 20.97%; 18% demands 38.00%. This city's hole is 18.03% of its ceiling, so it needs 38.03% growth to survive.

It is measured at 48.40%, so the city clears its own bar β€” but only while it keeps doing what earned that figure. The growth was measured across a pair of saves in which the player was zoning steadily, and almost all of it is new residents. Stop zoning and the growth that clears the bar stops with it, which is why Β§8's recommendation is a rate to keep up rather than a target to reach.

XP, and how milestones are reached

XPAccumulationSystem pays from two continuous sources. With XPPerPopulation = 48.0, XPPerHappiness = 22.4 and 32 updates a month:

XP/month = 1.5 Γ— new-peak population gained  +  22.4 Γ— average happiness

MilestoneSystem.NextMilestone does Creditworthiness.m_Amount += m_LoanLimit, so the ceiling is a running total. The cash reward is 25,000 Γ— the milestone number.

So here is the second countdown, for this city. It needs 3,548 more XP to reach milestone 5 and earns 1,056 a month from happiness alone, which puts rescue about 3.4 months away against the 4 months of money the table above gave it β€” it wins this round, and it wins it by about a fortnight. The round after is the one that decides anything: milestone 6 asks for 7,700 more, which on happiness alone is seven months of waiting funded by whatever milestone 5 just handed over. That is the margin the rest of this document is spent widening.

Reading the table: ceiling is what you are allowed to owe once you reach that milestone. total XP is what it takes to get there counting from the start of the game. XP over previous is how much more that is than the milestone before it β€” the wait you are actually facing while standing on the previous one.

milestone ceiling total XP XP over previous milestone ceiling total XP XP over previous
1 100,000 750 β€” 11 5,700,000 119,700 30,000
2 250,000 2,500 1,750 12 7,000,000 155,700 36,000
3 450,000 4,800 2,300 13 8,500,000 198,700 43,000
4 700,000 8,300 3,500 14 10,200,000 248,700 50,000
5 1,100,000 13,600 5,300 15 12,100,000 305,700 57,000
6 1,600,000 21,300 7,700 16 14,200,000 369,700 64,000
7 2,200,000 32,100 10,800 17 16,500,000 439,700 70,000
8 2,900,000 46,700 14,600 18 19,100,000 514,700 75,000
9 3,700,000 65,700 19,000 19 22,100,000 592,700 78,000
10 4,600,000 89,700 24,000 20 26,100,000 671,700 79,000

Across the twenty milestones the ceiling grows 37 times over, but the XP wait grows 45 times over. The money you can borrow is growing more slowly than the time you must survive to reach it, so each milestone finances less of its own wait than the one before. Borrowing through a deficit is an early-game move that stops working. At a modest 200 new-peak citizens a month and happiness 48, the biggest deficit you can carry and still keep climbing peaks at milestone 5 β€” 127,410 a month with a quarter of the ceiling borrowed β€” then shrinks the whole rest of the way: 81,190 at milestone 10, 16,239 at milestone 14, and past milestone 15 no deficit at all survives a quarter-borrowed position.

7. The levers, one at a time

Every lever on its own β€” what it is, what it is worth at this position, and the mechanism that bounds it β€” before Β§8 plays them together.

Tax β€” and the four rates are three different instruments

All four sectors sit at the default 10%, and that is where the similarity ends.

There are far more tax rates than the four sliders suggest. The game keeps 92 of them, in four groups. A rate is never stored as a single figure β€” it is always the sum of two or three entries, which is why a slider can move without any individual commodity's setting changing:

entries what they are the rate you actually pay
1 a global offset added to everything below
4 the four sector sliders global + sector
5 residential, per job level global + residential + that level
41 commercial, per commodity global + commercial + that commodity
41 industrial and office, per commodity global + the sector + that commodity

That is 1 + 4 + 5 + 41 + 41 = 92. Industrial and office share the last group safely, because their commodity lists do not overlap β€” office is exactly the four weightless goods.

The four sector sliders are the only ones this model moves. The 82 per-commodity rates are read and unused, and Β§12 records what that costs, because a rate you can set on one commodity is a different instrument from one you set across a whole sector.

What each area channel collects today. Residential's base is wages and the other three share production, which is why the last column cannot be read down as one set of numbers β€” only the three company rows belong to the same whole:

channel per point, per month the base it taxes its share of that base
industrial 11,223 production 0.7095
residential 10,025 wages 0.6631
commercial 4,471 production 0.2827
office 124 production 0.0078
the three company shares 1.0000

Roughly a hundred to one separates office from industrial. That the three company shares come to exactly 1.0000 is the check that the split is right: every guilder of production is taxed by one of those three and no other.

The office row is a label, not a rate. Nothing in the charging path ever asks for the office rate: office firms accrue at the industrial one and their payments are relabelled as office income on the way out. So "office, 124 a point" is a point of the industrial rate applied to office goods, and the model moves the two sliders independently as though they were separate instruments. Every save in this series sits at 10 on both, so none of them can tell the two apart.

But those figures describe today's sectors, not the rate itself. The take is rate Γ— taxable income / 100 β€” exactly linear in the rate β€” and the taxable income grows with the sector, so a point of industrial is worth more in a city with more industry. Β§8 charges a tax move as a fraction of its own base rather than a fixed sum, which is why it tracks. Held frozen, a +5 residential move reads 50,125 a month forever; charged properly it runs 56,200 in month one to 118,895 by month twelve on a city going 3,187 β†’ 9,281. That 2.1Γ— is the difference between the two.

The income terms beside it are constants, and correctly so: income per added worker is a marginal, i.e. a ratio, so it is scale-invariant β€” double the city and both company tax and workforce double. A yield per tax point is a level.

Tax is charged by a different rule from the one that estimates it. GetEstimatedCommercialTaxIncome and its twins apply the current slider to a city-wide statistic. What actually leaves a company is PayTaxJob.PayTax: round(0.01 Γ— m_AverageTaxRate Γ— m_UntaxedIncome), each payer's own accrued income at its own historical average rate. They cannot agree β€” 339 of 2,381 TaxPayer components carry an average rate of zero, in the statistic and paying nothing. The model spends what is charged.

Residential is a margin. Each point is worth roughly 10,025/month gross. CitizenHappinessSystem.GetTaxBonuses charges each citizen multiplier Γ— (residentialRate βˆ’ 10) wellbeing, with the multipliers of Β§4; on this city's education mix β€” 203/1,385/1,093/392/10 β€” that weighs to 1.71 wellbeing, i.e. 0.85 happiness per point. Only the residential rate reaches citizens at all; the other three act on companies. The demand feedback is exact too: m_TaxEffect = (2.0, 1.0, 1.0), so a residential point takes 2 points off residential demand. Net here, +5 points is +43,370/month, and Β§8 scores it as a real but second-order move.

Commercial is also a margin, and it is priceable. Re-seeding the per-resource demand at a given rate β€” tax = βˆ’0.05 Γ— (rate βˆ’ 10) Γ— m_TaxEffect.y, applied as want = round((1 + tax) Γ— want) β€” reproduces the bar this save stored, so the sweep is against the game rather than against our own arithmetic:

commercial tax rate, % 16 14 12 10 8 6 4 0
commercial building bar 33 37 42 47 52 57 61 71

Smooth and steady at about 2.4 points of bar per tax point, so you can trade revenue against growth a point at a time.

Cutting industrial tax puts nothing on the building bar. It opens the sector by emptying the lots instead.

Each sector carries two separate numbers. Company demand (industrialCompanyDemands[r]) is how badly firms want to operate, and the tax rate moves it through m_TaxEffect. Building demand (industrialBuildingDemand) is whether the game will put up a new building, and it is the only one that lets you zone. The test that decides it, read from IL, is

m_IndustrialBuildingDemands[r] = (m_FreeProperties[r] - m_Propertyless[r] > 0) ? 0 : 50

and the building bar only accumulates a commodity's company demand where that landed on 50. No tax term appears anywhere in it. So while free properties outnumber the firms waiting for one, cutting the rate raises company demand, building demand stays at zero, and no amount of cutting lets you zone that month.

Where the rate reaches the spawn gate β€” ZoneSpawnSystem's (industrialBuildingDemand + officeBuildingDemand) / 2 > 0, which is what the bar above feeds β€” is the other side of that subtraction. The test takes off the firms with no premises, and IndustrialSpawnSystem is what creates them: 2,048 passes a simulation month, each one spawning a firm for a commodity when a draw in 0 … 1,427 comes in below that commodity's company demand β€” the same industrialCompanyDemands[r] the rate moves (Β§5). The firm has no premises until it takes an empty lot, and once it does, m_FreeProperties[r] is one lower for good. Cut the rate and firms appear; the lots empty; the test starts passing.

On Beetham 4, the snapshot this section's tax yields are read from, that is the difference between never and immediately:

industrial rate, % industrialCompanyDemands[r], per manufactured commodity months until both spare factory lots are taken
10 0 never β€” nothing is trying
9 11 0.007
8 14 0.006
5 25 0.003
0 42 0.002

The first row is the finding. At the default rate not one of the eighteen manufactured commodities wants a factory, which is why the same two lots stand empty across all ten snapshots between 3,187 and 3,210 citizens β€” and why the sector was never going to open on its own. One point off puts 11 on each of the eighteen, and eighteen chances of 11-in-1,427 per pass means the first firm arrives inside about seven of the 2,048 passes a month holds. The remaining rows barely separate because two lots is a trivial target once anything at all is trying for them.

The city's nine raw materials β€” Grain, Vegetables, Oil, Ore, Coal, Stone, Livestock, Cotton and Fish β€” carry 424 of company demand between them at the same default rate and cannot use those lots: farm and mine properties are a separate stock and this city has none free, with one extractor firm already waiting.

What Β§8 does with this, and where it stops. The solver carries the free properties and the firms with no premises as state and re-decides the gate every month from them, so a play that cuts the rate opens the sector inside its first month and the rows below are scored with it open. What the solver does not carry is the other direction: once the gate opens, ZoneSpawnSystem puts up new industrial buildings, and each is a fresh empty lot β€” so m_FreeProperties[r] climbs back above m_Propertyless[r] and the test starts failing again. It paints residential only, so its vacancy count falls and never rises and it shows the sector staying open for the rest of the year. Read an opened industrial sector in Β§8 as the earliest it could open, not as a state that holds.

This city has crossed the line in both directions:

snapshot spare factory lots, per manufactured commodity industrial building demand, as the rate falls 10% β†’ 0%
population 3,187 (Beetham 4) +2 on all 18 stays 0 at every rate
population 3,305 (Beetham 7) none, or a firm already waiting climbs 0 β†’ 88

Once the lots are gone, cut deep rather than by a point. Each commodity's company demand (industrialCompanyDemands[r]) is the sum of four terms: how much of the good the city wants and is not getting, the tax term (taxFactor = βˆ’5 Γ— (rate βˆ’ 10)), and two workforce terms for unemployment and education. Only the workforce pair peaks at 9%. The tax term is linear in the cut and quickly outgrows them, so the curve steepens rather than flattening. On Beetham 7, where the lots are gone and the bar can move:

industrial rate, % tax term (taxFactor) workforce terms, net industrialCompanyDemands[r] summed over the 18 industrial building demand
10 0.00 0.00 7 0
9 5.00 +5.42 205 22
8 10.00 +3.89 277 30
5 25.00 βˆ’0.69 475 52
3 35.00 βˆ’3.75 601 66
0 50.00 βˆ’8.33 799 88

The bar is 2 Γ— that sum Γ· 18 on integer division, so the last two columns are the same fact twice. Cutting to zero is four times the demand of cutting one point. Whether that is worth the revenue is not a question this table can answer, because the rate moves demand, revenue, the debt and the milestone date at once β€” which is exactly what Β§8 scores as a package rather than as a lever.

Office reaches a different answer, and on Beetham 4 it is a flat no. The office branch of the same seed sits behind a test the tax term cannot reopen: a commodity whose unmet demand is zero takes company demand zero before the rate is added. All four office goods read zero on Beetham 4, so officeCompanyDemands[r] is zero from 16% down to 0% and cutting the office rate moves nothing whatever. On Beetham 7 they are not zero and the same sweep runs 18 β†’ 68 across the four β€” but that city holds one spare office lot and no firm waiting for it, so officeBuildingDemand stays 0 throughout and the demand builds nothing.

What raising a company rate costs, and the half of it nothing here prices. A rise suppresses that channel's company demand, so fewer firms spawn and the production base the rate is levied on grows more slowly β€” Β§8 charges exactly that, per channel, weighted by the channel's share of production. It also makes the firms already standing more likely to leave: (rate βˆ’ 10) Γ— 5 / 2 percent per check, from the same read. How often that check runs is not transcribed, and inventing a frequency would put a made-up number under every company-tax figure in the document β€” so nothing prices it, and every company-tax gain in Β§8 and Β§9 is an upper bound.

Spare lots are not a permanent condition, and this city has had none twice. On the snapshots at 1,866 (Beetham 2) and 2,786 citizens (Beetham 3) every office lot was taken and officeBuildingDemand read 100. So "fill the lots first" describes something this city has already done, not a theoretical instruction.

These sweeps are the game's own arithmetic rather than ours: the per-resource demand behind them is recomputed from the save and checked against the 41-entry array the game itself stored, and it refuses to answer on saves where that array was wiped on load.

Zoning, and which density

How much to zone is priced two subsections below. Which density is a separate decision, and the residential building bars are what decide it, because a zoned cell is not a house: ZoneSpawnSystem puts a building on a cell only while that density's own bar β€” one each for low, medium and high, the three UpdateResidentialDemandJob writes β€” is positive, so capacity painted into a shut bar stays land, while its road bill and its coverage thinning arrive anyway.

The same 150 a month, painted three ways over twelve units:

zoned into population money left households that never got built
low only 6,419 450,044 0
medium only 6,166 0 150
high only 6,419 450,044 0
spread evenly 6,334 261,084 50

Medium is shut on this city: more than 60 empty medium homes already stand against a buffer of 60 (Β§5), so cells zoned medium wait as land until arrivals draw the glut down and the bar reopens. The mistake corrects itself, but not for free β€” a month of capacity is lost, and the road, its construction and the thinning on land that housed nobody are billed throughout. On this city's thin margin that is the whole gap between low-only's 450,044 and zero. Read the bars before you paint. Spreading a third of the paint into medium β€” the "spread evenly" row β€” loses a third of the first month the same way.

Low is open, and it is the twitchiest of the three. Every unsold low house swings its term 20 points against 1.7 for medium and 1 for high, and the first house past the buffer also cancels that density's positive factors. At household demand 61 the low bar reads 100 with nothing standing empty, 10 with six empty, and 0 with seven β€” so seven houses built ahead of the people to fill them is the whole distance between a maxed bar and a dead one. The 100 it reads today says the buffer is tiny, not that the city is short of housing, and it will not survive a zoning rate that outruns intake.

What zoning buys

Only the amount of zoning changes between these rows. No extra borrowing, tax at the 10% default, nothing built. This is the Beetham 4 city.

Read this table as a ceiling being raised, not as people being created. Zoning does not attract anybody. Arrivals come from the housing demand bar, and that bar is driven by happiness, tax, jobs and how many homes already stand empty (Β§5). What zoning does is decide whether the people the bar is already asking for have anywhere to move in β€” so it is a cap on arrivals, never a source of them. Zone into a city with no demand and nothing happens.

That is why the rows stop separating. Three limits bite in turn:

  1. The demand bar itself. Arrivals each month are whatever the bar asks for, and it falls as the city fills β€” empty homes push it down directly, and every arrival takes a job slot, which pushes it down again next month.
  2. A zoned cell is not a house. Buildings only appear while that density's own bar is positive, and on this city seven empty low-density houses are enough to shut it (Β§5). Capacity zoned past that point stays as empty land.
  3. The land bank. There are 4,074 households of paintable cells on the tiles this city owns, so 600 a month runs out in seven.

money left is cash plus undrawn ceiling at the end of the run β€” room to act rather than profit; Β§8 defines it fully.

households zoned/mo population money left milestone reached stalls in interest rate
none 3,388 0 mo 4 mo 6 16.36%
60 4,062 0 mo 3 mo 7 17.30%
150 6,334 261,084 mo 3 β€” 15.33%
300 9,281 1,901,482 mo 2 β€” 5.00%
600 9,910 3,711,499 mo 2 β€” 2.00%

The population column is converging and the money column is not, and the two behave differently for a reason worth holding onto. Doubling from 300 to 600 adds 630 citizens β€” under 7% β€” because population is running into the three limits above. Money left keeps climbing because it is not measuring people: a bigger city services its debt sooner, so the interest column collapses from 16.36% to 2.00% and the undrawn ceiling stops being eaten. You stop buying population long before you stop buying solvency.

The none row is not a neutral baseline. It is what happens if you make no further decision at all: the city lives off housing already zoned but not yet built, which here is 87 empty homes plus 33 unbuilt β€” 120 households, about 202 citizens, worth 303 XP against the 3,548 needed for the next milestone. It is also the row that stalls.

The two stalled rows are not ranked against each other. Both report zero, because both ran out of ceiling; zoning 60 buys 673 more citizens and one extra month before that happens, and it still is not enough. The gap between 60 and 150 is where this decision actually lives.

And 600 is not worth twice 300 β€” it is barely worth more at all. The extra 300 a month is painted into a bar that has already shut and a land bank that is already spent, so it becomes empty ground rather than housing. The useful reading is that somewhere between 150 and 300 this city stops being short of housing and starts being short of something else β€” and what it is short of after that is jobs and happiness, which is why the levers below and not more zoning is where the next decision lives.

That settles what to do first. Zone before anything else. Until zoning moves, population barely grows, so the population half of the XP formula contributes almost nothing and every milestone has to be earned on happiness alone β€” and happiness gets weaker relative to the XP steps the further up the ladder you go.

Why zoning is nearly free. Zoning cells costs nothing. Buildings that spawn on them pay their own upkeep and pay tax on top. Only the roads you need to reach them add upkeep.

It is also the one quantity in this document that is a choice rather than a measurement. Every system that writes a zone cell's type lives under Game.Tools.*; none of them belongs to the simulation. Two saves of this city sit on the identical simulation frame β€” identical population, capacity and occupancy β€” with different zoning grids. No simulation time passed and the grid changed anyway, so there is no elapsed time to divide by and zoning cannot be expressed as a measured rate. You simply decide it.

The least zoning that works

One number here is a true minimum: the smallest amount of zoning that keeps the city out of a stall. It is quoted together with whatever else you are doing, because the other levers move it β€” a minimum quoted on its own would describe a position nobody is actually in. This is the Beetham 4 city.

what else you are doing fewest households/month you must zone
no extra borrowing, tax at 10%, nothing built 131
...and raise residential tax 5 points 8
...and borrow 210,000 156
...and build a 200,000 service costing 20,000/month 282

Zone less than that and the city runs out of borrowing room before income recovers. Zone more and income closes the gap first.

Each of the three moves the floor by what it does to the monthly hole before a single new citizen arrives. Five points of residential tax put 43,370 a month against a hole of 126,180, so a third of the problem is gone before anyone moves in and the floor falls to almost nothing. Borrowing does the reverse: drawing re-prices the whole balance (Β§3), so the interest bill rises in the month you take the money and nothing has yet arrived to pay it. Building is that same effect twice over β€” 20,000 a month of upkeep on top of the interest on its capital β€” and it is the one move here that adds a cost with no citizen attached, which is why it more than doubles what you then have to zone. Underneath all three rows sits the same fact: an arrival pays its taxes and costs 27.22 a month to serve (Β§10), so each household of zoning closes the hole by its margin and no more β€” which is what a floor this high is measuring.

Happiness, and what a purchase must deliver

Happiness is the largest single lever on the board: 48 β†’ 90 is +74,230/month of company tax with no construction, plus 941 XP/month, plus a demand factor. Those are three separate channels β€” the output multiplier (0.75 + h/200)Β² applied twice per worker (Β§4), XPPerHappiness at 22.4 an update, and the happiness term in UpdateResidentialDemandJob. It still does not close a 126,180 deficit alone.

The build ranking below prices what a specific building delivers. This asks the question from the other end β€” how much happiness would a purchase have to return to pay for itself at all β€” because that answer does not depend on knowing which building you buy, and it is the number to check a candidate against:

what else you are doing one-off cost cost per month happiness it must return to be worth buying
nothing β€” no zoning 200,000 20,000 no answer β€” the city stalls even without the building
zone 150 200,000 20,000 +16.9 happiness
zone 150, tax +5 200,000 20,000 +16.9 happiness
borrow for it, zone 150 200,000 20,000 +17.4 happiness

The middle rows agree because the threshold is a difference, not a level. Each row is two runs of the same city β€” one that makes the purchase and one that does not β€” and whatever else the move is doing, it does on both sides. The zoning, the tax and the arrivals they bring all cancel out of the comparison. What is left is the building's own price and upkeep weighed against the happiness it returns, and that does not shift because the city around it is growing faster.

The borrowed row is higher, and Β§3 says by what. There the draw rides with the purchase β€” buy it and you borrow for it, decline it and you borrow nothing β€” so the loan's side of the ledger does not cancel: the building must also pay the re-pricing its capital inflicted on every guilder already owed. Half a point of happiness is what that costs at this city's position. Capital bought on credit has to return more than capital in hand.

The first row is a different kind of answer. There the city stalls without the building ever being bought, so there is no surviving run to compare against. The purchase is not being called a bad deal; the question cannot be asked.

Two things hold generally. The bar rises with the purchase price, not just with the monthly upkeep β€” the capital comes out of borrowed money, borrowing re-prices the entire balance, and you pay that interest for as long as the building stands. And a purchase can also be too big to have a threshold at all: one that exhausts the ceiling by itself does not become a bad deal, it stalls the city, and no amount of happiness fixes that. Either way, when the calculation returns no reachable number, that is the right answer.

The limit on what any purchase can deliver β€” crime

A threshold is only useful if you know what is actually achievable, and crime gives you that limit exactly. Crime does not build up without limit β€” it is capped. CrimeAccumulationJob, per building per update:

increase = GetBuildingCrimeIncreasePerDay(prefab)
         Γ— m_CrimePoliceCoverageFactor Γ— max(0, 5 / (5 + coverage))
         Γ— local, district and city modifiers
m_Crime  = min(m_MaxCrimeAccumulation, m_Crime + increase / updatesPerDay)

and RequestPatrolIfNeeded returns immediately unless m_Crime has reached m_CrimeAccumulationTolerance; above it a patrol is requested, and an arriving police car subtracts PoliceCarData.m_CrimeReductionRate through PoliceCarAISystem/PoliceCarTickJob.TryReduceCrime.

So crime is a stock with an inflow and an outflow, and it rests where they balance. Coverage suppresses the inflow; the police fleet supplies the outflow. That gives three regimes, and only the middle one is the interesting case:

the fleet where crime rests what coverage does
services every request as it arrives just above the tolerance changes the patrol load only
services nothing at m_MaxCrimeAccumulation changes only how fast it gets there
partially loaded where inflow = service rate sets the resting level directly

In the interior regime more coverage means a lower equilibrium, because the same fleet is meeting a slower inflow. Reading the coverage factor as "how fast it climbs, not where it rests" is true only at the two saturated ends.

This city is at the zero-service end, and the reason is a broken station rather than anything about coverage. Crime is stored per building, so which regime a city is in can simply be read: 376 of its 486 buildings sit at exactly 25,000, the cap. Accumulation has stopped because nothing is removing crime β€” police coverage reads 0.000 on every road, including the one the station stands on, where healthcare and fire both read 5.00. The patrol cars never leave.

Two things follow. Building more police will not help while that reads zero, because the suppression term is 5/(5+coverage) and at zero coverage that is 1.000 however many stations you own. And because the penalty is already pinned at its maximum, the whole of it is recoverable in principle β€” so +11.4 happiness is the most any policing fix can return here. That is the ceiling on one of the two purchases this city has left; the park term below supplies the other, and the two are put together at the end of this section.

What a point of coverage is worth, by service

Two things decide what a service building is worth, and this is the first of them: how much happiness a single point of coverage buys. It is exact, and it differs by a factor of six between services. The second is how much of the city that building's coverage actually lands on, which is worked out next.

The build ranking below is the two multiplied together, which is why its figures are so much smaller than the ones here. A number in this table is what a point of coverage is worth to somebody who has it; a number in the ranking is what 100,000 spent on a particular building is worth to the city, after counting how few people a small building ever reaches. CitizenHappinessSystem reads NetUtils.GetServiceCoverage and converts:

service how wellbeing is computed from coverage this city's coverage now happiness from one more coverage point
Park min(1, √(cov/1.5)) Γ— 20 0.000 +8.16
Education √children Γ— 3.0 Γ— (cov βˆ’ 5) 9.992 +1.50
Mail Γ— 3.0 0.000 +1.50
Healthcare health Γ— 2.0 + wellbeing Γ— 0.8 4.999 +1.40

(every figure halved, because happiness is (wellbeing + health) / 2)

Park coverage stops paying at 1.5, which is the opposite of what you would guess. It is the largest single coverage term in the game β€” a full 10 happiness β€” and all of it is bought by the first 1.5 points. Past that a park returns nothing at all, at any price. So the service with the steepest return is also the one you stop building soonest, and a city sitting at zero coverage has the cheapest happiness in the game available to it.

Education works the other way round: it pays nothing until coverage passes 5, and it scales with the square root of the number of children, so it is worth nothing in a city of adults.

How far a building's coverage actually gets

The value per coverage point above is exact. What the build ranking below also needs is how many people ever see that coverage, and that is where a park and a clinic stop being comparable.

The game walks outward from the building along the road network. Each stretch of road it reaches gets

coverage = max(0, 1 βˆ’ costΒ²) Γ— the building's strength Γ— how well it is running

where cost runs from 0 at the door to 1 at the limit of its range, so coverage falls away as the square of the distance and stops entirely at the edge. The walk also has a budget β€” the building's capacity β€” and it spends that as it goes, nearest road first, stopping when it runs out.

Three numbers therefore describe a building: strength (how much coverage it writes), range (how far it can walk), and capacity (how much road it can afford to cover). All three are read from the game's own files.

Capacity is not measured in metres, and this is the part that makes it unintuitive. Every stretch of road costs its length Γ— √(people per metre on it), so a busy street costs more of the budget than an empty one. The game tracks people per metre on each road; the model reads it. Two consequences follow that a length-based reading would miss entirely:

Of the 39 coverage buildings this city has available, 28 run out of capacity first and 11 run out of range first, and the 28 are the parks and the small facilities.

Every park delivers the same happiness per person it reaches. Parks supply between 8 and 20 coverage against a term that stops paying at 1.5, so anywhere a park reaches at all it is far past saturation and pays the whole +10. The +8.16 in the table above is what the first coverage point buys, not what a park delivers. So the only thing separating one park from another is how many people it reaches:

park range capacity happiness where it reaches share of citizens reached
Tiny Park PocketPark01 500 200 +10 0.051
Campfire Site CampfireSite01 6,000 1,600 +10 0.250

A bigger park buys reach and not one point more happiness per person. Price rises faster than reach across the catalogue β€” 20Γ— the cost for 5Γ— the people β€” so the cheapest park wins on happiness per guilder every time, and you buy size only when you need a particular quarter of the city covered.

The whole walk is checked against the coverage the game itself recorded on each road. For the four service buildings this city owns it agrees to within 0.002 of the building's own strength on the pedestrian services and 0.01 on the vehicle ones. Parks are pedestrian, so the figures the ranking leans on are the accurate ones.

The three figures, put together

This is where the section's separate threads meet, and the answer falls out of them rather than needing anything new. Each was derived once, above:

what a 200,000 building must return to pay for itself +16.9 happiness
the most a policing fix can ever return here +11.4
the most park coverage can ever return here +10

Neither purchase clears the bar alone; together they clear it comfortably β€” and this city has done neither, so both are still available. That is the whole case for the recommendation in Β§9, and it is why the answer is "a park, then the police station", not "a large building".

What to build, ranked

Buy the service the city is short of, and nothing else. That sounds obvious until you see how much it disqualifies.

The rule underneath it is that coverage does not add up. When a building writes coverage onto a road that already has some, the game keeps the higher of the two rather than the sum:

what the road ends up with = max(what it already had, what this building supplies)

So a building is worth what it adds beyond what is already there β€” and once a service is covered, the next building of it is worth nothing at any price, however cheap it is.

That disqualifies most of the list. This city's healthcare coverage already reads 4.999 against a clinic that supplies 5, across its whole population β€” so a second clinic raises coverage by 0.001 and buys 0.0017 happiness per 100,000 spent. It owns no park at all, so a park delivers its entire term. This is the Beetham 7 city, the one the scenario solve below runs on:

building service happiness per 100,000 cost capacity range reach capacity-bound
Tiny Park PocketPark01 Park 34.17 1,500 200 500 0.051 yes
Urban Parkette PocketPark03 Park 29.28 2,500 400 1,000 0.073 yes
Campfire Site CampfireSite01 Park 8.35 30,000 1,600 6,000 0.250 yes
City Elementary School ElementarySchool03 Education 0.0075 150,000 15,000 3,500 0.985 no
Medical Clinic MedicalClinic01 Healthcare 0.0019 60,000 15,000 5,000 0.998 no

Two names, and you need both. The bold name is what the game shows you in the build menu; the small one is what the files call it, which is what the tools print and what you search the assets for. They are often not guessable from each other β€” the cheapest park in the game is filed as PocketPark01 and sold to you as a Tiny Park.

Reach is the column that makes the rest of the table comparable. It is the share of the city's citizens a building's coverage actually lands on, worked out just above. What it does here is stop a pocket park and a medical clinic being weighed against each other as though they served the same people: the park reaches 5% of this city and the clinic reaches 99.8%.

The first column is the other three multiplied, and the first row written out once says how: a park delivers the whole +10 park term to everyone it reaches (above), this one reaches 5.1% of the city, so one Tiny Park is worth 10 Γ— 0.051 = 0.51 happiness β€” and 0.51 on a cost of 1,500 is 34.17 per 100,000 spent. Every row is that same product: what the service term pays, times the share of citizens reached, over the price.

Two separate things limit that reach. Range is how far the coverage can travel from the building's door. Capacity is how much road it can afford to cover on the way, and road is charged by how busy it is β€” so a building can spend its whole capacity on a few crowded streets and stop well short of the edge of its range. Whichever limit it meets first is the one that decides what it is worth. A building that is capacity-bound has run out of road budget rather than distance, and giving it a longer range would not add a single citizen to what it covers.

The cheapest park still wins, and the reason is worth stating. A park's price and its reach rise together across the catalogue, so every row is discounted by roughly the same factor and the order comes out unchanged. What reach settles is the size of the prize rather than which building to buy β€” about 34 happiness per 100,000 spent, which is the figure the scenario solve weighs against zoning and policing.

Police and fire stations carry no value in this table at all. They do not feed wellbeing directly β€” they act by suppressing crime, which is priced and capped on its own terms above.

Building pays XP directly, which is a lever on the only binding constraint

Nothing else in this document buys the milestone without going through population. This does.

Every building carries a fixed XP reward β€” PlaceableObjectData.m_XPReward, which XPBuiltJob enqueues the moment it is placed β€” and every road pays PlaceableNetData.m_XPReward per 112 metres laid, through NetXPJob. Neither depends on who lives in the city. Only signature buildings carry the once-only marker; every ordinary building pays again on every copy you place.

Neither the price nor the reward is stored in a save; both are authored into the game's asset files, and all 336 buildings decode with none left unresolved. The spread across them is not subtle:

building cost XP XP per 100,000
bus stop, bicycle stop 50 10 20,000
small roundabout 200 10 5,000
the median of 272 priced buildings 300
hazardous waste processing site 6,360,000 5,000 79

Read that as a warning, not a plan. This city needs 3,548 XP to reach milestone 5, and at 10 XP a bus stop that is 355 bus stops for about 17,750 β€” against a credit ceiling of 700,000 and a position the rest of this document spends months of simulated time trying to survive. It is recorded because it is what the game does, and because a model that ranks strategies while not knowing the cheapest route to the only binding constraint is not really ranking anything.

Three things would decide whether it survives contact with the game, and none of them is established: whether a stop has to be connected to a road before the reward is paid, what a transport network costs to run (the thirteen buildings with authored upkeep are power, emergency and medical only), and whether anything limits how fast you can place them.

The usable form is the ordinary one: XP per unit of capital is computable with a 67Γ— spread, so "build something" is a ranked list, not one channel β€” and the ranking above sits beside the happiness ranking, not instead of it.

Placement XP is scored, and buying parks made it matter more

A package that spends capital is credited capital Γ· 100,000 Γ— that building's XP rate, in the month the capital is committed, because the game pays the reward the moment a building goes down. The rate is read for the same building the happiness rate came from β€” one purchase, both of what it pays β€” so the two cannot drift onto different buildings:

what the money buys the building happiness per 100,000 XP per 100,000
services Tiny Park PocketPark01 44.27 667
policing Small Police Station PoliceStation02 β€” (acts through crime) 300

The happiness figure is the Beetham 4 rate. The ranking above prices the same park at 34.17, which is the Beetham 7 snapshot, and the gap between the two is entirely reach β€” 6.6% of the earlier city against 5.1% of the later one. The XP rate is authored into the building and does not move.

A Tiny Park is an unusually good XP buy, and for an uninteresting reason. The reward is a flat 10 XP per placement whatever the building costs, so a 1,500 park returns 667 XP per 100,000 spent where a 60,000 clinic returns 250. That is the same degeneracy as the bus stop above, one step short of absurd: it is real, it is what the game does, and it rewards buying many cheap things rather than one expensive one.

Size it before believing it. Spending 190,000 on pocket parks earns about 1,270 XP against the 5,300 that milestone 5 costs over milestone 4 β€” roughly a quarter of one step, beside the 1,056 a month that happiness pays on its own. So it is a real term that shortens the wait by a few weeks, not the lever that decides anything. Where it shows up is in the ordering between packages that are otherwise close.

Road pays too, and it is the bigger half historically

Every road type carries its own XP reward β€” PlaceableNetData.m_XPReward, which NetXPJob pays per 112 metres laid:

XP = (m_XPReward + a bridge bonus) Γ— the road's length Γ· 112

The bridge bonus is added rather than multiplied, and it is exactly 1 or 0 β€” earned only where a road end sits above ground level, so a bridge collects it and a tunnel, being below, does not.

A road's length is not stored in the save; the game recomputes it every time it loads, walking the curve in sixteen equal steps and summing the straight lines between them. The model does the same thing, so this is not an approximation of the length β€” it is the game's own definition of it.

Finding this at all took reading the right place. A road's reward is not filed with the buildings; it sits on a separate record for networks, which is why searching the building list for roads turns up only a maintenance depot and two placeholders. Read from the right record, 226 road types decode, none unresolved, and 189 of them pay.

save population road metres XP road has paid city's total XP
Beetham 2 1,866 93,438 2,246 6,491
Beetham 4 3,187 98,253 2,297 10,052
Beetham 7 3,305 98,531 2,300 10,230

Road has paid 2,300 of this city's 10,230 XP β€” 22% of everything it has ever earned. Laying road is not a side effect of zoning; it is a fifth of this city's progress toward the only thing that raises its borrowing ceiling.

The mechanism and the habit are two different numbers

The XP a month of zoning earns is households zoned Γ— metres of road per household Γ— XP per metre. The last two are different kinds of quantity, and keeping them apart is the point β€” rolled into a single XP-per-household figure, an exact rule disappears inside a measurement that moves.

XP per metre is a rule. It is the road's own reward divided by 112, identical in every city that lays that road β€” and it is a decision, because road types differ by a factor of four:

road laid XP per metre
one-way highway, 3 lanes 0.0357
one-way highway, 2 lanes; medium seaway 0.0268
high-voltage line 0.0179
alley; narrow seaway 0.0089

Metres per household is this player's habit, and it is the term that moves. Across all 36 qualifying pairs it splits by which part of the city's life the window covers, and the split is a trend rather than scatter β€” eleven recent windows agree with each other tightly:

window metres per household XP per household
β‰₯ 0.4 months, spanning the build-out 5.6–6.7 0.059–0.072
0.13–0.18 months, recent only 2.9–3.8 0.026–0.034

The player laid ~5.9 metres of road per house while the arterial network went in and ~3.1 now that zoning infills along road that already exists. A pair spanning the early build-out over-credits future zoning by about 2Γ— β€” the same shape as absorption in Β§11, a coefficient measured on one part of a city's growth failing to describe the next, and the same remedy: calibrate on a recent pair. Windows under a tenth of a month are refused, because 31 of them read anywhere from zero upward.

This city is laying the cheapest road there is. Its recent rate runs at 0.0089 XP a metre, which is the alley tier. Laying a wider class over the same ground would pay up to four times the XP for the same metres β€” a real decision, and one a single blended figure could not have expressed. What the wider road costs to maintain is priced in Β§8's rails; what it earns is priced here.

It is charged on the capacity actually painted, so like the road bill beside it, it stops when the land bank does.

Building anything

Service upkeep is 97% of expenditure, and the income growth you need scales with the square root of D, so every building you add raises the bar you have to clear. Construction is the only thing here that adds a monthly cost without adding a citizen to pay for it, so it always shortens your deadline. The build rows at the end of this section show how far that goes at this city's margin: a 200,000 building costing 20,000 a month stalls the city in two months whether it is bought alone or alongside 150 households of zoning β€” that much zoning cannot outrun the upkeep plus the interest the capital forces. A purchase this size needs either a much larger city or the happiness return priced above, and this particular one delivers none.

Cutting service budgets

Exact on the money side β€” each point off every slider is 4,277/month here β€” and completely underived on the coverage side. The table below shows what it is worth: cutting 10% alone still stalls (month 9 instead of 6); cutting 10% and zoning 150 adds 1,264,890 of reserve over zoning alone. It is a real saving and not a substitute for zoning.

Each lever alone, so its direction and size are visible

The section's closing table: every lever at a fixed size, side by side, before Β§8 plays them together. The Beetham 4 city, straight from the loop.

move households zoned/mo tax points over 10% one-off build cost budget cut population money left milestone reached stalls in
hold β€” 0 0 0 3,388 0 mo 4 mo 6
zone 150 150 0 0 0 6,334 261,084 mo 3 β€”
zone 400 400 0 0 0 10,022 3,265,608 mo 2 β€”
tax +5 β€” 5 0 0 3,388 0 mo 4 mo 9
tax +5, zone 150 150 5 0 0 6,334 1,769,801 mo 3 β€”
cut budgets 10% β€” 0 0 10 3,388 0 mo 4 mo 9
cut 10%, zone 150 150 0 0 10 6,334 1,525,974 mo 3 β€”
build 200k/20k β€” 0 200,000 0 3,388 0 never mo 2
build + zone 150 150 0 200,000 0 3,809 0 never mo 2

What the columns show: only zoning changes whether the city survives. Tax and budget cuts move the stall by a few months and change nothing else on their own; beside zoning, tax +5 adds 1,508,717 of room and a 10% cut adds 1,264,890. And the build rows carry the sharpest warning in the table: a 200,000 building costing 20,000 a month stalls the city in two months whether or not 150 households of zoning stand beside it β€” at this margin, that pace cannot outrun the upkeep plus the interest the capital forces. Construction is the only lever here that adds a monthly cost without adding a citizen to pay for it.

A row that stalls is disqualified rather than ranked, and every stalled row is reported at the month it stalled rather than at the end of the horizon. That is not a presentation choice. The loop keeps stepping past a stall β€” happiness alone still earns XP, a later milestone lifts the ceiling, and the city draws against it again β€” so a figure read at the horizon is a snapshot of where the last month fell in a borrow-to-ceiling sawtooth. Read that way, the row that zones nothing reported more money left than the row that zones 60, purely because the milestone that rescued it landed later and the horizon caught it one month into a fresh ceiling instead of three.

8. Moves, and how they are scored

A move is the whole decision vector, not one lever.

"Policy" here always means the game's own Policy β€” the toggles and sliders under the Policies tab. Those are a separate lever class and this model does not price any of them, so every figure in Part II is "before Policies". The decision vector is called a move so the two are never confused. Β§12 says what scoring them would take, and why for this city it would mostly be a way of refusing one.

These are the levers a move can set:

lever what it does how solid the number is
borrowing adds to your cash and to what you owe exact, from the rate curve in Β§3
a purchase its price, paid once out of cash exact
its upkeep what that building then costs every month, for as long as it stands exact
a building programme that much more upkeep added every month, indefinitely exact
the XP it pays on placement earned the moment the building goes down exact, and different for every building
residential tax points above the 10% default exact on revenue, and on the happiness it costs per education tier; each point also takes 2 points off residential demand
a budget cut points taken off every service budget slider exact on money saved; what it costs in service coverage is not worked out anywhere
the happiness it buys what you assume the purchase delivers derived per building β€” see "what to build" below
zoning households of new housing capacity per month costs road, and road is charged twice β€” its construction out of cash the month the land is painted, its upkeep every month after

What a move is judged on: money left

One number ranks every move below β€” what the city has left to spend once the run is over:

money left = cash in hand + credit ceiling βˆ’ what you owe

It is not a bank balance, and the difference matters. Two of those three terms are borrowing: the ceiling is the most the game will let you owe, and taking off what you already owe leaves the credit you have not touched yet. A city reporting 1.5M might hold 300,000 in cash and 1.2M of unused credit behind it β€” and the moment you spend that second part, you start paying interest on it.

It is measured this way because the thing worth knowing about a city is whether it can still act. A city with no cash but plenty of credit can buy the park it needs; a city with neither can do nothing at all, which is the stall Β§6 describes. Money left is how far the city is from that, and it is the same quantity Β§6 counts in months β€” cash and unused credit, divided by how fast they are draining.

The number comes out of a played-forward run, not a formula. Each row is stepped a month at a time and the three figures are read off the last month, so the answer carries whatever error the run carries β€” and Β§11 puts that at tens of per cent on population. Compare the rows against one another; do not lean on the absolute figures.

A run that stalls reports zero. By then the city has drawn its ceiling in full and spent its cash, so there is nothing left on either side of the sum.

Every move is run through the whole feedback loop

There are two ways to score a move. Β§6's formulas hold the deficit still and ask how long you last. The other way runs the whole loop: demand produces arrivals, housing caps how many actually come, those people earn income, income and services move happiness, happiness earns XP, XP reaches a milestone, the milestone raises the ceiling, and the whole balance is re-priced at a new rate. The difference is not a shading. A frozen deficit cannot see zoning at all β€” it prices the hole as it stands, so a city that zones and a city that sits still score identically β€” and the loop gives those two moves opposite verdicts:

move scored by Β§6's formulas scored by the full loop
hold, zone nothing 3.8 months stalls at month 6
zone 150 the same 3.8 months β€” zoning is invisible to a frozen deficit never stalls, 261,084 left

So take Β§6's formulas as a bound on a position, never as the verdict on a move. Everything below is scored by the full loop.

There is only one test, and it is not a horizon

The city runs a deficit against a ceiling that only a milestone raises, so the question is never "where am I in three months". It is does the next milestone land before the borrowing room runs out β€” and then the one after that.

A run that stalls is disqualified whatever population it reports, because a stalled city cannot pay its bills and the simulation stops conserving money from that point on. A stall is one of those rounds lost: either the run never reached a milestone at all, or it reached one and ran out before the next β€” the zone-nothing row steps in month 4 and stalls in month 6. They are the same failure, and neither is redeemed by the population the row reports.

So every row below carries two dates β€” when it first stepped, and whether it ever stalled.

The rails every scenario runs inside

Every solved run below β€” the matrix, the plays, a package of your own through play β€” moves inside limits that are read, not assumed. They are quoted here once, off the Beetham 7 snapshot.

Every bound comes from the save, which took several passes to make true and is the difference between a solved answer and the edge of a typed range:

Borrowing is capped at Creditworthiness.m_Amount minus what is already drawn β€” 470,000 of room here. A ladder that offered more was offering a position the game refuses.

Zoning has two separate bounds and they answer different questions. How much can ever be painted is the land: a Block carries an m_Size cell grid, a ValidArea marks the usable rectangle, and a cell is paintable when it is inside that rectangle, carries no zone, and is neither Blocked nor Occupied β€” (m_State & 33) == 0, the mask UpdateLotSizeJob uses. That is 2,794 paintable cells of 13,076 valid. Converting at the city's own households per cell β€” 1.50 for medium against 0.08 for low, a 20Γ— spread β€” the land bank is 4,203 households at best density and 216 at worst.

The cell index is z * m_Size.x + x, row-major, read from CellBlockJobs/BlockCellsJob.CleanBlockedCells. Column-major counts 1,945 free cells instead of 2,794 and looks just as plausible, so this is one to read rather than assume.

That bank is the capacity of the tiles you have BOUGHT, not of the map, and the difference matters because it turns a wall into a purchase. MilestoneData.m_MapTiles grants a map-tile allowance at every milestone β€” 3, 4, 5, 6 through the first four, so 18 tiles granted by milestone 4 β€” on top of kAutoUnlockedTiles, which is 9. A city that has bought none of them is zoning inside its starting tiles, and the 4,203 households above is what those hold.

So a run that ends against the land bank is being told to buy land, not that the map is full. And since a tile costs cash, that bound is the same money bound as everything else in this document rather than a separate geographic one.

Two things about tiles are read and worth keeping straight. MapTileUpkeep is exactly zero while the owned count is at or below the 9 auto-unlocked β€” GetMapTileUpkeepCostMultiplier returns 0 on that branch before it ever reaches the curve β€” so a ledger showing no tile upkeep is correct rather than incomplete. Past 9 the multiplier comes off EconomyParameterData.m_MapTileUpkeepCostMultiplier, an authored curve in the tile count, so held land is a standing cost that grows with how much you hold.

What a tile costs is not transcribed. MapTilePurchaseSystem builds it from kMapTileSizeModifier, kResourceModifier and a per-map-feature baseline. Until that is read, this document can say the allowance exists and cannot say whether it is affordable β€” which, for a city with no cash, is the whole question.

How fast is the player's own measured pace, and this is the bound the zoning ladder's top is set from: capacity at two frames over elapsed simulation time, across all 36 windows long enough to measure, runs 1,414 to 1,591 households a month β€” tight, because it is one player's habit rather than a game rule. Windows under a tenth of a month are refused rather than extrapolated, and the reason is visible in what they return: the 35 short ones run 1,913 to 33,113. This is the one bound here that is measured rather than derived, because the real constraint is road capital and the player's own hands, and neither is in the file.

Which pair you hand the solver therefore moves the top of the ladder. Beetham 7 against Beetham 3 is a 0.174-month window and reads 1,591; Beetham 4 against Beetham 2 is 0.573 months and reads 1,430. Both qualify, and the shorter window reads high β€” so a ladder top is a measurement with a window attached, not a property of the city.

The land bank is what actually decides the population figures above. At 1,590 a month the map is painted out in under three months, so those numbers are what the land supports, not what demand would buy.

Happiness a purchase may claim is capped at what the city has left to recover, and each kind of spending is capped by the part it can recover: services by the coverage the city is short of, policing by the crime penalty. Adding the two together would let a services package promise happiness only a police station can deliver. On Beetham 7 that is +17.0 from services and +10.1 from policing. The policing figure is simply the crime penalty the city happens to be carrying, so it moves between snapshots β€” on Beetham 4 it is +11.4, which is the number Β§7 works against β€” while the coverage side barely shifts.

Road is charged, at 2.91 per household of new zoning per month. NetUtils.GetUpkeepCost bills per 8-metre cell, and eight metres is the zone cell size, so one road cell serves the zoning on both of its sides β€” which is what makes road-per-household a ratio rather than a layout question. The rate is measured: CollectedCityServiceUpkeepData accounts for every service building exactly, so the ledger's remainder is road. It is 1.4% of upkeep and does not change the ranking, which is worth knowing rather than assuming.

The matrix: one position, the decisions branched

The question the matrix answers: what does each decision cost, holding everything else still? A scenario is a complete tactic β€” this position, the whole twelve months, all the standing moves β€” and two scenarios differ on exactly one branch, so the gap between their money-left figures is the price of that one choice.

The moves that are simply right are not branches β€” you zone where demand is and where the bars are open, and every scenario here does. What a player actually weighs is branched:

The pace rows at the bottom vary the one thing the rest hold constant, to show what the held constant is worth. Every cell is the full loop β€” arrivals, income, coverage, road capital, XP, milestones, re-priced interest β€” and the whole table regenerates with python state/scenario_matrix.py <save.cok> <older.cok>.

The β‡’ column is the divider: everything left of it is input β€” how long the run is played (months) and the branches you choose β€” and everything right of it is output, read off the solved run. ms 5 and ms 6 are the months those milestones land; crossing is the first month income exceeds spending β€” the end of the deficit phase; income and upkeep are the final month's ledger; money left is cash plus undrawn ceiling at the end, the judging number defined at the top of this section. The city starts at happiness 48. These outputs are a summary β€” the loop records some twenty quantities every month for every row, population to demand to interest, and any row's full ledger is one play command away.

# what the move is β‡’ ms 5 ms 6 crossing population happiness income upkeep road capital money left
tax
1 zone 300, nothing built, residential -2 β‡’ mo 2 mo 6 mo 8 9,281 48.1 747,074 615,283 31,931 2,208,960
2 zone 300, nothing built, residential +0 β‡’ mo 2 mo 7 mo 7 9,281 46.4 787,139 615,283 31,931 1,901,482
3 zone 300, nothing built, residential +5 β‡’ mo 2 mo 7 mo 3 9,281 42.1 887,585 615,283 31,931 2,954,734
build
4 zone 300, park, from the flow, month 5, residential +0 β‡’ mo 2 mo 7 mo 7 9,281 47.0 789,733 615,433 31,931 2,703,350
5 zone 300, park, from the flow, month 5, residential +5 β‡’ mo 2 mo 7 mo 3 9,281 42.7 890,123 615,433 31,931 2,969,481
6 zone 300, park, borrowed month 1, residential +0 β‡’ mo 2 mo 7 mo 7 9,281 46.9 789,556 615,433 31,931 2,711,317
7 zone 300, park, borrowed month 1, residential +5 β‡’ mo 2 mo 7 mo 3 9,281 42.6 889,949 615,433 31,931 2,972,040
8 zone 300, park+police, from the flow, month 5, residential +0 β‡’ mo 2 mo 6 mo 6 9,281 58.3 840,875 625,433 31,931 2,855,539
9 zone 300, park+police, from the flow, month 5, residential +5 β‡’ mo 2 mo 6 mo 3 9,281 54.0 940,186 625,433 31,931 3,723,412
10 zone 300, park+police, borrowed month 1, residential +0 β‡’ mo 2 mo 6 mo 6 9,281 58.3 840,688 625,433 31,931 2,865,881
11 zone 300, park+police, borrowed month 1, residential +5 β‡’ mo 2 mo 6 mo 3 9,281 54.0 940,003 625,433 31,931 3,822,258
12 zone 300, school, from the flow, month 5, residential +0 β‡’ mo 2 mo 6 mo 7 9,281 46.6 788,029 630,283 31,931 2,336,146
13 zone 300, school, from the flow, month 5, residential +5 β‡’ mo 2 mo 7 mo 3 9,281 42.3 888,456 630,283 31,931 2,671,361
14 zone 300, school, borrowed month 1, residential +0 β‡’ mo 2 mo 6 mo 10 9,281 46.4 787,182 630,283 31,931 1,766,590
15 zone 300, school, borrowed month 1, residential +5 β‡’ mo 2 mo 7 mo 5 9,281 42.1 887,628 630,283 31,931 2,389,830
pace
16 zone 150, park, residential +5 β‡’ mo 3 mo 9 mo 7 6,334 43.5 631,902 528,317 15,965 1,780,859
17 zone 600, park, residential +5 β‡’ mo 2 mo 5 mo 2 9,910 42.4 944,286 634,384 36,134 4,148,950
18 zone 1590, park, residential +5 β‡’ mo 1 mo 4 mo 1 8,462 42.3 816,356 594,974 36,134 3,912,149
company tax
19 zone 300, park, residential +5, commercial +5 β‡’ mo 2 mo 7 mo 3 9,281 42.7 926,794 615,433 31,931 3,291,125
20 zone 300, park, residential +5, industrial +5 β‡’ mo 2 mo 7 mo 2 9,281 42.7 903,046 615,433 31,931 3,288,207
21 zone 300, park, residential +5, office +5 β‡’ mo 2 mo 7 mo 3 9,281 42.7 891,740 615,433 31,931 2,981,678
budget
22 zone 300, park, residential +5, every budget cut 10% β‡’ mo 2 mo 7 mo 2 9,281 42.7 890,123 572,668 31,931 3,429,286
policy
23 zone 300, park, residential +5, Paid Outside Services ON β‡’ β€” β€” β€” (STALLS mo 1) 3,725 43.7 400,620 451,369 31,931 0
land
24 zone 300, park, residential +5, buy 1 tile (price STATED 120,000) β‡’ mo 2 mo 7 mo 4 9,281 42.7 890,123 615,433 31,931 2,759,421
density
25 zone 300 LOW only, park, residential +5 β‡’ mo 2 mo 7 mo 3 9,449 42.7 905,013 620,016 31,931 3,077,932
26 zone 300 MEDIUM only (bar shut), park, residential +5 β‡’ mo 3 mo 7 mo 4 8,944 42.7 860,342 606,268 31,931 2,661,298
27 zone 300 split evenly, park, residential +5 β‡’ mo 2 mo 7 mo 3 9,281 42.7 890,123 615,433 31,931 2,969,481
borrowing
28 zone 300, nothing built, no borrowing β‡’ mo 2 mo 7 mo 7 9,281 46.4 787,139 615,283 31,931 1,901,482
29 zone 300, nothing built, draw 20,000 a month β‡’ mo 2 mo 7 mo 7 9,281 46.4 787,139 615,283 31,931 1,830,771
30 zone 300, nothing built, draw 40,000 a month β‡’ mo 2 mo 7 mo 7 9,281 46.4 787,139 615,283 31,931 1,734,687
31 zone 300, nothing built, draw 150,000 in month 1 β‡’ mo 2 mo 7 mo 7 9,281 46.4 787,139 615,283 31,931 1,837,247

Row 9 read longhand, so one verdict is fully unpacked: zone 300 a month; raise residential tax five points in month 1; in month 5, out of the month's own money, place a Tiny Park and a Small Police Station. Milestone 5 lands in month 2, income crosses upkeep in month 3, milestone 6 lands in month 6, and the year ends at 9,281 people, happiness 54.0, income 940,186 against 625,433 of upkeep, and 3,723,412 of room. Change exactly one thing β€” skip the police station β€” and you are reading row 5: happiness falls to 42.7, milestone 6 slips to month 7, and the year ends 753,931 poorer. That difference is what the police station is worth here. Every comparison below works the same way.

No scenario stalls β€” zoning 150-plus with any of these builds clears Β§7's floor of 131. Read the branches by their row pairs:

The tax branch is the biggest single number in the matrix, and it is not monotone β€” compare 1 / 2 / 3, or any build's 0-tax row against its +5 twin. +5 against hold pulls the crossing from month 7 to month 3 and is worth 1,053,252 with nothing built (2↔3), 867,873 behind a park and police station (8↔9) and 335,215 behind a school (12↔13). The charge is real β€” 4.3 happiness at this education mix, which is why the +5 rows sit at the bottom of the happiness column. Two consequences follow that a revenue-only reading misses. The βˆ’2 cut beats holding by 307,478 (1↔2) even though it pushes the crossing out to month 8: the 1.7 happiness it buys tips milestone 6 from month 7 into month 6, and the earlier ceiling, reward and cheaper rate outearn both the lost revenue and the later crossing. And where a build already delivers happiness the tax's cost eats into it β€” +5 on top of the park is worth only 266,131 (4↔5), against 1,053,252 with nothing built. The rate is a milestone-clock lever as much as a revenue one.

The build branch pays through three different mechanisms, and the happiness column is the tell β€” hold tax and financing still and walk 2 β†’ 4 β†’ 8 β†’ 12.

The park adds 801,868 and 0.6 happiness (2 β†’ 4) for 1,500 of capital β€” much the best return per guilder on the board, and small in absolute terms for a reason worth being precise about. Entertainment is a ten-happiness term and this city has none of it, so the citizens a park reaches get the whole term. A Tiny Park reaches 6.6% of them, so the city gains 0.066 Γ— 10 = 0.66. What makes it the best buy is the denominator, not the numerator: 1,500 against the police station's 125,000.

The police station adds 152,189 and 11.3 happiness (4 β†’ 8) by recovering the pinned crime penalty Β§7 bounds. It is much the biggest happiness block on the board and a smaller money gain than the park's, which is the point of reading both columns: happiness bought after the milestone it would have pulled forward has already landed is worth less than it looks.

The school adds 434,664 and 0.2 happiness (2 β†’ 12), and the mechanism is worth stating because it is not a failure of the school. Coverage takes the max over producers, not the sum β€” a citizen gets the best cover any building puts on them. This city's covered citizens already see 9.99 education from the school it owns; a second Elementary School authors magnitude 10, beats that by 0.008, and therefore adds essentially nothing anyone can feel. Its gain is the construction XP XPBuiltJob pays the moment it is placed, which pulls milestone 6 from month 7 to month 6. Treat that number as what it is: a milestone-clock effect, real at this position, not a rule that schools print money.

Whether to borrow-and-buy-now depends on whether the purchase pays monthly β€” the flow↔borrow pairs. The school, which returns nothing per month, loses 569,556 bought early on credit at hold-tax (12↔14) and 281,531 at +5 (13↔15): its capital, upkeep and interest arrive four months before the surplus that carries them, and nothing arrives with them. The park and the police station both win bought early β€” the park by 7,967 at hold (4↔6), the station by 10,342 at hold (8↔10) and 98,846 at +5 (9↔11) β€” because four extra months of the happiness they deliver outearn the early interest. Note the sizes: where the purchase is cheap the financing question is nearly free, and where it is expensive and idle it is the largest single mistake in the matrix. The rule the pairs spell out: borrow early for a building that pays every month; wait for the flow for one that only pays once.

Faster is not better past a point β€” rows 5 / 16 / 17 / 18, the pace sweep. 600 a month is the best tested: 4,148,950 and milestone 6 in month 5. This player's own 1,590 pace ends 236,801 lower and 1,448 people smaller (8,462 against 9,910) despite reaching milestone 6 a month earlier, because the land bank is painted out by month 3 and capacity painted ahead of demand bills its road, spends its construction capital and thins coverage while housing nobody. Halving to 150 (row 16) costs 2,368,091 against 600: too slow starves the XP engine instead.

Growth charges happiness, taxation charges it again, and only the crime penalty is a big enough block to pay both back. The city starts at 48.0. A year of zoning thins the standing services β€” the play tables below show education and healthcare falling month by month as new road arrives uncovered β€” and five tax points cost 4.3 more. Thirteen of the eighteen rows therefore end below where they started, between 42.1 and 47.0. The four police rows end at 58.3 and 54.0, and the βˆ’2 cut with nothing built ends at 48.1; those five are the whole of the board that finishes ahead. The build column is not a one-off decision; it is a programme that has to keep pace with the zoning column, which is why Β§9's last rule is written the way it is.

One play, opened month by month β€” the ledger

The matrix compresses each move to a single line of outputs. This opens one of them and shows both sides of the money: what came in, by channel, and what it went on, by channel. Same solver, same run β€” a matrix row and this ledger are two views of one trajectory.

The play is packages/play_steady.json β€” zone 300 a month where the bars are open, residential tax +5, a Tiny Park. Every package in packages/ runs the same way, and a package of your own runs the same way too:

python state/cs2.py "$SAVES/Beetham 4.cok" "$SAVES/Beetham 2.cok" play packages/play_steady.json

Read it as a ledger, and it reconciles in both directions. The three IN columns sum to income. The four OUT columns plus interest sum to what left. net is the difference. Capital sits apart from upkeep, because it is paid once out of cash rather than every month β€” which is exactly the distinction road spending needed, and exactly what a single upkeep column could not show. The start row is the save itself.

mo IN wage IN company IN tax income OUT services OUT growth OUT road OUT built OUT interest out CAP road CAP built net cash loan money left
start 151,187 158,193 β€” 309,380 435,560 β€” β€” β€” β€” 435,560 β€” β€” β€” -39 180,000 519,961
1 169,512 176,108 56,200 401,822 435,560 14,654 1,153 150 11,931 463,450 2,660 1,500 -61,628 0 245,828 454,171
2 186,703 197,904 61,900 446,508 435,560 28,402 2,307 150 4,805 471,226 2,660 0 -24,717 0 148,207 951,792
3 203,894 219,629 67,599 491,123 435,560 42,149 3,461 150 6,558 487,880 2,660 0 3,243 582 148,207 952,375
4 221,086 241,286 73,299 535,672 435,560 55,897 4,614 150 6,558 502,781 2,660 0 32,890 30,812 148,207 982,604
5 238,277 262,879 78,998 580,155 435,560 69,645 5,768 150 6,558 517,683 2,660 0 62,472 90,623 148,207 1,042,416
6 255,468 284,411 84,698 624,577 435,560 83,392 6,922 150 6,558 532,584 2,660 0 91,993 179,956 148,207 1,131,749
7 272,659 305,883 90,398 668,940 435,560 97,140 8,075 150 0 540,927 2,660 0 128,013 305,308 0 1,905,308
8 289,850 327,298 96,097 713,246 435,560 110,887 9,229 150 0 555,828 2,660 0 157,418 460,066 0 2,060,066
9 307,041 348,659 101,797 757,498 435,560 124,635 10,383 150 0 570,729 2,660 0 186,768 644,174 0 2,244,174
10 324,232 369,969 107,496 801,698 435,560 138,383 11,537 150 0 585,631 2,660 0 216,067 857,580 0 2,457,580
11 341,423 391,228 113,196 845,848 435,560 152,130 12,690 150 0 600,532 2,660 0 245,315 1,100,235 0 2,700,235
12 358,614 412,439 118,895 889,949 435,560 165,878 13,844 150 0 615,433 2,660 0 274,516 1,372,090 0 2,972,090

The growth charge is the largest thing this city spends money on, and it is not a building. By month 12 the services the arrivals need cost 165,878 a month β€” more than ten times the road they arrive on and sixty times the road's construction. It is measured rather than derived (Β§10), it scales with every citizen admitted, and no purchase decision touches it. A reader looking for where a growing city's money goes should look there first and at the build column second.

Road is charged twice and both charges are small. 13,844 a month of upkeep by month 12, and 2,660 a month of construction β€” the capital being 300 households at 8.87 apiece. Both are real, both were missing from this model until recently, and neither changes a decision at this scale. What they do is stop zoning from being free, which matters for the shape of the model even where it does not move the answer.

The deficit is two months long and self-funding. Months 1 and 2 run negative and the balance draws automatically β€” the loan rises 180,000 β†’ 245,828 and no further. Milestone 5 lands in month 2 and pays it down; income crosses upkeep in month 3; milestone 6 lands in month 7 and its reward clears the debt outright. Interest is 11,931 in month 1 and zero from month 7.

Income triples while upkeep grows by 41%, which is the whole engine: wage income 151,187 β†’ 358,614, company tax 158,193 β†’ 412,439, and the tax move adding 56,200 in month 1 rising to 118,895 by month 12 as the base it is charged on grows. That last column is why Β§7 insists a tax point is not a constant.

Branching every month, because holding from month 1 is not playing

Every row of the matrix above sets its levers in the first month and holds them for twelve. That makes the rows comparable to each other, and it is not what playing is: playing is reacting β€” buying the police station once crime bites, zoning harder once the money is there, stopping when the land runs out. A row has one bundle of levers and no notion of when each was pulled.

So the tree below pulls them at different times. Each month offers every move the save allows, and that vocabulary is derived rather than listed: the draws come from Creditworthiness, the zoning rates from the paintable land, the buildings from the ranked service value, the tax points from the range the game accepts. Each path is then played to the same horizon and judged on the same number. python state/cs2.py <save> <older> playouts --write.

Deriving it is not tidiness. The first version of this table used a hand-written list of nine moves; it contained no company-tax move, no budget cut, no policy, no density choice and a single borrow amount, and the search reported the best of what it had been handed as though it were the best on the board. A typed list of options fails the same way a typed table does, and more quietly, because nothing errors when an option is merely absent.

One class of move is still typed, and it is the one Β§7 has just made interesting. The company-tax points offered are rises β€” +5 and +10 on each of the three channels β€” so a rate cut, which Β§7 shows is the only thing that empties this city's spare factory lots, is not among the options ranked below. Read the table as the best of what was offered.

the search
moves offered each month 35
months branched 3
paths the tree could hold 42,875
pruned: the move would do nothing 2,829
pruned: the compiler would not price it 3,367
playouts actually run 35,217
of those, stalled and disqualified 11,598
left to rank 23,619

A branch is dropped only for a reason the table names. A move that would do nothing on the state it arrives at is not scored β€” a second building of a service the city already covers returns nothing a citizen can feel (Β§7), a tax move to the rate already set is not a move, a draw the ceiling no longer allows after the draws before it is not available, and zoning above the land still unpainted is the same branch as painting the remainder. A playout that stalls is disqualified rather than ranked, for the reason given at the top of this section.

The 3,367 the compiler would not price are all one move, and they are worth naming because they mark a disagreement rather than a bug. The rate ladder is sampled from TaxParameters, whose every limit pair is int2(-10, 30), so it offers the residential rate all the way down to βˆ’10% β€” a subsidy. package.py refuses anything below 0%. One of those two bounds is wrong and this document does not yet know which: the assets say the total may go to βˆ’10, and nothing here has read the interface that would confirm a player can set it there.

The menu still comes from the opening position, and that is the honest boundary of this table. The moves are derived once, from the save the run starts at, and the arithmetic above narrows them down a path β€” but nothing re-reads the game three months in, because three months in does not exist yet. Everything past month 1 is this model's forecast of itself, and Β§11 puts that forecast between βˆ’30% and +98%. So read the first move or two as advice and the rest as the reasoning behind it, and re-run this from the next save rather than playing the whole sequence off the page.

# the months, in order population happiness ms 5 ms 6 money left
1 zone 1020 β†’ cut budgets 20% β†’ industrial +20 9,674 46.0 mo 2 mo 4 8,647,140
2 zone 1020 β†’ build PoliceStation02 β†’ industrial +20 9,674 57.3 mo 2 mo 3 8,556,482
3 zone 1020 β†’ cut budgets 10% β†’ industrial +20 9,674 46.0 mo 2 mo 4 8,176,717
4 cut budgets 20% β†’ zone 1020 β†’ industrial +20 10,078 46.0 mo 2 mo 4 8,064,010
5 zone 1020 β†’ buy a tile β†’ industrial +20 10,896 45.7 mo 2 mo 4 7,997,031
6 zone 760 β†’ cut budgets 20% β†’ industrial +20 9,820 46.0 mo 2 mo 4 7,987,598
7 build PoliceStation02 β†’ zone 1020 β†’ industrial +20 10,078 57.3 mo 2 mo 4 7,908,382
8 zone 760 β†’ build PoliceStation02 β†’ industrial +20 9,820 57.4 mo 2 mo 4 7,832,968
9 zone 1020 β†’ borrow 210,000 β†’ industrial +20 9,674 46.0 mo 2 mo 4 7,788,003
10 zone 1020 β†’ borrow 100,000 β†’ industrial +20 9,674 46.0 mo 2 mo 4 7,769,844
11 zone 1020 β†’ build PocketPark01 β†’ industrial +20 9,674 46.5 mo 2 mo 4 7,752,258
12 zone 1020 β†’ office +20 β†’ industrial +20 9,674 46.0 mo 2 mo 4 7,710,933

The best sequence roughly doubles the best held stance. The matrix's strongest row finishes at 1,901,482 for zoning alone and 4,148,950 at its very best (row 17, the 600-a-month pace); the sequence at the top of this table finishes at 8,647,140. Two different things are doing that work and they are worth separating, because only one of them is about order.

Read the last column of the move list first, though. Every one of the twelve ends on industrial +20 β€” the top of the legal range, a 30% rate β€” and that is the model telling you something specific rather than the model liking tax. By month 4 the land bank is painted out and the production base stops growing, so after that point the demand a rate rise suppresses is growth the city was not going to get anyway, and the rise is close to free revenue. The unpriced half lands hardest exactly here. A firm's chance of leaving is (its rate βˆ’ 10) Γ— 5 / 2 percent per check and at 30% that is its maximum; Β§7 says every company-tax gain in this document is an upper bound, and at the top of the range that bound is at its loosest. Read these twelve as the shape of the answer β€” paint first, clamp the rate last β€” rather than as an instruction to set 30%.

The first is combination. The matrix varies one lever at a time against a fixed base, so no row on it zones at pace and cuts the budgets and moves a company rate. The tree does, because every month is free to pull a different lever. Nothing about that requires branching in principle β€” it is a wider grid β€” but the grid that would cover it is the one this table replaces.

The second is order, and that one is branching's alone. Below are the same three moves β€” the identical multiset β€” in every sequence they admit:

the same moves, in this order ms 6 money left cost of the ordering
zone 1020 β†’ cut budgets 20% β†’ industrial +20 mo 4 8,647,140 β€”
cut budgets 20% β†’ zone 1020 β†’ industrial +20 mo 4 8,064,010 583,130
zone 1020 β†’ industrial +20 β†’ cut budgets 20% mo 4 7,531,538 1,115,602
cut budgets 20% β†’ industrial +20 β†’ zone 1020 mo 5 6,829,188 1,817,952
industrial +20 β†’ zone 1020 β†’ cut budgets 20% mo 4 6,546,585 2,100,555
industrial +20 β†’ cut budgets 20% β†’ zone 1020 mo 5 6,480,411 2,166,729

Nothing separates the top row from the bottom but when each move was made, and the bottom is 2,166,729 behind β€” more than everything zoning alone earns in the matrix. Paint first, then cut the budgets, and clamp the company rate last. The reason is the one Β§7 spends the industrial section on: a company rate is charged on production, production comes from firms, and raising the rate suppresses the company demand that spawns them. Raise it in month 1 and you throttle the base for the whole year while the city is still growing; raise it in month 3, after the land is painted and the base has stopped growing anyway, and you keep the revenue and give up almost nothing. Moving it from last to first costs 2,100,555 of the 2,166,729.

The budget cut sits in the middle for a smaller and simpler reason: it is a step, taken once, and every month it stands earlier is a month of saved upkeep β€” but it saves a percentage of upkeep, and upkeep is larger once the arrivals the painting brought are being served. Cutting before painting is worth 583,130 less than cutting after it.

A set-and-hold row can price none of this, because in a set-and-hold row every lever is pulled in month 1 by construction β€” the ordering question cannot be asked, let alone answered.

And the winner opened out, on the same ledger the held play uses above, so the two can be read against each other month by month:

mo IN wage IN company IN tax income OUT services OUT growth OUT road OUT built OUT interest out CAP road CAP built net cash loan money left
start 151,187 158,193 β€” 309,380 435,560 β€” β€” β€” β€” 435,560 β€” β€” β€” -39 180,000 519,961
1 197,018 219,508 0 416,527 435,560 36,650 3,922 0 11,931 488,065 9,047 0 -71,538 0 260,624 439,375
2 255,468 295,961 0 551,429 350,029 83,392 7,845 0 5,722 446,989 9,047 0 104,439 95,392 135,624 1,059,767
3 313,918 316,853 449,599 1,080,370 350,029 130,134 11,767 0 5,722 497,654 9,047 0 582,716 669,061 135,624 1,633,436
4 372,011 337,537 478,949 1,188,498 350,029 176,591 15,666 0 0 542,287 8,992 0 646,211 1,306,280 0 2,906,280
5 372,011 336,048 476,835 1,184,895 350,029 176,591 15,666 0 0 542,287 0 0 642,607 1,948,888 0 3,548,888
6 372,011 336,048 476,835 1,184,895 350,029 176,591 15,666 0 0 542,287 0 0 642,607 2,591,495 0 4,191,495
7 372,011 336,048 476,835 1,184,895 350,029 176,591 15,666 0 0 542,287 0 0 642,607 3,234,103 0 4,834,103
8 372,011 336,048 476,835 1,184,895 350,029 176,591 15,666 0 0 542,287 0 0 642,607 3,876,710 0 5,476,710
9 372,011 336,048 476,835 1,184,895 350,029 176,591 15,666 0 0 542,287 0 0 642,607 4,519,318 0 6,119,318
10 372,011 336,048 476,835 1,184,895 350,029 176,591 15,666 0 0 542,287 0 0 642,607 5,161,925 0 6,761,925
11 372,011 336,048 476,835 1,184,895 350,029 176,591 15,666 0 0 542,287 0 0 642,607 5,804,533 0 7,404,533
12 372,011 336,048 476,835 1,184,895 350,029 176,591 15,666 0 0 542,287 0 0 642,607 6,447,140 0 8,647,140

Read the last eight rows. From month 5 the ledger stops moving β€” income pinned at 1,184,895, the growth charge at 176,591, road capital at zero. Nothing is being painted, because at this pace the land bank is gone in four months (Β§8, the rails). The winning play is not "grow fast for a year"; it is paint everything you own as quickly as the money allows, then live off it. That is the land constraint of Β§8 restated by a search that was never told about it, and it is the strongest evidence in this document that the constraint is real.

The honest limits. The tree is three months deep, so this searches openings, not whole games β€” the held tail is the same for every path and no move after month 3 is being chosen. Its moves are single levers, so a month that both builds and raises a rate is not reachable. And the ranked buildings collapse to one per service, because coverage takes the max over producers and a second park would be nineteen no-ops in every month of the tree.

9. The standing order

What Β§8's matrix resolves into, one rule per branch. Each rule names the rows that earned it; nothing here is argued that a row has not already shown.

  1. Zone first, at a pace the land and the demand can absorb, where the bars are open. Below Β§7's floor of 131 a month the city stalls whatever else it does; the matrix's pace sweep (rows 5, 16–18) puts the best tested pace at 600 β€” half speed costs 2,368,091 by starving the XP engine, and full speed costs 236,801 and 1,448 people too, painting land whose road bill, construction capital and thinning arrive before its people do. Capacity in a shut bar is the same mistake in miniature: the same 300 into medium instead of low costs 505 people and 416,634 (Β§8's lever table), because ZoneSpawnSystem spawns nothing for a sector whose bar is zero.
  2. The residential rate is the big tax lever here, and the company rates are second-order. Five residential points are worth 1,053,252 with nothing built and pull the crossing from month 7 to month 3 (rows 2↔3), at a cost of 4.3 happiness. Against the same base, five industrial points are worth 318,726 and five commercial 321,644 (rows 5↔20, 5↔19). They cost no happiness β€” only the residential rate reaches citizens (Β§7) β€” but they are not free either: a company rate is charged on production, and raising it suppresses the company demand that spawns the firms producing it. Industrial is 71% of this city's production base and five points takes 53% off its company demand, so the arrivals' production income comes in at 62% of what it otherwise would. Five office points are worth 12,197 (5↔21), which is the sector's size, not its rate.
  3. Buy the service the city has none of, and stop when it is covered. Coverage takes the max over producers, not the sum, so a second building of a covered service returns nothing a citizen can feel. This city's covered citizens see 9.99 education and no entertainment at all, and the matrix reads exactly that way: a second school earns 434,664 almost entirely through construction XP and moves happiness 0.2 (rows 2↔12), while the first Tiny Park earns 801,868 for 1,500 (rows 2↔4). The uncovered terms here are the park β€” a ten-happiness term delivered whole to everyone it reaches β€” and the crime penalty (+11.3, rows 4↔8).
  4. Borrow early for a building that pays every month; wait for the flow for one that only pays once. A draw re-prices everything you already owe (Β§3), so credit is priced by what rides on it: the school, all cost and no stream, loses 569,556 bought early at hold-tax (12↔14); the park wins by 7,967 (4↔6) and the police station by 98,846 at +5 (9↔11), because four extra months of the happiness they deliver outearn the early interest. Where there is nothing to buy, borrowing is a pure cost β€” the five plays above settle that, and the cost is the interest and nothing else.
  5. Take the next milestone; it is worth more than it looks. Reaching milestone 5 pays 125,000 in cash and lifts the ceiling to 1,100,000. Put the cash against the debt and the rate falls 6.63% β†’ 2.90% β€” 10,336 a month saved on debt you already hold, before counting the new room. The school rows are the same fact from the other side: its whole 434,664 is one month of earlier milestone, bought with construction XP alone.
  6. Keep building as you grow, because growth erodes what you built. Thirteen of eighteen matrix rows end below the 48.0 they started at β€” twelve months of zoning thins the standing services, visible month by month in the coverage columns of the play tables below, and only recovering the crime penalty is a big enough block to beat it. The build rule is not a purchase, it is a pace.

  7. A company rate is a lever on a base that is still growing, so it is the last move, not the first. Every one of Β§8's twelve best sequences ends on a company-tax rise and none opens with one, and the ordering table puts 2,100,555 between those two positions for the identical three moves. The mechanism is rule 2's, running forward: the rise suppresses the demand that spawns the firms whose production it taxes, so it costs most while the city is still adding them and least once the land bank is painted out and the base has stopped growing. Wait until the painting is done.

In one line, for this city: paint at pace, cut the budgets, then clamp the company rate. That is the order Β§8's search ranks first; rules 1 and 2 are the matrix rows underneath it, and rule 7 is why the third clause comes third.


Part III β€” what to trust

10. Exact, derived, counted, measured, fitted

Not every number in this document is known to the same standard. These are the five levels, strongest first: exact means read out of the game's own code and checked against values the game itself stored; derived means computed from those rules plus the save's state; counted means tallied directly out of the save; measured means observed across two saves rather than derived; and fitted means a coefficient tuned to match observed behaviour, which is the weakest kind and the one most likely to be wrong.

Exact β€” transcribed from IL and held against the game's own stored values: residential demand from happiness, tax, unemployment, students and free workplaces, including the unlock gate; demand β†’ gross spawn pressure; the spawn threshold's fall with population; XP β†’ milestone β†’ ceiling and cash reward; the rate curve; happiness β†’ output, twice, on company tax only; the commercial and industrial demand aggregation, checked against stored values on eight saves.

The residential transcription reproduces the save's stored household demand and all three bars, and β€” the stronger test β€” it reproduces the change between two saves: at happiness 57 the city stored 75, at happiness 48 it stored 61, and the transcribed terms move the happiness contribution by βˆ’18 and unemployment by +4. 75 βˆ’ 18 + 4 = 61 on the nose. It now agrees on ten of eleven saves; the eleventh is the founding save, where every stored value is zero because the demand systems have not run once, so the comparison is empty rather than wrong.

Derived from rules and state: the residential-tax marginal, from GetHouseholdIncome over the job-level histogram; the company-tax marginal, because GetCompanyProductionPerDay is linear in GetWorkforce and the tax estimators are linear in the gauge it drives β€” so the marginal is the current take times the added worker's share of workforce, and the happiness factor cancels out of that ratio. Also occupants per spawned household: the spawn job draws a prefab by m_Weight, and InitializeHouseholdJob fills the adult, elderly and student slots exactly but runs the child loop random.NextInt(m_ChildCount) times. m_ChildCount is a maximum, not a count, so the expectation is (cβˆ’1)/2 and the weighted mean is 1.766 for ordinary households, 1.0 for student ones, and 1.684 mixed at this save's own student share β€” which is also the counted standing ratio, 1.635–1.695 across six saves.

Exact, and worth separating from the habit beside it: construction XP, both channels. PlaceableObjectData.m_XPReward per building and PlaceableNetData.m_XPReward Γ· 112 per metre of net are read from resources.assets β€” 336 placeable objects and 226 net prefabs, 0 unresolved on each β€” and the rules that spend them (XPBuiltJob's once-only marker on signature buildings, NetXPJob's added elevation bonus of 1 or 0) are read from IL. A road's XP per metre is therefore the same number in every city that lays that road. What is not exact is how much road a player lays per house, which is measured below. Every figure in this document that mixes the two says which half is which, because a rule and a habit fail in different ways: a rule is wrong only if the transcription is wrong, and a habit stops describing the city the moment the city changes.

Derived end to end β€” road construction capital. NetUtils.GetConstructionCost is transcribed from IL and prices a road per eight-metre cell: max(1, round(length/8)) Γ— (m_ConstructionCost + elevation steps Γ— m_ElevationCost), the same cell the upkeep half uses and the same eight metres as the zone cell.

The per-cell figure is the composition's, and the composition is resolved rather than assumed. Each section and piece carries NetPieceRequirements; which of those hold is decided by the edge's CompositionFlags through ApplyPrefabsSystem.CreateRequirementArray. That map is not transcribed β€” the oracle in state/derive/netreq loads the shipped Game.dll and calls NetCompositionHelpers.GetRequirementFlags for every requirement, the same technique state/oracle/ uses for the economy functions, with the result committed at reference/net_piece_requirements.json. A plain stretch of road between two nodes carries Edge and implies exactly that one requirement.

All 315 PlaceableNetPiece objects, 166 NetPieceObjects buffers and 226 net prefabs decode with 0 unresolved. Per cell at grade: Gravel 8, Alley 12, Small Road 20, Medium Road 32, Large Road 44. Over the road this player actually laid β€” 3,012 m of Alley, 1,013 m of pipe, 860 m of cable, for 819 households β€” that is 8.87 per household, about 2,700 a month at 300 households.

The save cannot be read for it: PlaceableNetData is present but its Serialize writes only m_PlacementFlags, so the costs on it are recomputed at load. Nor is the ledger a check β€” the city pays nothing for the map-edge connections that make up most of its network, so the same compositions applied to the whole 98 km give fifteen times what it actually pays. Full derivation, and the wrong first answer it replaced, in reference/road_construction_cost.md.

Counted, then carried β€” coverage. Each service is held as a pair: the fraction of citizens it reaches and the level those citizens see, both counted out of the save. New road arrives uncovered, so growth thins the fraction, at a rate measured across the pair (0.74 of proportional for Education, 0.57 for Healthcare) and checked out of sample against a pair it was not fitted to. A purchase raises the level for the share it reaches, and only where it beats what is already there β€” coverage takes the max over producers, not the sum.

The pair matters rather than being fussiness: happiness is computed per citizen from that citizen's own coverage, and two of the four service terms are not linear. Averaging first and then applying a saturating curve to the average values a pocket park reaching 6.6% of the city at nine times its worth, because a concave function of an average is not the average of the function.

Counted, not fitted: service upkeep per service, out of CollectedCityServiceUpkeepData; free housing, capacity minus occupancy per density; the household-size distribution, grouped by HouseholdMember; crime per building, out of CrimeProducer.m_Crime.

Measured, not derived β€” road per house. Metres of road laid per household of new capacity: 5.6–6.7 across windows spanning the build-out, 2.9–3.8 across recent ones. It is a property of how this player builds and it is falling as the city infills, so it carries the same warning as absorption: a rate measured on one stretch does not describe the next. It is the only empirical term in the road XP line; the XP per metre beside it is exact.

Measured, not derived β€” what a new citizen costs to serve. City upkeep rose by 29.50 per citizen gained across the calibration pair, of which the road share is billed separately, leaving 27.22 per citizen per month charged on every arrival. There is no per-citizen term in the game's own upkeep path β€” buildings charge by their own usage β€” so this is the measured aggregate of that usage scaling plus the services this player actually added as the city grew, standing in for a mechanism that has no closed form. It is what makes the early-game deficit representable at all: credit an arrival its full income and charge it only road, and growth becomes free money, which one session's tables briefly believed.

Measured, not derived β€” coverage thinning as the city grows. Coverage is written onto roads, so a network that grows dilutes the standing services: new streets arrive covered by nothing. Across the calibration pair, education coverage fell 10.390 β†’ 9.992 and healthcare 5.149 β†’ 4.999 over 4,815 new metres of road β€” and stayed flat through every later save where the network stayed flat, which is what localises the cause to road growth. Priced through the exact per-point values above, that is a small happiness loss per household zoned that compounds at scale: zoning at 300 a month costs several happiness points by year's end unless services are added β€” which is the mechanism that makes building a requirement of growth rather than a luxury.

Measured, not derived: how many job slots the city gains per worker it gains. This was set to 1.0 β€” slots keep pace forever β€” on the evidence that the free-workplace term sat pinned through a large population rise. It does not keep pace: measured across pairs it runs 1.93 early and about 0.24 latterly, and the fall lands where the industrial and office building bars reach zero. A sector whose bar is zero spawns nothing, so it adds no slots. That single assumed constant was worth a factor of three in projected population.

Fitted, and it bends: absorption β€” the fraction of gross spawn pressure the city keeps, standing in for HouseholdFindPropertySystem, whose ProcessFindHome scores each candidate with pollution grids, telecom, coverage and a pathfind and has no aggregate form. It is the weakest number in the model, and the zoning rate is the brake beside it: because you state how much capacity goes in, new housing enters the answer as something you decided rather than as something the fitted coefficient produced.

The obvious alternative was checked and eliminated. The same system carries a rate limit β€” at most 128 ordinary and 1,280 homeless households placed per update β€” and it would be a clean thing to derive absorption from if it were what bound. It is not: against 16,384 updates a month it is nowhere near binding, so the throttle never fires and explains none of the shortfall. What actually decides how many arrivals stay is the scoring, and that is the part with no closed form.

Exact, and evaluated rather than read β€” the industrial spawn gate. ZoneSpawnSystem decides whether industrial and office may build from (industrialBuildingDemand + officeBuildingDemand) / 2 > 0 on integer division, and each of those bars is decided per commodity by (m_FreeProperties[r] βˆ’ m_Propertyless[r] > 0) ? 0 : 50. The loop works that out every month from the free properties and the firms with no premises that it carries, and from the company demand at that month's rate β€” rather than reading the answer one save happened to store, which is a constant no play can move. The company demand at a rate no save holds is the game's own seed re-run where the save carries the production array that needs, and the same seed shifted off the stored array where it does not; the shift is checked entry for entry against the re-run on every save that can validate one, at every rate from 0% to 15%, over 192 sweeps with no difference.

Not modelled, and it biases that gate toward open: new industrial buildings. Once the gate opens ZoneSpawnSystem puts buildings up on zoned industrial land, and every new one is a fresh empty lot β€” m_FreeProperties[r] climbs back above m_Propertyless[r] and the test starts failing again. This loop paints residential only and carries no industrial zoned land, so its vacancy count falls and never rises, and a play that opens the sector is shown holding it open for the rest of the year. The commercial and storage bars are held at the save's own reading for a related reason: their inputs β€” commercial free properties, service firms with no premises, storage capacity β€” are not carried either.

Not modelled, deliberately: construction timing β€” whether a zoned cell becomes a building involves the spawn systems and geometry. The model says demand supports N more households; it cannot say when buildings appear.

11. The model has now been scored, and it is worse than it looked

The check was owed for the whole life of this model and has been run. Not forward β€” the city has existed for about 1.5 simulation units in total and the model steps in whole ones, so "play a month and score it" needs a month nobody has played. Instead it is scored on the time that has been played: the save series holds seven distinct simulation frames of one city, so absorption can be fitted on one span and asked to forecast a later, disjoint span using only what is knowable at the base save.

calibrated on this stretch of growth asked to predict this one simulation months population actually gained population predicted error
founding β†’ 1,866 β†’ 2,786 0.44 920 1,821 +98.0%
founding β†’ 1,866 β†’ 3,305 0.61 1,439 2,546 +76.9%
founding β†’ 2,786 β†’ 3,187 0.14 401 564 +40.6%
1,866 β†’ 2,786 β†’ 3,187 0.14 401 288 βˆ’28.2%
1,866 β†’ 2,786 β†’ 3,305 0.17 519 371 βˆ’28.5%

Thirteen of these could be scored. Median error +40%, ranging βˆ’30% to +98%.

The error is a consistent lean, not random scatter. Hold the stretch that absorption was calibrated on fixed, and the error barely changes across every target it is asked to predict β€” βˆ’28.2%, βˆ’28.7%, βˆ’29.5%, βˆ’28.5% for one calibration. That is not noise around a right answer; it is a number that does not carry from one stretch of growth to the next. Absorption measured on one part of a city's growth does not describe the next part.

Two things follow. Read every population figure in Part II as carrying tens of per cent of error, in a direction set by which pair the run was calibrated on. And it is the strongest available argument for the instruction in Β§8: state the zoning rate and let housing decide arrivals, because once housing is what binds, the fitted coefficient stops affecting the answer at all.

The band, the bias and absorption's own instability are asserted in tests/test_validation.py, so a change in any of them fails rather than passing quietly β€” in both directions, because a model that silently improves is one whose error bar is now wrong.

12. What is still open

What is now bounded. Every axis of the scenario solve takes its limit from the save: borrowing from Creditworthiness.m_Amount, total zoning from the paintable cells actually counted, the zoning rate from this player's own measured pace, happiness from what the city has left to recover, and road from the 8-metre-cell geometry. Each derivation is in Β§7 and Β§8.

What a building delivers is now replayed rather than assumed β€” Β§7 has both the mechanism and the ranking it produces. What belongs here is the size of the correction: weighing every service purchase by how many people it actually reaches cut the top of the build ranking by about twenty times without reordering it, because a park's price and its reach rise together. A ranking that looks unchanged and is worth a twentieth of what it claimed is exactly the kind of error reading the table cannot catch.

It also replaced a number that was measuring something else. Dividing a service's standing coverage by the strength of the building supplying it gives 0.999 here, and that figure is real β€” but it describes how coverage fades across the roads that already have some, and says nothing about how much of the city has none at all. A pocket park scores about 1.0 on it while reaching a twentieth of the citizens. The two agree only for buildings big enough to blanket the city, which is why it looked right for as long as this city owned nothing else.

Tax is charged by a different rule from the one that estimates it (Β§7), and a tax point is not a constant (Β§7). Both are settled and priced; neither is an open question.

Two lever classes are read and unscored, and they are the largest gap left.

Policies, and for this city the answer is mostly that they are worth nothing. There are 23 in the game, 16 of them available to the player, and none of them costs money to switch on β€” what gates a policy is whether you have unlocked it, not a price. Each one works by hanging a modifier on the city, and a save records the modifiers it currently has, so what a city is running can be checked rather than assumed. This one runs exactly one policy.

Nine of the sixteen apply to districts, and this city has no districts, so they are inapplicable rather than merely unpriced. Of the rest, one is modelled, and modelling it is how you refuse it with confidence: Paid Outside Services costs exactly 620,000 a month at this population β€” six times the deficit β€” and steps up by another 155,000 with every thousand citizens. A play package can switch it on and watch the charge track the city's own growth month by month, which is precisely the run that shows why nobody should.

That figure is computed rather than quoted. The policy buys police, ambulance, hearse, fire and rubbish services from outside the city, and each is charged the same way:

band  = population Γ· 1000, rounded DOWN, plus 1
charge = the service's fee Γ— band Γ— 1000

with fees of 50 for police, 25 each for ambulance and hearse, 50 for fire and 5 for rubbish. They sum to 155 per band, so a city anywhere in the 3,000s pays 155 Γ— 4 Γ— 1000 = 620,000. Nothing else enters it β€” not how much service the city needs, not how many callouts it makes, not how many stations it already owns. A city of 3,001 and a city of 3,999 pay exactly the same. Easy mode halves four of the five fees.

That policy also exposed a hole in this model's ledger, and it is now closed. Spending was totalled by adding up the expense figures the game records over time β€” and those five import charges are recorded nowhere. The money leaves the treasury and no running total ever sees it, so the total was short by the whole amount the moment the policy was switched on. The model now rebuilds the five charges from the population band, the published fees and whether the policy is active, and adds them in.

The in-game panel is not blind to this, which is worth saying because the natural guess is that it would be: the game's budget screen lists all fifteen kinds of expense and groups these five under Imports. What cannot see them is anything reading the recorded history β€” this model before the fix, and the expense graph, which plots exactly that history.

But policies are not the only source of a city-wide effect, and the other source is the one that matters. Buildings grant them too, through a separate authoring path β€” and where the five policies between them touch eight effects, sixty-two buildings touch thirty-five. Everything that reaches the middle of this model comes from that second group:

effect what grants it value
loan interest Central Bank Γ—0.5 β€” halves it (Β§3)
tax tolerance Central Bank +1 happiness
industrial efficiency eleven signature factories, and the Technical University +1 to +10
office efficiency seven signature offices, the Technical University, the airport +1 to +10
the cost of buying services from outside City Hall βˆ’15%
service building upkeep City Hall βˆ’5%

So the door is open rather than shut, and this model does not price any of it β€” a city with a Central Bank is paying half the interest every figure in Part II assumes. reference/city_modifiers.md lists all 134 effects across all 67 sources, generated from the game's own files rather than transcribed.

The per-resource tax rates, and this is the largest priced-out lever in the document. Β§7 lays out the four banks: 82 of the 92 rates are per-commodity, and the model moves only the four area sliders.

That would be a footnote if the two did the same thing at different granularity. They do not, and the reason is that what zoning needs is a threshold, not a size: industrialBuildingDemand and its office twin only have to sum to 2. Anything reaching 2 lets you zone; anything past it is overshoot you paid for.

industrialBuildingDemand is twice the average of industrialCompanyDemands[r] across the 18 industrial commodities, and the divisor stays 18 whether one commodity contributes or all of them do. So one commodity carries real weight:

cut… company demand summed over the 18 industrial building demand enough to zone?
nothing (all at 10%) 7 0 no
one commodity, by one point 18 2 yes
one commodity to 0% 51 5 yes
the whole industrial slider to 0% 799 88 yes

One point off one commodity is enough to zone. The sector slider gets there too, but it buys eleven times more building demand than zoning needs and charges all 28 taxable commodities to do it. Measured on building demand the sector slider is worth about 17.6 times the single commodity β€” which is simply the number of commodities, and is the honest way to compare the two. Comparing them on monthly revenue instead gives a far larger ratio and answers a different question.

The precondition is the empty lot, and the cut is what removes it. A commodity counts toward that total only once its free properties are gone (Β§5), and no tax term appears in that test β€” so on a city with a spare lot for every commodity, which is the save this document's matrix is scored on, a cut puts nothing on the bar in the month it is made. It acts on the vacancies instead: IndustrialSpawnSystem draws against the same industrialCompanyDemands[r] the cut raises, the firms it creates take the empty lots, and the bar opens behind them (Β§7). The single-commodity cut is therefore a two-step lever, and the step that is easy to miss is the first one.

Two limits are read and both favour the lever. A commodity's effective rate can be pushed to βˆ’10, an outright subsidy, while the rest of the sector pays 10. And the game's tidying pass β€” which pulls any offset shared by every commodity back into the sector slider β€” leaves a single-commodity cut alone, because the shared part of one cut is zero.

What is unmodelled is the cost side, and it is also per-commodity. A firm's chance of leaving the city is (its rate βˆ’ 10) Γ— 5 / 2 percent per check. Subsidising one commodity to 0% gives its firms βˆ’25, which effectively pins them in place against the +5 and +20 that understaffing adds; pushing a rate to 30% adds +50. That is the trade this lever actually makes, and nothing here prices it.

One further correction from the same read: nothing in the charging path ever asks for the office rate. Office firms accrue at the industrial rate and their payments are relabelled as office income on the way out β€” so Β§7's "office, 125 a point" is a point of the industrial rate applied to office goods. Every rate in this save series sits at 10, so no save here can tell the two apart.

Construction XP is scored on both channels β€” placement and road, both worked through in Β§7. Since XP is what clears the milestone and the milestone is what raises the ceiling, it is the one lever class that reaches the binding constraint without going through population first. reference/construction_xp.md has the full read, including why the cheapest row on it is a degenerate case rather than advice.

Where you put a building is a choice, not a gap. Its strength, its range and how much road it can afford to cover are all read (Β§7); the only thing not in the file is the walking distance from a particular site to a particular road, and that is a consequence of where you choose to put it rather than something the model is missing.

A note on what "underivable" has meant here. Three things were carried as blocked in this project's own records, and all three turned out to be assertions made without reading the relevant code: occupants per household (an arithmetic error β€” m_ChildCount is a ceiling, not a count), the crime stock (clamped, and the clamp is in the save), and the company spawn rate (a binary gate, not a rate). Each was inferred from what the data looked like rather than read from what the code does, and the standing rule exists because of them: read the assembly; do not infer from data patterns.

And one measurement caveat worth keeping. A per-arrival marginal is a population change divided by an elapsed time, and over a short window both are small. Measured across every pair spanning at least a tenth of a simulation month, the same quantity runs from 26.72 to 97.68 per head β€” a 3.7Γ— spread. The size of any residual is decided mostly by which pair you measure over, which is why the honest form is the spread and not a number.