Townsfolk and the first hour
Decision #123. The people of the colony's towns, played by the server, and the guided start a new
colonist gets in Aquais. Builds on the economy (#121, docs/economy.md) and the towns of the
baked world (#103, #111, #112).
1. Who lives where
Every town of the registry (uo_world::towns) gets a roster (uo_world::townsfolk::roster),
deterministic per world and computed once per town:
| Role | Where | Count |
|---|---|---|
| Banker | beside the exchange | 1 (not in lawless towns) |
| Fence | beside the exchange of a lawless town (isles, wilds) | 1 |
| Healer | at the temple's door, else beside the exchange | 1 |
| Guard | barracks doors, beside the exchange, the town's doors, the zone's corners and sides | capital 8, city 6, town and fort 4, village 2, free port 6, lawless 0 |
| Smith | at each smithy's door (up to 2), else beside the exchange | 1–2 |
| Innkeeper | at each inn's door | up to 2 |
| Shopkeeper | at each shop's door | up to 3 |
| Harbour master | Aquais: where colonists land (world.json start) | 1 |
| Mint master, store clerk, patent clerk | Aquais: around the exchange | 1 each |
Posts are walkable, unblocked tiles at least two tiles from the exchange (the vault and the counter stand there), at least two tiles inside their region. A town without buildings (the synthetic towns of generated test maps) also gets a yard of crafting stations next to its smith: sawhorse, anvil, forge and campfire, raised as runtime statics.
Entity ids are NPC_BIT | town << 12 | n (NPC_BIT = bits 62 and 60), so they never meet a
player's or a mob's. Names come from a short English list per role, by town and index.
2. On the wire
EntityKind::Npc { name, role, equipment }: the client draws a dressed human of the role's outfit (NpcRole::outfit: catalog items, the same parts as players; only creatures are capsules) with "Name, the role" over its head in pale brass, no health bar.Command::Talk { npc }: withinTALK_RANGE(3 tiles) the NPC answers at once; up toTALK_WALK(24) the server walks the player up and the dialogue opens on arrival (given up after 20 s or when the walk ends elsewhere); farther is refused.GameEvent::Dialogue(DialogueView { npc, name, role, text, options, open }): private.openasks the client to open a window beside it (Service::Market,Port { tab }for the free port's mint/store/patents/export tabs,Craft,Errands,Help).Command::Choose { npc, option }: answers with an option's key; the NPC may act (buy a patent, clean stolen goods) and speaks again.byejust closes the window.Command::SkipErrand { all }andGameEvent::Hint { key, title, text }(§4).- The gateway routes
Talk/Chooselike attacks: an NPC in a neighbouring region's arena moves the player into that region's battle.
Ghosts may talk (to a healer, say). Nobody may attack an NPC: Attack and harmful Cast aimed at
one are refused ("They are under the crown's protection").
3. On the server
crates/uo-server/src/sim/region/npcs.rs. Each region plays the NPCs whose post stands in its
rectangle: fighters of its battle on a side of their own (u32::MAX) with Controller::Player
(no AI), 10 000 hits topped up every tick, so no blow, blast or Mega Explosion ends them.
- Townsfolk are ghosts in the battle (
Battle::set_ghost): they walk, block nobody, and nothing can target them. Healers are added to the region's healer tiles, so a ghost within two tiles of one stands up again (after the usual 30 s, #121). - Guards are ghosts while they patrol (their post and the two nearest other guard posts, a leg
every 30 s) and turn solid to hunt. Every tick, a grey player (
Notoriety::Grey: a crime within two minutes or stolen goods) or a murderer (Notoriety::Murderer, #131) standing in a non-lawless guard zone in this region is hunted by the nearest free guard of that town: it shouts "Halt, criminal!", steps out on a free tile next to the criminal (and again whenever the criminal gets more than 4 tiles away), runs and strikes with a halberd for 100–140 (UO's guards end a criminal in a blow or two). The hunt ends when the criminal is dead, a ghost, innocent again or out of the zone; the guard turns back into a ghost and walks back to its round. - The raid window: while a town's vault may be raided (its window, #121) its guards leave grey players alone: raids and the chase after them are the players' business. Outside it, a thief carrying stolen goods through town is cut down. A town owned by another region (its exchange is elsewhere) counts as closed.
- The refusal of attacks on innocents inside guard zones (#121) stays: guards only deal with the grey and the red.
- Guards are invulnerable (decision): a killable guard is a free loot piñata for a party, and the alpha has no respawn economy for them. Sieges (#77) will need town defenders that can fall; that is later work.
4. Onboarding: the harbour master's errands
uo_proto::errands (pure rules, shared), progress in Citizen::errands (stored with the
character, travels with handoffs; old records load with nothing started).
| # | Errand | Done when | Reward |
|---|---|---|---|
| 0 | Landfall | the player takes the errands in the harbour master's dialogue | — |
| 1 | The exchange | standing within reach of Aquais' exchange (teaches running) | 2 bread |
| 2 | Timber for the colony | 5 logs chopped | a saw |
| 3 | First trade | any sale at an exchange | 2 cooked fish |
| 4 | A colonist must eat | eating anything | a pouch |
| 5 | Papers, please | buying a work patent (the patent clerk sells Carpentry) | 7 days of Carpentry |
| 6 | Tools of the trade | crafting a tool (boards at a workbench, then a fishing pole) | 7 days of Fishing |
| 7 | The guarded highway | standing in another town's guard zone | a bag |
| 8 | Another town's market | opening a market that isn't the free port's | 3 cooked fish |
| 9 | Death and the healer | talking to a healer | 7 days of Mining |
| 10 | The law | talking to a town guard | 7 days of Lumberjacking |
- Rewards are items or patent days, never coin: the mint stays the colony's only faucet.
- Taking the errands sets satiety to at most 70 ("a long crossing"), so the Eat errand can be done (a full colonist can't eat).
- Skippable: the harbour master offers "I know the colony: no errands" before and "Skip this
errand" / "Skip all" during; the errand log has the same buttons (
SkipErrand). Skips pay nothing. - Signals: the server counts harvests and crafts from the
Workedevents of the tick, sales, meals, patents and opened markets by comparing the character before and after the command, and where the player stands every tick (exchange, other town). No economy code changed for it. - The toast that announces the timber errand names the nearest trees from Aquais' exchange (the craft errand: the nearest workbench); in Aquais they are outside the walls.
- The harbour master also explains the colony and gives directions (the exchange, the healer, the three nearest towns with paces and screen directions).
Hints
First-time hints (Hint, seen-once bits in Errands::hints), checked every second, sent as
GameEvent::Hint and shown as a toast at the top of the screen and in the journal:
| Key | When |
|---|---|
welcome | a colonist who hasn't taken or skipped the errands |
errands | the errands are taken (points at L and F1) |
death | the character is a ghost |
grey | the character is grey |
full_pack | carrying at least 90 % of what they can |
hungry | satiety at 20 or below |
tool_worn | a tool with 10 uses or fewer left |
patent_expiring | a patent running out within a day |
Finishing or skipping an errand sends a hint with key errand (the reward and the next goal).
5. On the client
crates/uo-client/src/online/townsfolk.rs:
- clicking a townsperson sends
Talk(instead ofAttack); Tab never picks them; the hover card says "click: talk"; - the dialogue window (ui_kit, #59 style) shows the text and one button per option; it closes
on "Goodbye", the window's x, or when the player walks more than 6 tiles away;
openservices open the market (on the right tab), crafting, the errand log or help; - the errand log (L; J is the journal) lists the eleven errands with done/skipped/current marks, the current goal, progress and reward, and Skip buttons;
- the help window (F1) explains the controls, the windows, the loop, towns, death and notoriety;
- toasts: up to three hints at the top of the screen for 10 s each, also in the journal;
- the status panel shows the current errand's goal.
UO_TEST_CLICKS="5:talk:harbour_master" talks to the nearest NPC of a role (or any) in a
scripted run.
6. Bots
uo_sdk::bot::Behaviour::Onboarding (onboarding): a brand-new colonist plays the whole chain
through the protocol — talks to the harbour master and accepts, runs to the exchange, chops like
the lumberjack, sells a log at the free port, eats, buys Carpentry from the patent
clerk through the dialogue, makes boards and a fishing pole at the nearest workbench (chopping
more when a failed craft ate the logs), walks the guarded highway to the nearest town, opens its
market and talks to its healer and a guard. View keeps the last dialogue, the hints and the
errands.
Two things it had to learn on the baked world, both worth knowing for any bot:
- Trees are scarce in Aquais. Gatherer bots (
miner,lumberjack, andonboardingwhen it chops) now head for the nearest unworked node within 200 tiles when nothing is within 40, and give up a random walk that hasn't moved them for 12 s (a goal across the coast). - The server walks far goals in straight 24-tile legs inside the region's arena, which can't
route out of a walled city. The bot walks the guarded highway's polyline (
world.jsonguarded_roads), picking waypoints a stride ahead but inside its current region's arena; the region handoff brings the next stretch into reach. A person follows the road on screen.
crates/uo-server/tests/onboarding.rs runs it against a real node on a generated map and prints
how long the chain took; tests/npcs.rs checks rosters, talking, protection, the patent clerk,
skipping and the guards in one region.
Measured (2026-10-22)
The bot plays the chain without hesitation, so these are floors, not a person's time:
| World | Total | Notes |
|---|---|---|
generated 192² (tests/onboarding.rs) | 70 s | towns 48 tiles apart |
| Felucca (baked), a fresh colonist | 186 s (3.1 min) | landfall 4 s, exchange 15 s, 5 logs by 45 s, sale, meal and patent by 53 s, fishing pole at 69 s, the highway to Fort Aeriaion (≈ 450 tiles) by 179 s, the fort's market, healer and guard by 190 s |
A person reading the dialogues, finding trees and walking by hand should take 15–30 minutes, well inside the first hour; the playtest will tell.
Felucca's rosters: 269 towns, 1746 townsfolk, 616 of them guards; Aquais has 19.
Server cost: rosters are computed once per town; a region puts its townsfolk into its battle when it loads (off the tick thread). Guards check only grey and red players each tick; hints are checked once a second per online player.
7. Later
- Walkers in the streets, shop names on signs, vendors who sell their own stock.
- Guards that can fall in a siege.
- A "how to play the alpha" page on the site.
- Far walks: the server plans long
WalkTos in straight 24-tile legs inside the region's arena, which can't route out of a walled city (the bot follows the highway's polyline instead); a route planner over regions would help people who click far away too. - MCP tools for
Talk/Choose(agents can send the commands; the bridge has no tool yet). - Voice lines and portraits in the dialogue window.