Town Simulation and Supply¶
Design Goals¶
Towns should feel alive because they react to success, neglect, shortages, danger, and investment. Their quest boards, prices, services, and appearance should come from actual local state rather than static scripts.
Dynamic events should be the visible expression of those state changes.
Core Town State¶
Each town should maintain a live state profile with at least:
- population
- security
- morale
- prosperity
- food reserve
- water reserve
- fuel reserve
- medicine reserve
- building materials reserve
- sanitation
- storage capacity
- market liquidity
- militia readiness
Town Health Bands¶
Every major state should resolve into readable bands such as:
- failing
- strained
- stable
- growing
- prosperous
These bands drive UI, NPC behavior, and generated content.
Reserve Units¶
Town simulation should resolve inputs into normalized reserve units rather than only raw item counts. Individual items still matter for trade, crafting, and contracts, but the civic model should aggregate them into shared pools:
food reserve: grain, bread, meat, fish, rations, preserved goodswater reserve: potable water, barrels, ice, treated waterfuel reserve: firewood, charcoal, peat, lamp oilmedicine reserve: herbs, salves, tonics, poulticesbuilding reserve: timber, planks, stone blocks, rope, iron fittings, nails
Every deliverable item template should carry a town_reserve_value by reserve class so the same shipment can update raw stock, contract validation, and shortage relief.
Daily Settlement Formula¶
Use one daily settlement pass per town to convert production, imports, projects, and losses into state changes.
For each reserve class:
net_change = local_production + completed_imports + player_deliveries + npc_baseline_supply - civilian_consumption - militia_consumption - project_draw - spoilage - event_loss
Recommended demand formulas:
food_need = population × climate_food_factor × activity_factor × refugee_factorwater_need = population × climate_water_factor × disease_factorfuel_need = households × climate_fuel_factor + building_fuel_draw + project_fuel_drawmedicine_need = base_medicine_load + injury_load + plague_modifierbuilding_need = active_project_draw + infrastructure_maintenance + event_repair_draw
Then days_of_cover = reserve_units / max(daily_need, 1) should drive both town health bands and market pressure.
Reserve Bands¶
Unless a reserve class has a special rule, use the same cover thresholds:
| Days of Cover | Band | Effects |
|---|---|---|
0-1.9 |
failing | emergency contracts, service shutdown risk, major price spike |
2.0-4.9 |
strained | shortage warnings, higher fees, reduced vendor stock |
5.0-9.9 |
stable | normal board and service behavior |
10.0-19.9 |
growing | project acceleration, mild price relief, broader stock |
20+ |
prosperous | expansion opportunities, festivals, stronger NPC buffer |
A town can be stable overall while one reserve class is failing. The board, market, and event generator should read the worst band first rather than average everything away.
Supply and Demand Engine¶
Town demand should not be a fake number. It should come from actual formulas based on population, climate, active buildings, projects, and disruptions.
Examples:
- more population increases food and water draw
- winter raises fuel demand
- barracks upgrades increase weapon, armor, and ration demand
- plague raises medicine demand and labor loss
- caravan loss lowers imported supply and raises price pressure
Price Index Movement¶
Each market category should use a smoothed local price index instead of raw spot chaos.
pressure_ratio = target_days_of_cover / max(actual_days_of_cover, 1)
instant_index = base_price × scarcity_multiplier × route_multiplier × event_multiplier × tax_multiplier × liquidity_multiplier
next_index = current_index × 0.70 + instant_index × 0.30
Guidelines:
- scarcity should dominate staple food, water, fuel, medicine, and building materials
- route multiplier should rise when caravans fail, roads close, or escort losses mount
- event multiplier should handle spikes such as plague, festival, bridge collapse, or monster surge
- liquidity should keep small towns from matching large-market depth even if both are prosperous
Cap normal daily movement to about 15% outside of crisis states so the market stays readable.
Service State Rules¶
Services should consume the same reserve data instead of using separate script logic.
- low food or water suppresses tavern quality, inn availability, and long-haul contract volume
- low fuel reduces smelting, kiln work, winter comfort, and bathhouse or heat-based services
- low medicine raises healer fees, reduces recovery quality, and increases expedition injury risk
- low building reserve slows repairs, wagon work, and public works throughput
- low liquidity narrows vendor stock and reduces large buy-order depth
The emergency public ration and water floor from the agriculture system should keep a town alive at poor efficiency rather than hard-locking it.
NPC Quest Generation¶
NPC quests should be generated from deficits, opportunities, and risks.
Those same inputs should also drive automatic local event generation.
Deficit-Driven Quests¶
- food shortage creates gather, delivery, hunt, farming, or caravan defense work
- low security creates patrol, bounty, escort, or fortification work
- low medicine creates herb gathering, healer escort, or swamp survey work
Opportunity-Driven Quests¶
- strong surplus can fund expansion projects
- new mine discoveries create labor, guard, and transport jobs
- prosperous towns can host festivals, tournaments, and rare merchant events
Board Priority Calculation¶
Generate town-board work from normalized town_urgency_score rather than fixed category quotas.
Recommended rule:
town_urgency_score = clamp(reserve_deficit × 0.45 + route_pressure × 0.20 + event_pressure × 0.20 + project_priority × 0.15 - recent_completion_relief, 0, 100)
This is same score consumed by expedition-board generation. If analytics need raw contributors, store those as separate snapshot fields instead of inventing a second board-priority formula.
Recommended board mix per refresh:
50%highest-urgency deficit or emergency work30%current opportunity or expansion work20%steady background contracts for routine play
Dynamic Town Events¶
Towns should automatically generate local events when pressure or prosperity crosses thresholds.
Examples:
- food riots or emergency ration drives
- harvest festivals
- plague quarantine
- refugee camps
- public works rushes
- merchant fairs
These events should affect contracts, services, prices, and visible town condition.
Town Upgrades¶
Towns should improve through sustained surplus and project completion.
Potential upgrade paths:
- granary
- well network
- mill
- smokehouse
- infirmary
- barracks
- market hall
- walls
- dockyard
- shrine or mage tower
Upgrades should unlock services, recipes, vendors, and better contract pools.
Project Draw and Maintenance¶
Each town project should have at least foundation, structural, and finishing phases. Phases pull from different reserve pools and should stall visibly if inputs are missing.
- granaries, wells, and mills mostly draw building reserve and labor
- barracks and walls draw building reserve, fuel, and security attention
- market halls and dockyards draw building reserve plus ongoing liquidity support
- infirmaries and shrines consume medicine or upkeep supplies once active
Completed upgrades should also have a maintenance draw. If upkeep is ignored for long enough, the upgrade should degrade before it fully disappears.
Town Degradation¶
If key reserves remain low or danger stays high, towns should degrade.
Possible effects:
- worse vendor stock
- higher prices
- fewer workers available
- building closure
- quest desperation
- refugee events
- disease outbreaks
- lower militia cover on roads
Visual and UX Changes¶
Players should see the town state, not only read about it.
What Players Do in Town¶
Town is the hub between expeditions. Each visit has a natural sequence:
Sell and collect
- Sell gathered materials via market sell orders or directly to NPC vendors
- Collect contract payouts from settled expeditions
- Sell survey reports and codex submissions to the Archivist
Recover and prepare
- Rest at the inn to clear fatigue — cost and quality scale with town prosperity
- Visit the physician to treat expedition injuries — cost and recovery speed scale with medicine reserve band
- Repair worn gear at the forge — material and coin cost, throughput tied to building reserve
Stock up for next expedition
- Buy food, water, medicine, ammo, and camp supplies from the General Merchant — prices reflect current reserve bands
- Buy crafted gear from NPC vendors or player market orders
- Buy mount feed if traveling mounted — required before departure
Find work
- Browse the town board, guild board, event board, and caravan board
- Accept a solo contract or form a group before accepting a group board item
Craft
- Use district workshops (forge, carpenter's bench, alchemist's table) to craft gear, trade goods, and supplies
- Refine raw materials: smelt ore, process timber, brew medicines
Teach and learn
- Book a skill lesson from an advanced player or guild teacher
- Post a teaching listing if the character has a sufficient skill band in a relevant skill
Invest in the town
- Contribute materials to active town projects — drives building reserve and project phase completion
- Donating during a shortage builds local standing and can unlock access to board tiers with better contract pools
Trade with other players
- Post market buy or sell orders
- Direct peer-to-peer trade with server-side confirmation
- Browse market history to price goods before listing
Trevalkaan NPC Roster¶
NPCs are tied to districts and to the reserve bands that affect them. Their behavior, pricing, and board output shift with town state — they do not behave the same in a prosperous town as in a strained one.
North Gate Ward¶
Gate Sergeant (Intixabi — Rumiarr origin) Source of the security and patrol board. Posts wolf culls, bandit watches, road-clearing work, and militia support contracts. Board urgency and payout scale with the security band. In a failing security state he posts emergency work and adds extra contract slots. When security is growing he runs a lighter maintenance board at standard rates.
Caravan Master (Solvig — Polheen origin) Source of the regional caravan board. Posts cargo escort, supply transport, and convoy defense work. Tracks route disruption states — when major roads are closed or caravans have failed, his rates climb and his board volume increases. Recovery contracts appear when an important route reopens.
River Market¶
River Trader (Arulokai — Arujoki origin) Buys and sells bulk commodities — grain, timber, leather, iron — at prices driven by town reserve bands. Acts as a fallback buyer when no player buy orders exist, paying slightly below the current market index. His sell stock is limited and reflects actual town surplus; he will not produce goods the town does not have.
Warehouse Factor (Boldanwen — Talmaes origin) Holds cargo for caravan contract settlement and expedition extraction storage. Provides short-term paid storage for oversized hauls. Important settlement point for group caravan arrivals.
Shrine Quarter¶
Town Physician (Kaisaarul — Metsadu origin) Sells medicine, healing salves, and antidotes. Treats post-expedition injuries for a coin fee. Recovery speed and service quality are directly tied to the medicine reserve band. When medicine is strained, he charges more and works slower; when prosperous, he can offer pre-expedition treatments that reduce injury risk on departure.
Archivist (Gwydnila — Coedwair and Arujoki roots) Sells codex pages, monster knowledge reports, regional maps, and survey extracts. Buys player-submitted survey data and dungeon records. Posts occasional research or scouting board items when the codex on a monster family or area is sparse. His stock expands as players contribute knowledge.
Forge Row¶
Blacksmith (Gwayra — Coedwair origin) Sells weapons, tools, and repair services. Buys ore, metal ingots, and salvageable parts. Workshop benches available for player smithing. Repair throughput and quality scale with building reserve — when iron and fuel are low, repair queues slow and quality drops.
Carpenter and Cooper (Qorwyn — Rumiarr and Welsh roots) Sells crates, barrels, tool handles, wagon parts, and basic building materials. Buys timber and processed wood. Key for player crafting chains that need containers or structural components, and for town projects drawing from building reserve.
General Merchant (Senaavel — Polheen origin) Sells camp gear, rations, water containers, rope, cloth, and common tools. The default pre-expedition supply stop. Prices and stock depth directly reflect reserve bands — when food is strained his ration stock shrinks and prices rise; when prosperous his shelves are full and prices settle.
Outer Fields¶
Field Warden (Enkwenol — Talmaes origin) Posts harvest contracts, crop protection, and pest-control work. Responds directly to food reserve pressure. As the food reserve declines, his board fills with higher-urgency work at better rates. His board is the first signal that the town's food situation is degrading.
Mill Operator (Anbukais — Arujoki and Metsadu roots) Processes grain into flour and rations. Not a vendor — a conversion service. Raw grain delivered to town must pass through the mill before it contributes its full value to the food reserve. If the mill is understaffed or under-supplied with fuel, processing slows and the food band lags deliveries.
NPC Baseline Supply¶
Each NPC and their associated district runs a daily baseline production tick. The Blacksmith smelts a small iron quota. The Field Warden's farms yield grain. The Physician draws from the medicine reserve to treat the town's civilian population.
This baseline is calibrated to hold the town at the stable band indefinitely if players are completely offline. It cannot push the town to growing or prosperous — those bands require active player delivery above the consumption floor.
Events, raids, droughts, and disease can spike consumption above the baseline. When that happens, the town begins sliding down the bands even with NPC production running. That is when the board generates premium emergency work and players have the strongest incentive to respond.
NPC-Player Economy Loop¶
The loop runs on a daily settlement cycle:
Step 1 — NPC baseline tick NPCs produce their daily output and consume their share of reserves. The town starts the day with whatever players left it at plus the NPC baseline delta.
Step 2 — Board generation The town coordinator reads current reserve bands, event state, and project state and generates contracts. Deficits produce shortage and emergency work at elevated rates. Surpluses produce expansion and opportunity work at standard rates. NPC vendor buy-order prices reflect the same bands.
Step 3 — Player activity Players go out on expeditions, gather, hunt, and complete contracts. On return they sell to market or directly to NPC vendors. Contract completion writes to the reserve pool. Market sales update the price index and vendor stock depth. Coin flows from NPC contract payouts and NPC vendor purchases into player inventories.
Step 4 — Settlement writebacks The daily pass recalculates all reserve levels incorporating player deliveries, NPC baseline output, event losses, and civilian consumption. Reserve bands update. The next board generation pass reads the new bands — a town that players actively supplied today will have a calmer, lower-premium board tomorrow. A town they ignored will have a more urgent and better-paying board.
The core property: NPC behavior is not scripted. Their prices, stock depth, service quality, board urgency, and payout rates all respond to the same reserve state that player deliveries change. Every expedition that ends in a return with materials shifts tomorrow's board.
Coin flow:
| Direction | Source |
|---|---|
| Into player wallets | NPC contract payouts, NPC vendor purchases of player goods |
| Out of player wallets | Market taxes, inn, physician fees, repair costs, crafting inputs, teaching fees |
The difference is the player's net session profit. NPC payouts are the primary coin injector; NPC service fees are the primary sink.
Examples:
- town banners and overlays show condition bands
- market screen shows shortage warnings
- quest board gains urgent tags
- roads show caravan disruption markers
- certain services become disabled or premium-priced
Technical Model¶
Town Coordinator¶
Use one coordinator per town for high-contention state updates such as project contribution, reserve adjustments, tax application, and board refresh.
Persistent Records¶
Store:
towntown_reservetown_buildingtown_projecttown_project_phasetown_condition_snapshottown_generated_contracttown_price_indextown_daily_ledgertown_service_statetown_trade_lane_statetown_reserve_conversion_rule
Tick Model¶
Use two timescales:
- a short tick for active changes such as deliveries, project completion, and board refresh
- a daily settlement tick for consumption, condition recalculation, and long-form project progress
The daily settlement tick should run in this order:
- apply completed local production and inbound shipments
- apply player deliveries, project turn-ins, and event losses
- subtract consumption, spoilage, and maintenance
- resolve reserve bands and service states
- update price indices and contract urgency
- write a
town_condition_snapshotfor UI and event generation
Read Models¶
Expose fast public read models for:
- current shortages and surpluses
- active town projects
- visible service state
- job board urgency
- active local events
These can be cached because they are read-heavy and update on a schedule.
Guild Interaction¶
If a guild controls a town, it should influence policy but not fully replace town needs. A guild can choose tax rates, project priority, and militia spending within guardrails, but hunger and supply pressure still obey the same simulation rules.
Controller policy should change weights, taxes, and project priority, but never bypass shortage math. A wealthy guild can buffer a town with deliveries and spending; it cannot declare famine nonexistent.
Settlement Tick Cadence and Technical Trigger Spec¶
Cadence¶
The daily settlement tick runs once per real-world day at a fixed UTC wall-clock time.
| Environment | Tick time (UTC) |
|---|---|
| Production | 06:00 UTC |
| Staging | 06:30 UTC |
| Development | configurable; default 06:00 UTC |
One tick = one in-game day for all formulas in this document. Tick frequency is not adjustable at runtime. If the game needs faster iteration for testing, the admin endpoint can issue a manual tick; it does not change the wall-clock schedule.
Trigger Mechanism¶
Each town has a Town Settlement Durable Object responsible for owning that town's authoritative state. The DO sets a Cloudflare Alarm at creation time, targeting the next scheduled tick wall-clock timestamp.
DO alarm fires
→ lock town state (DO serializes all concurrent updates)
→ run settlement pass (see order below)
→ write D1 records and KV snapshots
→ set next alarm for T + 24h
→ release lock
If the alarm fires more than 5 minutes late (Cloudflare delivery delay), the DO logs the drift and continues normally. The tick does not attempt to compensate for lost time — a late tick is a single tick with real-world elapsed state, not a catch-up.
If the alarm fires twice within a 1-hour window (duplicate delivery), the DO checks last_tick_timestamp in its state; if it is within the last 6 hours, it skips the duplicate and resets the alarm. This prevents double-consumption.
Settlement Pass Order¶
The pass runs synchronously inside the DO. Each step reads from the DO's in-memory state; writes are batched and committed once at the end.
1. Snapshot pre-tick state
└─ Record reserve levels, band states, active events at T−1
2. Apply inbound supply
├─ NPC baseline production (per NPC config)
├─ Player delivery credits (committed by player DO on delivery confirm)
├─ Caravan arrivals (scheduled; confirmed by caravan DO handoff)
└─ Import credits from trade lane settlements
3. Apply consumption
├─ Civilian food and water draw (population × climate_factor × refugee_modifier)
├─ Militia ration and equipment draw
├─ Active project phase draw (building reserve + fuel)
├─ NPC service baseline consumption (physician medicine draw, etc.)
└─ Event-driven extra consumption (plague: +medicine; siege: +food+fuel)
4. Apply spoilage and losses
└─ Per-reserve spoilage rate × current_units (capped at 5%/day baseline; drought or rot events modify)
5. Compute net reserves
└─ reserve_units_t = reserve_units_t−1 + inbound − consumption − spoilage − event_loss
6. Resolve reserve bands
└─ For each reserve class: band = f(days_of_cover) per band table
7. Resolve composite town health
└─ Weighted average of band scores; sets town_health_state
8. Apply active event outcomes
├─ Advance active events by 1 tick
├─ Expire completed or resolved events
└─ Apply expiry penalties or resolution bonuses to reserves
9. Run event director
├─ Read area condition scores (security, food, weather, etc.)
├─ Evaluate eligible event templates against trigger_conditions
└─ Spawn 0–N new events based on weighted template selection
10. Update market price indices
└─ Recalculate instant_index for each market category; apply smoothing
11. Board generation pass
├─ Score board urgency per category using town_urgency_score formula
├─ Expire stale orders past their expiry_ticks
└─ Append new generated board orders to fill gaps
12. Write persistence
├─ D1: upsert town_reserve, town_condition_snapshot, town_daily_ledger, town_price_index
├─ KV: write town_snapshot:{town_id} (read model for client; 5-minute TTL)
└─ KV: write board_snapshot:{town_id} (read model for board UI; 5-minute TTL)
13. Set next alarm: T + 24h
Between-Tick Updates¶
The settlement tick owns the daily math. Between ticks, the DO accepts real-time state mutations without running the full pass:
| Event | What updates |
|---|---|
| Player completes delivery | delivery_credit queue in DO state; flushed on next tick |
| Player completes board contract | contract_completion record; board order marked filled |
| Guild submits tax change | Queued; applied on next tick (24-hour delay enforced) |
| Admin forces manual tick | Full pass runs immediately; next alarm reset to T + 24h from now |
| Event resolves early | Event director runs immediately; board updates within 5 minutes via KV TTL expiry |
Player deliveries do not update reserves mid-tick. They are queued and consumed by step 2 of the next tick. This prevents partial-state reads and keeps the reserve math deterministic. The client shows "pending delivery" status for in-transit credits.
Failure Recovery¶
If the settlement pass throws an unhandled exception, the DO:
- Rolls back all in-memory mutations (the D1 batch was not committed)
- Logs the failure with tick timestamp and error detail
- Schedules a retry alarm for T + 5 minutes
- Retries the full pass (idempotent because it reads from committed D1 state)
Retry cap: 3 attempts. After 3 failures, the DO enters degraded state, skips the pass, and fires an admin alert. The town remains on last-known committed state until manual intervention. Reserve bands and board do not update during degraded state.
Tick Observability¶
Each settlement pass writes a town_daily_ledger record with:
tick_timestamp
pre_tick_reserves (per class)
inbound_supply (per class, per source)
consumption (per class, per consumer)
spoilage (per class)
event_losses (per class)
net_change (per class)
post_tick_reserves (per class)
post_tick_bands (per class)
events_spawned (list of event ids)
events_expired (list of event ids)
board_orders_generated (count per category)
board_orders_expired (count)
tick_duration_ms
This ledger is the audit trail for any "why did the food reserve drop?" investigation. It is retained for 30 days in D1 before purge.
Related Systems¶
- farming and food supply
- regional markets and caravans
- player contracts and job boards
- guild governance and taxation