Files
turnstone/examples/door-game/understone/world/data/world.json
T
Patrick Buckley 393a6fc2b2 feat(examples): Understone v0.10 — the satchel, the ore-forge, and the vault
A game-loop mechanics patch: the satchel becomes a real stacking inventory,
forging now demands ore won in combat (not just gold), and a vault lets a
hero protect coin from ambush.

- Stacking satchel: the bag re-encodes from a flat id list to "id:qty"
  stacks, so potions stack (three Minor Potions fill one slot, not three)
  and materials ride alongside. satchel_max now caps distinct KINDS (3);
  per-kind quantity is unbounded. quaff/death-save still pull the strongest
  potion and ignore materials. One pure codec (engine/satchel.py) owns the
  encoding; the façade, the Watch, and the sim all decode through it — no
  three-way drift (the v0.9 single-source lesson). The codec parses a bare
  id as qty 1, so it can never silently drop a malformed stack.
- Ore-gated forge: ore is a material that drops from won dungeon-rung
  fights (and, less often, forest fights), stacks in the satchel, and is
  not buyable or sellable — you earn your edge by fighting for it. Forging
  now costs gold AND ore ((plus+1) ore per tier), so a rich-but-idle hero
  can no longer buy power at the dice table. The dungeon is now also the
  mine.
- The vault: deposit/withdraw at the inn moves coin to a strongbox that
  ambush cannot touch and that SURVIVES the Wyrm-win legacy reset — the
  carry-vs-protect decision the PvP economy was missing.
- Surfaced on both the /watch lobby TV and the in-chat door_status sheet:
  each hero's stacked satchel, carried gold, and vaulted gold.
- Tuning (the sim is the instrument): the ore gate added ~2 days to the
  Vale and ~1.6 to the Cinder Wastes; the greedy bot still slays the Wyrm
  3/3 on both, fully forged to +3/+3, so the loop is not stalled. Defaults
  held — no numbers needed retuning.

Four new banded settings (forge_ore_item, forge_ore_per_plus,
ore_dungeon_drop, ore_forest_chance); both worlds gained an ore item.
Schema mutated in place (banked column, satchel re-encoding) — pre-1.0, no
migration by design; a real migration story is owed at 1.0. Tests 382 ->
419; the vault-survives-rebirth invariant and the codec are revert-verified.
2026-06-13 04:40:40 -07:00

137 lines
6.5 KiB
JSON

{
"name": "The Vale of Understone",
"width": 96,
"height": 48,
"spawn": [20, 24],
"legend": {
".": "grass",
"T": "tree",
"~": "water",
"=": "road",
"f": "forest",
"#": "wall"
},
"terrain_rows": [
"TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT",
"TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT",
"TT..............................................f....f.ff.ffffffffffffffffffffffffffffffffffffTT",
"TT..............................................f..f...f.fffffffffffffffffffffffffffffffffffffTT",
"TT....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ffffTT",
"TT....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ffffTT",
"TT....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ffffTT",
"TT....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ffffTT",
"TT................................................f.ff.ff.fff.ffffffffffffffffffffffffffffffffTT",
"TT................................................f..ff.f.ffffffffffffffffffffffffffffffffffffTT",
"TT.....................................................ffffff.ffffffffffffffffffffffffffffffffTT",
"TT...................................................f.ff...ffffffff##f##fffffffffffffffffffffTT",
"TT.............................................f.f.f..f.ffffffffffff#=.f#fffffffffffffffffffffTT",
"TT....................................................f.f.ff.fffff====f##fffffffffffffffffffffTT",
"TT.................................................f.f...fff.fffff=fffffffffffffffffffffffffffTT",
"TT......................................................fff.ffffff=fffffffffffffffffffffffffffTT",
"TT................................................f...fffff.ffffff=fffffffffffffffffffffffffffTT",
"TT.........................................................ff.ffff=fffffffffffffffffffffffffffTT",
"TT...................................................f.f.ff.ffffff=fffffffffffffffffffffffffffTT",
"TT.....................................................ffff..fffff=fffffffffffffffffffffffffffTT",
"TT................................................f....f....ffffff=fffffffffffffffffffffffffffTT",
"TT................................................f..f.ffff..fffff=fffffffffffffffffffffffffffTT",
"TT.......................................................ff.f.ffff=fffffffffffffffffffffffffffTT",
"TT...............................................f.ff.f.....ffffff=fffffffffffffffffffffffffffTT",
"TT..................==.============================================fffffffffffffffffffffffffffTT",
"TT...............................................f..f....fff.fffffffffffffffffffffffffffffffffTT",
"TT...................................................ff.f.f.f.ffffffffffffffffffffffffffffffffTT",
"TT..................................................f...f.fff.ffffffffffffffffffffffffffffffffTT",
"TT...................................................f...ffff.ffffffffffffffffffffffffffffffffTT",
"TT..................................................ff.fff.ff.ffffffffffffffffffffffffffffffffTT",
"TT.................................................f......f.ffffffffffffffffffffffffffffffffffTT",
"TT....................................................ff..ff..ffffffffffffffffffffffffffffffffTT",
"TT....................................................ff..f..fffffffffffffffffffffffffffffffffTT",
"TT......................................................ffffffffffffffffffffffffffffffffffffffTT",
"TT....................................................f.fff...ffffffffffffffffffffffffffffffffTT",
"TT.................................................ff....fffffffffffffffffffffffffffffffffffffTT",
"TT...............................................f........ffffffffffffffffffffffffffffffffffffTT",
"TT..................................................f.ff.....fffffffffffffffffffffffffffffffffTT",
"TT...............................................f.f...ff.f..fffffffffffffffffffffffffffffffffTT",
"TT.....................................................ff..f.fffffffffffffffffffffffffffffffffTT",
"TT...................................................ff...ffffffffffffffffffffffffffffffffffffTT",
"TT................................................f....f.ffff.ffffffffffffffffffffffffffffffffTT",
"TT..................................................f...ff.fffffffffffffffffffffffffffffffffffTT",
"TT....................................................f.ff.f..ffffffffffffffffffffffffffffffffTT",
"TT.............................................ff......fffffffffffffffffffffffffffffffffffffffTT",
"TT................................................f.f...f....fffffffffffffffffffffffffffffffffTT",
"TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT",
"TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT"
],
"locations": [
{
"key": "inn",
"x": 18,
"y": 24
},
{
"key": "shop",
"x": 22,
"y": 24
},
{
"key": "healer",
"x": 20,
"y": 22
},
{
"key": "dungeon",
"x": 70,
"y": 12
}
],
"zones": [
{
"key": "forest_near",
"rect": [30, 18, 60, 36],
"tier_lo": 1,
"tier_hi": 2
},
{
"key": "dungeon_deep",
"rect": [66, 8, 80, 20],
"tier_lo": 3,
"tier_hi": 5
}
],
"settings": {
"daily_turns": 10,
"rest_cost": 15,
"heal_cost_per_hp": 2,
"starting_gold": 20,
"starting_weapon": "rusty_dagger",
"starting_armor": "cloth_tunic",
"start_hp": 20,
"start_atk": 3,
"start_def": 0,
"xp_base": 100,
"growth": {
"max_hp": 6,
"atk": 2,
"def": 1
},
"bestow_daily_budget": 25,
"dungeon_tiers": [3, 4, 5],
"boss_monster": "wyrm_below",
"wyrm_min_level": 6,
"ambush_min_level": 3,
"ambush_level_band": 2,
"ambush_gold_pct": 25,
"post_daily_cap": 5,
"gamble_max_bet": 50,
"gamble_daily_cap": 5,
"satchel_max": 3,
"forge_base_cost": 60,
"forge_max_plus": 3,
"rare_drop_item": "greater_potion",
"forge_ore_item": "iron_ore",
"forge_ore_per_plus": 1,
"ore_dungeon_drop": 2,
"ore_forest_chance": 0.2,
"watch_theme": "phosphor"
}
}