Skip to content

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 goods
  • water reserve: potable water, barrels, ice, treated water
  • fuel reserve: firewood, charcoal, peat, lamp oil
  • medicine reserve: herbs, salves, tonics, poultices
  • building 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_factor
  • water_need = population × climate_water_factor × disease_factor
  • fuel_need = households × climate_fuel_factor + building_fuel_draw + project_fuel_draw
  • medicine_need = base_medicine_load + injury_load + plague_modifier
  • building_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 work
  • 30% current opportunity or expansion work
  • 20% 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:

  • town
  • town_reserve
  • town_building
  • town_project
  • town_project_phase
  • town_condition_snapshot
  • town_generated_contract
  • town_price_index
  • town_daily_ledger
  • town_service_state
  • town_trade_lane_state
  • town_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:

  1. apply completed local production and inbound shipments
  2. apply player deliveries, project turn-ins, and event losses
  3. subtract consumption, spoilage, and maintenance
  4. resolve reserve bands and service states
  5. update price indices and contract urgency
  6. write a town_condition_snapshot for 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:

  1. Rolls back all in-memory mutations (the D1 batch was not committed)
  2. Logs the failure with tick timestamp and error detail
  3. Schedules a retry alarm for T + 5 minutes
  4. 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.


  • farming and food supply
  • regional markets and caravans
  • player contracts and job boards
  • guild governance and taxation