Skip to content
Felucca Online

Docs

World dressing

Decision #104. The towns were alive and the world around them empty (user directive): this is the plan for filling every location of Felucca with props, and the order of 1060 new sprites it needs (assets/requests/world-props.md). Everything here is placed by the bake (crates/uo-atlas/src/dress.rs), deterministically from the world seed, so the server and every client see the same world; players change it on top (#100).

Principles

  • Every place tells what happens there. A clearing has a woodcutter's stump with an axe in it, a field has its haystacks and a scarecrow, a battlefield its broken ballista and torn banners of both realms. Props come in vignettes (designed set pieces with variation), not as salt-and-pepper noise.
  • Drifts, not confetti. Ground cover and flowers grow in patches chosen by low-frequency noise (a meadow has a drift of poppies here, daisies there), at a density that falls off at the patch's edge.
  • Edges are where the detail is: forest edges, river banks, lake shores, beaches, the foot of every mountain, the border between realms.
  • Paths stay open. Blocking props keep the 2 × 2 rule of the nature bake (at most one blocker per cell); vignettes are checked for a walkable way through.
  • Budget. Wild regions stay at a few hundred statics each (flat ground cover counts least: its shadow shell is nearly empty); dense vignettes are small. Frame time is measured on the densest places before shipping.
  • Real size (#74): trees 10–17 m, haystacks 3 m, a skull a hand span.

Layers

1. Biome scatter (every land tile)

Per biome: trees and big blockers (the existing nature bake), then undergrowth, ground cover (flat) and rocks, each from weighted lists by biome and climate (north/south), in noise patches:

BiomeUndergrowth and coverRocks
forestbracken, ferns, bluebells, violets, leaf litter, twigs, branches, pinecones/acorns, mushrooms (fly agaric, porcini, chanterelles), mossy and hollow logs, stumps, wild roses, hazel, hollymossy
taigapine needles, juniper, blueberry, saplings, snags, birch logs, mushroomsgranite
Elderwoodglowing mushrooms, moss, moonflowers, glow moss, orchids, ferns, ancient rootsmossy, crystals rarely
jungletall ferns, tree ferns, banana plants, monstera, bromeliads, orchids, jungle flowers, hanging vinesmossy
swampsedge, cattails, rushes, bog cotton, pitcher plants, dead swamp trees, mangroves on the water's edge, duckweed and lilies on the waterriver
grasslandmeadow grass, poppy/daisy/buttercup/cornflower/clover drifts, dandelions, thistles, nettles, strawberries, sunflowers rarelygranite
steppedry grass, sagebrush, tumbleweed, dry bushes, lichensandstone
heathheather (purple, white), gorse, juniper, grass tuftsgranite, sandstone
hillsgrass tufts, thistles, gorse, scree at slopesgranite
tundratundra grass, cotton grass, arctic willow, lichen, frost flowers, mammoth bones rarelylimestone, granite
snow, glaciersnowdrifts, snowy small pines, frozen bushes, ice blocks and spikessnow cliffs, frozen boulders
beachdune grass, shells, seaweed, starfish, driftwoodbeach
ash landsash shrubs, fire lilies, sulfur moss, obsidian shards, lava crust, steam vents, fumarolesbasalt, lava rock

2. Edges

  • Rivers and lakes: cattails, rushes, horsetail and river rocks on the bank tiles; water lilies and duckweed on still water near the shore; stepping stones where a path meets a brook; washing stones near villages; fish weirs, beaver dams in the wilds.
  • Coasts: driftwood, seaweed, shells, starfish, crab shells, barnacled rocks, tide pools; rarely a whale skeleton or a beached rowboat; kelp in the shallows.
  • Mountains: cliff faces (cliff_<rock>_x/_y with corners) where rock meets walkable ground, scree and gravel at the foot, outcrops and spires, ore veins where the atlas has deposits.
  • Forest edges: saplings, brambles, bracken, young oaks, fallen branches.

3. Fields and farmsteads

Farmland (the atlas's fields around every settlement) is cut into plots of 8–16 × 6–12 tiles. Each plot grows one crop (by climate: rye, oats, barley and flax in the north; wheat, cabbages, turnips, onions, beans and hops in the middle; grapevines and melons in the warm south) at one growth stage (sprout, young, grown, ripe), or lies harvested (stubble with stooks, haystacks, sheaves). Plots are divided by wattle, split-rail or hedge fences with gaps and stiles, by tracks with a farm wagon or a hand cart. Some plots have a scarecrow.

Farmsteads stand among the fields of villages and along roads: a farmhouse or cottage from the building generator with its yard (haystack, granary on staddles, chicken coop, rabbit hutch, beehives, woodpile, chopping block, well sweep, manure heap, milk churns, plough and harrow). Every farming village has an orchard (rows of apple trees, a ladder, windfall apples, an apple crate), the south vineyards, and a village on a rise a windmill; one on a river a water wheel.

4. Roads

Milestones every ~400 tiles (in the realm's style), signposts at junctions, wayside shrines of the realm every ~1500 tiles, lanterns on the last stretch before a town, benches and wells near villages, border posts where a road crosses into another realm (toll barriers on highways), bridges where a road fords a river (stone in the realms, wood in the wilds: deck pieces over the ford, parapets or railings, piers), and now and then a broken wagon, a dropped crate, a traveller's pack or a memorial cross (more where the danger is high).

5. Towns

On top of the town plans (#103): stalls by trade with their goods in the market squares, trade signs by trade at the doors (smith, inn, bank, tailor, baker, butcher, alchemist, mage, healer, bowyer, jeweller, carpenter, guild, provisioner, stable), banners and wall flags of the town's realm, lamp posts in the realm's style, flower boxes under windows in rich quarters, laundry lines between houses in poor ones, crates, barrels and sacks by warehouses and inns, building works (scaffolding, beams and bricks) on some free plots, puddles and rubbish in back streets.

6. Places of interest (vignettes)

Place (count at seed 1)Vignette
ruin (650)a ruined building of the Old Empire or a later war: rooms of ruined walls in the region's wall set, rubble, columns, a toppled statue, floor patches, overgrowth; bones where it is dangerous
hermit's hut (353)a cottage from the generator, herb garden, goat pen, drying racks, mortar on a stump, bee skep, woodpile, wind chimes or bone charms
shrine (352)one of the eight virtue shrines on a paved dais, votive candles, offering bowls, prayer flags, benches; in the realms their own altars
monster lair (236)the camp's monsters (#100) plus a nest of bones, gnawed bones, carcasses, claw marks, skulls, webs or slime by biome
bandit camp (234)the camp (#69) plus ragged tents, loot piles, a wanted board, a card table, a ransom cage, a lookout, stake palisades
standing stones (131)a stone circle (menhirs, a few fallen, trilithons in the big ones), an ancient altar in the middle, rune stones, heather and flowers
graveyard (128)a fenced yard of graves in rows (mounds and stones of the realm), a tomb or mausoleum, an open grave with a shovel, dead trees, candles
ancient tree (127)the ancient tree, its root ridges, ribbons of offerings, a carved face, glow moss and a ring of mushrooms
wizard's tower (74)a tower from the generator, an arcane circle, crystal pylons, an astrolabe, a telescope, a bubbling cauldron, rune pillars, floating books, ward posts
watchtower (71)a tower from the generator, a stake palisade, a signal beacon, a weapon rack, the realm's banner, a campfire
abandoned mine (63)a mine entrance into the nearest rock, rails, ore carts, tailings, broken supports, tools, a skeleton
orc camp (57)the camp plus orc huts, totems, bone fences, a war drum, a fire pit, a cage, a crude throne, trophy racks
battlefield (55)a wide field of the war: torn banners of both realms, broken siege engines, weapons in the ground, shields, skeletons in armour, horse skeletons, scorch marks, stake fields, a mass grave and a memorial
shipwreck (52)a hull on the beach, its bow or stern, a fallen mast, barrels, crates, a sea chest, a cannon, skeletons, driftwood
fey ring (36)a fairy ring of mushrooms, moonflowers, fey stones, wisps, a branch arch, a mushroom house
waystone (23)a waystone on a paved circle with benches
inn (17)an inn from the generator with a stable yard: hitching rails, troughs, hay, a wagon, its sign and lanterns, a well
lighthouse (1)the lighthouse and a beacon on the rocks

7. Dungeon entrances

Every dungeon of the atlas (166) gets its entrance sprite (entrance_<kind>) facing the camera, a trodden approach, and its dressing: carts and rails at mines, cairns and grave mounds around barrows, a graveyard around a crypt, bones at caves, half-sunk columns at sunken temples, fey lights at fey hollows, lava crust and scorch at fire lairs, ice at ice caves, barnacled rocks at sea grottos, ruined walls at ruined keeps, and around the Old Capital the ruins of a whole city behind its triumphal gate. Warning skull posts and braziers (green at crypts) mark the dangerous ones.

8. Resource nodes

The atlas's deposits become things to gather: ore veins of the nine ores and quarry faces on rock at the foot of mountains, gems in the deep places, reagent plants (mandrake, nightshade, ginseng, garlic, blood moss, spider silk, black pearls, sulfurous ash) in their biomes. Gathering itself is later work (resource-items).

9. Danger

The encounter zones' danger raises the share of grim props: more bones, skulls, broken carts and graves where the roads are unsafe, battle debris along the frontier, skull posts and totems in the wilds, pirate flags, cannons and rum barrels on the isles' coasts.

Built

Code: crates/uo-atlas/src/dress/ (props.rs the order as a table, scatter.rs per region, sites.rs the vignettes), town dressing in towns.rs. Run:

cargo run --release -p uo-atlas -- --no-tiles --out /tmp/atlas --bake assets/world/felucca   # ≈ 25 s
cargo run --release -p uo-atlas -- --plans-only --out /tmp/x --sites-near 10102,3599          # what was planned near a point
python3 tools/world_props_usage.py                                                           # every ordered prop has a rule
cargo test --release -p uo-atlas                                                             # landmarks kept, doors free, bake reads back
  • The 1060 props were modelled by nine parallel sessions, one per group, and merged: 1698 sprites in the catalog now (156 MB). tools/world_props_usage.py checks that every one of them is placed by some rule.
  • Rules worth knowing: random clutter takes either orientation (_s ↔ _e, direction-free _x ↔ _y, props::twin); a site whose centre is on rock or water moves to the nearest open ground within 30 tiles, and its landmark goes to the nearest spot where it fits (Site::put_near); sites clear a glade (no trees within 6–12 tiles, 26 on battlefields, which also trample their fields); earlier, more important sites win where two overlap; blockers never wall a free tile in and keep the 2 × 2 rule; nothing blocking stands on or next to a front door.
  • Blocking: multi-tile blockers block their whole footprint (statics chunks carry the extra tiles); ruined walls, cliffs, palisades, barricades, bridge parapets, portcullises and sealed doors block their edge like walls (blocked_edges); toll and road-repair barriers stand beside the road and block nothing.
  • Water props (props::on_water) stand on water tiles: plants of the shallows, boats, piers and docks, bridge piers, the water wheel, ferries. Docks and boats are not walkable yet (the server treats water as unwalkable); bridges stand on the road's ford, which is.
  • Shadows: sprites lower than 0.4 units (ground cover, flowers, pebbles, shells) cast no shadow shell; that halved the cost of a dressed meadow.

Numbers

Seed 1: 13.97 M statics (6.8 M before the dressing), 4232 sites (636 ruins, 347 shrines, 372 farmsteads, 128 graveyards, 125 ancient trees, 124 stone circles, 966 work camps at deposits and fishing villages, 89 orchards and vineyards, 66 windmills, 16 watermills, 15 harbours, …). Statics per land region: mean 465 → about 530, the capitals 4000–5600.

Frame time (2560×1600, zoom 4, headless, a busy machine with load 8–15: compare within these runs only, #49):

PlaceStatics streamedFrame
meadow near Skartor (drifts, fields at the edge)8 4677.6–9.3 ms
farmland10 60010.1–10.3 ms
the middle of Skartor13 544≈ 15 ms
dense forest2 34524–26 ms

The forest's cost is its real-size trees (22 ms before the dressing); the dressing adds little there.

Not done yet

  • Docks, piers and boats can't be walked on; no ships to sail.
  • Field crops are one static per tile; growth stages don't advance with time (the world is static, #100).
  • Resource nodes are only scenery until gathering exists (resource-items).