aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-09-20 15:35:58 -0400
committerhistoria <[not public]>2026-09-20 15:35:58 -0400
commit91b466b6923d3eb1df1658199960fe7aa6db36dc (patch)
treee8a5f308530037f9471e19e6f194177c784c36b6
parentbab5dd653039d026eb3d4e46da7aafef7137fe7c (diff)
downloadthehouseoficarus-91b466b6923d3eb1df1658199960fe7aa6db36dc.tar.gz
feat: new placeholder world
-rw-r--r--building_guide/concurrency.md26
-rw-r--r--data/.admin_history.json1
-rw-r--r--data/courses/brumalia_circuit.yaml47
-rw-r--r--data/courses/domita_circuit.yaml47
-rw-r--r--data/courses/forest_circuit.yaml47
-rw-r--r--data/courses/numisia_circuit.yaml47
-rw-r--r--data/courses/observatory_circuit.yaml47
-rw-r--r--data/economy/journal.jsonl0
-rw-r--r--data/mobs/vesta/apprentice_frame.yaml41
-rw-r--r--data/mobs/vesta/brumalia_chandler.yaml31
-rw-r--r--data/mobs/vesta/brumalia_cook.yaml25
-rw-r--r--data/mobs/vesta/brumalia_reagent.yaml43
-rw-r--r--data/mobs/vesta/brumalia_resident.yaml14
-rw-r--r--data/mobs/vesta/brumalia_tackle.yaml34
-rw-r--r--data/mobs/vesta/casino_archivist.yaml15
-rw-r--r--data/mobs/vesta/casino_cashier.yaml15
-rw-r--r--data/mobs/vesta/casino_host.yaml16
-rw-r--r--data/mobs/vesta/casino_patron.yaml61
-rw-r--r--data/mobs/vesta/corporate_auditor.yaml61
-rw-r--r--data/mobs/vesta/dock_factor.yaml61
-rw-r--r--data/mobs/vesta/domita_assayer.yaml32
-rw-r--r--data/mobs/vesta/domita_contracts.yaml75
-rw-r--r--data/mobs/vesta/domita_resident.yaml14
-rw-r--r--data/mobs/vesta/domita_supplier.yaml34
-rw-r--r--data/mobs/vesta/domita_surgeon.yaml29
-rw-r--r--data/mobs/vesta/domita_technician.yaml29
-rw-r--r--data/mobs/vesta/forest_warden.yaml16
-rw-r--r--data/mobs/vesta/harbor_winch.yaml41
-rw-r--r--data/mobs/vesta/irrigation_frame.yaml41
-rw-r--r--data/mobs/vesta/joanna_lucci.yaml15
-rw-r--r--data/mobs/vesta/numisia_carpenter.yaml22
-rw-r--r--data/mobs/vesta/numisia_chemist.yaml25
-rw-r--r--data/mobs/vesta/numisia_contracts.yaml65
-rw-r--r--data/mobs/vesta/numisia_engineer.yaml39
-rw-r--r--data/mobs/vesta/numisia_fisher.yaml25
-rw-r--r--data/mobs/vesta/numisia_grocer.yaml28
-rw-r--r--data/mobs/vesta/numisia_guide.yaml15
-rw-r--r--data/mobs/vesta/numisia_outfitter.yaml34
-rw-r--r--data/mobs/vesta/numisia_potter.yaml34
-rw-r--r--data/mobs/vesta/numisia_tailor.yaml25
-rw-r--r--data/mobs/vesta/survey_frame.yaml41
-rw-r--r--data/mobs/vesta/tuccia_carpenter.yaml25
-rw-r--r--data/mobs/vesta/tuccia_contracts.yaml75
-rw-r--r--data/mobs/vesta/tuccia_estate_broker.yaml70
-rw-r--r--data/mobs/vesta/tuccia_fletcher.yaml26
-rw-r--r--data/mobs/vesta/tuccia_herbalist.yaml35
-rw-r--r--data/mobs/vesta/tuccia_reclaimer.yaml23
-rw-r--r--data/mobs/vesta/tuccia_resident.yaml14
-rw-r--r--data/mobs/vesta/vestalia_botanist.yaml29
-rw-r--r--data/mobs/vesta/vestalia_seedkeeper.yaml59
-rw-r--r--data/modules/transport_deep_mine.yaml2
-rw-r--r--data/modules/transport_fishing.yaml2
-rw-r--r--data/modules/transport_forest.yaml2
-rw-r--r--data/modules/transport_forge.yaml2
-rw-r--r--data/modules/transport_home.yaml2
-rw-r--r--data/modules/transport_mine.yaml2
-rw-r--r--data/modules/transport_scavenge.yaml2
-rw-r--r--data/modules/transport_town.yaml2
-rw-r--r--data/objects/vesta/brumalia_circuit_exit.yaml5
-rw-r--r--data/objects/vesta/coastal_net_spot.yaml41
-rw-r--r--data/objects/vesta/coastal_tuna_spot.yaml30
-rw-r--r--data/objects/vesta/domita_circuit_exit.yaml5
-rw-r--r--data/objects/vesta/flax_bed.yaml15
-rw-r--r--data/objects/vesta/forest_circuit_exit.yaml5
-rw-r--r--data/objects/vesta/irrigation_relay.yaml16
-rw-r--r--data/objects/vesta/marsh_berries.yaml15
-rw-r--r--data/objects/vesta/numisia_circuit_exit.yaml5
-rw-r--r--data/objects/vesta/observatory_circuit_exit.yaml5
-rw-r--r--data/objects/vesta/observatory_relay.yaml16
-rw-r--r--data/objects/vesta/reagent_thicket.yaml16
-rw-r--r--data/objects/vesta/saltgrass.yaml15
-rw-r--r--data/objects/vesta/survey_relay.yaml15
-rw-r--r--data/objects/vesta/tidal_relay.yaml15
-rw-r--r--data/objects/vesta/training_relay.yaml16
-rw-r--r--data/rooms/agility/8100.yaml8
-rw-r--r--data/rooms/agility/8101.yaml11
-rw-r--r--data/rooms/agility/8102.yaml9
-rw-r--r--data/rooms/agility/8103.yaml9
-rw-r--r--data/rooms/agility/8104.yaml8
-rw-r--r--data/rooms/agility/8105.yaml11
-rw-r--r--data/rooms/agility/8106.yaml9
-rw-r--r--data/rooms/agility/8107.yaml9
-rw-r--r--data/rooms/agility/8108.yaml8
-rw-r--r--data/rooms/agility/8109.yaml11
-rw-r--r--data/rooms/agility/8110.yaml9
-rw-r--r--data/rooms/agility/8111.yaml9
-rw-r--r--data/rooms/agility/8112.yaml8
-rw-r--r--data/rooms/agility/8113.yaml11
-rw-r--r--data/rooms/agility/8114.yaml9
-rw-r--r--data/rooms/agility/8115.yaml9
-rw-r--r--data/rooms/agility/8116.yaml8
-rw-r--r--data/rooms/agility/8117.yaml11
-rw-r--r--data/rooms/agility/8118.yaml9
-rw-r--r--data/rooms/agility/8119.yaml9
-rw-r--r--data/rooms/brumalia/2100.yaml8
-rw-r--r--data/rooms/brumalia/2101.yaml12
-rw-r--r--data/rooms/brumalia/2102.yaml12
-rw-r--r--data/rooms/brumalia/2103.yaml12
-rw-r--r--data/rooms/brumalia/2104.yaml18
-rw-r--r--data/rooms/brumalia/2105.yaml12
-rw-r--r--data/rooms/brumalia/2106.yaml12
-rw-r--r--data/rooms/brumalia/2107.yaml12
-rw-r--r--data/rooms/brumalia/2108.yaml10
-rw-r--r--data/rooms/brumalia/2109.yaml8
-rw-r--r--data/rooms/brumalia/2110.yaml11
-rw-r--r--data/rooms/brumalia/2111.yaml6
-rw-r--r--data/rooms/brumalia/2112.yaml10
-rw-r--r--data/rooms/brumalia/2113.yaml12
-rw-r--r--data/rooms/brumalia/2114.yaml12
-rw-r--r--data/rooms/brumalia/2115.yaml7
-rw-r--r--data/rooms/brumalia/2116.yaml7
-rw-r--r--data/rooms/brumalia/2117.yaml7
-rw-r--r--data/rooms/brumalia/2118.yaml7
-rw-r--r--data/rooms/brumalia/2119.yaml9
-rw-r--r--data/rooms/brumalia/2120.yaml7
-rw-r--r--data/rooms/brumalia/2121.yaml7
-rw-r--r--data/rooms/brumalia/2122.yaml7
-rw-r--r--data/rooms/brumalia/2123.yaml8
-rw-r--r--data/rooms/brumalia/2124.yaml7
-rw-r--r--data/rooms/brumalia/2125.yaml7
-rw-r--r--data/rooms/brumalia/2126.yaml7
-rw-r--r--data/rooms/brumalia/2127.yaml7
-rw-r--r--data/rooms/brumalia/2128.yaml5
-rw-r--r--data/rooms/brumalia/2129.yaml5
-rw-r--r--data/rooms/brumalia/2130.yaml7
-rw-r--r--data/rooms/brumalia/2131.yaml5
-rw-r--r--data/rooms/brumalia/2132.yaml7
-rw-r--r--data/rooms/casino/6100.yaml16
-rw-r--r--data/rooms/casino/6101.yaml8
-rw-r--r--data/rooms/casino/6102.yaml15
-rw-r--r--data/rooms/casino/6103.yaml10
-rw-r--r--data/rooms/casino/6104.yaml12
-rw-r--r--data/rooms/casino/6105.yaml12
-rw-r--r--data/rooms/casino/6106.yaml12
-rw-r--r--data/rooms/casino/6107.yaml8
-rw-r--r--data/rooms/casino/6108.yaml34
-rw-r--r--data/rooms/casino/6109.yaml8
-rw-r--r--data/rooms/casino/6110.yaml34
-rw-r--r--data/rooms/casino/6111.yaml8
-rw-r--r--data/rooms/casino/6112.yaml34
-rw-r--r--data/rooms/casino/6113.yaml8
-rw-r--r--data/rooms/casino/6114.yaml34
-rw-r--r--data/rooms/casino/6115.yaml8
-rw-r--r--data/rooms/casino/6116.yaml34
-rw-r--r--data/rooms/casino/6117.yaml8
-rw-r--r--data/rooms/casino/6118.yaml19
-rw-r--r--data/rooms/casino/6119.yaml8
-rw-r--r--data/rooms/casino/6120.yaml19
-rw-r--r--data/rooms/casino/6121.yaml8
-rw-r--r--data/rooms/casino/6122.yaml21
-rw-r--r--data/rooms/casino/6123.yaml8
-rw-r--r--data/rooms/casino/6124.yaml21
-rw-r--r--data/rooms/casino/6125.yaml8
-rw-r--r--data/rooms/casino/6126.yaml19
-rw-r--r--data/rooms/casino/6127.yaml23
-rw-r--r--data/rooms/casino/6128.yaml23
-rw-r--r--data/rooms/casino/6129.yaml23
-rw-r--r--data/rooms/casino/6130.yaml9
-rw-r--r--data/rooms/casino/6131.yaml6
-rw-r--r--data/rooms/casino/6132.yaml7
-rw-r--r--data/rooms/casino/6133.yaml5
-rw-r--r--data/rooms/casino/6134.yaml7
-rw-r--r--data/rooms/casino/6135.yaml5
-rw-r--r--data/rooms/casino/6136.yaml5
-rw-r--r--data/rooms/casino/6137.yaml10
-rw-r--r--data/rooms/casino/6138.yaml6
-rw-r--r--data/rooms/casino/6139.yaml5
-rw-r--r--data/rooms/casino/6140.yaml12
-rw-r--r--data/rooms/casino/6141.yaml6
-rw-r--r--data/rooms/casino/6142.yaml5
-rw-r--r--data/rooms/casino/6143.yaml12
-rw-r--r--data/rooms/casino/6144.yaml6
-rw-r--r--data/rooms/casino/6145.yaml5
-rw-r--r--data/rooms/casino/6146.yaml12
-rw-r--r--data/rooms/casino/6147.yaml6
-rw-r--r--data/rooms/casino/6148.yaml7
-rw-r--r--data/rooms/casino/6149.yaml14
-rw-r--r--data/rooms/casino/6150.yaml6
-rw-r--r--data/rooms/casino/6151.yaml5
-rw-r--r--data/rooms/casino/6152.yaml10
-rw-r--r--data/rooms/casino/6153.yaml6
-rw-r--r--data/rooms/casino/6154.yaml5
-rw-r--r--data/rooms/casino/6155.yaml12
-rw-r--r--data/rooms/casino/6156.yaml6
-rw-r--r--data/rooms/casino/6157.yaml5
-rw-r--r--data/rooms/casino/6158.yaml12
-rw-r--r--data/rooms/casino/6159.yaml6
-rw-r--r--data/rooms/casino/6160.yaml5
-rw-r--r--data/rooms/casino/6161.yaml12
-rw-r--r--data/rooms/casino/6162.yaml6
-rw-r--r--data/rooms/casino/6163.yaml5
-rw-r--r--data/rooms/casino/6164.yaml14
-rw-r--r--data/rooms/casino/6165.yaml6
-rw-r--r--data/rooms/casino/6166.yaml5
-rw-r--r--data/rooms/casino/6167.yaml10
-rw-r--r--data/rooms/casino/6168.yaml6
-rw-r--r--data/rooms/casino/6169.yaml5
-rw-r--r--data/rooms/casino/6170.yaml12
-rw-r--r--data/rooms/casino/6171.yaml6
-rw-r--r--data/rooms/casino/6172.yaml5
-rw-r--r--data/rooms/casino/6173.yaml12
-rw-r--r--data/rooms/casino/6174.yaml6
-rw-r--r--data/rooms/casino/6175.yaml5
-rw-r--r--data/rooms/casino/6176.yaml12
-rw-r--r--data/rooms/casino/6177.yaml6
-rw-r--r--data/rooms/casino/6178.yaml5
-rw-r--r--data/rooms/casino/6179.yaml12
-rw-r--r--data/rooms/casino/6180.yaml6
-rw-r--r--data/rooms/casino/6181.yaml5
-rw-r--r--data/rooms/coast/2200.yaml10
-rw-r--r--data/rooms/coast/2201.yaml12
-rw-r--r--data/rooms/coast/2202.yaml12
-rw-r--r--data/rooms/coast/2203.yaml12
-rw-r--r--data/rooms/coast/2204.yaml12
-rw-r--r--data/rooms/coast/2205.yaml10
-rw-r--r--data/rooms/coast/2206.yaml10
-rw-r--r--data/rooms/coast/2207.yaml10
-rw-r--r--data/rooms/coast/2208.yaml8
-rw-r--r--data/rooms/coast/2209.yaml8
-rw-r--r--data/rooms/coast/2210.yaml8
-rw-r--r--data/rooms/coast/2211.yaml8
-rw-r--r--data/rooms/coast/2212.yaml8
-rw-r--r--data/rooms/coast/2213.yaml8
-rw-r--r--data/rooms/coast/2214.yaml8
-rw-r--r--data/rooms/coast/2215.yaml8
-rw-r--r--data/rooms/coast/2216.yaml7
-rw-r--r--data/rooms/coast/2217.yaml7
-rw-r--r--data/rooms/coast/2218.yaml7
-rw-r--r--data/rooms/coast/2219.yaml7
-rw-r--r--data/rooms/coast/2220.yaml7
-rw-r--r--data/rooms/coast/2221.yaml12
-rw-r--r--data/rooms/coast/2222.yaml17
-rw-r--r--data/rooms/coast/2223.yaml16
-rw-r--r--data/rooms/coast/2224.yaml10
-rw-r--r--data/rooms/coast/2225.yaml7
-rw-r--r--data/rooms/coast/2226.yaml8
-rw-r--r--data/rooms/domita/5100.yaml10
-rw-r--r--data/rooms/domita/5101.yaml12
-rw-r--r--data/rooms/domita/5102.yaml12
-rw-r--r--data/rooms/domita/5103.yaml12
-rw-r--r--data/rooms/domita/5104.yaml19
-rw-r--r--data/rooms/domita/5105.yaml12
-rw-r--r--data/rooms/domita/5106.yaml12
-rw-r--r--data/rooms/domita/5107.yaml12
-rw-r--r--data/rooms/domita/5108.yaml10
-rw-r--r--data/rooms/domita/5109.yaml10
-rw-r--r--data/rooms/domita/5110.yaml11
-rw-r--r--data/rooms/domita/5111.yaml8
-rw-r--r--data/rooms/domita/5112.yaml8
-rw-r--r--data/rooms/domita/5113.yaml12
-rw-r--r--data/rooms/domita/5114.yaml10
-rw-r--r--data/rooms/domita/5115.yaml7
-rw-r--r--data/rooms/domita/5116.yaml7
-rw-r--r--data/rooms/domita/5117.yaml9
-rw-r--r--data/rooms/domita/5118.yaml7
-rw-r--r--data/rooms/domita/5119.yaml9
-rw-r--r--data/rooms/domita/5120.yaml7
-rw-r--r--data/rooms/domita/5121.yaml7
-rw-r--r--data/rooms/domita/5122.yaml7
-rw-r--r--data/rooms/domita/5123.yaml7
-rw-r--r--data/rooms/domita/5124.yaml7
-rw-r--r--data/rooms/domita/5125.yaml8
-rw-r--r--data/rooms/domita/5126.yaml7
-rw-r--r--data/rooms/domita/5127.yaml7
-rw-r--r--data/rooms/domita/5128.yaml7
-rw-r--r--data/rooms/domita/5129.yaml5
-rw-r--r--data/rooms/domita/5130.yaml9
-rw-r--r--data/rooms/domita/5131.yaml7
-rw-r--r--data/rooms/domita/5132.yaml7
-rw-r--r--data/rooms/domita/5133.yaml5
-rw-r--r--data/rooms/domita/5134.yaml10
-rw-r--r--data/rooms/domita/5135.yaml5
-rw-r--r--data/rooms/domita/5136.yaml9
-rw-r--r--data/rooms/domita/5137.yaml7
-rw-r--r--data/rooms/domita/5138.yaml9
-rw-r--r--data/rooms/domita/5139.yaml5
-rw-r--r--data/rooms/domita/5140.yaml8
-rw-r--r--data/rooms/domita/5141.yaml5
-rw-r--r--data/rooms/domita/5142.yaml10
-rw-r--r--data/rooms/domita/5143.yaml5
-rw-r--r--data/rooms/domita/5144.yaml9
-rw-r--r--data/rooms/domita/5145.yaml7
-rw-r--r--data/rooms/domita/5146.yaml9
-rw-r--r--data/rooms/domita/5147.yaml5
-rw-r--r--data/rooms/domita/5148.yaml10
-rw-r--r--data/rooms/domita/5149.yaml5
-rw-r--r--data/rooms/example_unused/player_housing/99999300.yaml17
-rw-r--r--data/rooms/example_unused/player_housing/99999301.yaml9
-rw-r--r--data/rooms/example_unused/town/999991.yaml89
-rw-r--r--data/rooms/example_unused/town/9999910.yaml12
-rw-r--r--data/rooms/example_unused/town/9999911.yaml26
-rw-r--r--data/rooms/example_unused/town/9999912.yaml30
-rw-r--r--data/rooms/example_unused/town/9999913.yaml48
-rw-r--r--data/rooms/example_unused/town/9999914.yaml26
-rw-r--r--data/rooms/example_unused/town/9999915.yaml18
-rw-r--r--data/rooms/example_unused/town/9999916.yaml19
-rw-r--r--data/rooms/example_unused/town/9999917.yaml18
-rw-r--r--data/rooms/example_unused/town/9999918.yaml16
-rw-r--r--data/rooms/example_unused/town/999992.yaml19
-rw-r--r--data/rooms/example_unused/town/9999920.yaml14
-rw-r--r--data/rooms/example_unused/town/9999922.yaml8
-rw-r--r--data/rooms/example_unused/town/9999923.yaml8
-rw-r--r--data/rooms/example_unused/town/9999924.yaml8
-rw-r--r--data/rooms/example_unused/town/9999925.yaml8
-rw-r--r--data/rooms/example_unused/town/9999926.yaml8
-rw-r--r--data/rooms/example_unused/town/9999927.yaml8
-rw-r--r--data/rooms/example_unused/town/9999928.yaml6
-rw-r--r--data/rooms/example_unused/town/999993.yaml21
-rw-r--r--data/rooms/example_unused/town/9999931.yaml14
-rw-r--r--data/rooms/example_unused/town/999994.yaml46
-rw-r--r--data/rooms/example_unused/town/999995.yaml18
-rw-r--r--data/rooms/example_unused/town/999996.yaml18
-rw-r--r--data/rooms/example_unused/town/999997.yaml17
-rw-r--r--data/rooms/example_unused/town/999998.yaml13
-rw-r--r--data/rooms/example_unused/town/999999.yaml17
-rw-r--r--data/rooms/example_unused/wilderness/99999150.yaml36
-rw-r--r--data/rooms/example_unused/wilderness/99999151.yaml20
-rw-r--r--data/rooms/example_unused/wilderness/99999152.yaml20
-rw-r--r--data/rooms/example_unused/wilderness/99999153.yaml16
-rw-r--r--data/rooms/example_unused/wilderness/99999154.yaml14
-rw-r--r--data/rooms/example_unused/wilderness/99999160.yaml26
-rw-r--r--data/rooms/example_unused/wilderness/99999161.yaml25
-rw-r--r--data/rooms/example_unused/wilderness/99999162.yaml14
-rw-r--r--data/rooms/example_unused/wilderness/99999170.yaml17
-rw-r--r--data/rooms/example_unused/wilderness/99999171.yaml15
-rw-r--r--data/rooms/example_unused/wilderness/99999180.yaml9
-rw-r--r--data/rooms/example_unused/wilderness/99999181.yaml12
-rw-r--r--data/rooms/forest/4100.yaml16
-rw-r--r--data/rooms/forest/4101.yaml9
-rw-r--r--data/rooms/forest/4102.yaml18
-rw-r--r--data/rooms/forest/4103.yaml18
-rw-r--r--data/rooms/forest/4104.yaml18
-rw-r--r--data/rooms/forest/4105.yaml16
-rw-r--r--data/rooms/forest/4106.yaml12
-rw-r--r--data/rooms/forest/4107.yaml12
-rw-r--r--data/rooms/forest/4108.yaml10
-rw-r--r--data/rooms/forest/4109.yaml8
-rw-r--r--data/rooms/forest/4110.yaml9
-rw-r--r--data/rooms/forest/4111.yaml7
-rw-r--r--data/rooms/forest/4112.yaml7
-rw-r--r--data/rooms/forest/4113.yaml8
-rw-r--r--data/rooms/forest/4114.yaml11
-rw-r--r--data/rooms/forest/4115.yaml10
-rw-r--r--data/rooms/forest/4116.yaml10
-rw-r--r--data/rooms/forest/4117.yaml10
-rw-r--r--data/rooms/forest/4118.yaml7
-rw-r--r--data/rooms/forest/4119.yaml7
-rw-r--r--data/rooms/highlands/5200.yaml8
-rw-r--r--data/rooms/highlands/5201.yaml10
-rw-r--r--data/rooms/highlands/5202.yaml12
-rw-r--r--data/rooms/highlands/5203.yaml8
-rw-r--r--data/rooms/highlands/5204.yaml7
-rw-r--r--data/rooms/highlands/5205.yaml10
-rw-r--r--data/rooms/highlands/5206.yaml10
-rw-r--r--data/rooms/highlands/5207.yaml8
-rw-r--r--data/rooms/highlands/5208.yaml10
-rw-r--r--data/rooms/highlands/5209.yaml17
-rw-r--r--data/rooms/highlands/5210.yaml12
-rw-r--r--data/rooms/highlands/5211.yaml10
-rw-r--r--data/rooms/highlands/5212.yaml17
-rw-r--r--data/rooms/highlands/5213.yaml12
-rw-r--r--data/rooms/highlands/5214.yaml8
-rw-r--r--data/rooms/highlands/5215.yaml8
-rw-r--r--data/rooms/highlands/5216.yaml8
-rw-r--r--data/rooms/highlands/5217.yaml8
-rw-r--r--data/rooms/highlands/5218.yaml8
-rw-r--r--data/rooms/highlands/5219.yaml8
-rw-r--r--data/rooms/highlands/5220.yaml16
-rw-r--r--data/rooms/highlands/5221.yaml17
-rw-r--r--data/rooms/highlands/5222.yaml16
-rw-r--r--data/rooms/highlands/5223.yaml16
-rw-r--r--data/rooms/highlands/5224.yaml10
-rw-r--r--data/rooms/highlands/5225.yaml10
-rw-r--r--data/rooms/highlands/5226.yaml7
-rw-r--r--data/rooms/highlands/5227.yaml7
-rw-r--r--data/rooms/highlands/5228.yaml7
-rw-r--r--data/rooms/intro/1001.yaml2
-rw-r--r--data/rooms/intro/1003.yaml2
-rw-r--r--data/rooms/intro/1004.yaml13
-rw-r--r--data/rooms/intro/1005.yaml14
-rw-r--r--data/rooms/intro/1006.yaml13
-rw-r--r--data/rooms/intro/2001.yaml75
-rw-r--r--data/rooms/intro/2006.yaml14
-rw-r--r--data/rooms/numisia/1100.yaml8
-rw-r--r--data/rooms/numisia/1101.yaml14
-rw-r--r--data/rooms/numisia/1102.yaml12
-rw-r--r--data/rooms/numisia/1103.yaml12
-rw-r--r--data/rooms/numisia/1104.yaml19
-rw-r--r--data/rooms/numisia/1105.yaml12
-rw-r--r--data/rooms/numisia/1106.yaml12
-rw-r--r--data/rooms/numisia/1107.yaml12
-rw-r--r--data/rooms/numisia/1108.yaml8
-rw-r--r--data/rooms/numisia/1109.yaml8
-rw-r--r--data/rooms/numisia/1110.yaml11
-rw-r--r--data/rooms/numisia/1111.yaml8
-rw-r--r--data/rooms/numisia/1112.yaml8
-rw-r--r--data/rooms/numisia/1113.yaml12
-rw-r--r--data/rooms/numisia/1114.yaml12
-rw-r--r--data/rooms/numisia/1115.yaml7
-rw-r--r--data/rooms/numisia/1116.yaml9
-rw-r--r--data/rooms/numisia/1117.yaml8
-rw-r--r--data/rooms/numisia/1118.yaml7
-rw-r--r--data/rooms/numisia/1119.yaml10
-rw-r--r--data/rooms/numisia/1120.yaml9
-rw-r--r--data/rooms/numisia/1121.yaml7
-rw-r--r--data/rooms/numisia/1122.yaml7
-rw-r--r--data/rooms/numisia/1123.yaml7
-rw-r--r--data/rooms/numisia/1124.yaml10
-rw-r--r--data/rooms/numisia/1125.yaml9
-rw-r--r--data/rooms/numisia/1126.yaml7
-rw-r--r--data/rooms/numisia/1127.yaml7
-rw-r--r--data/rooms/numisia/1128.yaml7
-rw-r--r--data/rooms/numisia/1129.yaml7
-rw-r--r--data/rooms/numisia/1130.yaml7
-rw-r--r--data/rooms/numisia/1131.yaml25
-rw-r--r--data/rooms/numisia/1132.yaml7
-rw-r--r--data/rooms/numisia/1133.yaml8
-rw-r--r--data/rooms/numisia/1134.yaml12
-rw-r--r--data/rooms/numisia_outskirts/1200.yaml7
-rw-r--r--data/rooms/numisia_outskirts/1201.yaml11
-rw-r--r--data/rooms/numisia_outskirts/1202.yaml9
-rw-r--r--data/rooms/numisia_outskirts/1203.yaml7
-rw-r--r--data/rooms/numisia_outskirts/1204.yaml9
-rw-r--r--data/rooms/numisia_outskirts/1205.yaml7
-rw-r--r--data/rooms/numisia_outskirts/1206.yaml7
-rw-r--r--data/rooms/numisia_outskirts/1207.yaml9
-rw-r--r--data/rooms/numisia_outskirts/1208.yaml7
-rw-r--r--data/rooms/numisia_outskirts/1209.yaml9
-rw-r--r--data/rooms/numisia_outskirts/1210.yaml8
-rw-r--r--data/rooms/numisia_outskirts/1211.yaml7
-rw-r--r--data/rooms/numisia_outskirts/1212.yaml9
-rw-r--r--data/rooms/numisia_outskirts/1213.yaml10
-rw-r--r--data/rooms/numisia_outskirts/1214.yaml9
-rw-r--r--data/rooms/numisia_outskirts/1215.yaml8
-rw-r--r--data/rooms/numisia_outskirts/1216.yaml7
-rw-r--r--data/rooms/roads/7100.yaml12
-rw-r--r--data/rooms/roads/7101.yaml7
-rw-r--r--data/rooms/roads/7102.yaml8
-rw-r--r--data/rooms/roads/7103.yaml8
-rw-r--r--data/rooms/roads/7104.yaml7
-rw-r--r--data/rooms/roads/7105.yaml8
-rw-r--r--data/rooms/roads/7106.yaml8
-rw-r--r--data/rooms/roads/7107.yaml7
-rw-r--r--data/rooms/roads/7108.yaml8
-rw-r--r--data/rooms/roads/7109.yaml8
-rw-r--r--data/rooms/roads/7110.yaml7
-rw-r--r--data/rooms/roads/7111.yaml8
-rw-r--r--data/rooms/roads/7112.yaml8
-rw-r--r--data/rooms/roads/7113.yaml8
-rw-r--r--data/rooms/roads/7114.yaml8
-rw-r--r--data/rooms/roads/7115.yaml8
-rw-r--r--data/rooms/roads/7116.yaml8
-rw-r--r--data/rooms/roads/7117.yaml8
-rw-r--r--data/rooms/roads/7118.yaml8
-rw-r--r--data/rooms/roads/7119.yaml8
-rw-r--r--data/rooms/roads/7120.yaml8
-rw-r--r--data/rooms/roads/7121.yaml8
-rw-r--r--data/rooms/roads/7122.yaml8
-rw-r--r--data/rooms/roads/7123.yaml7
-rw-r--r--data/rooms/roads/7124.yaml8
-rw-r--r--data/rooms/roads/7125.yaml7
-rw-r--r--data/rooms/roads/7126.yaml8
-rw-r--r--data/rooms/roads/7127.yaml7
-rw-r--r--data/rooms/roads/7128.yaml8
-rw-r--r--data/rooms/roads/7129.yaml7
-rw-r--r--data/rooms/roads/7130.yaml8
-rw-r--r--data/rooms/roads/7131.yaml7
-rw-r--r--data/rooms/roads/7132.yaml8
-rw-r--r--data/rooms/roads/7133.yaml8
-rw-r--r--data/rooms/roads/7134.yaml10
-rw-r--r--data/rooms/roads/7135.yaml8
-rw-r--r--data/rooms/roads/7136.yaml8
-rw-r--r--data/rooms/roads/7137.yaml8
-rw-r--r--data/rooms/roads/7138.yaml8
-rw-r--r--data/rooms/roads/7139.yaml8
-rw-r--r--data/rooms/roads/7140.yaml8
-rw-r--r--data/rooms/roads/7141.yaml8
-rw-r--r--data/rooms/roads/7142.yaml8
-rw-r--r--data/rooms/roads/7143.yaml8
-rw-r--r--data/rooms/roads/7144.yaml8
-rw-r--r--data/rooms/roads/7145.yaml8
-rw-r--r--data/rooms/roads/7146.yaml8
-rw-r--r--data/rooms/tuccia/3100.yaml8
-rw-r--r--data/rooms/tuccia/3101.yaml12
-rw-r--r--data/rooms/tuccia/3102.yaml12
-rw-r--r--data/rooms/tuccia/3103.yaml12
-rw-r--r--data/rooms/tuccia/3104.yaml18
-rw-r--r--data/rooms/tuccia/3105.yaml12
-rw-r--r--data/rooms/tuccia/3106.yaml12
-rw-r--r--data/rooms/tuccia/3107.yaml12
-rw-r--r--data/rooms/tuccia/3108.yaml6
-rw-r--r--data/rooms/tuccia/3109.yaml8
-rw-r--r--data/rooms/tuccia/3110.yaml11
-rw-r--r--data/rooms/tuccia/3111.yaml8
-rw-r--r--data/rooms/tuccia/3112.yaml8
-rw-r--r--data/rooms/tuccia/3113.yaml12
-rw-r--r--data/rooms/tuccia/3114.yaml12
-rw-r--r--data/rooms/tuccia/3115.yaml7
-rw-r--r--data/rooms/tuccia/3116.yaml7
-rw-r--r--data/rooms/tuccia/3117.yaml7
-rw-r--r--data/rooms/tuccia/3118.yaml9
-rw-r--r--data/rooms/tuccia/3119.yaml9
-rw-r--r--data/rooms/tuccia/3120.yaml8
-rw-r--r--data/rooms/tuccia/3121.yaml7
-rw-r--r--data/rooms/tuccia/3122.yaml7
-rw-r--r--data/rooms/tuccia/3123.yaml7
-rw-r--r--data/rooms/tuccia/3124.yaml9
-rw-r--r--data/rooms/tuccia/3125.yaml8
-rw-r--r--data/rooms/tuccia/3126.yaml7
-rw-r--r--data/rooms/tuccia/3127.yaml7
-rw-r--r--data/rooms/tuccia/3128.yaml5
-rw-r--r--data/rooms/tuccia/3129.yaml5
-rw-r--r--data/rooms/tuccia/3130.yaml7
-rw-r--r--data/rooms/tuccia/3131.yaml7
-rw-r--r--data/rooms/tuccia/3132.yaml7
-rw-r--r--data/rooms/tuccia/3133.yaml7
-rw-r--r--data/rooms/vestalia/1300.yaml10
-rw-r--r--data/rooms/vestalia/1301.yaml8
-rw-r--r--data/rooms/vestalia/1302.yaml12
-rw-r--r--data/rooms/vestalia/1303.yaml12
-rw-r--r--data/rooms/vestalia/1304.yaml12
-rw-r--r--data/rooms/vestalia/1305.yaml12
-rw-r--r--data/rooms/vestalia/1306.yaml18
-rw-r--r--data/rooms/vestalia/1307.yaml12
-rw-r--r--data/rooms/vestalia/1308.yaml12
-rw-r--r--data/rooms/vestalia/1309.yaml12
-rw-r--r--data/rooms/vestalia/1310.yaml12
-rw-r--r--data/rooms/vestalia/1311.yaml10
-rw-r--r--data/rooms/vestalia/1312.yaml8
-rw-r--r--data/rooms/vestalia/1313.yaml8
-rw-r--r--data/rooms/vestalia/1314.yaml7
-rw-r--r--data/rooms/vestalia/1315.yaml7
-rw-r--r--data/rooms/vestalia/1316.yaml7
-rw-r--r--data/rooms/vestalia/1317.yaml9
-rw-r--r--data/rooms/vestalia/1318.yaml7
-rw-r--r--data/rooms/vestalia/1319.yaml7
-rw-r--r--data/rooms/vestalia/1320.yaml9
-rw-r--r--data/rooms/vestalia/1321.yaml7
-rw-r--r--data/rooms/vestalia/1322.yaml7
-rw-r--r--data/rooms/vestalia/1323.yaml7
-rw-r--r--data/rooms/vestalia/1324.yaml7
-rw-r--r--data/rooms/vestalia/1325.yaml7
-rw-r--r--data/rooms/vestalia/1326.yaml7
-rw-r--r--data/rooms/vestalia/1327.yaml7
-rw-r--r--data/rooms/vestalia/1328.yaml7
-rw-r--r--data/rooms/vestalia/1329.yaml7
-rw-r--r--data/rooms/vestalia/1330.yaml7
-rw-r--r--data/rooms/vestalia/1331.yaml7
-rw-r--r--data/rooms/vestalia/1332.yaml13
-rw-r--r--data/rooms/vestalia/1333.yaml8
-rw-r--r--data/rooms/wetlands/3200.yaml12
-rw-r--r--data/rooms/wetlands/3201.yaml10
-rw-r--r--data/rooms/wetlands/3202.yaml10
-rw-r--r--data/rooms/wetlands/3203.yaml12
-rw-r--r--data/rooms/wetlands/3204.yaml10
-rw-r--r--data/rooms/wetlands/3205.yaml10
-rw-r--r--data/rooms/wetlands/3206.yaml8
-rw-r--r--data/rooms/wetlands/3207.yaml8
-rw-r--r--data/rooms/wetlands/3208.yaml8
-rw-r--r--data/rooms/wetlands/3209.yaml8
-rw-r--r--data/rooms/wetlands/3210.yaml8
-rw-r--r--data/rooms/wetlands/3211.yaml8
-rw-r--r--data/rooms/wetlands/3212.yaml8
-rw-r--r--data/rooms/wetlands/3213.yaml8
-rw-r--r--data/rooms/wetlands/3214.yaml8
-rw-r--r--data/rooms/wetlands/3215.yaml12
-rw-r--r--data/rooms/wetlands/3216.yaml16
-rw-r--r--data/rooms/wetlands/3217.yaml17
-rw-r--r--data/rooms/wetlands/3218.yaml16
-rw-r--r--data/rooms/wetlands/3219.yaml10
-rw-r--r--internal/game/casino.go59
-rw-r--r--internal/game/casino_durability_test.go135
-rw-r--r--internal/game/content_refs.go4
-rw-r--r--internal/game/vesta_world_test.go379
-rw-r--r--internal/persistence/txn.go60
-rw-r--r--internal/persistence/txn_directory_durability_test.go175
576 files changed, 6965 insertions, 998 deletions
diff --git a/building_guide/concurrency.md b/building_guide/concurrency.md
index 40be4d9..187b942 100644
--- a/building_guide/concurrency.md
+++ b/building_guide/concurrency.md
@@ -137,10 +137,14 @@ there is no cross-file crash window to reconcile.
kind, credits as credits) and clears the ledger in one save. Graceful
shutdown (`Game.runShutdown` → `Casino.RefundAll`) and eviction use it.
-A failed save reverts the in-memory balance and ledger together, so a player
-is never charged for, credited with, or refunded a stake that is not durable.
-On `persistence.ErrDurabilityUncertain` a wager keeps its in-memory debit and
-pending entry, because the visible file already carries both.
+A save failure **before replacement** reverts the in-memory balance and
+ledger together. On `persistence.ErrDurabilityUncertain`, every wallet
+operation (wager, payout, stake resolution, refund) instead keeps the applied
+balance and ledger, because the visible file already carries both. The wallet
+logs the storage fault and reports the operation as applied so callers do not
+retry a payout or refund a resolved stake. This does not promise survival of
+a subsequent OS/power crash; it prevents a later save from overwriting the
+visible result with reverted memory.
At startup (`game.New` → `recoverPendingWagers`, `internal/game/money.go`)
any stake still listed in a character's `PendingWagers` is refunded: a listed
@@ -160,8 +164,9 @@ at a cost of ~1,400 lines of engine code and ~2,000 lines of tests.
With the crash-consistency bar deliberately lowered to "a rare ungraceful
stop may lose or refund one in-flight stake, and must never double-pay", the
single atomic character save is sufficient: a listed pending stake is
-refunded, and a settlement whose save fails simply leaves the stake pending
-and the win unannounced (never paid on top of the refund). Do not reintroduce
+refunded, and a settlement whose save fails before replacement leaves the
+stake pending and the win unannounced (never paid on top of the refund).
+Post-replacement uncertainty follows the applied-state policy above. Do not reintroduce
a second money store, per-record ordering, or an operator-inspection queue
without an explicit decision to restore bank-grade guarantees.
@@ -178,9 +183,12 @@ payouts) clamp at the cap and log rather than wrap.
Account and character lifecycle operations (create, rename, delete, purge)
are single journal transactions (`internal/persistence/txn.go`): a journal
entry with before-images is written durably BEFORE any file changes, the
-operations apply, and the journal is removed at the commit point. Any
-failure rolls back every applied operation; a crash mid-commit is rolled
-back at the next startup by `persistence.Recover`.
+operations apply, and the journal is removed at the commit point. Deletes
+sync their parent directory; moves sync both affected directories (once if
+they are the same). Rollback also syncs deletions, including retries where
+the file is already absent, before retiring the journal. An apply failure
+attempts rollback; if rollback fails, the journal stays for recovery. A crash
+mid-commit is rolled back at the next startup by `persistence.Recover`.
Characters carry a stable UUID (`player.Player.ID`) and owner field
(`player.Player.Account`), assigned at creation and backfilled at first
diff --git a/data/.admin_history.json b/data/.admin_history.json
deleted file mode 100644
index e856da6..0000000
--- a/data/.admin_history.json
+++ /dev/null
@@ -1 +0,0 @@
-{"history":[{"time":"2026-07-31T13:48:03-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"id: 2001\nname: Test Room\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 1005\n south:\n room: 2006\n west:\n room: 1001\nobjects:\n - name: hidden guy\n hidden: true\n description:\n - text: YOU FOUND HIM\n - id: tree\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 1\n - id: bucket_of_water\n quantity: 1\n respawn_ticks: 1\nmobs:\n - id: man\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\ncasino_tables:\n - id: slots\n game: slots\n max_players: 8\n betting_ticks: 20\n min_bet: 1\n max_bet: 1000\n\n","new_content":"block_transport: false\ncasino_tables:\n - betting_ticks: 20\n game: slots\n id: slots\n max_bet: 1000\n max_players: 8\n min_bet: 1\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 1005\n south:\n room: 2006\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 1\n - id: bucket_of_water\n quantity: 1\n respawn_ticks: 1\n - id: chips\n quantity: 1\n respawn_ticks: 0\nmobs:\n - id: man\nname: Test Room\nobjects:\n - description:\n - text: YOU FOUND HIM\n hidden: true\n name: hidden guy\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-07-31T13:48:06-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncasino_tables:\n - betting_ticks: 20\n game: slots\n id: slots\n max_bet: 1000\n max_players: 8\n min_bet: 1\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 1005\n south:\n room: 2006\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 1\n - id: bucket_of_water\n quantity: 1\n respawn_ticks: 1\n - id: chips\n quantity: 1\n respawn_ticks: 0\nmobs:\n - id: man\nname: Test Room\nobjects:\n - description:\n - text: YOU FOUND HIM\n hidden: true\n name: hidden guy\n - id: tree\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncasino_tables:\n - betting_ticks: 20\n game: slots\n id: slots\n max_bet: 1000\n max_players: 8\n min_bet: 1\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 1005\n south:\n room: 2006\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 1\n - id: bucket_of_water\n quantity: 1\n respawn_ticks: 1\n - id: chips\n quantity: 5000\n respawn_ticks: 0\nmobs:\n - id: man\nname: Test Room\nobjects:\n - description:\n - text: YOU FOUND HIM\n hidden: true\n name: hidden guy\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-07-31T13:48:07-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncasino_tables:\n - betting_ticks: 20\n game: slots\n id: slots\n max_bet: 1000\n max_players: 8\n min_bet: 1\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 1005\n south:\n room: 2006\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 1\n - id: bucket_of_water\n quantity: 1\n respawn_ticks: 1\n - id: chips\n quantity: 5000\n respawn_ticks: 0\nmobs:\n - id: man\nname: Test Room\nobjects:\n - description:\n - text: YOU FOUND HIM\n hidden: true\n name: hidden guy\n - id: tree\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncasino_tables:\n - betting_ticks: 20\n game: slots\n id: slots\n max_bet: 1000\n max_players: 8\n min_bet: 1\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 1005\n south:\n room: 2006\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 1\n - id: bucket_of_water\n quantity: 1\n respawn_ticks: 1\n - id: chips\n quantity: 5000\n respawn_ticks: 1\nmobs:\n - id: man\nname: Test Room\nobjects:\n - description:\n - text: YOU FOUND HIM\n hidden: true\n name: hidden guy\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false}],"redo":null} \ No newline at end of file
diff --git a/data/courses/brumalia_circuit.yaml b/data/courses/brumalia_circuit.yaml
new file mode 100644
index 0000000..e67a561
--- /dev/null
+++ b/data/courses/brumalia_circuit.yaml
@@ -0,0 +1,47 @@
+name: Brumalia Rigging Circuit
+required_level: 20
+start_room: 8108
+completion_xp: 130
+obstacles:
+- room_id: 8109
+ verb: balance
+ xp: 28
+ fail_damage:
+ - 1
+ - 3
+ phases:
+ - message: You approach the balance beam.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
+- room_id: 8110
+ verb: vault
+ xp: 28
+ fail_damage:
+ - 1
+ - 3
+ phases:
+ - message: You approach the broken wall.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
+- room_id: 8111
+ verb: crawl
+ xp: 28
+ fail_damage:
+ - 1
+ - 3
+ phases:
+ - message: You approach the low tunnel.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
diff --git a/data/courses/domita_circuit.yaml b/data/courses/domita_circuit.yaml
new file mode 100644
index 0000000..6827d94
--- /dev/null
+++ b/data/courses/domita_circuit.yaml
@@ -0,0 +1,47 @@
+name: Domita Survey Circuit
+required_level: 30
+start_room: 8112
+completion_xp: 180
+obstacles:
+- room_id: 8113
+ verb: balance
+ xp: 38
+ fail_damage:
+ - 1
+ - 3
+ phases:
+ - message: You approach the balance beam.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
+- room_id: 8114
+ verb: vault
+ xp: 38
+ fail_damage:
+ - 1
+ - 3
+ phases:
+ - message: You approach the broken wall.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
+- room_id: 8115
+ verb: crawl
+ xp: 38
+ fail_damage:
+ - 1
+ - 3
+ phases:
+ - message: You approach the low tunnel.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
diff --git a/data/courses/forest_circuit.yaml b/data/courses/forest_circuit.yaml
new file mode 100644
index 0000000..3fd187c
--- /dev/null
+++ b/data/courses/forest_circuit.yaml
@@ -0,0 +1,47 @@
+name: Forest Ranger Circuit
+required_level: 10
+start_room: 8104
+completion_xp: 80
+obstacles:
+- room_id: 8105
+ verb: balance
+ xp: 18
+ fail_damage:
+ - 1
+ - 2
+ phases:
+ - message: You approach the balance beam.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
+- room_id: 8106
+ verb: vault
+ xp: 18
+ fail_damage:
+ - 1
+ - 2
+ phases:
+ - message: You approach the broken wall.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
+- room_id: 8107
+ verb: crawl
+ xp: 18
+ fail_damage:
+ - 1
+ - 2
+ phases:
+ - message: You approach the low tunnel.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
diff --git a/data/courses/numisia_circuit.yaml b/data/courses/numisia_circuit.yaml
new file mode 100644
index 0000000..f31afb2
--- /dev/null
+++ b/data/courses/numisia_circuit.yaml
@@ -0,0 +1,47 @@
+name: Numisia Field Circuit
+required_level: 1
+start_room: 8100
+completion_xp: 35
+obstacles:
+- room_id: 8101
+ verb: balance
+ xp: 9
+ fail_damage:
+ - 1
+ - 2
+ phases:
+ - message: You approach the balance beam.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
+- room_id: 8102
+ verb: vault
+ xp: 9
+ fail_damage:
+ - 1
+ - 2
+ phases:
+ - message: You approach the broken wall.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
+- room_id: 8103
+ verb: crawl
+ xp: 9
+ fail_damage:
+ - 1
+ - 2
+ phases:
+ - message: You approach the low tunnel.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
diff --git a/data/courses/observatory_circuit.yaml b/data/courses/observatory_circuit.yaml
new file mode 100644
index 0000000..1d96a15
--- /dev/null
+++ b/data/courses/observatory_circuit.yaml
@@ -0,0 +1,47 @@
+name: Observatory Circuit
+required_level: 40
+start_room: 8116
+completion_xp: 230
+obstacles:
+- room_id: 8117
+ verb: balance
+ xp: 48
+ fail_damage:
+ - 1
+ - 4
+ phases:
+ - message: You approach the balance beam.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
+- room_id: 8118
+ verb: vault
+ xp: 48
+ fail_damage:
+ - 1
+ - 4
+ phases:
+ - message: You approach the broken wall.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
+- room_id: 8119
+ verb: crawl
+ xp: 48
+ fail_damage:
+ - 1
+ - 4
+ phases:
+ - message: You approach the low tunnel.
+ delay: 0
+ - message: You test your footing and commit to the obstacle.
+ delay: 2
+ fail_check: true
+ - message: You reach the next marker.
+ delay: 2
diff --git a/data/economy/journal.jsonl b/data/economy/journal.jsonl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/data/economy/journal.jsonl
diff --git a/data/mobs/vesta/apprentice_frame.yaml b/data/mobs/vesta/apprentice_frame.yaml
new file mode 100644
index 0000000..86f5305
--- /dev/null
+++ b/data/mobs/vesta/apprentice_frame.yaml
@@ -0,0 +1,41 @@
+combat:
+ aggressive: false
+ attack_types:
+ - crush
+ kind: task
+ respawn_ticks: 40
+ size: medium
+ stats:
+ bonuses:
+ attack_bonus: 0
+ ranged_bonus: 0
+ ranged_strength_bonus: 0
+ science_bonus: 0
+ science_percent_bonus: 0
+ strength_bonus: 0
+ defense: 1
+ defenses:
+ crush_defense: 0
+ ranged_defense: 10
+ science_defense: 10
+ slash_defense: 40
+ stab_defense: 40
+ hp: 12
+ max_melee_hit: 0
+ speed: 5
+description: A public maintenance worksite. Work on it to practice combat skills without fighting; completed
+ jobs pay credits.
+drops:
+ loot:
+ - item_id: credits
+ quantity: 20
+ weight: 1
+idle_descriptions:
+- stands half-assembled, panels waiting to be fitted
+- has loose cabling dangling from an open junction box
+- catches the light on its few mounted panels
+name: apprentice panel frame
+task:
+ complete_message: The mechanism passes its final check. Your maintenance payment is ready to collect.
+ progress_noun: assembly
+ verb: assemble
diff --git a/data/mobs/vesta/brumalia_chandler.yaml b/data/mobs/vesta/brumalia_chandler.yaml
new file mode 100644
index 0000000..3f9eed2
--- /dev/null
+++ b/data/mobs/vesta/brumalia_chandler.yaml
@@ -0,0 +1,31 @@
+name: Dena the chandler
+description: Dena smells faintly of wax and sea salt.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Every ship needs a saw. Every traveler eventually needs a light.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: saw
+ stock: 15
+ restock_ticks: 100
+ - item_id: hammer
+ stock: 15
+ restock_ticks: 100
+ - item_id: firesteel
+ stock: 15
+ restock_ticks: 100
+ - item_id: lighter
+ stock: 15
+ restock_ticks: 100
+ - item_id: empty_bucket
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/brumalia_cook.yaml b/data/mobs/vesta/brumalia_cook.yaml
new file mode 100644
index 0000000..c4928a6
--- /dev/null
+++ b/data/mobs/vesta/brumalia_cook.yaml
@@ -0,0 +1,25 @@
+name: Ressa the galley cook
+description: Ressa tests the stove with a drop of water.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - A raw shark is no use in a fight. The public galley is next door.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: salt
+ stock: 15
+ restock_ticks: 100
+ - item_id: pot_of_flour
+ stock: 15
+ restock_ticks: 100
+ - item_id: chocolate_dust
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/brumalia_reagent.yaml b/data/mobs/vesta/brumalia_reagent.yaml
new file mode 100644
index 0000000..7e3e3b0
--- /dev/null
+++ b/data/mobs/vesta/brumalia_reagent.yaml
@@ -0,0 +1,43 @@
+name: Jun the reagent factor
+description: Jun stores reagent bottles in padded cargo crates.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Coastal salvage feeds the hydro and cosmic altars. Do not enter the wreck holds unprepared.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: hydro_identifier
+ stock: 15
+ restock_ticks: 100
+ - item_id: cosmic_identifier
+ stock: 15
+ restock_ticks: 100
+ - item_id: chaos_identifier
+ stock: 15
+ restock_ticks: 100
+ - item_id: vial
+ stock: 100
+ restock_ticks: 100
+ - item_id: arachnid_enzyme
+ stock: 15
+ restock_ticks: 100
+ - item_id: lawjunk
+ stock: 250
+ restock_ticks: 20
+ - item_id: naturejunk
+ stock: 250
+ restock_ticks: 20
+ - item_id: cosmicjunk
+ stock: 250
+ restock_ticks: 20
+ - item_id: chaosjunk
+ stock: 250
+ restock_ticks: 20
diff --git a/data/mobs/vesta/brumalia_resident.yaml b/data/mobs/vesta/brumalia_resident.yaml
new file mode 100644
index 0000000..172d85f
--- /dev/null
+++ b/data/mobs/vesta/brumalia_resident.yaml
@@ -0,0 +1,14 @@
+name: Leto the sail mender
+description: Leto’s fingers move constantly around a half-finished seam.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - People arrive with fortunes and leave with stories. I would settle for a dry roof.
+ options:
+ - text: Thank you.
diff --git a/data/mobs/vesta/brumalia_tackle.yaml b/data/mobs/vesta/brumalia_tackle.yaml
new file mode 100644
index 0000000..bd9cdd5
--- /dev/null
+++ b/data/mobs/vesta/brumalia_tackle.yaml
@@ -0,0 +1,34 @@
+name: Captain Orso
+description: Orso has retired from sailing, not from arguing about fish.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - 'The outer piers are safe. '
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: fly_fishing_rod
+ stock: 15
+ restock_ticks: 100
+ - item_id: big_fishing_net
+ stock: 15
+ restock_ticks: 100
+ - item_id: lobster_pot
+ stock: 15
+ restock_ticks: 100
+ - item_id: harpoon
+ stock: 15
+ restock_ticks: 100
+ - item_id: fishing_bait
+ stock: 100
+ restock_ticks: 100
+ - item_id: feather
+ stock: 100
+ restock_ticks: 100
diff --git a/data/mobs/vesta/casino_archivist.yaml b/data/mobs/vesta/casino_archivist.yaml
new file mode 100644
index 0000000..197497e
--- /dev/null
+++ b/data/mobs/vesta/casino_archivist.yaml
@@ -0,0 +1,15 @@
+name: Marlo the archivist
+description: Marlo files building plans under obsolete company names.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - The corporation owns the lights, the pavement and most of the debts. The original town charter
+ is in the civic archive, not in this building.
+ options:
+ - text: Thank you.
diff --git a/data/mobs/vesta/casino_cashier.yaml b/data/mobs/vesta/casino_cashier.yaml
new file mode 100644
index 0000000..c02cd10
--- /dev/null
+++ b/data/mobs/vesta/casino_cashier.yaml
@@ -0,0 +1,15 @@
+name: Fel the cashier
+description: Fel counts credits beneath a brass grille.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - The bank booth handles your storage. Tables and machines wager credits directly; there is no chip
+ exchange fee. Read the limits in each room before joining.
+ options:
+ - text: Thank you.
diff --git a/data/mobs/vesta/casino_host.yaml b/data/mobs/vesta/casino_host.yaml
new file mode 100644
index 0000000..8d3e4da
--- /dev/null
+++ b/data/mobs/vesta/casino_host.yaml
@@ -0,0 +1,16 @@
+name: Cassia the floor host
+description: Cassia’s golden lapel bears the Icarus Leisure seal.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Welcome to the House of Icarus. Every game has its own room and posted rules. The upper floors
+ are open to visitors but their gaming halls are not operating yet. No membership or wager is needed
+ to explore.
+ options:
+ - text: Thank you.
diff --git a/data/mobs/vesta/casino_patron.yaml b/data/mobs/vesta/casino_patron.yaml
new file mode 100644
index 0000000..ae7e236
--- /dev/null
+++ b/data/mobs/vesta/casino_patron.yaml
@@ -0,0 +1,61 @@
+combat:
+ aggressive: false
+ attack_types:
+ - crush
+ combat_descriptions:
+ - jabs a syringe at %s
+ - is being overpowered by %s
+ - fights desperately against %s
+ kind: combat
+ respawn_ticks: 50
+ size: small
+ stats:
+ attack: 6
+ bonuses:
+ attack_bonus: 0
+ ranged_bonus: 0
+ ranged_strength_bonus: 0
+ science_bonus: 0
+ science_percent_bonus: 0
+ strength_bonus: 0
+ defense: 5
+ defenses:
+ crush_defense: 0
+ ranged_defense: 0
+ science_defense: 0
+ slash_defense: 0
+ stab_defense: 0
+ hp: 25
+ max_melee_hit: 1
+ speed: 5
+ strength: 4
+description: A prosperous local with a guarded purse. Pickpocketing is an optional risk; this person never
+ initiates combat otherwise.
+drops:
+ loot:
+ - item_id: sweetcorn_seed
+ quantity: 2
+ weight: 30
+ - item_id: strawberry_seed
+ quantity: 1
+ weight: 25
+ - item_id: watermelon_seed
+ quantity: 1
+ weight: 15
+ - item_id: ranarr_seed
+ quantity: 1
+ weight: 5
+ remains: bones
+idle_descriptions:
+- scribbles notes on a clipboard
+- carefully inspects a vial of green liquid
+- adjusts her safety goggles
+- mutters about gene splicing yields
+name: casino patron
+steal:
+ level: 40
+ speed: 5
+ xp: 50
+ drops:
+ - table: farmer_steal
+ weight: 1
diff --git a/data/mobs/vesta/corporate_auditor.yaml b/data/mobs/vesta/corporate_auditor.yaml
new file mode 100644
index 0000000..281d7bf
--- /dev/null
+++ b/data/mobs/vesta/corporate_auditor.yaml
@@ -0,0 +1,61 @@
+combat:
+ aggressive: false
+ attack_types:
+ - crush
+ combat_descriptions:
+ - jabs a syringe at %s
+ - is being overpowered by %s
+ - fights desperately against %s
+ kind: combat
+ respawn_ticks: 50
+ size: small
+ stats:
+ attack: 6
+ bonuses:
+ attack_bonus: 0
+ ranged_bonus: 0
+ ranged_strength_bonus: 0
+ science_bonus: 0
+ science_percent_bonus: 0
+ strength_bonus: 0
+ defense: 5
+ defenses:
+ crush_defense: 0
+ ranged_defense: 0
+ science_defense: 0
+ slash_defense: 0
+ stab_defense: 0
+ hp: 25
+ max_melee_hit: 1
+ speed: 5
+ strength: 4
+description: A prosperous local with a guarded purse. Pickpocketing is an optional risk; this person never
+ initiates combat otherwise.
+drops:
+ loot:
+ - item_id: sweetcorn_seed
+ quantity: 2
+ weight: 30
+ - item_id: strawberry_seed
+ quantity: 1
+ weight: 25
+ - item_id: watermelon_seed
+ quantity: 1
+ weight: 15
+ - item_id: ranarr_seed
+ quantity: 1
+ weight: 5
+ remains: bones
+idle_descriptions:
+- scribbles notes on a clipboard
+- carefully inspects a vial of green liquid
+- adjusts her safety goggles
+- mutters about gene splicing yields
+name: corporate auditor
+steal:
+ level: 30
+ speed: 5
+ xp: 38
+ drops:
+ - table: farmer_steal
+ weight: 1
diff --git a/data/mobs/vesta/dock_factor.yaml b/data/mobs/vesta/dock_factor.yaml
new file mode 100644
index 0000000..310b163
--- /dev/null
+++ b/data/mobs/vesta/dock_factor.yaml
@@ -0,0 +1,61 @@
+combat:
+ aggressive: false
+ attack_types:
+ - crush
+ combat_descriptions:
+ - jabs a syringe at %s
+ - is being overpowered by %s
+ - fights desperately against %s
+ kind: combat
+ respawn_ticks: 50
+ size: small
+ stats:
+ attack: 6
+ bonuses:
+ attack_bonus: 0
+ ranged_bonus: 0
+ ranged_strength_bonus: 0
+ science_bonus: 0
+ science_percent_bonus: 0
+ strength_bonus: 0
+ defense: 5
+ defenses:
+ crush_defense: 0
+ ranged_defense: 0
+ science_defense: 0
+ slash_defense: 0
+ stab_defense: 0
+ hp: 25
+ max_melee_hit: 1
+ speed: 5
+ strength: 4
+description: A prosperous local with a guarded purse. Pickpocketing is an optional risk; this person never
+ initiates combat otherwise.
+drops:
+ loot:
+ - item_id: sweetcorn_seed
+ quantity: 2
+ weight: 30
+ - item_id: strawberry_seed
+ quantity: 1
+ weight: 25
+ - item_id: watermelon_seed
+ quantity: 1
+ weight: 15
+ - item_id: ranarr_seed
+ quantity: 1
+ weight: 5
+ remains: bones
+idle_descriptions:
+- scribbles notes on a clipboard
+- carefully inspects a vial of green liquid
+- adjusts her safety goggles
+- mutters about gene splicing yields
+name: dock factor
+steal:
+ level: 25
+ speed: 5
+ xp: 30
+ drops:
+ - table: farmer_steal
+ weight: 1
diff --git a/data/mobs/vesta/domita_assayer.yaml b/data/mobs/vesta/domita_assayer.yaml
new file mode 100644
index 0000000..29f1b60
--- /dev/null
+++ b/data/mobs/vesta/domita_assayer.yaml
@@ -0,0 +1,32 @@
+name: Vesper the assayer
+description: Vesper distrusts both counterfeit chips and fool’s gold.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - The western quarry supplies coal and gold. The maintained mine galleries have no roaming monsters.
+ Richer ores lie in regions beyond our present survey.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: chisel
+ stock: 15
+ restock_ticks: 100
+ - item_id: ring_mould
+ stock: 15
+ restock_ticks: 100
+ - item_id: necklace_mould
+ stock: 15
+ restock_ticks: 100
+ - item_id: bracelet_mould
+ stock: 15
+ restock_ticks: 100
+ - item_id: amulet_mould
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/domita_contracts.yaml b/data/mobs/vesta/domita_contracts.yaml
new file mode 100644
index 0000000..b6af5be
--- /dev/null
+++ b/data/mobs/vesta/domita_contracts.yaml
@@ -0,0 +1,75 @@
+name: Commissioner Sable
+description: A practical official keeps a stack of field reports beside a stamped ledger.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Choose a contract suited to your equipment. You can hold one at a time; use task to check progress.
+ Supplies are sold here.
+ options:
+ - text: 15 rat — Numisia drainage ditch (Assassin 1).
+ condition:
+ player_flag: assassin_task_mob
+ not: true
+ action:
+ set_player_flags:
+ assassin_task_mob: rat
+ assassin_task_remaining: 15
+ assassin_task_total: 15
+ goto: assigned
+ - text: 15 drone — forest relay enclosure (Assassin 15).
+ condition:
+ player_flag: assassin_task_mob
+ not: true
+ action:
+ set_player_flags:
+ assassin_task_mob: drone
+ assassin_task_remaining: 15
+ assassin_task_total: 15
+ goto: assigned
+ - text: 12 crawler — Tuccia root cellar; use acid vial to finish (Assassin 30).
+ condition:
+ player_flag: assassin_task_mob
+ not: true
+ action:
+ set_player_flags:
+ assassin_task_mob: crawler
+ assassin_task_remaining: 12
+ assassin_task_total: 12
+ goto: assigned
+ - text: Cancel my current contract (resets streak).
+ condition:
+ player_flag: assassin_task_mob
+ action:
+ set_player_flags:
+ assassin_task_mob: ''
+ assassin_task_remaining: 0
+ assassin_task_total: 0
+ assassin_streak: 0
+ goto: start
+ - text: Goodbye.
+ assigned:
+ messages:
+ - Contract recorded. Follow the directions in the job listing. You gain Assassin experience only
+ for your assigned targets.
+ options:
+ - text: Understood.
+shop:
+ items:
+ - item_id: salt
+ stock: 15
+ restock_ticks: 100
+ - item_id: acid_vial
+ stock: 15
+ restock_ticks: 100
+ - item_id: insulated_gloves
+ stock: 15
+ restock_ticks: 100
+ - item_id: spectral_visor
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/domita_resident.yaml b/data/mobs/vesta/domita_resident.yaml
new file mode 100644
index 0000000..626b132
--- /dev/null
+++ b/data/mobs/vesta/domita_resident.yaml
@@ -0,0 +1,14 @@
+name: Nessa the night porter
+description: Nessa carries three keys and a lunch wrapped in yesterday’s odds sheet.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - They call the casino a public amenity. My rent says otherwise. At least the roads are still ours.
+ options:
+ - text: Thank you.
diff --git a/data/mobs/vesta/domita_supplier.yaml b/data/mobs/vesta/domita_supplier.yaml
new file mode 100644
index 0000000..44abbc5
--- /dev/null
+++ b/data/mobs/vesta/domita_supplier.yaml
@@ -0,0 +1,34 @@
+name: Merrit the instrument seller
+description: Merrit oils tools rather than gambling on the next delivery.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Ore makes better tools. I sell the instruments to build them, not your next suit of armour.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: hammer
+ stock: 15
+ restock_ticks: 100
+ - item_id: saw
+ stock: 15
+ restock_ticks: 100
+ - item_id: chisel
+ stock: 15
+ restock_ticks: 100
+ - item_id: needle
+ stock: 15
+ restock_ticks: 100
+ - item_id: thread
+ stock: 100
+ restock_ticks: 100
+ - item_id: lighter
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/domita_surgeon.yaml b/data/mobs/vesta/domita_surgeon.yaml
new file mode 100644
index 0000000..3fb0bb3
--- /dev/null
+++ b/data/mobs/vesta/domita_surgeon.yaml
@@ -0,0 +1,29 @@
+name: Doctor Myrrh
+description: Myrrh writes prescriptions on casino stationery with the logo crossed out.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Local farms supply herbs for your first compounds. Greater remedies will take ingredients from
+ other regions.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: vial
+ stock: 100
+ restock_ticks: 100
+ - item_id: arachnid_enzyme
+ stock: 15
+ restock_ticks: 100
+ - item_id: chocolate_dust
+ stock: 15
+ restock_ticks: 100
+ - item_id: eye_of_newt
+ stock: 100
+ restock_ticks: 100
diff --git a/data/mobs/vesta/domita_technician.yaml b/data/mobs/vesta/domita_technician.yaml
new file mode 100644
index 0000000..9a72698
--- /dev/null
+++ b/data/mobs/vesta/domita_technician.yaml
@@ -0,0 +1,29 @@
+name: Archivist Pell
+description: Pell’s coat pockets bulge with obsolete connectors.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Cosmic identification needs 27 Scavenging, eco 28 and chaos 35. The northern relays are apprentice
+ survey equipment, not the ancient deep arrays.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: cosmic_identifier
+ stock: 15
+ restock_ticks: 100
+ - item_id: eco_identifier
+ stock: 15
+ restock_ticks: 100
+ - item_id: chaos_identifier
+ stock: 15
+ restock_ticks: 100
+ - item_id: vial
+ stock: 100
+ restock_ticks: 100
diff --git a/data/mobs/vesta/forest_warden.yaml b/data/mobs/vesta/forest_warden.yaml
new file mode 100644
index 0000000..fda7480
--- /dev/null
+++ b/data/mobs/vesta/forest_warden.yaml
@@ -0,0 +1,16 @@
+name: Warden Sabin
+description: Sabin marks trees with washable chalk.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - The surfaced fork reaches Domita northwest and Tuccia south. The managed timber stands supply
+ common logs, oak, willow and a small teak plantation. The great forests lie beyond this district.
+ Red markers mean combat, not a shortcut.
+ options:
+ - text: Thank you.
diff --git a/data/mobs/vesta/harbor_winch.yaml b/data/mobs/vesta/harbor_winch.yaml
new file mode 100644
index 0000000..0a5f1d6
--- /dev/null
+++ b/data/mobs/vesta/harbor_winch.yaml
@@ -0,0 +1,41 @@
+combat:
+ aggressive: false
+ attack_types:
+ - crush
+ kind: task
+ respawn_ticks: 40
+ size: medium
+ stats:
+ bonuses:
+ attack_bonus: 0
+ ranged_bonus: 0
+ ranged_strength_bonus: 0
+ science_bonus: 0
+ science_percent_bonus: 0
+ strength_bonus: 0
+ defense: 20
+ defenses:
+ crush_defense: 0
+ ranged_defense: 10
+ science_defense: 10
+ slash_defense: 40
+ stab_defense: 40
+ hp: 50
+ max_melee_hit: 0
+ speed: 5
+description: A public maintenance worksite. Work on it to practice combat skills without fighting; completed
+ jobs pay credits.
+drops:
+ loot:
+ - item_id: credits
+ quantity: 70
+ weight: 1
+idle_descriptions:
+- stands half-assembled, panels waiting to be fitted
+- has loose cabling dangling from an open junction box
+- catches the light on its few mounted panels
+name: harbor winch frame
+task:
+ complete_message: The mechanism passes its final check. Your maintenance payment is ready to collect.
+ progress_noun: assembly
+ verb: assemble
diff --git a/data/mobs/vesta/irrigation_frame.yaml b/data/mobs/vesta/irrigation_frame.yaml
new file mode 100644
index 0000000..ce5b020
--- /dev/null
+++ b/data/mobs/vesta/irrigation_frame.yaml
@@ -0,0 +1,41 @@
+combat:
+ aggressive: false
+ attack_types:
+ - crush
+ kind: task
+ respawn_ticks: 40
+ size: medium
+ stats:
+ bonuses:
+ attack_bonus: 0
+ ranged_bonus: 0
+ ranged_strength_bonus: 0
+ science_bonus: 0
+ science_percent_bonus: 0
+ strength_bonus: 0
+ defense: 10
+ defenses:
+ crush_defense: 0
+ ranged_defense: 10
+ science_defense: 10
+ slash_defense: 40
+ stab_defense: 40
+ hp: 35
+ max_melee_hit: 0
+ speed: 5
+description: A public maintenance worksite. Work on it to practice combat skills without fighting; completed
+ jobs pay credits.
+drops:
+ loot:
+ - item_id: credits
+ quantity: 45
+ weight: 1
+idle_descriptions:
+- stands half-assembled, panels waiting to be fitted
+- has loose cabling dangling from an open junction box
+- catches the light on its few mounted panels
+name: irrigation pump frame
+task:
+ complete_message: The mechanism passes its final check. Your maintenance payment is ready to collect.
+ progress_noun: assembly
+ verb: assemble
diff --git a/data/mobs/vesta/joanna_lucci.yaml b/data/mobs/vesta/joanna_lucci.yaml
new file mode 100644
index 0000000..f0b9fcf
--- /dev/null
+++ b/data/mobs/vesta/joanna_lucci.yaml
@@ -0,0 +1,15 @@
+name: Director Joanna Lucci
+description: The director wears a plain jacket with a repaired cuff.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - 'Welcome to Numisia. The north road reaches Vestalia Terra, east reaches Brumalia, and west enters
+ the forest. Stay on the marked roads: no toll, no contract, no fighting required.'
+ options:
+ - text: Thank you.
diff --git a/data/mobs/vesta/numisia_carpenter.yaml b/data/mobs/vesta/numisia_carpenter.yaml
new file mode 100644
index 0000000..75c2747
--- /dev/null
+++ b/data/mobs/vesta/numisia_carpenter.yaml
@@ -0,0 +1,22 @@
+name: Ada the joiner
+description: Ada’s measuring rule is polished with use.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Common logs become planks at a workbench with a saw. Oak, teak and mahogany will take more practice.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: saw
+ stock: 15
+ restock_ticks: 100
+ - item_id: hammer
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/numisia_chemist.yaml b/data/mobs/vesta/numisia_chemist.yaml
new file mode 100644
index 0000000..820aa80
--- /dev/null
+++ b/data/mobs/vesta/numisia_chemist.yaml
@@ -0,0 +1,25 @@
+name: Doctor Vale
+description: Vale labels each bottle twice.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Clean guam from the northern herb beds, then mix it with water and eye of newt.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: vial
+ stock: 100
+ restock_ticks: 100
+ - item_id: eye_of_newt
+ stock: 100
+ restock_ticks: 100
+ - item_id: antitoxin_powder
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/numisia_contracts.yaml b/data/mobs/vesta/numisia_contracts.yaml
new file mode 100644
index 0000000..44e4304
--- /dev/null
+++ b/data/mobs/vesta/numisia_contracts.yaml
@@ -0,0 +1,65 @@
+name: Inspector Cato
+description: A practical official keeps a stack of field reports beside a stamped ledger.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Choose a contract suited to your equipment. You can hold one at a time; use task to check progress.
+ Supplies are sold here.
+ options:
+ - text: 12 rat — Numisia drainage ditch (Assassin 1).
+ condition:
+ player_flag: assassin_task_mob
+ not: true
+ action:
+ set_player_flags:
+ assassin_task_mob: rat
+ assassin_task_remaining: 12
+ assassin_task_total: 12
+ goto: assigned
+ - text: 10 slug — Vestalia irrigation sump; use salt to finish (Assassin 1).
+ condition:
+ player_flag: assassin_task_mob
+ not: true
+ action:
+ set_player_flags:
+ assassin_task_mob: slug
+ assassin_task_remaining: 10
+ assassin_task_total: 10
+ goto: assigned
+ - text: Cancel my current contract (resets streak).
+ condition:
+ player_flag: assassin_task_mob
+ action:
+ set_player_flags:
+ assassin_task_mob: ''
+ assassin_task_remaining: 0
+ assassin_task_total: 0
+ assassin_streak: 0
+ goto: start
+ - text: Goodbye.
+ assigned:
+ messages:
+ - Contract recorded. Follow the directions in the job listing. You gain Assassin experience only
+ for your assigned targets.
+ options:
+ - text: Understood.
+shop:
+ items:
+ - item_id: salt
+ stock: 15
+ restock_ticks: 100
+ - item_id: acid_vial
+ stock: 15
+ restock_ticks: 100
+ - item_id: insulated_gloves
+ stock: 15
+ restock_ticks: 100
+ - item_id: spectral_visor
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/numisia_engineer.yaml b/data/mobs/vesta/numisia_engineer.yaml
new file mode 100644
index 0000000..a736404
--- /dev/null
+++ b/data/mobs/vesta/numisia_engineer.yaml
@@ -0,0 +1,39 @@
+name: Ivo the radio mender
+description: Ivo listens to a silent receiver.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Mine scrap at the reclamation yard. A solar identifier and the field altar turn it into Science
+ supplies. Use the training relay to improve Technology. I also stock imported elemental junk so
+ beginners can trigger bio strike before they learn identification.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: basic_deck
+ stock: 15
+ restock_ticks: 100
+ - item_id: solar_identifier
+ stock: 15
+ restock_ticks: 100
+ - item_id: hydro_identifier
+ stock: 15
+ restock_ticks: 100
+ - item_id: biojunk
+ stock: 250
+ restock_ticks: 20
+ - item_id: hydrojunk
+ stock: 250
+ restock_ticks: 20
+ - item_id: ecojunk
+ stock: 250
+ restock_ticks: 20
+ - item_id: solarjunk
+ stock: 250
+ restock_ticks: 20
diff --git a/data/mobs/vesta/numisia_fisher.yaml b/data/mobs/vesta/numisia_fisher.yaml
new file mode 100644
index 0000000..d9aa957
--- /dev/null
+++ b/data/mobs/vesta/numisia_fisher.yaml
@@ -0,0 +1,25 @@
+name: Neri the netmaker
+description: A knotted cord measures every net Neri makes.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - The nursery pools are south of town. Brumalia has deep-water tackle.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: small_fishing_net
+ stock: 15
+ restock_ticks: 100
+ - item_id: fishing_rod
+ stock: 15
+ restock_ticks: 100
+ - item_id: fishing_bait
+ stock: 100
+ restock_ticks: 100
diff --git a/data/mobs/vesta/numisia_grocer.yaml b/data/mobs/vesta/numisia_grocer.yaml
new file mode 100644
index 0000000..0af3cd9
--- /dev/null
+++ b/data/mobs/vesta/numisia_grocer.yaml
@@ -0,0 +1,28 @@
+name: Pella the grocer
+description: Pella weighs produce on a balance made from spoons.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - The kitchens are public. Grow or catch your meals; I sell the pantry odds and ends.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: pot_of_flour
+ stock: 15
+ restock_ticks: 100
+ - item_id: empty_jug
+ stock: 15
+ restock_ticks: 100
+ - item_id: salt
+ stock: 15
+ restock_ticks: 100
+ - item_id: chocolate_dust
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/numisia_guide.yaml b/data/mobs/vesta/numisia_guide.yaml
new file mode 100644
index 0000000..c486092
--- /dev/null
+++ b/data/mobs/vesta/numisia_guide.yaml
@@ -0,0 +1,15 @@
+name: Tavi the arrivals guide
+description: Tavi carries a board with a lovingly redrawn map.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Tools are west along the market street. Free starter supplies are on the arrivals shelf. Train
+ on rats or repair worksites outside the walls; follow the road, not the red danger markers.
+ options:
+ - text: Thank you.
diff --git a/data/mobs/vesta/numisia_outfitter.yaml b/data/mobs/vesta/numisia_outfitter.yaml
new file mode 100644
index 0000000..a3ee8e6
--- /dev/null
+++ b/data/mobs/vesta/numisia_outfitter.yaml
@@ -0,0 +1,34 @@
+name: Mara the outfitter
+description: Mara stitches a torn pack between customers.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Tools last longer than luck. Take a net to the south shore or a pick to the eastern quarry.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: bronze_pickaxe
+ stock: 15
+ restock_ticks: 100
+ - item_id: bronze_axe
+ stock: 15
+ restock_ticks: 100
+ - item_id: hammer
+ stock: 15
+ restock_ticks: 100
+ - item_id: knife
+ stock: 15
+ restock_ticks: 100
+ - item_id: matches
+ stock: 15
+ restock_ticks: 100
+ - item_id: small_fishing_net
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/numisia_potter.yaml b/data/mobs/vesta/numisia_potter.yaml
new file mode 100644
index 0000000..66a1d20
--- /dev/null
+++ b/data/mobs/vesta/numisia_potter.yaml
@@ -0,0 +1,34 @@
+name: Olin the potter
+description: Clay fingerprints cover Olin’s apron.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Mine clay east of town. Wet it, shape it at my wheel, then fire it in the kiln.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: empty_bucket
+ stock: 15
+ restock_ticks: 100
+ - item_id: empty_jug
+ stock: 15
+ restock_ticks: 100
+ - item_id: empty_pot
+ stock: 15
+ restock_ticks: 100
+ - item_id: chisel
+ stock: 15
+ restock_ticks: 100
+ - item_id: ring_mould
+ stock: 15
+ restock_ticks: 100
+ - item_id: amulet_mould
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/numisia_tailor.yaml b/data/mobs/vesta/numisia_tailor.yaml
new file mode 100644
index 0000000..6b65752
--- /dev/null
+++ b/data/mobs/vesta/numisia_tailor.yaml
@@ -0,0 +1,25 @@
+name: Sera the tailor
+description: Sera pins a pattern cut from an old shipping manifest.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Shear the sheep in Vestalia Terra. Spin wool here; cowhides go to the tanner.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: needle
+ stock: 15
+ restock_ticks: 100
+ - item_id: thread
+ stock: 100
+ restock_ticks: 100
+ - item_id: shears
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/survey_frame.yaml b/data/mobs/vesta/survey_frame.yaml
new file mode 100644
index 0000000..f1f240c
--- /dev/null
+++ b/data/mobs/vesta/survey_frame.yaml
@@ -0,0 +1,41 @@
+combat:
+ aggressive: false
+ attack_types:
+ - crush
+ kind: task
+ respawn_ticks: 40
+ size: medium
+ stats:
+ bonuses:
+ attack_bonus: 0
+ ranged_bonus: 0
+ ranged_strength_bonus: 0
+ science_bonus: 0
+ science_percent_bonus: 0
+ strength_bonus: 0
+ defense: 30
+ defenses:
+ crush_defense: 0
+ ranged_defense: 10
+ science_defense: 10
+ slash_defense: 40
+ stab_defense: 40
+ hp: 65
+ max_melee_hit: 0
+ speed: 5
+description: A public maintenance worksite. Work on it to practice combat skills without fighting; completed
+ jobs pay credits.
+drops:
+ loot:
+ - item_id: credits
+ quantity: 95
+ weight: 1
+idle_descriptions:
+- stands half-assembled, panels waiting to be fitted
+- has loose cabling dangling from an open junction box
+- catches the light on its few mounted panels
+name: survey instrument frame
+task:
+ complete_message: The mechanism passes its final check. Your maintenance payment is ready to collect.
+ progress_noun: assembly
+ verb: assemble
diff --git a/data/mobs/vesta/tuccia_carpenter.yaml b/data/mobs/vesta/tuccia_carpenter.yaml
new file mode 100644
index 0000000..c394b4f
--- /dev/null
+++ b/data/mobs/vesta/tuccia_carpenter.yaml
@@ -0,0 +1,25 @@
+name: Bell the carpenter
+description: Bell keeps offcuts sorted by the sound they make.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - The estate office registers houses. My benches are open whether you own one or not.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: saw
+ stock: 15
+ restock_ticks: 100
+ - item_id: hammer
+ stock: 15
+ restock_ticks: 100
+ - item_id: chisel
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/tuccia_contracts.yaml b/data/mobs/vesta/tuccia_contracts.yaml
new file mode 100644
index 0000000..6b08016
--- /dev/null
+++ b/data/mobs/vesta/tuccia_contracts.yaml
@@ -0,0 +1,75 @@
+name: Agent Venn
+description: A practical official keeps a stack of field reports beside a stamped ledger.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Choose a contract suited to your equipment. You can hold one at a time; use task to check progress.
+ Supplies are sold here.
+ options:
+ - text: 15 slug — Vestalia irrigation sump; use salt to finish (Assassin 1).
+ condition:
+ player_flag: assassin_task_mob
+ not: true
+ action:
+ set_player_flags:
+ assassin_task_mob: slug
+ assassin_task_remaining: 15
+ assassin_task_total: 15
+ goto: assigned
+ - text: 12 drone — forest relay enclosure (Assassin 15).
+ condition:
+ player_flag: assassin_task_mob
+ not: true
+ action:
+ set_player_flags:
+ assassin_task_mob: drone
+ assassin_task_remaining: 12
+ assassin_task_total: 12
+ goto: assigned
+ - text: 10 crawler — Tuccia root cellar; use acid vial to finish (Assassin 30).
+ condition:
+ player_flag: assassin_task_mob
+ not: true
+ action:
+ set_player_flags:
+ assassin_task_mob: crawler
+ assassin_task_remaining: 10
+ assassin_task_total: 10
+ goto: assigned
+ - text: Cancel my current contract (resets streak).
+ condition:
+ player_flag: assassin_task_mob
+ action:
+ set_player_flags:
+ assassin_task_mob: ''
+ assassin_task_remaining: 0
+ assassin_task_total: 0
+ assassin_streak: 0
+ goto: start
+ - text: Goodbye.
+ assigned:
+ messages:
+ - Contract recorded. Follow the directions in the job listing. You gain Assassin experience only
+ for your assigned targets.
+ options:
+ - text: Understood.
+shop:
+ items:
+ - item_id: salt
+ stock: 15
+ restock_ticks: 100
+ - item_id: acid_vial
+ stock: 15
+ restock_ticks: 100
+ - item_id: insulated_gloves
+ stock: 15
+ restock_ticks: 100
+ - item_id: spectral_visor
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/tuccia_estate_broker.yaml b/data/mobs/vesta/tuccia_estate_broker.yaml
new file mode 100644
index 0000000..6f79940
--- /dev/null
+++ b/data/mobs/vesta/tuccia_estate_broker.yaml
@@ -0,0 +1,70 @@
+description: Elia has drawn a small house beside every paid entry in the neighborhood ledger.
+idle_descriptions:
+- flashes a professional smile
+name: Elia the estate broker
+protected: true
+talk:
+ nodes:
+ already_own:
+ messages:
+ - Yes, you're already a proud homeowner here! Your house is waiting for you. Use the Estate Directory
+ to enter it, and use its workshop.
+ options:
+ - goto: start
+ text: Good to know.
+ goodbye:
+ messages:
+ - Come back when you're ready to invest in your future!
+ info:
+ messages:
+ - Each house comes with an entrance hall and a workshop equipped with a workbench. You can use the
+ workbench with a saw to turn logs into planks, or assemble planks into furniture. Furniture can
+ be sold for a profit or displayed in your home. Future developments will allow adding more rooms
+ to your house.
+ options:
+ - action:
+ credits: -10
+ set_player_flags:
+ owns_house_local_neighborhood: local_neighborhood
+ condition:
+ all_of:
+ - player_flag: owns_house_local_neighborhood
+ not: true
+ - min_credits: 10
+ goto: purchased
+ text: Sounds great! I'll buy one.
+ - goto: goodbye
+ text: Maybe later.
+ purchased:
+ messages:
+ - Excellent! The plot is yours. You'll find your new home in the Local Neighborhood south of the
+ town square, west of the south gate. Use the Estate Directory terminal to enter your house. The
+ home comes with a workshop — perfect for construction projects.
+ options:
+ - goto: start
+ text: Thanks!
+ start:
+ messages:
+ - Welcome to the Local Neighborhood development! I'm selling premium housing plots for only 10 credits.
+ Interested in buying a house?
+ options:
+ - action:
+ credits: -10
+ set_player_flags:
+ owns_house_local_neighborhood: local_neighborhood
+ condition:
+ all_of:
+ - player_flag: owns_house_local_neighborhood
+ not: true
+ - min_credits: 10
+ goto: purchased
+ text: Yes, I'd like to buy a house.
+ - condition:
+ player_flag: owns_house_local_neighborhood
+ goto: already_own
+ text: I already own a house here.
+ - goto: goodbye
+ text: No thanks.
+ - goto: info
+ text: What do I get with a house?
+unique: true
diff --git a/data/mobs/vesta/tuccia_fletcher.yaml b/data/mobs/vesta/tuccia_fletcher.yaml
new file mode 100644
index 0000000..b6c40f1
--- /dev/null
+++ b/data/mobs/vesta/tuccia_fletcher.yaml
@@ -0,0 +1,26 @@
+name: Rook the fletcher
+description: Rook straightens arrow shafts against a scarred tabletop.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Willows along the marsh and teak in the western forest make fine bows. Bring a knife and work
+ your own wood.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: knife
+ stock: 15
+ restock_ticks: 100
+ - item_id: feather
+ stock: 100
+ restock_ticks: 100
+ - item_id: thread
+ stock: 100
+ restock_ticks: 100
diff --git a/data/mobs/vesta/tuccia_herbalist.yaml b/data/mobs/vesta/tuccia_herbalist.yaml
new file mode 100644
index 0000000..411ac5c
--- /dev/null
+++ b/data/mobs/vesta/tuccia_herbalist.yaml
@@ -0,0 +1,35 @@
+name: Aunt Celandine
+description: Celandine dries leaves in the lining of her hat.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - The marsh boardwalk is safe; the crypts are not. Bring your own herbs and I can supply the second
+ ingredients.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: vial
+ stock: 100
+ restock_ticks: 100
+ - item_id: limpwurt_root
+ stock: 15
+ restock_ticks: 100
+ - item_id: white_berries
+ stock: 15
+ restock_ticks: 100
+ - item_id: snape_grass
+ stock: 15
+ restock_ticks: 100
+ - item_id: antitoxin_powder
+ stock: 15
+ restock_ticks: 100
+ - item_id: blight_spore
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/tuccia_reclaimer.yaml b/data/mobs/vesta/tuccia_reclaimer.yaml
new file mode 100644
index 0000000..07978a1
--- /dev/null
+++ b/data/mobs/vesta/tuccia_reclaimer.yaml
@@ -0,0 +1,23 @@
+name: Moss the reclaimer
+description: Moss wears circuit boards as sleeve patches.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Eco is 28 Scavenging. The woodland altar is outside town, not in my back room. Seek the other
+ old arrays in regions beyond this district.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: eco_identifier
+ stock: 15
+ restock_ticks: 100
+ - item_id: chaos_identifier
+ stock: 15
+ restock_ticks: 100
diff --git a/data/mobs/vesta/tuccia_resident.yaml b/data/mobs/vesta/tuccia_resident.yaml
new file mode 100644
index 0000000..492a515
--- /dev/null
+++ b/data/mobs/vesta/tuccia_resident.yaml
@@ -0,0 +1,14 @@
+name: Old Mera
+description: Mera has lived through three proposals to drain the marsh.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - The mist does not hurt anyone. What lives beneath the ruined chapel is a different matter.
+ options:
+ - text: Thank you.
diff --git a/data/mobs/vesta/vestalia_botanist.yaml b/data/mobs/vesta/vestalia_botanist.yaml
new file mode 100644
index 0000000..e250a54
--- /dev/null
+++ b/data/mobs/vesta/vestalia_botanist.yaml
@@ -0,0 +1,29 @@
+name: Professor Senna
+description: Senna has soil under every fingernail.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - The research terraces beyond the granary are open to everyone. Learn with the local seeds before
+ seeking rarer varieties in distant regions.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: ranarr_seed
+ stock: 100
+ restock_ticks: 100
+ - item_id: toadflax_seed
+ stock: 100
+ restock_ticks: 100
+ - item_id: sweetcorn_seed
+ stock: 100
+ restock_ticks: 100
+ - item_id: strawberry_seed
+ stock: 100
+ restock_ticks: 100
diff --git a/data/mobs/vesta/vestalia_seedkeeper.yaml b/data/mobs/vesta/vestalia_seedkeeper.yaml
new file mode 100644
index 0000000..10c964e
--- /dev/null
+++ b/data/mobs/vesta/vestalia_seedkeeper.yaml
@@ -0,0 +1,59 @@
+name: Livia the seedkeeper
+description: Livia keeps seed envelopes in an old ammunition chest.
+protected: true
+unique: true
+idle_descriptions:
+- looks up as footsteps approach
+- checks a pencilled list
+talk:
+ nodes:
+ start:
+ messages:
+ - Allotments, flowers and herbs grow in separate fields. Higher-level seeds need better Farming,
+ not a city permit.
+ options:
+ - text: Thank you.
+shop:
+ items:
+ - item_id: potato_seed
+ stock: 100
+ restock_ticks: 100
+ - item_id: onion_seed
+ stock: 100
+ restock_ticks: 100
+ - item_id: cabbage_seed
+ stock: 100
+ restock_ticks: 100
+ - item_id: tomato_seed
+ stock: 100
+ restock_ticks: 100
+ - item_id: sweetcorn_seed
+ stock: 100
+ restock_ticks: 100
+ - item_id: strawberry_seed
+ stock: 100
+ restock_ticks: 100
+ - item_id: guam_seed
+ stock: 100
+ restock_ticks: 100
+ - item_id: marrentill_seed
+ stock: 100
+ restock_ticks: 100
+ - item_id: tarromin_seed
+ stock: 100
+ restock_ticks: 100
+ - item_id: harralander_seed
+ stock: 100
+ restock_ticks: 100
+ - item_id: rake
+ stock: 15
+ restock_ticks: 100
+ - item_id: spade
+ stock: 15
+ restock_ticks: 100
+ - item_id: watering_can
+ stock: 15
+ restock_ticks: 100
+ - item_id: plant_cure
+ stock: 15
+ restock_ticks: 100
diff --git a/data/modules/transport_deep_mine.yaml b/data/modules/transport_deep_mine.yaml
index 1a6d68c..511eb3d 100644
--- a/data/modules/transport_deep_mine.yaml
+++ b/data/modules/transport_deep_mine.yaml
@@ -3,7 +3,7 @@ level: 61
max_hit: 0
base_xp: 60
category: transport
-destination: 999997
+destination: 5207
junk_cost:
lawjunk: 2
ecojunk: 1
diff --git a/data/modules/transport_fishing.yaml b/data/modules/transport_fishing.yaml
index cdb1ac2..4eee673 100644
--- a/data/modules/transport_fishing.yaml
+++ b/data/modules/transport_fishing.yaml
@@ -3,7 +3,7 @@ level: 55
max_hit: 0
base_xp: 56
category: transport
-destination: 999992
+destination: 1207
junk_cost:
lawjunk: 1
hydrojunk: 1
diff --git a/data/modules/transport_forest.yaml b/data/modules/transport_forest.yaml
index 6e9f598..f24cd9f 100644
--- a/data/modules/transport_forest.yaml
+++ b/data/modules/transport_forest.yaml
@@ -3,7 +3,7 @@ level: 45
max_hit: 0
base_xp: 48
category: transport
-destination: 999994
+destination: 4100
junk_cost:
lawjunk: 1
ecojunk: 1
diff --git a/data/modules/transport_forge.yaml b/data/modules/transport_forge.yaml
index bcb6a55..fb6dd57 100644
--- a/data/modules/transport_forge.yaml
+++ b/data/modules/transport_forge.yaml
@@ -3,7 +3,7 @@ level: 31
max_hit: 0
base_xp: 35
category: transport
-destination: 9999912
+destination: 1116
junk_cost:
lawjunk: 1
ecojunk: 1
diff --git a/data/modules/transport_home.yaml b/data/modules/transport_home.yaml
index f7a35b5..8c4861e 100644
--- a/data/modules/transport_home.yaml
+++ b/data/modules/transport_home.yaml
@@ -3,7 +3,7 @@ level: 1
max_hit: 0
base_xp: 0
category: transport
-destination: 1002
+destination: 1104
junk_cost: {}
sequence:
- message: "You radio for a transport shuttle..."
diff --git a/data/modules/transport_mine.yaml b/data/modules/transport_mine.yaml
index aea5fae..1a4cd05 100644
--- a/data/modules/transport_mine.yaml
+++ b/data/modules/transport_mine.yaml
@@ -3,7 +3,7 @@ level: 37
max_hit: 0
base_xp: 40
category: transport
-destination: 999996
+destination: 1201
junk_cost:
lawjunk: 1
ecojunk: 1
diff --git a/data/modules/transport_scavenge.yaml b/data/modules/transport_scavenge.yaml
index 52583e5..9a83cf6 100644
--- a/data/modules/transport_scavenge.yaml
+++ b/data/modules/transport_scavenge.yaml
@@ -3,7 +3,7 @@ level: 51
max_hit: 0
base_xp: 52
category: transport
-destination: 999999
+destination: 1212
junk_cost:
lawjunk: 1
naturejunk: 1
diff --git a/data/modules/transport_town.yaml b/data/modules/transport_town.yaml
index 7db4f05..00d6407 100644
--- a/data/modules/transport_town.yaml
+++ b/data/modules/transport_town.yaml
@@ -3,7 +3,7 @@ level: 25
max_hit: 0
base_xp: 27
category: transport
-destination: 999991
+destination: 1104
junk_cost:
lawjunk: 1
solarjunk: 1
diff --git a/data/objects/vesta/brumalia_circuit_exit.yaml b/data/objects/vesta/brumalia_circuit_exit.yaml
new file mode 100644
index 0000000..5efb11a
--- /dev/null
+++ b/data/objects/vesta/brumalia_circuit_exit.yaml
@@ -0,0 +1,5 @@
+name: exit marker
+description: Use exit marker to abandon the course and return to the rest yard.
+on_use:
+- steps:
+ - teleport: 8108
diff --git a/data/objects/vesta/coastal_net_spot.yaml b/data/objects/vesta/coastal_net_spot.yaml
new file mode 100644
index 0000000..98c54b5
--- /dev/null
+++ b/data/objects/vesta/coastal_net_spot.yaml
@@ -0,0 +1,41 @@
+color: 6E
+description: A sheltered local fishing ground. These coastal stocks support early fishing; the deep-sea
+ grounds lie beyond this region.
+gather:
+ depleted_message: You don't see any fish swimming here.
+ drops:
+ - item_id: raw_shrimps
+ level: 1
+ success_message: You catch some {4B}raw shrimps{/}.
+ tool: small_net
+ weight: 50
+ xp: 10
+ - item_id: raw_anchovies
+ level: 1
+ success_message: You catch some {4B}raw anchovies{/}.
+ tool: small_net
+ weight: 50
+ xp: 10
+ - item_id: raw_mackerel
+ level: 16
+ success_message: You catch a {45}raw mackerel{/}.
+ tool: small_net
+ weight: 50
+ xp: 20
+ - item_id: raw_cod
+ level: 23
+ success_message: You catch a {45}raw cod{/}.
+ tool: big_net
+ weight: 50
+ xp: 30
+ fail_message: You catch nothing.
+ gather_message: You cast your net into the water...
+ skill: fishing
+ success:
+ base: 0.5
+ cap: 0.9
+ per_level: 0.005
+ tools:
+ - small_net
+ - big_net
+name: coastal net fishing spot
diff --git a/data/objects/vesta/coastal_tuna_spot.yaml b/data/objects/vesta/coastal_tuna_spot.yaml
new file mode 100644
index 0000000..9aeb8a1
--- /dev/null
+++ b/data/objects/vesta/coastal_tuna_spot.yaml
@@ -0,0 +1,30 @@
+aliases: []
+color: 6E
+description: A sheltered local fishing ground. These coastal stocks support early fishing; the deep-sea
+ grounds lie beyond this region.
+gather:
+ bait: ''
+ depleted_message: ''
+ drops:
+ - depletes: false
+ item_id: raw_tuna
+ level: 35
+ quantity: 0
+ table: ''
+ weight: 60
+ xp: 80
+ exhausted_message: ''
+ fail_message: You fail to spear anything.
+ gather_message: You ready your harpoon...
+ respawn_broadcast: ''
+ skill: fishing
+ success:
+ base: 0.4
+ cap: 0.8
+ per_level: 0.005
+ tools:
+ - harpoon
+hidden: false
+inroom_description: ''
+name: coastal tuna spot
+removal_item: ''
diff --git a/data/objects/vesta/domita_circuit_exit.yaml b/data/objects/vesta/domita_circuit_exit.yaml
new file mode 100644
index 0000000..7885f83
--- /dev/null
+++ b/data/objects/vesta/domita_circuit_exit.yaml
@@ -0,0 +1,5 @@
+name: exit marker
+description: Use exit marker to abandon the course and return to the rest yard.
+on_use:
+- steps:
+ - teleport: 8112
diff --git a/data/objects/vesta/flax_bed.yaml b/data/objects/vesta/flax_bed.yaml
new file mode 100644
index 0000000..4363120
--- /dev/null
+++ b/data/objects/vesta/flax_bed.yaml
@@ -0,0 +1,15 @@
+name: flax bed
+description: Blue-flowered flax grows between the field drains. Use flax bed to pick fibers for spinning.
+gather:
+ skill: farming
+ no_tool_speed: 6
+ gather_message: You begin working at the flax bed...
+ success:
+ base: 0.8
+ cap: 0.95
+ per_level: 0.002
+ drops:
+ - item_id: flax
+ weight: 100
+ level: 1
+ xp: 4
diff --git a/data/objects/vesta/forest_circuit_exit.yaml b/data/objects/vesta/forest_circuit_exit.yaml
new file mode 100644
index 0000000..9acac33
--- /dev/null
+++ b/data/objects/vesta/forest_circuit_exit.yaml
@@ -0,0 +1,5 @@
+name: exit marker
+description: Use exit marker to abandon the course and return to the rest yard.
+on_use:
+- steps:
+ - teleport: 8104
diff --git a/data/objects/vesta/irrigation_relay.yaml b/data/objects/vesta/irrigation_relay.yaml
new file mode 100644
index 0000000..ada17fd
--- /dev/null
+++ b/data/objects/vesta/irrigation_relay.yaml
@@ -0,0 +1,16 @@
+name: irrigation relay
+description: A field controller with several timing circuits. Use irrigation relay to train Technology
+ (10).
+gather:
+ skill: technology
+ no_tool_speed: 6
+ gather_message: You begin working at the irrigation relay...
+ success:
+ base: 0.8
+ cap: 0.95
+ per_level: 0.002
+ drops:
+ - item_id: scrap
+ weight: 100
+ level: 10
+ xp: 22
diff --git a/data/objects/vesta/marsh_berries.yaml b/data/objects/vesta/marsh_berries.yaml
new file mode 100644
index 0000000..50a5895
--- /dev/null
+++ b/data/objects/vesta/marsh_berries.yaml
@@ -0,0 +1,15 @@
+name: marsh berries
+description: Pale berries grow above the waterline. Use marsh berries to gather Pharmacy ingredients.
+gather:
+ skill: farming
+ no_tool_speed: 6
+ gather_message: You begin working at the marsh berries...
+ success:
+ base: 0.8
+ cap: 0.95
+ per_level: 0.002
+ drops:
+ - item_id: white_berries
+ weight: 100
+ level: 35
+ xp: 28
diff --git a/data/objects/vesta/numisia_circuit_exit.yaml b/data/objects/vesta/numisia_circuit_exit.yaml
new file mode 100644
index 0000000..b830acb
--- /dev/null
+++ b/data/objects/vesta/numisia_circuit_exit.yaml
@@ -0,0 +1,5 @@
+name: exit marker
+description: Use exit marker to abandon the course and return to the rest yard.
+on_use:
+- steps:
+ - teleport: 8100
diff --git a/data/objects/vesta/observatory_circuit_exit.yaml b/data/objects/vesta/observatory_circuit_exit.yaml
new file mode 100644
index 0000000..bbaf805
--- /dev/null
+++ b/data/objects/vesta/observatory_circuit_exit.yaml
@@ -0,0 +1,5 @@
+name: exit marker
+description: Use exit marker to abandon the course and return to the rest yard.
+on_use:
+- steps:
+ - teleport: 8116
diff --git a/data/objects/vesta/observatory_relay.yaml b/data/objects/vesta/observatory_relay.yaml
new file mode 100644
index 0000000..a73e456
--- /dev/null
+++ b/data/objects/vesta/observatory_relay.yaml
@@ -0,0 +1,16 @@
+name: observatory relay
+description: A shielded observatory controller on a safe maintenance spur. Use observatory relay to train
+ Technology (40).
+gather:
+ skill: technology
+ no_tool_speed: 6
+ gather_message: You begin working at the observatory relay...
+ success:
+ base: 0.8
+ cap: 0.95
+ per_level: 0.002
+ drops:
+ - item_id: scrap
+ weight: 100
+ level: 40
+ xp: 60
diff --git a/data/objects/vesta/reagent_thicket.yaml b/data/objects/vesta/reagent_thicket.yaml
new file mode 100644
index 0000000..92ef268
--- /dev/null
+++ b/data/objects/vesta/reagent_thicket.yaml
@@ -0,0 +1,16 @@
+name: reagent thicket
+description: Tangled roots grow outside the cultivated fields. Use reagent thicket to gather Pharmacy
+ ingredients.
+gather:
+ skill: farming
+ no_tool_speed: 6
+ gather_message: You begin working at the reagent thicket...
+ success:
+ base: 0.8
+ cap: 0.95
+ per_level: 0.002
+ drops:
+ - item_id: limpwurt_root
+ weight: 100
+ level: 20
+ xp: 18
diff --git a/data/objects/vesta/saltgrass.yaml b/data/objects/vesta/saltgrass.yaml
new file mode 100644
index 0000000..3bc4a24
--- /dev/null
+++ b/data/objects/vesta/saltgrass.yaml
@@ -0,0 +1,15 @@
+name: saltgrass
+description: A salt-tolerant medicinal grass. Use saltgrass to harvest it.
+gather:
+ skill: farming
+ no_tool_speed: 6
+ gather_message: You begin working at the saltgrass...
+ success:
+ base: 0.8
+ cap: 0.95
+ per_level: 0.002
+ drops:
+ - item_id: snape_grass
+ weight: 100
+ level: 30
+ xp: 24
diff --git a/data/objects/vesta/survey_relay.yaml b/data/objects/vesta/survey_relay.yaml
new file mode 100644
index 0000000..1d4da6f
--- /dev/null
+++ b/data/objects/vesta/survey_relay.yaml
@@ -0,0 +1,15 @@
+name: survey relay
+description: A redundant survey array. Use survey relay to train Technology (30).
+gather:
+ skill: technology
+ no_tool_speed: 6
+ gather_message: You begin working at the survey relay...
+ success:
+ base: 0.8
+ cap: 0.95
+ per_level: 0.002
+ drops:
+ - item_id: scrap
+ weight: 100
+ level: 30
+ xp: 45
diff --git a/data/objects/vesta/tidal_relay.yaml b/data/objects/vesta/tidal_relay.yaml
new file mode 100644
index 0000000..60fd816
--- /dev/null
+++ b/data/objects/vesta/tidal_relay.yaml
@@ -0,0 +1,15 @@
+name: tidal relay
+description: A tide-gauge controller. Use tidal relay to train Technology (20).
+gather:
+ skill: technology
+ no_tool_speed: 6
+ gather_message: You begin working at the tidal relay...
+ success:
+ base: 0.8
+ cap: 0.95
+ per_level: 0.002
+ drops:
+ - item_id: scrap
+ weight: 100
+ level: 20
+ xp: 32
diff --git a/data/objects/vesta/training_relay.yaml b/data/objects/vesta/training_relay.yaml
new file mode 100644
index 0000000..911198d
--- /dev/null
+++ b/data/objects/vesta/training_relay.yaml
@@ -0,0 +1,16 @@
+name: training relay
+description: An isolated low-voltage relay. Use training relay to calibrate it and train Technology; no
+ tools needed.
+gather:
+ skill: technology
+ no_tool_speed: 6
+ gather_message: You begin working at the training relay...
+ success:
+ base: 0.8
+ cap: 0.95
+ per_level: 0.002
+ drops:
+ - item_id: scrap
+ weight: 100
+ level: 1
+ xp: 12
diff --git a/data/rooms/agility/8100.yaml b/data/rooms/agility/8100.yaml
new file mode 100644
index 0000000..f45c79b
--- /dev/null
+++ b/data/rooms/agility/8100.yaml
@@ -0,0 +1,8 @@
+name: Numisia Field Circuit — Rest Yard
+description: A marked practice circuit begins here. Agility 1 required. Failures return here; use the
+ exit marker at any obstacle to abandon the lap.
+exits:
+ west:
+ room: 1216
+ north:
+ room: 8101
diff --git a/data/rooms/agility/8101.yaml b/data/rooms/agility/8101.yaml
new file mode 100644
index 0000000..066d0ab
--- /dev/null
+++ b/data/rooms/agility/8101.yaml
@@ -0,0 +1,11 @@
+name: Numisia Field Circuit — Balance Beam
+description: The marked obstacle continues the circuit. Type balance to attempt it; use exit marker to
+ abandon the lap safely.
+exits:
+ south:
+ room: 8100
+ east:
+ room: 8102
+ always_blocked: true
+objects:
+- id: numisia_circuit_exit
diff --git a/data/rooms/agility/8102.yaml b/data/rooms/agility/8102.yaml
new file mode 100644
index 0000000..5e3628d
--- /dev/null
+++ b/data/rooms/agility/8102.yaml
@@ -0,0 +1,9 @@
+name: Numisia Field Circuit — Broken Wall
+description: The marked obstacle continues the circuit. Type vault to attempt it; use exit marker to abandon
+ the lap safely.
+exits:
+ south:
+ room: 8103
+ always_blocked: true
+objects:
+- id: numisia_circuit_exit
diff --git a/data/rooms/agility/8103.yaml b/data/rooms/agility/8103.yaml
new file mode 100644
index 0000000..21af016
--- /dev/null
+++ b/data/rooms/agility/8103.yaml
@@ -0,0 +1,9 @@
+name: Numisia Field Circuit — Low Tunnel
+description: The marked obstacle continues the circuit. Type crawl to attempt it; use exit marker to abandon
+ the lap safely.
+exits:
+ west:
+ room: 8100
+ always_blocked: true
+objects:
+- id: numisia_circuit_exit
diff --git a/data/rooms/agility/8104.yaml b/data/rooms/agility/8104.yaml
new file mode 100644
index 0000000..11a277c
--- /dev/null
+++ b/data/rooms/agility/8104.yaml
@@ -0,0 +1,8 @@
+name: Forest Ranger Circuit — Rest Yard
+description: A marked practice circuit begins here. Agility 10 required. Failures return here; use the
+ exit marker at any obstacle to abandon the lap.
+exits:
+ east:
+ room: 4119
+ north:
+ room: 8105
diff --git a/data/rooms/agility/8105.yaml b/data/rooms/agility/8105.yaml
new file mode 100644
index 0000000..914baa6
--- /dev/null
+++ b/data/rooms/agility/8105.yaml
@@ -0,0 +1,11 @@
+name: Forest Ranger Circuit — Balance Beam
+description: The marked obstacle continues the circuit. Type balance to attempt it; use exit marker to
+ abandon the lap safely.
+exits:
+ south:
+ room: 8104
+ west:
+ room: 8106
+ always_blocked: true
+objects:
+- id: forest_circuit_exit
diff --git a/data/rooms/agility/8106.yaml b/data/rooms/agility/8106.yaml
new file mode 100644
index 0000000..d56dfeb
--- /dev/null
+++ b/data/rooms/agility/8106.yaml
@@ -0,0 +1,9 @@
+name: Forest Ranger Circuit — Broken Wall
+description: The marked obstacle continues the circuit. Type vault to attempt it; use exit marker to abandon
+ the lap safely.
+exits:
+ south:
+ room: 8107
+ always_blocked: true
+objects:
+- id: forest_circuit_exit
diff --git a/data/rooms/agility/8107.yaml b/data/rooms/agility/8107.yaml
new file mode 100644
index 0000000..b4f05db
--- /dev/null
+++ b/data/rooms/agility/8107.yaml
@@ -0,0 +1,9 @@
+name: Forest Ranger Circuit — Low Tunnel
+description: The marked obstacle continues the circuit. Type crawl to attempt it; use exit marker to abandon
+ the lap safely.
+exits:
+ east:
+ room: 8104
+ always_blocked: true
+objects:
+- id: forest_circuit_exit
diff --git a/data/rooms/agility/8108.yaml b/data/rooms/agility/8108.yaml
new file mode 100644
index 0000000..6e93238
--- /dev/null
+++ b/data/rooms/agility/8108.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Rigging Circuit — Rest Yard
+description: A marked practice circuit begins here. Agility 20 required. Failures return here; use the
+ exit marker at any obstacle to abandon the lap.
+exits:
+ north:
+ room: 2225
+ south:
+ room: 8109
diff --git a/data/rooms/agility/8109.yaml b/data/rooms/agility/8109.yaml
new file mode 100644
index 0000000..45abc24
--- /dev/null
+++ b/data/rooms/agility/8109.yaml
@@ -0,0 +1,11 @@
+name: Brumalia Rigging Circuit — Balance Beam
+description: The marked obstacle continues the circuit. Type balance to attempt it; use exit marker to
+ abandon the lap safely.
+exits:
+ north:
+ room: 8108
+ east:
+ room: 8110
+ always_blocked: true
+objects:
+- id: brumalia_circuit_exit
diff --git a/data/rooms/agility/8110.yaml b/data/rooms/agility/8110.yaml
new file mode 100644
index 0000000..2d1a9ee
--- /dev/null
+++ b/data/rooms/agility/8110.yaml
@@ -0,0 +1,9 @@
+name: Brumalia Rigging Circuit — Broken Wall
+description: The marked obstacle continues the circuit. Type vault to attempt it; use exit marker to abandon
+ the lap safely.
+exits:
+ north:
+ room: 8111
+ always_blocked: true
+objects:
+- id: brumalia_circuit_exit
diff --git a/data/rooms/agility/8111.yaml b/data/rooms/agility/8111.yaml
new file mode 100644
index 0000000..8c55b37
--- /dev/null
+++ b/data/rooms/agility/8111.yaml
@@ -0,0 +1,9 @@
+name: Brumalia Rigging Circuit — Low Tunnel
+description: The marked obstacle continues the circuit. Type crawl to attempt it; use exit marker to abandon
+ the lap safely.
+exits:
+ west:
+ room: 8108
+ always_blocked: true
+objects:
+- id: brumalia_circuit_exit
diff --git a/data/rooms/agility/8112.yaml b/data/rooms/agility/8112.yaml
new file mode 100644
index 0000000..1c14b88
--- /dev/null
+++ b/data/rooms/agility/8112.yaml
@@ -0,0 +1,8 @@
+name: Domita Survey Circuit — Rest Yard
+description: A marked practice circuit begins here. Agility 30 required. Failures return here; use the
+ exit marker at any obstacle to abandon the lap.
+exits:
+ west:
+ room: 5226
+ north:
+ room: 8113
diff --git a/data/rooms/agility/8113.yaml b/data/rooms/agility/8113.yaml
new file mode 100644
index 0000000..5e14548
--- /dev/null
+++ b/data/rooms/agility/8113.yaml
@@ -0,0 +1,11 @@
+name: Domita Survey Circuit — Balance Beam
+description: The marked obstacle continues the circuit. Type balance to attempt it; use exit marker to
+ abandon the lap safely.
+exits:
+ south:
+ room: 8112
+ east:
+ room: 8114
+ always_blocked: true
+objects:
+- id: domita_circuit_exit
diff --git a/data/rooms/agility/8114.yaml b/data/rooms/agility/8114.yaml
new file mode 100644
index 0000000..19e24f2
--- /dev/null
+++ b/data/rooms/agility/8114.yaml
@@ -0,0 +1,9 @@
+name: Domita Survey Circuit — Broken Wall
+description: The marked obstacle continues the circuit. Type vault to attempt it; use exit marker to abandon
+ the lap safely.
+exits:
+ south:
+ room: 8115
+ always_blocked: true
+objects:
+- id: domita_circuit_exit
diff --git a/data/rooms/agility/8115.yaml b/data/rooms/agility/8115.yaml
new file mode 100644
index 0000000..c8c5b55
--- /dev/null
+++ b/data/rooms/agility/8115.yaml
@@ -0,0 +1,9 @@
+name: Domita Survey Circuit — Low Tunnel
+description: The marked obstacle continues the circuit. Type crawl to attempt it; use exit marker to abandon
+ the lap safely.
+exits:
+ west:
+ room: 8112
+ always_blocked: true
+objects:
+- id: domita_circuit_exit
diff --git a/data/rooms/agility/8116.yaml b/data/rooms/agility/8116.yaml
new file mode 100644
index 0000000..6ba63d1
--- /dev/null
+++ b/data/rooms/agility/8116.yaml
@@ -0,0 +1,8 @@
+name: Observatory Circuit — Rest Yard
+description: A marked practice circuit begins here. Agility 40 required. Failures return here; use the
+ exit marker at any obstacle to abandon the lap.
+exits:
+ south:
+ room: 5227
+ north:
+ room: 8117
diff --git a/data/rooms/agility/8117.yaml b/data/rooms/agility/8117.yaml
new file mode 100644
index 0000000..7e9028b
--- /dev/null
+++ b/data/rooms/agility/8117.yaml
@@ -0,0 +1,11 @@
+name: Observatory Circuit — Balance Beam
+description: The marked obstacle continues the circuit. Type balance to attempt it; use exit marker to
+ abandon the lap safely.
+exits:
+ south:
+ room: 8116
+ east:
+ room: 8118
+ always_blocked: true
+objects:
+- id: observatory_circuit_exit
diff --git a/data/rooms/agility/8118.yaml b/data/rooms/agility/8118.yaml
new file mode 100644
index 0000000..f366ff5
--- /dev/null
+++ b/data/rooms/agility/8118.yaml
@@ -0,0 +1,9 @@
+name: Observatory Circuit — Broken Wall
+description: The marked obstacle continues the circuit. Type vault to attempt it; use exit marker to abandon
+ the lap safely.
+exits:
+ south:
+ room: 8119
+ always_blocked: true
+objects:
+- id: observatory_circuit_exit
diff --git a/data/rooms/agility/8119.yaml b/data/rooms/agility/8119.yaml
new file mode 100644
index 0000000..5cb15f5
--- /dev/null
+++ b/data/rooms/agility/8119.yaml
@@ -0,0 +1,9 @@
+name: Observatory Circuit — Low Tunnel
+description: The marked obstacle continues the circuit. Type crawl to attempt it; use exit marker to abandon
+ the lap safely.
+exits:
+ west:
+ room: 8116
+ always_blocked: true
+objects:
+- id: observatory_circuit_exit
diff --git a/data/rooms/brumalia/2100.yaml b/data/rooms/brumalia/2100.yaml
new file mode 100644
index 0000000..1176768
--- /dev/null
+++ b/data/rooms/brumalia/2100.yaml
@@ -0,0 +1,8 @@
+name: Brumalia — West Gate
+description: The west road passes between worn boundary stones. Behind you, Anchor Street runs past separate
+ shopfronts toward the town center.
+exits:
+ east:
+ room: 2101
+ west:
+ room: 7110
diff --git a/data/rooms/brumalia/2101.yaml b/data/rooms/brumalia/2101.yaml
new file mode 100644
index 0000000..6480ade
--- /dev/null
+++ b/data/rooms/brumalia/2101.yaml
@@ -0,0 +1,12 @@
+name: Brumalia — Anchor Street West 3
+description: Upper windows overlook Anchor Street; downstairs, merchants have propped their doors open
+ for passing trade.
+exits:
+ west:
+ room: 2100
+ east:
+ room: 2102
+ north:
+ room: 2115
+ south:
+ room: 2121
diff --git a/data/rooms/brumalia/2102.yaml b/data/rooms/brumalia/2102.yaml
new file mode 100644
index 0000000..5423981
--- /dev/null
+++ b/data/rooms/brumalia/2102.yaml
@@ -0,0 +1,12 @@
+name: Brumalia — Anchor Street West 2
+description: An old drain runs beside the paving. The smell from an open shop door changes whenever the
+ wind turns.
+exits:
+ west:
+ room: 2101
+ east:
+ room: 2103
+ north:
+ room: 2116
+ south:
+ room: 2122
diff --git a/data/rooms/brumalia/2103.yaml b/data/rooms/brumalia/2103.yaml
new file mode 100644
index 0000000..b2319f6
--- /dev/null
+++ b/data/rooms/brumalia/2103.yaml
@@ -0,0 +1,12 @@
+name: Brumalia — Anchor Street West 1
+description: Awnings shade this stretch of Anchor Street. Each doorway belongs to a different business;
+ delivery handcarts leave a narrow path between them.
+exits:
+ west:
+ room: 2102
+ east:
+ room: 2104
+ north:
+ room: 2117
+ south:
+ room: 2123
diff --git a/data/rooms/brumalia/2104.yaml b/data/rooms/brumalia/2104.yaml
new file mode 100644
index 0000000..fd288a1
--- /dev/null
+++ b/data/rooms/brumalia/2104.yaml
@@ -0,0 +1,18 @@
+name: Brumalia — Town Square
+description: Anchor Street opens around a public notice pillar. Foot traffic divides between the shops,
+ the north avenue and the quieter houses to the south.
+exits:
+ west:
+ room: 2103
+ east:
+ room: 2105
+ north:
+ room: 2109
+ south:
+ room: 2112
+objects:
+- id: aps_tower
+- name: wayboard
+ description: 'Brumalia: Numisia west. Fishing piers east outside town; dangerous wrecks south beyond
+ the beach. Tackle, bank, forge and kitchens occupy separate Anchor Street shops.'
+ inroom_description: A wayboard stands where travelers can read it.
diff --git a/data/rooms/brumalia/2105.yaml b/data/rooms/brumalia/2105.yaml
new file mode 100644
index 0000000..f84dee5
--- /dev/null
+++ b/data/rooms/brumalia/2105.yaml
@@ -0,0 +1,12 @@
+name: Brumalia — Anchor Street East 1
+description: Awnings shade this stretch of Anchor Street. Each doorway belongs to a different business;
+ delivery handcarts leave a narrow path between them.
+exits:
+ west:
+ room: 2104
+ east:
+ room: 2106
+ north:
+ room: 2118
+ south:
+ room: 2124
diff --git a/data/rooms/brumalia/2106.yaml b/data/rooms/brumalia/2106.yaml
new file mode 100644
index 0000000..d8b544a
--- /dev/null
+++ b/data/rooms/brumalia/2106.yaml
@@ -0,0 +1,12 @@
+name: Brumalia — Anchor Street East 2
+description: An old drain runs beside the paving. The smell from an open shop door changes whenever the
+ wind turns.
+exits:
+ west:
+ room: 2105
+ east:
+ room: 2107
+ north:
+ room: 2119
+ south:
+ room: 2125
diff --git a/data/rooms/brumalia/2107.yaml b/data/rooms/brumalia/2107.yaml
new file mode 100644
index 0000000..af42164
--- /dev/null
+++ b/data/rooms/brumalia/2107.yaml
@@ -0,0 +1,12 @@
+name: Brumalia — Anchor Street East 3
+description: Upper windows overlook Anchor Street; downstairs, merchants have propped their doors open
+ for passing trade.
+exits:
+ west:
+ room: 2106
+ east:
+ room: 2108
+ north:
+ room: 2120
+ south:
+ room: 2126
diff --git a/data/rooms/brumalia/2108.yaml b/data/rooms/brumalia/2108.yaml
new file mode 100644
index 0000000..8c5924f
--- /dev/null
+++ b/data/rooms/brumalia/2108.yaml
@@ -0,0 +1,10 @@
+name: Brumalia — East Gate
+description: Cart tracks cross the eastern boundary. Lamps mark the safe road; the shops of Anchor Street
+ remain within easy walking distance.
+exits:
+ west:
+ room: 2107
+ east:
+ room: 2200
+ south:
+ room: 2225
diff --git a/data/rooms/brumalia/2109.yaml b/data/rooms/brumalia/2109.yaml
new file mode 100644
index 0000000..92e9db9
--- /dev/null
+++ b/data/rooms/brumalia/2109.yaml
@@ -0,0 +1,8 @@
+name: Brumalia — North Avenue
+description: Wide paving carries carts toward the northern boundary. A street board lists the next settlements,
+ not their recommended combat levels.
+exits:
+ south:
+ room: 2104
+ north:
+ room: 2110
diff --git a/data/rooms/brumalia/2110.yaml b/data/rooms/brumalia/2110.yaml
new file mode 100644
index 0000000..bebc0a1
--- /dev/null
+++ b/data/rooms/brumalia/2110.yaml
@@ -0,0 +1,11 @@
+name: Brumalia — Civic Walk
+description: Stone benches face municipal doorways. None of the offices charges admission.
+exits:
+ south:
+ room: 2109
+ north:
+ room: 2111
+ west:
+ room: 2127
+ east:
+ room: 2128
diff --git a/data/rooms/brumalia/2111.yaml b/data/rooms/brumalia/2111.yaml
new file mode 100644
index 0000000..1f4f30d
--- /dev/null
+++ b/data/rooms/brumalia/2111.yaml
@@ -0,0 +1,6 @@
+name: Brumalia — North Gate
+description: Beyond the gate the maintained road continues into open country. Dangerous side paths have
+ their own warning boards.
+exits:
+ south:
+ room: 2110
diff --git a/data/rooms/brumalia/2112.yaml b/data/rooms/brumalia/2112.yaml
new file mode 100644
index 0000000..0574753
--- /dev/null
+++ b/data/rooms/brumalia/2112.yaml
@@ -0,0 +1,10 @@
+name: Brumalia — Lantern Lane
+description: Laundry strings cross above the lane, well clear of the lamps. Residents have painted their
+ doors different colors.
+exits:
+ north:
+ room: 2104
+ south:
+ room: 2113
+mobs:
+- id: dock_factor
diff --git a/data/rooms/brumalia/2113.yaml b/data/rooms/brumalia/2113.yaml
new file mode 100644
index 0000000..38d53b7
--- /dev/null
+++ b/data/rooms/brumalia/2113.yaml
@@ -0,0 +1,12 @@
+name: Brumalia — Residential Court
+description: A shared wash basin occupies a tiny court. Conversations drift through shutters rather than
+ out of a crowded marketplace.
+exits:
+ north:
+ room: 2112
+ south:
+ room: 2114
+ west:
+ room: 2129
+ east:
+ room: 2130
diff --git a/data/rooms/brumalia/2114.yaml b/data/rooms/brumalia/2114.yaml
new file mode 100644
index 0000000..70a3c0d
--- /dev/null
+++ b/data/rooms/brumalia/2114.yaml
@@ -0,0 +1,12 @@
+name: Brumalia — South Gate
+description: The southern road leaves the houses behind. Its boundary posts are white; hazardous detours
+ are marked red.
+exits:
+ north:
+ room: 2113
+ west:
+ room: 2131
+ east:
+ room: 2132
+ south:
+ room: 2220
diff --git a/data/rooms/brumalia/2115.yaml b/data/rooms/brumalia/2115.yaml
new file mode 100644
index 0000000..29cc400
--- /dev/null
+++ b/data/rooms/brumalia/2115.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — Orso’s Tackle
+description: Floats bob from the ceiling as if the rafters were underwater.
+exits:
+ south:
+ room: 2101
+mobs:
+- id: brumalia_tackle
diff --git a/data/rooms/brumalia/2116.yaml b/data/rooms/brumalia/2116.yaml
new file mode 100644
index 0000000..84d2e23
--- /dev/null
+++ b/data/rooms/brumalia/2116.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — Harbor Bank
+description: Salt has whitened the lower courses of stone below the bank counter.
+exits:
+ south:
+ room: 2102
+objects:
+- id: bank_booth
diff --git a/data/rooms/brumalia/2117.yaml b/data/rooms/brumalia/2117.yaml
new file mode 100644
index 0000000..11a3694
--- /dev/null
+++ b/data/rooms/brumalia/2117.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — Chandlery
+description: Wax, rope and lamp oil give the shop a warm industrial smell.
+exits:
+ south:
+ room: 2103
+mobs:
+- id: brumalia_chandler
diff --git a/data/rooms/brumalia/2118.yaml b/data/rooms/brumalia/2118.yaml
new file mode 100644
index 0000000..c988af3
--- /dev/null
+++ b/data/rooms/brumalia/2118.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — Reagent Factors
+description: Fragile cargo rests in individual padded pigeonholes.
+exits:
+ south:
+ room: 2105
+mobs:
+- id: brumalia_reagent
diff --git a/data/rooms/brumalia/2119.yaml b/data/rooms/brumalia/2119.yaml
new file mode 100644
index 0000000..da07754
--- /dev/null
+++ b/data/rooms/brumalia/2119.yaml
@@ -0,0 +1,9 @@
+name: Brumalia — Sail Loft
+description: Long seams stretch across a clean floor beside a wheel for cordage.
+exits:
+ south:
+ room: 2106
+objects:
+- id: spinning_wheel
+mobs:
+- id: brumalia_resident
diff --git a/data/rooms/brumalia/2120.yaml b/data/rooms/brumalia/2120.yaml
new file mode 100644
index 0000000..6a1dcc0
--- /dev/null
+++ b/data/rooms/brumalia/2120.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — Shipwright’s Workshop
+description: A half-built tender occupies the middle of the shop; the public bench stands by the door.
+exits:
+ south:
+ room: 2107
+objects:
+- id: workbench
diff --git a/data/rooms/brumalia/2121.yaml b/data/rooms/brumalia/2121.yaml
new file mode 100644
index 0000000..69e3960
--- /dev/null
+++ b/data/rooms/brumalia/2121.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — Galley Stores
+description: A tide table doubles as the cook’s inventory sheet.
+exits:
+ north:
+ room: 2101
+mobs:
+- id: brumalia_cook
diff --git a/data/rooms/brumalia/2122.yaml b/data/rooms/brumalia/2122.yaml
new file mode 100644
index 0000000..e5c8741
--- /dev/null
+++ b/data/rooms/brumalia/2122.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — Public Galley
+description: Deep windows frame the harbor beyond a row of hotplates.
+exits:
+ north:
+ room: 2102
+objects:
+- id: cooking_range
diff --git a/data/rooms/brumalia/2123.yaml b/data/rooms/brumalia/2123.yaml
new file mode 100644
index 0000000..a5dfe8f
--- /dev/null
+++ b/data/rooms/brumalia/2123.yaml
@@ -0,0 +1,8 @@
+name: Brumalia — Anchor Forge
+description: Ship fittings cool on racks beside the furnace.
+exits:
+ north:
+ room: 2103
+objects:
+- id: furnace
+- id: anvil
diff --git a/data/rooms/brumalia/2124.yaml b/data/rooms/brumalia/2124.yaml
new file mode 100644
index 0000000..adcc2ae
--- /dev/null
+++ b/data/rooms/brumalia/2124.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — Customs Reading Office
+description: Old manifests can be queried from a battered cargo terminal.
+exits:
+ north:
+ room: 2105
+objects:
+- id: terminal_advanced
diff --git a/data/rooms/brumalia/2125.yaml b/data/rooms/brumalia/2125.yaml
new file mode 100644
index 0000000..c35ae47
--- /dev/null
+++ b/data/rooms/brumalia/2125.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — Battery Exchange
+description: Every socket is numbered; none charges a traveler for a recharge.
+exits:
+ north:
+ room: 2106
+objects:
+- id: charging_station
diff --git a/data/rooms/brumalia/2126.yaml b/data/rooms/brumalia/2126.yaml
new file mode 100644
index 0000000..fe9ebf7
--- /dev/null
+++ b/data/rooms/brumalia/2126.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — The Bent Oar
+description: The tavern’s namesake hangs above a table polished by elbows.
+exits:
+ north:
+ room: 2107
+mobs:
+- id: man
diff --git a/data/rooms/brumalia/2127.yaml b/data/rooms/brumalia/2127.yaml
new file mode 100644
index 0000000..ae5dc51
--- /dev/null
+++ b/data/rooms/brumalia/2127.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — Harbormaster’s Chart Room
+description: Colored pins mark fishing piers east of town and wrecks beyond the southern beach.
+exits:
+ east:
+ room: 2110
+mobs:
+- id: guard
diff --git a/data/rooms/brumalia/2128.yaml b/data/rooms/brumalia/2128.yaml
new file mode 100644
index 0000000..b8b0385
--- /dev/null
+++ b/data/rooms/brumalia/2128.yaml
@@ -0,0 +1,5 @@
+name: Brumalia — Mariners’ Chapel
+description: Names of overdue vessels are written in chalk, ready to be erased when they return.
+exits:
+ west:
+ room: 2110
diff --git a/data/rooms/brumalia/2129.yaml b/data/rooms/brumalia/2129.yaml
new file mode 100644
index 0000000..9e3fb12
--- /dev/null
+++ b/data/rooms/brumalia/2129.yaml
@@ -0,0 +1,5 @@
+name: Brumalia — Pilot’s Cottage
+description: Sea charts have been repurposed as wallpaper.
+exits:
+ east:
+ room: 2113
diff --git a/data/rooms/brumalia/2130.yaml b/data/rooms/brumalia/2130.yaml
new file mode 100644
index 0000000..7f40ab7
--- /dev/null
+++ b/data/rooms/brumalia/2130.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — Dockworkers’ Lodging
+description: Boots dry beneath a row of narrow bunks.
+exits:
+ west:
+ room: 2113
+mobs:
+- id: man
diff --git a/data/rooms/brumalia/2131.yaml b/data/rooms/brumalia/2131.yaml
new file mode 100644
index 0000000..ca9390d
--- /dev/null
+++ b/data/rooms/brumalia/2131.yaml
@@ -0,0 +1,5 @@
+name: Brumalia — Salt Window House
+description: The window glass distorts every passing lantern into a ship’s light.
+exits:
+ east:
+ room: 2114
diff --git a/data/rooms/brumalia/2132.yaml b/data/rooms/brumalia/2132.yaml
new file mode 100644
index 0000000..94fde6f
--- /dev/null
+++ b/data/rooms/brumalia/2132.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — Public Pump
+description: Fresh water arrives through a pipe carefully insulated from the salt tide.
+exits:
+ west:
+ room: 2114
+objects:
+- id: lumby_fountain
diff --git a/data/rooms/casino/6100.yaml b/data/rooms/casino/6100.yaml
new file mode 100644
index 0000000..40c69ed
--- /dev/null
+++ b/data/rooms/casino/6100.yaml
@@ -0,0 +1,16 @@
+name: House of Icarus — Vestibule
+description: A ceiling of tiny brass suns hangs over polished stone. Icarus Leisure’s emblem repeats on
+ every column. Stairs and galleries are open to all visitors.
+exits:
+ south:
+ room: 5111
+ north:
+ room: 6101
+mobs:
+- id: casino_host
+objects:
+- name: wayboard
+ description: 'Grand stair: ground gaming floor above the entrance podium. West: five blackjack salons,
+ three baccarat salons. East: five slot rooms. Three upper galleries reserve fifteen future game halls.
+ All floors are open without a wager.'
+ inroom_description: A wayboard stands where travelers can read it.
diff --git a/data/rooms/casino/6101.yaml b/data/rooms/casino/6101.yaml
new file mode 100644
index 0000000..cb6d6dc
--- /dev/null
+++ b/data/rooms/casino/6101.yaml
@@ -0,0 +1,8 @@
+name: House of Icarus — Grand Atrium
+description: A ceiling of tiny brass suns hangs over polished stone. Icarus Leisure’s emblem repeats on
+ every column. Stairs and galleries are open to all visitors.
+exits:
+ south:
+ room: 6100
+ up:
+ room: 6102
diff --git a/data/rooms/casino/6102.yaml b/data/rooms/casino/6102.yaml
new file mode 100644
index 0000000..dd3f94e
--- /dev/null
+++ b/data/rooms/casino/6102.yaml
@@ -0,0 +1,15 @@
+name: House of Icarus — Ground Gaming Floor Landing
+description: The entrance stair rises onto a broad podium, the casino’s ground gaming floor. A directory
+ divides the floor into card salons west and machine galleries east. Higher stairs lead to future gaming
+ floors.
+exits:
+ down:
+ room: 6101
+ south:
+ room: 6106
+ west:
+ room: 6115
+ east:
+ room: 6125
+ up:
+ room: 6149
diff --git a/data/rooms/casino/6103.yaml b/data/rooms/casino/6103.yaml
new file mode 100644
index 0000000..2a65f07
--- /dev/null
+++ b/data/rooms/casino/6103.yaml
@@ -0,0 +1,10 @@
+name: House of Icarus — South Gaming Rotunda
+description: Deep carpet quiets footsteps between individual gaming salons. Each doorway displays its
+ own rules and wager limits.
+exits:
+ north:
+ room: 6104
+ west:
+ room: 6107
+ east:
+ room: 6117
diff --git a/data/rooms/casino/6104.yaml b/data/rooms/casino/6104.yaml
new file mode 100644
index 0000000..e356fb2
--- /dev/null
+++ b/data/rooms/casino/6104.yaml
@@ -0,0 +1,12 @@
+name: House of Icarus — Amber Concourse
+description: Deep carpet quiets footsteps between individual gaming salons. Each doorway displays its
+ own rules and wager limits.
+exits:
+ south:
+ room: 6103
+ north:
+ room: 6105
+ west:
+ room: 6109
+ east:
+ room: 6119
diff --git a/data/rooms/casino/6105.yaml b/data/rooms/casino/6105.yaml
new file mode 100644
index 0000000..8f76703
--- /dev/null
+++ b/data/rooms/casino/6105.yaml
@@ -0,0 +1,12 @@
+name: House of Icarus — Central Gaming Concourse
+description: Deep carpet quiets footsteps between individual gaming salons. Each doorway displays its
+ own rules and wager limits.
+exits:
+ south:
+ room: 6104
+ north:
+ room: 6106
+ west:
+ room: 6111
+ east:
+ room: 6121
diff --git a/data/rooms/casino/6106.yaml b/data/rooms/casino/6106.yaml
new file mode 100644
index 0000000..bc4cd7a
--- /dev/null
+++ b/data/rooms/casino/6106.yaml
@@ -0,0 +1,12 @@
+name: House of Icarus — Marble Concourse
+description: Deep carpet quiets footsteps between individual gaming salons. Each doorway displays its
+ own rules and wager limits.
+exits:
+ south:
+ room: 6105
+ north:
+ room: 6102
+ west:
+ room: 6113
+ east:
+ room: 6123
diff --git a/data/rooms/casino/6107.yaml b/data/rooms/casino/6107.yaml
new file mode 100644
index 0000000..ed810a1
--- /dev/null
+++ b/data/rooms/casino/6107.yaml
@@ -0,0 +1,8 @@
+name: House of Icarus — Copper Blackjack Anteroom
+description: A quiet seating bay separates the concourse from Copper Blackjack. A brass plaque states
+ the rules before anyone joins a game.
+exits:
+ east:
+ room: 6103
+ west:
+ room: 6108
diff --git a/data/rooms/casino/6108.yaml b/data/rooms/casino/6108.yaml
new file mode 100644
index 0000000..734308b
--- /dev/null
+++ b/data/rooms/casino/6108.yaml
@@ -0,0 +1,34 @@
+name: House of Icarus — Copper Blackjack
+description: An individual blackjack salon opens beyond the anteroom. Limits are 1–100 credits. No wager
+ is required to watch or pass through.
+exits:
+ east:
+ room: 6107
+ west:
+ room: 6127
+casino_tables:
+- id: copper
+ game: blackjack
+ max_players: 6
+ betting_ticks: 30
+ min_bet: 1
+ max_bet: 100
+ blackjack:
+ decks: 6
+ shuffle_at: 0.25
+ blackjack_payout: 1.5
+ dealer_hit_soft_17: false
+ max_split_hands: 4
+ resplit_aces: false
+ double_after_split: true
+ double_split_blackjack: false
+ insurance_payout: 2
+ surrender: false
+ action_ticks: 40
+ split_unlike_ten_values: false
+objects:
+- name: rules plaque
+ description: Play blackjack; bet min, bet max or bet <amount>. Blackjack pays 3:2; insurance 2:1. 6
+ deck(s). Dealer stands on soft 17. No surrender. Double after split allowed. Split 21 pays 1:1; split
+ identical ranks only.
+ inroom_description: A rules plaque stands where travelers can read it.
diff --git a/data/rooms/casino/6109.yaml b/data/rooms/casino/6109.yaml
new file mode 100644
index 0000000..6b026fe
--- /dev/null
+++ b/data/rooms/casino/6109.yaml
@@ -0,0 +1,8 @@
+name: House of Icarus — Classic Blackjack Anteroom
+description: A quiet seating bay separates the concourse from Classic Blackjack. A brass plaque states
+ the rules before anyone joins a game.
+exits:
+ east:
+ room: 6104
+ west:
+ room: 6110
diff --git a/data/rooms/casino/6110.yaml b/data/rooms/casino/6110.yaml
new file mode 100644
index 0000000..1ef79cd
--- /dev/null
+++ b/data/rooms/casino/6110.yaml
@@ -0,0 +1,34 @@
+name: House of Icarus — Classic Blackjack
+description: An individual blackjack salon opens beyond the anteroom. Limits are 10–1000 credits. No wager
+ is required to watch or pass through.
+exits:
+ east:
+ room: 6109
+ west:
+ room: 6130
+casino_tables:
+- id: classic
+ game: blackjack
+ max_players: 6
+ betting_ticks: 30
+ min_bet: 10
+ max_bet: 1000
+ blackjack:
+ decks: 6
+ shuffle_at: 0.25
+ blackjack_payout: 1.5
+ dealer_hit_soft_17: false
+ max_split_hands: 4
+ resplit_aces: false
+ double_after_split: true
+ double_split_blackjack: false
+ insurance_payout: 2
+ surrender: false
+ action_ticks: 25
+ split_unlike_ten_values: false
+objects:
+- name: rules plaque
+ description: Play blackjack; bet min, bet max or bet <amount>. Blackjack pays 3:2; insurance 2:1. 6
+ deck(s). Dealer stands on soft 17. No surrender. Double after split allowed. Split 21 pays 1:1; split
+ identical ranks only.
+ inroom_description: A rules plaque stands where travelers can read it.
diff --git a/data/rooms/casino/6111.yaml b/data/rooms/casino/6111.yaml
new file mode 100644
index 0000000..d1bb348
--- /dev/null
+++ b/data/rooms/casino/6111.yaml
@@ -0,0 +1,8 @@
+name: House of Icarus — Mercy Blackjack Anteroom
+description: A quiet seating bay separates the concourse from Mercy Blackjack. A brass plaque states the
+ rules before anyone joins a game.
+exits:
+ east:
+ room: 6105
+ west:
+ room: 6112
diff --git a/data/rooms/casino/6112.yaml b/data/rooms/casino/6112.yaml
new file mode 100644
index 0000000..098ae6a
--- /dev/null
+++ b/data/rooms/casino/6112.yaml
@@ -0,0 +1,34 @@
+name: House of Icarus — Mercy Blackjack
+description: An individual blackjack salon opens beyond the anteroom. Limits are 2–500 credits. No wager
+ is required to watch or pass through.
+exits:
+ east:
+ room: 6111
+ west:
+ room: 6128
+casino_tables:
+- id: mercy
+ game: blackjack
+ max_players: 6
+ betting_ticks: 30
+ min_bet: 2
+ max_bet: 500
+ blackjack:
+ decks: 6
+ shuffle_at: 0.25
+ blackjack_payout: 1.5
+ dealer_hit_soft_17: false
+ max_split_hands: 4
+ resplit_aces: false
+ double_after_split: true
+ double_split_blackjack: false
+ insurance_payout: 2
+ surrender: true
+ action_ticks: 25
+ split_unlike_ten_values: false
+objects:
+- name: rules plaque
+ description: Play blackjack; bet min, bet max or bet <amount>. Blackjack pays 3:2; insurance 2:1. 6
+ deck(s). Dealer stands on soft 17. Late surrender offered. Double after split allowed. Split 21 pays
+ 1:1; split identical ranks only.
+ inroom_description: A rules plaque stands where travelers can read it.
diff --git a/data/rooms/casino/6113.yaml b/data/rooms/casino/6113.yaml
new file mode 100644
index 0000000..667ac21
--- /dev/null
+++ b/data/rooms/casino/6113.yaml
@@ -0,0 +1,8 @@
+name: House of Icarus — Single Deck Salon Anteroom
+description: A quiet seating bay separates the concourse from Single Deck Salon. A brass plaque states
+ the rules before anyone joins a game.
+exits:
+ east:
+ room: 6106
+ west:
+ room: 6114
diff --git a/data/rooms/casino/6114.yaml b/data/rooms/casino/6114.yaml
new file mode 100644
index 0000000..17440d9
--- /dev/null
+++ b/data/rooms/casino/6114.yaml
@@ -0,0 +1,34 @@
+name: House of Icarus — Single Deck Salon
+description: An individual blackjack salon opens beyond the anteroom. Limits are 25–2500 credits. No wager
+ is required to watch or pass through.
+exits:
+ east:
+ room: 6113
+ west:
+ room: 6131
+casino_tables:
+- id: single
+ game: blackjack
+ max_players: 6
+ betting_ticks: 30
+ min_bet: 25
+ max_bet: 2500
+ blackjack:
+ decks: 1
+ shuffle_at: 0.25
+ blackjack_payout: 1.5
+ dealer_hit_soft_17: false
+ max_split_hands: 2
+ resplit_aces: false
+ double_after_split: false
+ double_split_blackjack: false
+ insurance_payout: 2
+ surrender: false
+ action_ticks: 25
+ split_unlike_ten_values: false
+objects:
+- name: rules plaque
+ description: Play blackjack; bet min, bet max or bet <amount>. Blackjack pays 3:2; insurance 2:1. 1
+ deck(s). Dealer stands on soft 17. No surrender. No double after split. Split 21 pays 1:1; split identical
+ ranks only.
+ inroom_description: A rules plaque stands where travelers can read it.
diff --git a/data/rooms/casino/6115.yaml b/data/rooms/casino/6115.yaml
new file mode 100644
index 0000000..2d834d7
--- /dev/null
+++ b/data/rooms/casino/6115.yaml
@@ -0,0 +1,8 @@
+name: House of Icarus — Midnight Blackjack Anteroom
+description: A quiet seating bay separates the concourse from Midnight Blackjack. A brass plaque states
+ the rules before anyone joins a game.
+exits:
+ east:
+ room: 6102
+ west:
+ room: 6116
diff --git a/data/rooms/casino/6116.yaml b/data/rooms/casino/6116.yaml
new file mode 100644
index 0000000..283aaea
--- /dev/null
+++ b/data/rooms/casino/6116.yaml
@@ -0,0 +1,34 @@
+name: House of Icarus — Midnight Blackjack
+description: An individual blackjack salon opens beyond the anteroom. Limits are 100–10000 credits. No
+ wager is required to watch or pass through.
+exits:
+ east:
+ room: 6115
+ west:
+ room: 6129
+casino_tables:
+- id: midnight
+ game: blackjack
+ max_players: 6
+ betting_ticks: 30
+ min_bet: 100
+ max_bet: 10000
+ blackjack:
+ decks: 6
+ shuffle_at: 0.25
+ blackjack_payout: 1.5
+ dealer_hit_soft_17: true
+ max_split_hands: 4
+ resplit_aces: false
+ double_after_split: true
+ double_split_blackjack: false
+ insurance_payout: 2
+ surrender: false
+ action_ticks: 25
+ split_unlike_ten_values: false
+objects:
+- name: rules plaque
+ description: Play blackjack; bet min, bet max or bet <amount>. Blackjack pays 3:2; insurance 2:1. 6
+ deck(s). Dealer hits soft 17. No surrender. Double after split allowed. Split 21 pays 1:1; split identical
+ ranks only.
+ inroom_description: A rules plaque stands where travelers can read it.
diff --git a/data/rooms/casino/6117.yaml b/data/rooms/casino/6117.yaml
new file mode 100644
index 0000000..d9eb7ad
--- /dev/null
+++ b/data/rooms/casino/6117.yaml
@@ -0,0 +1,8 @@
+name: House of Icarus — Penny Reels Anteroom
+description: A quiet seating bay separates the concourse from Penny Reels. A brass plaque states the rules
+ before anyone joins a game.
+exits:
+ west:
+ room: 6103
+ east:
+ room: 6118
diff --git a/data/rooms/casino/6118.yaml b/data/rooms/casino/6118.yaml
new file mode 100644
index 0000000..bf89d59
--- /dev/null
+++ b/data/rooms/casino/6118.yaml
@@ -0,0 +1,19 @@
+name: House of Icarus — Penny Reels
+description: An individual slots salon opens beyond the anteroom. Limits are 1–25 credits. No wager is
+ required to watch or pass through.
+exits:
+ west:
+ room: 6117
+ east:
+ room: 6132
+casino_machines:
+- id: penny_reels
+ game: slots
+ min_bet: 1
+ max_bet: 25
+ spin_ticks: 2
+ payout: 0.95
+objects:
+- name: machine plaque
+ description: Play slots. Wagers 1–25 credits. Configured long-run RTP 95%; outcomes are not guaranteed.
+ inroom_description: A machine plaque stands where travelers can read it.
diff --git a/data/rooms/casino/6119.yaml b/data/rooms/casino/6119.yaml
new file mode 100644
index 0000000..b943467
--- /dev/null
+++ b/data/rooms/casino/6119.yaml
@@ -0,0 +1,8 @@
+name: House of Icarus — Silver Reels Anteroom
+description: A quiet seating bay separates the concourse from Silver Reels. A brass plaque states the
+ rules before anyone joins a game.
+exits:
+ west:
+ room: 6104
+ east:
+ room: 6120
diff --git a/data/rooms/casino/6120.yaml b/data/rooms/casino/6120.yaml
new file mode 100644
index 0000000..7f0316b
--- /dev/null
+++ b/data/rooms/casino/6120.yaml
@@ -0,0 +1,19 @@
+name: House of Icarus — Silver Reels
+description: An individual slots salon opens beyond the anteroom. Limits are 10–500 credits. No wager
+ is required to watch or pass through.
+exits:
+ west:
+ room: 6119
+ east:
+ room: 6133
+casino_machines:
+- id: silver_reels
+ game: slots
+ min_bet: 10
+ max_bet: 500
+ spin_ticks: 2
+ payout: 0.95
+objects:
+- name: machine plaque
+ description: Play slots. Wagers 10–500 credits. Configured long-run RTP 95%; outcomes are not guaranteed.
+ inroom_description: A machine plaque stands where travelers can read it.
diff --git a/data/rooms/casino/6121.yaml b/data/rooms/casino/6121.yaml
new file mode 100644
index 0000000..94d8101
--- /dev/null
+++ b/data/rooms/casino/6121.yaml
@@ -0,0 +1,8 @@
+name: House of Icarus — Timber Reels Anteroom
+description: A quiet seating bay separates the concourse from Timber Reels. A brass plaque states the
+ rules before anyone joins a game.
+exits:
+ west:
+ room: 6105
+ east:
+ room: 6122
diff --git a/data/rooms/casino/6122.yaml b/data/rooms/casino/6122.yaml
new file mode 100644
index 0000000..c0ae041
--- /dev/null
+++ b/data/rooms/casino/6122.yaml
@@ -0,0 +1,21 @@
+name: House of Icarus — Timber Reels
+description: An individual slots salon opens beyond the anteroom. Limits are 1–100 credits. No wager is
+ required to watch or pass through.
+exits:
+ west:
+ room: 6121
+ east:
+ room: 6134
+casino_machines:
+- id: timber_reels
+ game: slots
+ min_bet: 1
+ max_bet: 100
+ spin_ticks: 2
+ payout: 0.97
+ variant: huff_and_even_more_puff
+objects:
+- name: machine plaque
+ description: Play huff_and_even_more_puff. Wagers 1–100 credits. Configured long-run RTP 97%; outcomes
+ are not guaranteed.
+ inroom_description: A machine plaque stands where travelers can read it.
diff --git a/data/rooms/casino/6123.yaml b/data/rooms/casino/6123.yaml
new file mode 100644
index 0000000..6e892e7
--- /dev/null
+++ b/data/rooms/casino/6123.yaml
@@ -0,0 +1,8 @@
+name: House of Icarus — Golden Timber Reels Anteroom
+description: A quiet seating bay separates the concourse from Golden Timber Reels. A brass plaque states
+ the rules before anyone joins a game.
+exits:
+ west:
+ room: 6106
+ east:
+ room: 6124
diff --git a/data/rooms/casino/6124.yaml b/data/rooms/casino/6124.yaml
new file mode 100644
index 0000000..5edbd43
--- /dev/null
+++ b/data/rooms/casino/6124.yaml
@@ -0,0 +1,21 @@
+name: House of Icarus — Golden Timber Reels
+description: An individual slots salon opens beyond the anteroom. Limits are 25–2500 credits. No wager
+ is required to watch or pass through.
+exits:
+ west:
+ room: 6123
+ east:
+ room: 6135
+casino_machines:
+- id: golden_timber_reels
+ game: slots
+ min_bet: 25
+ max_bet: 2500
+ spin_ticks: 2
+ payout: 0.97
+ variant: huff_and_even_more_puff
+objects:
+- name: machine plaque
+ description: Play huff_and_even_more_puff. Wagers 25–2500 credits. Configured long-run RTP 97%; outcomes
+ are not guaranteed.
+ inroom_description: A machine plaque stands where travelers can read it.
diff --git a/data/rooms/casino/6125.yaml b/data/rooms/casino/6125.yaml
new file mode 100644
index 0000000..3dc7cce
--- /dev/null
+++ b/data/rooms/casino/6125.yaml
@@ -0,0 +1,8 @@
+name: House of Icarus — Platinum Reels Anteroom
+description: A quiet seating bay separates the concourse from Platinum Reels. A brass plaque states the
+ rules before anyone joins a game.
+exits:
+ west:
+ room: 6102
+ east:
+ room: 6126
diff --git a/data/rooms/casino/6126.yaml b/data/rooms/casino/6126.yaml
new file mode 100644
index 0000000..9c6ee89
--- /dev/null
+++ b/data/rooms/casino/6126.yaml
@@ -0,0 +1,19 @@
+name: House of Icarus — Platinum Reels
+description: An individual slots salon opens beyond the anteroom. Limits are 100–10000 credits. No wager
+ is required to watch or pass through.
+exits:
+ west:
+ room: 6125
+ east:
+ room: 6136
+casino_machines:
+- id: platinum_reels
+ game: slots
+ min_bet: 100
+ max_bet: 10000
+ spin_ticks: 2
+ payout: 0.95
+objects:
+- name: machine plaque
+ description: Play slots. Wagers 100–10000 credits. Configured long-run RTP 95%; outcomes are not guaranteed.
+ inroom_description: A machine plaque stands where travelers can read it.
diff --git a/data/rooms/casino/6127.yaml b/data/rooms/casino/6127.yaml
new file mode 100644
index 0000000..40642f7
--- /dev/null
+++ b/data/rooms/casino/6127.yaml
@@ -0,0 +1,23 @@
+name: House of Icarus — Harbor Baccarat
+description: Green baize and shaded lamps distinguish this quiet baccarat salon from the neighboring blackjack
+ room. Its own rules are engraved at the entrance.
+exits:
+ east:
+ room: 6108
+casino_tables:
+- id: harbor_baccarat
+ game: baccarat
+ min_bet: 1
+ max_bet: 100
+ max_players: 8
+ betting_ticks: 35
+ baccarat:
+ decks: 8
+ shuffle_at: 0.25
+ tie_payout: 8
+ banker_payout: 0.95
+objects:
+- name: rules plaque
+ description: Play baccarat. Bet 1–100 credits on player, banker or tie. Player pays 1:1, banker 0.95:1
+ (commission rounded up), tie 8:1. 8 decks; fixed punto banco drawing rules.
+ inroom_description: A rules plaque stands where travelers can read it.
diff --git a/data/rooms/casino/6128.yaml b/data/rooms/casino/6128.yaml
new file mode 100644
index 0000000..80ec1db
--- /dev/null
+++ b/data/rooms/casino/6128.yaml
@@ -0,0 +1,23 @@
+name: House of Icarus — Charter Baccarat
+description: Green baize and shaded lamps distinguish this quiet baccarat salon from the neighboring blackjack
+ room. Its own rules are engraved at the entrance.
+exits:
+ east:
+ room: 6112
+casino_tables:
+- id: charter_baccarat
+ game: baccarat
+ min_bet: 25
+ max_bet: 2500
+ max_players: 8
+ betting_ticks: 35
+ baccarat:
+ decks: 6
+ shuffle_at: 0.25
+ tie_payout: 9
+ banker_payout: 0.95
+objects:
+- name: rules plaque
+ description: Play baccarat. Bet 25–2500 credits on player, banker or tie. Player pays 1:1, banker 0.95:1
+ (commission rounded up), tie 9:1. 6 decks; fixed punto banco drawing rules.
+ inroom_description: A rules plaque stands where travelers can read it.
diff --git a/data/rooms/casino/6129.yaml b/data/rooms/casino/6129.yaml
new file mode 100644
index 0000000..be6eee4
--- /dev/null
+++ b/data/rooms/casino/6129.yaml
@@ -0,0 +1,23 @@
+name: House of Icarus — Crown Baccarat
+description: Green baize and shaded lamps distinguish this quiet baccarat salon from the neighboring blackjack
+ room. Its own rules are engraved at the entrance.
+exits:
+ east:
+ room: 6116
+casino_tables:
+- id: crown_baccarat
+ game: baccarat
+ min_bet: 100
+ max_bet: 10000
+ max_players: 8
+ betting_ticks: 35
+ baccarat:
+ decks: 8
+ shuffle_at: 0.25
+ tie_payout: 8
+ banker_payout: 0.98
+objects:
+- name: rules plaque
+ description: Play baccarat. Bet 100–10000 credits on player, banker or tie. Player pays 1:1, banker
+ 0.98:1 (commission rounded up), tie 8:1. 8 decks; fixed punto banco drawing rules.
+ inroom_description: A rules plaque stands where travelers can read it.
diff --git a/data/rooms/casino/6130.yaml b/data/rooms/casino/6130.yaml
new file mode 100644
index 0000000..cdb960f
--- /dev/null
+++ b/data/rooms/casino/6130.yaml
@@ -0,0 +1,9 @@
+name: House of Icarus — Cashier Gallery
+description: A long brass grille protects the counting desk; the public bank booth remains outside it.
+exits:
+ east:
+ room: 6110
+objects:
+- id: bank_booth
+mobs:
+- id: casino_cashier
diff --git a/data/rooms/casino/6131.yaml b/data/rooms/casino/6131.yaml
new file mode 100644
index 0000000..0f48d2f
--- /dev/null
+++ b/data/rooms/casino/6131.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — Responsible Play Lounge
+description: Quiet chairs face a clock with unusually large numerals. A sign reminds visitors that the
+ next hand does not owe them a win.
+exits:
+ east:
+ room: 6114
diff --git a/data/rooms/casino/6132.yaml b/data/rooms/casino/6132.yaml
new file mode 100644
index 0000000..2c2febb
--- /dev/null
+++ b/data/rooms/casino/6132.yaml
@@ -0,0 +1,7 @@
+name: House of Icarus — South Buffet
+description: A public range lets travelers cook their own food alongside the dining tables.
+exits:
+ west:
+ room: 6118
+objects:
+- id: cooking_range
diff --git a/data/rooms/casino/6133.yaml b/data/rooms/casino/6133.yaml
new file mode 100644
index 0000000..b025e0e
--- /dev/null
+++ b/data/rooms/casino/6133.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — Cloakroom
+description: Numbered hooks and clean benches serve visitors who only came to see the building.
+exits:
+ west:
+ room: 6120
diff --git a/data/rooms/casino/6134.yaml b/data/rooms/casino/6134.yaml
new file mode 100644
index 0000000..9c24441
--- /dev/null
+++ b/data/rooms/casino/6134.yaml
@@ -0,0 +1,7 @@
+name: House of Icarus — Guest Services
+description: A charger sits beneath a directory of every floor.
+exits:
+ west:
+ room: 6122
+objects:
+- id: charging_station
diff --git a/data/rooms/casino/6135.yaml b/data/rooms/casino/6135.yaml
new file mode 100644
index 0000000..bee87bb
--- /dev/null
+++ b/data/rooms/casino/6135.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — Musicians’ Alcove
+description: A mechanical piano waits between performances.
+exits:
+ west:
+ room: 6124
diff --git a/data/rooms/casino/6136.yaml b/data/rooms/casino/6136.yaml
new file mode 100644
index 0000000..d7e8de8
--- /dev/null
+++ b/data/rooms/casino/6136.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — Observation Lounge
+description: Tall windows show Domita’s slate roofs far below the illuminated signs.
+exits:
+ west:
+ room: 6126
diff --git a/data/rooms/casino/6137.yaml b/data/rooms/casino/6137.yaml
new file mode 100644
index 0000000..b9db44f
--- /dev/null
+++ b/data/rooms/casino/6137.yaml
@@ -0,0 +1,10 @@
+name: House of Icarus — First Gallery South Rotunda
+description: The first gallery is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ west:
+ room: 6138
+ east:
+ room: 6139
+ north:
+ room: 6140
diff --git a/data/rooms/casino/6138.yaml b/data/rooms/casino/6138.yaml
new file mode 100644
index 0000000..a2ab602
--- /dev/null
+++ b/data/rooms/casino/6138.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — First Gallery Future Tournament Hall
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6137
diff --git a/data/rooms/casino/6139.yaml b/data/rooms/casino/6139.yaml
new file mode 100644
index 0000000..693249a
--- /dev/null
+++ b/data/rooms/casino/6139.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — First Gallery Balcony Lounge
+description: A sheltered balcony overlooks the city without requiring a ticket.
+exits:
+ west:
+ room: 6137
diff --git a/data/rooms/casino/6140.yaml b/data/rooms/casino/6140.yaml
new file mode 100644
index 0000000..63d0598
--- /dev/null
+++ b/data/rooms/casino/6140.yaml
@@ -0,0 +1,12 @@
+name: House of Icarus — First Gallery Promenade
+description: The first gallery is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ south:
+ room: 6137
+ west:
+ room: 6141
+ east:
+ room: 6142
+ north:
+ room: 6143
diff --git a/data/rooms/casino/6141.yaml b/data/rooms/casino/6141.yaml
new file mode 100644
index 0000000..da13e24
--- /dev/null
+++ b/data/rooms/casino/6141.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — First Gallery Future Card Salon
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6140
diff --git a/data/rooms/casino/6142.yaml b/data/rooms/casino/6142.yaml
new file mode 100644
index 0000000..af9b116
--- /dev/null
+++ b/data/rooms/casino/6142.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — First Gallery Refreshment Room
+description: Empty serving counters stand ready for the next expansion.
+exits:
+ west:
+ room: 6140
diff --git a/data/rooms/casino/6143.yaml b/data/rooms/casino/6143.yaml
new file mode 100644
index 0000000..1431cd5
--- /dev/null
+++ b/data/rooms/casino/6143.yaml
@@ -0,0 +1,12 @@
+name: House of Icarus — First Gallery Central Landing
+description: The first gallery is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ south:
+ room: 6140
+ west:
+ room: 6144
+ east:
+ room: 6145
+ north:
+ room: 6146
diff --git a/data/rooms/casino/6144.yaml b/data/rooms/casino/6144.yaml
new file mode 100644
index 0000000..a918b34
--- /dev/null
+++ b/data/rooms/casino/6144.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — First Gallery Future Wheel Gallery
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6143
diff --git a/data/rooms/casino/6145.yaml b/data/rooms/casino/6145.yaml
new file mode 100644
index 0000000..4376b53
--- /dev/null
+++ b/data/rooms/casino/6145.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — First Gallery Exhibition Room
+description: Building models show the corporation’s increasingly extravagant plans.
+exits:
+ west:
+ room: 6143
diff --git a/data/rooms/casino/6146.yaml b/data/rooms/casino/6146.yaml
new file mode 100644
index 0000000..0012476
--- /dev/null
+++ b/data/rooms/casino/6146.yaml
@@ -0,0 +1,12 @@
+name: House of Icarus — First Gallery North Promenade
+description: The first gallery is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ south:
+ room: 6143
+ west:
+ room: 6147
+ east:
+ room: 6148
+ north:
+ room: 6149
diff --git a/data/rooms/casino/6147.yaml b/data/rooms/casino/6147.yaml
new file mode 100644
index 0000000..83d277c
--- /dev/null
+++ b/data/rooms/casino/6147.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — First Gallery Future Dice Salon
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6146
diff --git a/data/rooms/casino/6148.yaml b/data/rooms/casino/6148.yaml
new file mode 100644
index 0000000..8c37c12
--- /dev/null
+++ b/data/rooms/casino/6148.yaml
@@ -0,0 +1,7 @@
+name: House of Icarus — First Gallery Staff History Gallery
+description: Photographs remember workers whose names do not appear on the marble dedication.
+exits:
+ west:
+ room: 6146
+mobs:
+- id: casino_patron
diff --git a/data/rooms/casino/6149.yaml b/data/rooms/casino/6149.yaml
new file mode 100644
index 0000000..bf959ef
--- /dev/null
+++ b/data/rooms/casino/6149.yaml
@@ -0,0 +1,14 @@
+name: House of Icarus — First Gallery Grand Stair
+description: The first gallery is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ south:
+ room: 6146
+ down:
+ room: 6102
+ west:
+ room: 6150
+ east:
+ room: 6151
+ up:
+ room: 6164
diff --git a/data/rooms/casino/6150.yaml b/data/rooms/casino/6150.yaml
new file mode 100644
index 0000000..015b219
--- /dev/null
+++ b/data/rooms/casino/6150.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — First Gallery Future Private Table Hall
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6149
diff --git a/data/rooms/casino/6151.yaml b/data/rooms/casino/6151.yaml
new file mode 100644
index 0000000..6eac0cd
--- /dev/null
+++ b/data/rooms/casino/6151.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — First Gallery Viewing Terrace
+description: A long window gives a clear view of the roads that belong to everyone.
+exits:
+ west:
+ room: 6149
diff --git a/data/rooms/casino/6152.yaml b/data/rooms/casino/6152.yaml
new file mode 100644
index 0000000..62b3ecd
--- /dev/null
+++ b/data/rooms/casino/6152.yaml
@@ -0,0 +1,10 @@
+name: House of Icarus — Second Gallery South Rotunda
+description: The second gallery is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ west:
+ room: 6153
+ east:
+ room: 6154
+ north:
+ room: 6155
diff --git a/data/rooms/casino/6153.yaml b/data/rooms/casino/6153.yaml
new file mode 100644
index 0000000..4c79b6d
--- /dev/null
+++ b/data/rooms/casino/6153.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — Second Gallery Future Tournament Hall
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6152
diff --git a/data/rooms/casino/6154.yaml b/data/rooms/casino/6154.yaml
new file mode 100644
index 0000000..ea908ea
--- /dev/null
+++ b/data/rooms/casino/6154.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — Second Gallery Balcony Lounge
+description: A sheltered balcony overlooks the city without requiring a ticket.
+exits:
+ west:
+ room: 6152
diff --git a/data/rooms/casino/6155.yaml b/data/rooms/casino/6155.yaml
new file mode 100644
index 0000000..383209a
--- /dev/null
+++ b/data/rooms/casino/6155.yaml
@@ -0,0 +1,12 @@
+name: House of Icarus — Second Gallery Promenade
+description: The second gallery is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ south:
+ room: 6152
+ west:
+ room: 6156
+ east:
+ room: 6157
+ north:
+ room: 6158
diff --git a/data/rooms/casino/6156.yaml b/data/rooms/casino/6156.yaml
new file mode 100644
index 0000000..ae8bd00
--- /dev/null
+++ b/data/rooms/casino/6156.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — Second Gallery Future Card Salon
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6155
diff --git a/data/rooms/casino/6157.yaml b/data/rooms/casino/6157.yaml
new file mode 100644
index 0000000..c3aca67
--- /dev/null
+++ b/data/rooms/casino/6157.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — Second Gallery Refreshment Room
+description: Empty serving counters stand ready for the next expansion.
+exits:
+ west:
+ room: 6155
diff --git a/data/rooms/casino/6158.yaml b/data/rooms/casino/6158.yaml
new file mode 100644
index 0000000..f02f93b
--- /dev/null
+++ b/data/rooms/casino/6158.yaml
@@ -0,0 +1,12 @@
+name: House of Icarus — Second Gallery Central Landing
+description: The second gallery is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ south:
+ room: 6155
+ west:
+ room: 6159
+ east:
+ room: 6160
+ north:
+ room: 6161
diff --git a/data/rooms/casino/6159.yaml b/data/rooms/casino/6159.yaml
new file mode 100644
index 0000000..ea7309f
--- /dev/null
+++ b/data/rooms/casino/6159.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — Second Gallery Future Wheel Gallery
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6158
diff --git a/data/rooms/casino/6160.yaml b/data/rooms/casino/6160.yaml
new file mode 100644
index 0000000..063211a
--- /dev/null
+++ b/data/rooms/casino/6160.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — Second Gallery Exhibition Room
+description: Building models show the corporation’s increasingly extravagant plans.
+exits:
+ west:
+ room: 6158
diff --git a/data/rooms/casino/6161.yaml b/data/rooms/casino/6161.yaml
new file mode 100644
index 0000000..38fa612
--- /dev/null
+++ b/data/rooms/casino/6161.yaml
@@ -0,0 +1,12 @@
+name: House of Icarus — Second Gallery North Promenade
+description: The second gallery is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ south:
+ room: 6158
+ west:
+ room: 6162
+ east:
+ room: 6163
+ north:
+ room: 6164
diff --git a/data/rooms/casino/6162.yaml b/data/rooms/casino/6162.yaml
new file mode 100644
index 0000000..073ec10
--- /dev/null
+++ b/data/rooms/casino/6162.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — Second Gallery Future Dice Salon
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6161
diff --git a/data/rooms/casino/6163.yaml b/data/rooms/casino/6163.yaml
new file mode 100644
index 0000000..9ca359e
--- /dev/null
+++ b/data/rooms/casino/6163.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — Second Gallery Staff History Gallery
+description: Photographs remember workers whose names do not appear on the marble dedication.
+exits:
+ west:
+ room: 6161
diff --git a/data/rooms/casino/6164.yaml b/data/rooms/casino/6164.yaml
new file mode 100644
index 0000000..126b647
--- /dev/null
+++ b/data/rooms/casino/6164.yaml
@@ -0,0 +1,14 @@
+name: House of Icarus — Second Gallery Grand Stair
+description: The second gallery is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ south:
+ room: 6161
+ down:
+ room: 6149
+ west:
+ room: 6165
+ east:
+ room: 6166
+ up:
+ room: 6179
diff --git a/data/rooms/casino/6165.yaml b/data/rooms/casino/6165.yaml
new file mode 100644
index 0000000..72dd191
--- /dev/null
+++ b/data/rooms/casino/6165.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — Second Gallery Future Private Table Hall
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6164
diff --git a/data/rooms/casino/6166.yaml b/data/rooms/casino/6166.yaml
new file mode 100644
index 0000000..e14493e
--- /dev/null
+++ b/data/rooms/casino/6166.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — Second Gallery Viewing Terrace
+description: A long window gives a clear view of the roads that belong to everyone.
+exits:
+ west:
+ room: 6164
diff --git a/data/rooms/casino/6167.yaml b/data/rooms/casino/6167.yaml
new file mode 100644
index 0000000..d6b3470
--- /dev/null
+++ b/data/rooms/casino/6167.yaml
@@ -0,0 +1,10 @@
+name: House of Icarus — Crown Floor South Rotunda
+description: The crown floor is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ west:
+ room: 6168
+ east:
+ room: 6169
+ north:
+ room: 6170
diff --git a/data/rooms/casino/6168.yaml b/data/rooms/casino/6168.yaml
new file mode 100644
index 0000000..ba15c4e
--- /dev/null
+++ b/data/rooms/casino/6168.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — Crown Floor Future Tournament Hall
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6167
diff --git a/data/rooms/casino/6169.yaml b/data/rooms/casino/6169.yaml
new file mode 100644
index 0000000..fe90e29
--- /dev/null
+++ b/data/rooms/casino/6169.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — Crown Floor Balcony Lounge
+description: A sheltered balcony overlooks the city without requiring a ticket.
+exits:
+ west:
+ room: 6167
diff --git a/data/rooms/casino/6170.yaml b/data/rooms/casino/6170.yaml
new file mode 100644
index 0000000..4bd05af
--- /dev/null
+++ b/data/rooms/casino/6170.yaml
@@ -0,0 +1,12 @@
+name: House of Icarus — Crown Floor Promenade
+description: The crown floor is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ south:
+ room: 6167
+ west:
+ room: 6171
+ east:
+ room: 6172
+ north:
+ room: 6173
diff --git a/data/rooms/casino/6171.yaml b/data/rooms/casino/6171.yaml
new file mode 100644
index 0000000..0acac0f
--- /dev/null
+++ b/data/rooms/casino/6171.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — Crown Floor Future Card Salon
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6170
diff --git a/data/rooms/casino/6172.yaml b/data/rooms/casino/6172.yaml
new file mode 100644
index 0000000..595cf6b
--- /dev/null
+++ b/data/rooms/casino/6172.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — Crown Floor Refreshment Room
+description: Empty serving counters stand ready for the next expansion.
+exits:
+ west:
+ room: 6170
diff --git a/data/rooms/casino/6173.yaml b/data/rooms/casino/6173.yaml
new file mode 100644
index 0000000..227a32e
--- /dev/null
+++ b/data/rooms/casino/6173.yaml
@@ -0,0 +1,12 @@
+name: House of Icarus — Crown Floor Central Landing
+description: The crown floor is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ south:
+ room: 6170
+ west:
+ room: 6174
+ east:
+ room: 6175
+ north:
+ room: 6176
diff --git a/data/rooms/casino/6174.yaml b/data/rooms/casino/6174.yaml
new file mode 100644
index 0000000..ca27a14
--- /dev/null
+++ b/data/rooms/casino/6174.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — Crown Floor Future Wheel Gallery
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6173
diff --git a/data/rooms/casino/6175.yaml b/data/rooms/casino/6175.yaml
new file mode 100644
index 0000000..5e2707e
--- /dev/null
+++ b/data/rooms/casino/6175.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — Crown Floor Exhibition Room
+description: Building models show the corporation’s increasingly extravagant plans.
+exits:
+ west:
+ room: 6173
diff --git a/data/rooms/casino/6176.yaml b/data/rooms/casino/6176.yaml
new file mode 100644
index 0000000..5318ed6
--- /dev/null
+++ b/data/rooms/casino/6176.yaml
@@ -0,0 +1,12 @@
+name: House of Icarus — Crown Floor North Promenade
+description: The crown floor is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ south:
+ room: 6173
+ west:
+ room: 6177
+ east:
+ room: 6178
+ north:
+ room: 6179
diff --git a/data/rooms/casino/6177.yaml b/data/rooms/casino/6177.yaml
new file mode 100644
index 0000000..b950ff5
--- /dev/null
+++ b/data/rooms/casino/6177.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — Crown Floor Future Dice Salon
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6176
diff --git a/data/rooms/casino/6178.yaml b/data/rooms/casino/6178.yaml
new file mode 100644
index 0000000..c99c4f1
--- /dev/null
+++ b/data/rooms/casino/6178.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — Crown Floor Staff History Gallery
+description: Photographs remember workers whose names do not appear on the marble dedication.
+exits:
+ west:
+ room: 6176
diff --git a/data/rooms/casino/6179.yaml b/data/rooms/casino/6179.yaml
new file mode 100644
index 0000000..ab86719
--- /dev/null
+++ b/data/rooms/casino/6179.yaml
@@ -0,0 +1,12 @@
+name: House of Icarus — Crown Floor Grand Stair
+description: The crown floor is freely open for exploration. Completed corridors face unfurnished gaming
+ rooms; signs explicitly say that no games operate on this floor yet.
+exits:
+ south:
+ room: 6176
+ down:
+ room: 6164
+ west:
+ room: 6180
+ east:
+ room: 6181
diff --git a/data/rooms/casino/6180.yaml b/data/rooms/casino/6180.yaml
new file mode 100644
index 0000000..9d67c12
--- /dev/null
+++ b/data/rooms/casino/6180.yaml
@@ -0,0 +1,6 @@
+name: House of Icarus — Crown Floor Future Private Table Hall
+description: Power sockets, table anchor points and service passages are installed, but there is no playable
+ game here yet. This hall is reserved for a future casino expansion.
+exits:
+ east:
+ room: 6179
diff --git a/data/rooms/casino/6181.yaml b/data/rooms/casino/6181.yaml
new file mode 100644
index 0000000..ff1cf79
--- /dev/null
+++ b/data/rooms/casino/6181.yaml
@@ -0,0 +1,5 @@
+name: House of Icarus — Crown Floor Viewing Terrace
+description: A long window gives a clear view of the roads that belong to everyone.
+exits:
+ west:
+ room: 6179
diff --git a/data/rooms/coast/2200.yaml b/data/rooms/coast/2200.yaml
new file mode 100644
index 0000000..f68b8ba
--- /dev/null
+++ b/data/rooms/coast/2200.yaml
@@ -0,0 +1,10 @@
+name: Brumalia Coast — Coastal Gatepath
+description: A maintained boardwalk follows the coast outside Brumalia. Rails separate walkers from working
+ fishing platforms; none of these piers is a combat zone.
+exits:
+ west:
+ room: 2108
+ east:
+ room: 2201
+ north:
+ room: 2208
diff --git a/data/rooms/coast/2201.yaml b/data/rooms/coast/2201.yaml
new file mode 100644
index 0000000..934a39b
--- /dev/null
+++ b/data/rooms/coast/2201.yaml
@@ -0,0 +1,12 @@
+name: Brumalia Coast — Tidal Walk
+description: A maintained boardwalk follows the coast outside Brumalia. Rails separate walkers from working
+ fishing platforms; none of these piers is a combat zone.
+exits:
+ west:
+ room: 2200
+ east:
+ room: 2202
+ north:
+ room: 2209
+ south:
+ room: 2216
diff --git a/data/rooms/coast/2202.yaml b/data/rooms/coast/2202.yaml
new file mode 100644
index 0000000..55557cb
--- /dev/null
+++ b/data/rooms/coast/2202.yaml
@@ -0,0 +1,12 @@
+name: Brumalia Coast — Netters’ Jetty
+description: A maintained boardwalk follows the coast outside Brumalia. Rails separate walkers from working
+ fishing platforms; none of these piers is a combat zone.
+exits:
+ west:
+ room: 2201
+ east:
+ room: 2203
+ north:
+ room: 2210
+ south:
+ room: 2217
diff --git a/data/rooms/coast/2203.yaml b/data/rooms/coast/2203.yaml
new file mode 100644
index 0000000..8c332da
--- /dev/null
+++ b/data/rooms/coast/2203.yaml
@@ -0,0 +1,12 @@
+name: Brumalia Coast — Long Pier
+description: A maintained boardwalk follows the coast outside Brumalia. Rails separate walkers from working
+ fishing platforms; none of these piers is a combat zone.
+exits:
+ west:
+ room: 2202
+ east:
+ room: 2204
+ north:
+ room: 2211
+ south:
+ room: 2226
diff --git a/data/rooms/coast/2204.yaml b/data/rooms/coast/2204.yaml
new file mode 100644
index 0000000..8d21958
--- /dev/null
+++ b/data/rooms/coast/2204.yaml
@@ -0,0 +1,12 @@
+name: Brumalia Coast — Pot Landing
+description: A maintained boardwalk follows the coast outside Brumalia. Rails separate walkers from working
+ fishing platforms; none of these piers is a combat zone.
+exits:
+ west:
+ room: 2203
+ east:
+ room: 2205
+ north:
+ room: 2212
+ south:
+ room: 2218
diff --git a/data/rooms/coast/2205.yaml b/data/rooms/coast/2205.yaml
new file mode 100644
index 0000000..1d1e737
--- /dev/null
+++ b/data/rooms/coast/2205.yaml
@@ -0,0 +1,10 @@
+name: Brumalia Coast — Deep Channel
+description: A maintained boardwalk follows the coast outside Brumalia. Rails separate walkers from working
+ fishing platforms; none of these piers is a combat zone.
+exits:
+ west:
+ room: 2204
+ east:
+ room: 2206
+ north:
+ room: 2213
diff --git a/data/rooms/coast/2206.yaml b/data/rooms/coast/2206.yaml
new file mode 100644
index 0000000..96163f0
--- /dev/null
+++ b/data/rooms/coast/2206.yaml
@@ -0,0 +1,10 @@
+name: Brumalia Coast — Outer Breakwater
+description: A maintained boardwalk follows the coast outside Brumalia. Rails separate walkers from working
+ fishing platforms; none of these piers is a combat zone.
+exits:
+ west:
+ room: 2205
+ east:
+ room: 2207
+ north:
+ room: 2214
diff --git a/data/rooms/coast/2207.yaml b/data/rooms/coast/2207.yaml
new file mode 100644
index 0000000..eed8f15
--- /dev/null
+++ b/data/rooms/coast/2207.yaml
@@ -0,0 +1,10 @@
+name: Brumalia Coast — Coastal Shelter
+description: A maintained boardwalk follows the coast outside Brumalia. Rails separate walkers from working
+ fishing platforms; none of these piers is a combat zone.
+exits:
+ west:
+ room: 2206
+ north:
+ room: 2215
+ south:
+ room: 2219
diff --git a/data/rooms/coast/2208.yaml b/data/rooms/coast/2208.yaml
new file mode 100644
index 0000000..f86764e
--- /dev/null
+++ b/data/rooms/coast/2208.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Coast — Shallow Net Platform
+description: The working platform sits apart from the travel path. Inspect the fishing spot for tools
+ and level requirements.
+exits:
+ south:
+ room: 2200
+objects:
+- id: coastal_net_spot
diff --git a/data/rooms/coast/2209.yaml b/data/rooms/coast/2209.yaml
new file mode 100644
index 0000000..520c37d
--- /dev/null
+++ b/data/rooms/coast/2209.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Coast — Bait Platform
+description: The working platform sits apart from the travel path. Inspect the fishing spot for tools
+ and level requirements.
+exits:
+ south:
+ room: 2201
+objects:
+- id: bait_fishing_spot
diff --git a/data/rooms/coast/2210.yaml b/data/rooms/coast/2210.yaml
new file mode 100644
index 0000000..d1d12ec
--- /dev/null
+++ b/data/rooms/coast/2210.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Coast — Wide Net Platform
+description: The working platform sits apart from the travel path. Inspect the fishing spot for tools
+ and level requirements.
+exits:
+ south:
+ room: 2202
+objects:
+- id: coastal_net_spot
diff --git a/data/rooms/coast/2211.yaml b/data/rooms/coast/2211.yaml
new file mode 100644
index 0000000..f6221ee
--- /dev/null
+++ b/data/rooms/coast/2211.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Coast — Tuna Point
+description: The working platform sits apart from the travel path. Inspect the fishing spot for tools
+ and level requirements.
+exits:
+ south:
+ room: 2203
+objects:
+- id: coastal_tuna_spot
diff --git a/data/rooms/coast/2212.yaml b/data/rooms/coast/2212.yaml
new file mode 100644
index 0000000..1ef17a4
--- /dev/null
+++ b/data/rooms/coast/2212.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Coast — Lobster Dock
+description: The working platform sits apart from the travel path. Inspect the fishing spot for tools
+ and level requirements.
+exits:
+ south:
+ room: 2204
+objects:
+- id: cage_fishing_spot
diff --git a/data/rooms/coast/2213.yaml b/data/rooms/coast/2213.yaml
new file mode 100644
index 0000000..0eb0963
--- /dev/null
+++ b/data/rooms/coast/2213.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Coast — Outer Tuna Ledge
+description: The working platform sits apart from the travel path. Inspect the fishing spot for tools
+ and level requirements.
+exits:
+ south:
+ room: 2205
+objects:
+- id: coastal_tuna_spot
diff --git a/data/rooms/coast/2214.yaml b/data/rooms/coast/2214.yaml
new file mode 100644
index 0000000..d6ae480
--- /dev/null
+++ b/data/rooms/coast/2214.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Coast — Potters’ Platform
+description: The working platform sits apart from the travel path. Inspect the fishing spot for tools
+ and level requirements.
+exits:
+ south:
+ room: 2206
+objects:
+- id: cage_fishing_spot
diff --git a/data/rooms/coast/2215.yaml b/data/rooms/coast/2215.yaml
new file mode 100644
index 0000000..3fa669c
--- /dev/null
+++ b/data/rooms/coast/2215.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Coast — Coastal Angling
+description: The working platform sits apart from the travel path. Inspect the fishing spot for tools
+ and level requirements.
+exits:
+ south:
+ room: 2207
+objects:
+- id: bait_fishing_spot
diff --git a/data/rooms/coast/2216.yaml b/data/rooms/coast/2216.yaml
new file mode 100644
index 0000000..45d82c9
--- /dev/null
+++ b/data/rooms/coast/2216.yaml
@@ -0,0 +1,7 @@
+name: Brumalia Coast — Drift Salvage
+description: Cold scrap washes up behind a protective boom.
+exits:
+ north:
+ room: 2201
+objects:
+- id: scrap_pile
diff --git a/data/rooms/coast/2217.yaml b/data/rooms/coast/2217.yaml
new file mode 100644
index 0000000..9867046
--- /dev/null
+++ b/data/rooms/coast/2217.yaml
@@ -0,0 +1,7 @@
+name: Brumalia Coast — Cosmic Tide Shrine
+description: A tide-polished array identifies cosmicjunk at Scavenging 27.
+exits:
+ north:
+ room: 2202
+objects:
+- id: cosmic_altar
diff --git a/data/rooms/coast/2218.yaml b/data/rooms/coast/2218.yaml
new file mode 100644
index 0000000..f5a5bca
--- /dev/null
+++ b/data/rooms/coast/2218.yaml
@@ -0,0 +1,7 @@
+name: Brumalia Coast — Tide Controller
+description: Safe calibration work trains Technology from level 20.
+exits:
+ north:
+ room: 2204
+objects:
+- id: tidal_relay
diff --git a/data/rooms/coast/2219.yaml b/data/rooms/coast/2219.yaml
new file mode 100644
index 0000000..a2d4b54
--- /dev/null
+++ b/data/rooms/coast/2219.yaml
@@ -0,0 +1,7 @@
+name: Brumalia Coast — Saltgrass Shoal
+description: Medicinal grasses root in sand behind the seawall.
+exits:
+ north:
+ room: 2207
+objects:
+- id: saltgrass
diff --git a/data/rooms/coast/2220.yaml b/data/rooms/coast/2220.yaml
new file mode 100644
index 0000000..78f083d
--- /dev/null
+++ b/data/rooms/coast/2220.yaml
@@ -0,0 +1,7 @@
+name: Brumalia Coast — Beach Road
+description: The public beach road ends at a signposted wreck access ramp.
+exits:
+ north:
+ room: 2114
+ south:
+ room: 2221
diff --git a/data/rooms/coast/2221.yaml b/data/rooms/coast/2221.yaml
new file mode 100644
index 0000000..5f2c2b1
--- /dev/null
+++ b/data/rooms/coast/2221.yaml
@@ -0,0 +1,12 @@
+name: Brumalia Coast — Wreck Ramp
+description: A warning board distinguishes the beach from the dangerous wreck interiors.
+exits:
+ north:
+ room: 2220
+ east:
+ room: 2222
+objects:
+- name: danger marker
+ description: 'DANGER beyond this side trail: scrap bot, scrap bot. The public road and gathering path
+ are safe; this detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
diff --git a/data/rooms/coast/2222.yaml b/data/rooms/coast/2222.yaml
new file mode 100644
index 0000000..19faf75
--- /dev/null
+++ b/data/rooms/coast/2222.yaml
@@ -0,0 +1,17 @@
+name: Brumalia Coast — Broken Freighter
+description: A grounded hull still houses hostile salvage machines. This is an off-road combat area; hostile
+ creatures remain here.
+exits:
+ west:
+ room: 2221
+ east:
+ room: 2223
+objects:
+- id: rock_outcrop
+- name: danger marker
+ description: 'DANGER beyond this side trail: security turret. The public road and gathering path are
+ safe; this detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
+mobs:
+- id: scrap_bot
+- id: scrap_bot
diff --git a/data/rooms/coast/2223.yaml b/data/rooms/coast/2223.yaml
new file mode 100644
index 0000000..c633839
--- /dev/null
+++ b/data/rooms/coast/2223.yaml
@@ -0,0 +1,16 @@
+name: Brumalia Coast — Cargo Hold
+description: Automated defenses protect cargo that spoiled decades ago. This is an off-road combat area;
+ hostile creatures remain here.
+exits:
+ west:
+ room: 2222
+ east:
+ room: 2224
+objects:
+- id: rock_outcrop
+- name: danger marker
+ description: 'DANGER beyond this side trail: lesser drone. The public road and gathering path are safe;
+ this detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
+mobs:
+- id: security_turret
diff --git a/data/rooms/coast/2224.yaml b/data/rooms/coast/2224.yaml
new file mode 100644
index 0000000..61b9980
--- /dev/null
+++ b/data/rooms/coast/2224.yaml
@@ -0,0 +1,10 @@
+name: Brumalia Coast — Engine Compartment
+description: An old drone moves between the silent engines. This is an off-road combat area; hostile creatures
+ remain here.
+exits:
+ west:
+ room: 2223
+objects:
+- id: rock_outcrop
+mobs:
+- id: lesser_drone
diff --git a/data/rooms/coast/2225.yaml b/data/rooms/coast/2225.yaml
new file mode 100644
index 0000000..bb08949
--- /dev/null
+++ b/data/rooms/coast/2225.yaml
@@ -0,0 +1,7 @@
+name: Brumalia — Rigging Practice Track
+description: A path follows the town boundary toward a land-based rigging course.
+exits:
+ north:
+ room: 2108
+ south:
+ room: 8108
diff --git a/data/rooms/coast/2226.yaml b/data/rooms/coast/2226.yaml
new file mode 100644
index 0000000..b2b504b
--- /dev/null
+++ b/data/rooms/coast/2226.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Coast — Winch Repair Platform
+description: An isolated winch frame waits for repair beside the working docks. This is paid work, not
+ a combat area.
+exits:
+ north:
+ room: 2203
+mobs:
+- id: harbor_winch
diff --git a/data/rooms/domita/5100.yaml b/data/rooms/domita/5100.yaml
new file mode 100644
index 0000000..07b4fe9
--- /dev/null
+++ b/data/rooms/domita/5100.yaml
@@ -0,0 +1,10 @@
+name: Domita — West Gate
+description: The west road passes between worn boundary stones. Behind you, Charter Boulevard runs past
+ separate shopfronts toward the town center.
+exits:
+ east:
+ room: 5101
+ north:
+ room: 5134
+ west:
+ room: 5200
diff --git a/data/rooms/domita/5101.yaml b/data/rooms/domita/5101.yaml
new file mode 100644
index 0000000..2767ba0
--- /dev/null
+++ b/data/rooms/domita/5101.yaml
@@ -0,0 +1,12 @@
+name: Domita — Charter Boulevard West 3
+description: Upper windows overlook Charter Boulevard; downstairs, merchants have propped their doors
+ open for passing trade.
+exits:
+ west:
+ room: 5100
+ east:
+ room: 5102
+ north:
+ room: 5115
+ south:
+ room: 5121
diff --git a/data/rooms/domita/5102.yaml b/data/rooms/domita/5102.yaml
new file mode 100644
index 0000000..0f0cb9b
--- /dev/null
+++ b/data/rooms/domita/5102.yaml
@@ -0,0 +1,12 @@
+name: Domita — Charter Boulevard West 2
+description: An old drain runs beside the paving. The smell from an open shop door changes whenever the
+ wind turns.
+exits:
+ west:
+ room: 5101
+ east:
+ room: 5103
+ north:
+ room: 5116
+ south:
+ room: 5122
diff --git a/data/rooms/domita/5103.yaml b/data/rooms/domita/5103.yaml
new file mode 100644
index 0000000..085f3b9
--- /dev/null
+++ b/data/rooms/domita/5103.yaml
@@ -0,0 +1,12 @@
+name: Domita — Charter Boulevard West 1
+description: Awnings shade this stretch of Charter Boulevard. Each doorway belongs to a different business;
+ delivery handcarts leave a narrow path between them.
+exits:
+ west:
+ room: 5102
+ east:
+ room: 5104
+ north:
+ room: 5117
+ south:
+ room: 5123
diff --git a/data/rooms/domita/5104.yaml b/data/rooms/domita/5104.yaml
new file mode 100644
index 0000000..feb9a94
--- /dev/null
+++ b/data/rooms/domita/5104.yaml
@@ -0,0 +1,19 @@
+name: Domita — Town Square
+description: Charter Boulevard opens around a public notice pillar. Foot traffic divides between the shops,
+ the north avenue and the quieter houses to the south.
+exits:
+ west:
+ room: 5103
+ east:
+ room: 5105
+ north:
+ room: 5109
+ south:
+ room: 5112
+objects:
+- id: aps_tower
+- name: wayboard
+ description: 'Domita: forest and Numisia southeast by the east gate. Quarry west; safe survey road beyond
+ the east gardens. House of Icarus north. The corporation owns the casino, not your right to travel.
+ This is still Vesta’s settled starting district; the roads beyond await future expansion.'
+ inroom_description: A wayboard stands where travelers can read it.
diff --git a/data/rooms/domita/5105.yaml b/data/rooms/domita/5105.yaml
new file mode 100644
index 0000000..20c2360
--- /dev/null
+++ b/data/rooms/domita/5105.yaml
@@ -0,0 +1,12 @@
+name: Domita — Charter Boulevard East 1
+description: Awnings shade this stretch of Charter Boulevard. Each doorway belongs to a different business;
+ delivery handcarts leave a narrow path between them.
+exits:
+ west:
+ room: 5104
+ east:
+ room: 5106
+ north:
+ room: 5118
+ south:
+ room: 5124
diff --git a/data/rooms/domita/5106.yaml b/data/rooms/domita/5106.yaml
new file mode 100644
index 0000000..783b465
--- /dev/null
+++ b/data/rooms/domita/5106.yaml
@@ -0,0 +1,12 @@
+name: Domita — Charter Boulevard East 2
+description: An old drain runs beside the paving. The smell from an open shop door changes whenever the
+ wind turns.
+exits:
+ west:
+ room: 5105
+ east:
+ room: 5107
+ north:
+ room: 5119
+ south:
+ room: 5125
diff --git a/data/rooms/domita/5107.yaml b/data/rooms/domita/5107.yaml
new file mode 100644
index 0000000..ded1713
--- /dev/null
+++ b/data/rooms/domita/5107.yaml
@@ -0,0 +1,12 @@
+name: Domita — Charter Boulevard East 3
+description: Upper windows overlook Charter Boulevard; downstairs, merchants have propped their doors
+ open for passing trade.
+exits:
+ west:
+ room: 5106
+ east:
+ room: 5108
+ north:
+ room: 5120
+ south:
+ room: 5126
diff --git a/data/rooms/domita/5108.yaml b/data/rooms/domita/5108.yaml
new file mode 100644
index 0000000..42fea22
--- /dev/null
+++ b/data/rooms/domita/5108.yaml
@@ -0,0 +1,10 @@
+name: Domita — East Gate
+description: Cart tracks cross the eastern boundary. Lamps mark the safe road; the shops of Charter Boulevard
+ remain within easy walking distance.
+exits:
+ west:
+ room: 5107
+ north:
+ room: 5142
+ southeast:
+ room: 7146
diff --git a/data/rooms/domita/5109.yaml b/data/rooms/domita/5109.yaml
new file mode 100644
index 0000000..309d02b
--- /dev/null
+++ b/data/rooms/domita/5109.yaml
@@ -0,0 +1,10 @@
+name: Domita — North Avenue
+description: Wide paving carries carts toward the northern boundary. A street board lists the next settlements,
+ not their recommended combat levels.
+exits:
+ south:
+ room: 5104
+ north:
+ room: 5110
+mobs:
+- id: corporate_auditor
diff --git a/data/rooms/domita/5110.yaml b/data/rooms/domita/5110.yaml
new file mode 100644
index 0000000..3f59aad
--- /dev/null
+++ b/data/rooms/domita/5110.yaml
@@ -0,0 +1,11 @@
+name: Domita — Civic Walk
+description: Stone benches face municipal doorways. None of the offices charges admission.
+exits:
+ south:
+ room: 5109
+ north:
+ room: 5111
+ west:
+ room: 5127
+ east:
+ room: 5128
diff --git a/data/rooms/domita/5111.yaml b/data/rooms/domita/5111.yaml
new file mode 100644
index 0000000..c872c39
--- /dev/null
+++ b/data/rooms/domita/5111.yaml
@@ -0,0 +1,8 @@
+name: Domita — North Gate
+description: Beyond the gate the maintained road continues into open country. Dangerous side paths have
+ their own warning boards.
+exits:
+ south:
+ room: 5110
+ north:
+ room: 6100
diff --git a/data/rooms/domita/5112.yaml b/data/rooms/domita/5112.yaml
new file mode 100644
index 0000000..6f974a6
--- /dev/null
+++ b/data/rooms/domita/5112.yaml
@@ -0,0 +1,8 @@
+name: Domita — Lantern Lane
+description: Laundry strings cross above the lane, well clear of the lamps. Residents have painted their
+ doors different colors.
+exits:
+ north:
+ room: 5104
+ south:
+ room: 5113
diff --git a/data/rooms/domita/5113.yaml b/data/rooms/domita/5113.yaml
new file mode 100644
index 0000000..ed5e1c6
--- /dev/null
+++ b/data/rooms/domita/5113.yaml
@@ -0,0 +1,12 @@
+name: Domita — Residential Court
+description: A shared wash basin occupies a tiny court. Conversations drift through shutters rather than
+ out of a crowded marketplace.
+exits:
+ north:
+ room: 5112
+ south:
+ room: 5114
+ west:
+ room: 5129
+ east:
+ room: 5130
diff --git a/data/rooms/domita/5114.yaml b/data/rooms/domita/5114.yaml
new file mode 100644
index 0000000..8a73ead
--- /dev/null
+++ b/data/rooms/domita/5114.yaml
@@ -0,0 +1,10 @@
+name: Domita — South Gate
+description: The southern road leaves the houses behind. Its boundary posts are white; hazardous detours
+ are marked red.
+exits:
+ north:
+ room: 5113
+ west:
+ room: 5131
+ east:
+ room: 5132
diff --git a/data/rooms/domita/5115.yaml b/data/rooms/domita/5115.yaml
new file mode 100644
index 0000000..49fe27a
--- /dev/null
+++ b/data/rooms/domita/5115.yaml
@@ -0,0 +1,7 @@
+name: Domita — Assayer’s Instruments
+description: A brass scale stands beneath a poster claiming that Icarus credits are as sound as gold.
+exits:
+ south:
+ room: 5101
+mobs:
+- id: domita_assayer
diff --git a/data/rooms/domita/5116.yaml b/data/rooms/domita/5116.yaml
new file mode 100644
index 0000000..23b28d5
--- /dev/null
+++ b/data/rooms/domita/5116.yaml
@@ -0,0 +1,7 @@
+name: Domita — Charter Bank
+description: The independent bank has refused to replace its old stone sign with a casino logo.
+exits:
+ south:
+ room: 5102
+objects:
+- id: bank_booth
diff --git a/data/rooms/domita/5117.yaml b/data/rooms/domita/5117.yaml
new file mode 100644
index 0000000..763e297
--- /dev/null
+++ b/data/rooms/domita/5117.yaml
@@ -0,0 +1,9 @@
+name: Domita — Guild Forge
+description: A tall chimney keeps smoke above the boulevard. Master metalworkers share the furnace and
+ anvil.
+exits:
+ south:
+ room: 5103
+objects:
+- id: furnace
+- id: anvil
diff --git a/data/rooms/domita/5118.yaml b/data/rooms/domita/5118.yaml
new file mode 100644
index 0000000..39a4e39
--- /dev/null
+++ b/data/rooms/domita/5118.yaml
@@ -0,0 +1,7 @@
+name: Domita — Merrit’s Instruments
+description: Saw teeth and polished chisels shine behind clear glass.
+exits:
+ south:
+ room: 5105
+mobs:
+- id: domita_supplier
diff --git a/data/rooms/domita/5119.yaml b/data/rooms/domita/5119.yaml
new file mode 100644
index 0000000..426c300
--- /dev/null
+++ b/data/rooms/domita/5119.yaml
@@ -0,0 +1,9 @@
+name: Domita — Pell’s Technical Archive
+description: A hand-operated card index sits beside a secure research terminal.
+exits:
+ south:
+ room: 5106
+objects:
+- id: terminal_secure
+mobs:
+- id: domita_technician
diff --git a/data/rooms/domita/5120.yaml b/data/rooms/domita/5120.yaml
new file mode 100644
index 0000000..d227e38
--- /dev/null
+++ b/data/rooms/domita/5120.yaml
@@ -0,0 +1,7 @@
+name: Domita — Myrrh’s Dispensary
+description: The consultation screen is patched with offcuts of expensive casino velvet.
+exits:
+ south:
+ room: 5107
+mobs:
+- id: domita_surgeon
diff --git a/data/rooms/domita/5121.yaml b/data/rooms/domita/5121.yaml
new file mode 100644
index 0000000..043d7e2
--- /dev/null
+++ b/data/rooms/domita/5121.yaml
@@ -0,0 +1,7 @@
+name: Domita — Commission Office
+description: Targets are filed by danger, not by the value of their bounty.
+exits:
+ north:
+ room: 5101
+mobs:
+- id: domita_contracts
diff --git a/data/rooms/domita/5122.yaml b/data/rooms/domita/5122.yaml
new file mode 100644
index 0000000..19a4277
--- /dev/null
+++ b/data/rooms/domita/5122.yaml
@@ -0,0 +1,7 @@
+name: Domita — The Workers’ Kitchen
+description: Public stoves feed people who spend their shifts feeding the casino.
+exits:
+ north:
+ room: 5102
+objects:
+- id: cooking_range
diff --git a/data/rooms/domita/5123.yaml b/data/rooms/domita/5123.yaml
new file mode 100644
index 0000000..5903ee4
--- /dev/null
+++ b/data/rooms/domita/5123.yaml
@@ -0,0 +1,7 @@
+name: Domita — Fine Cabinetmakers
+description: Mahogany patterns lie beneath weighted sheets on a long workbench.
+exits:
+ north:
+ room: 5103
+objects:
+- id: workbench
diff --git a/data/rooms/domita/5124.yaml b/data/rooms/domita/5124.yaml
new file mode 100644
index 0000000..fbb3ba9
--- /dev/null
+++ b/data/rooms/domita/5124.yaml
@@ -0,0 +1,7 @@
+name: Domita — Guild Textile Hall
+description: A full wall of thread samples faces a public spinning wheel.
+exits:
+ north:
+ room: 5105
+objects:
+- id: spinning_wheel
diff --git a/data/rooms/domita/5125.yaml b/data/rooms/domita/5125.yaml
new file mode 100644
index 0000000..aaef4de
--- /dev/null
+++ b/data/rooms/domita/5125.yaml
@@ -0,0 +1,8 @@
+name: Domita — Ceramics Gallery
+description: Elegant glazed vessels surround a practical wheel and firing oven.
+exits:
+ north:
+ room: 5106
+objects:
+- id: pottery_wheel
+- id: pottery_oven
diff --git a/data/rooms/domita/5126.yaml b/data/rooms/domita/5126.yaml
new file mode 100644
index 0000000..69fd46a
--- /dev/null
+++ b/data/rooms/domita/5126.yaml
@@ -0,0 +1,7 @@
+name: Domita — Municipal Charging Room
+description: The city charger remains public despite the corporate crest newly riveted above it.
+exits:
+ north:
+ room: 5107
+objects:
+- id: charging_station
diff --git a/data/rooms/domita/5127.yaml b/data/rooms/domita/5127.yaml
new file mode 100644
index 0000000..b8def2a
--- /dev/null
+++ b/data/rooms/domita/5127.yaml
@@ -0,0 +1,7 @@
+name: Domita — Old Council Chamber
+description: The council’s wooden chairs face an empty plinth where the charter once stood.
+exits:
+ east:
+ room: 5110
+mobs:
+- id: domita_resident
diff --git a/data/rooms/domita/5128.yaml b/data/rooms/domita/5128.yaml
new file mode 100644
index 0000000..49b6230
--- /dev/null
+++ b/data/rooms/domita/5128.yaml
@@ -0,0 +1,7 @@
+name: Domita — Public Charter Archive
+description: A glass case holds the town charter. The casino’s founding lease is conspicuously shorter.
+exits:
+ west:
+ room: 5110
+mobs:
+- id: casino_archivist
diff --git a/data/rooms/domita/5129.yaml b/data/rooms/domita/5129.yaml
new file mode 100644
index 0000000..c762090
--- /dev/null
+++ b/data/rooms/domita/5129.yaml
@@ -0,0 +1,5 @@
+name: Domita — Porter’s Lodging
+description: A uniform hangs over a basin; the window looks toward someone else’s bright marquee.
+exits:
+ east:
+ room: 5113
diff --git a/data/rooms/domita/5130.yaml b/data/rooms/domita/5130.yaml
new file mode 100644
index 0000000..ded0a0d
--- /dev/null
+++ b/data/rooms/domita/5130.yaml
@@ -0,0 +1,9 @@
+name: Domita — Watch House
+description: The watch keeps the city roads safe and the gambling rooms out of its jurisdiction.
+exits:
+ west:
+ room: 5113
+ down:
+ room: 5133
+mobs:
+- id: guard
diff --git a/data/rooms/domita/5131.yaml b/data/rooms/domita/5131.yaml
new file mode 100644
index 0000000..31905cf
--- /dev/null
+++ b/data/rooms/domita/5131.yaml
@@ -0,0 +1,7 @@
+name: Domita — Union Tenement
+description: A painted notice asks residents not to buy their supper on credit.
+exits:
+ east:
+ room: 5114
+mobs:
+- id: man
diff --git a/data/rooms/domita/5132.yaml b/data/rooms/domita/5132.yaml
new file mode 100644
index 0000000..0b69fa5
--- /dev/null
+++ b/data/rooms/domita/5132.yaml
@@ -0,0 +1,7 @@
+name: Domita — Civic Fountain
+description: Clean water trickles over a plaque sponsored, inevitably, by Icarus Leisure.
+exits:
+ west:
+ room: 5114
+objects:
+- id: lumby_fountain
diff --git a/data/rooms/domita/5133.yaml b/data/rooms/domita/5133.yaml
new file mode 100644
index 0000000..8c71064
--- /dev/null
+++ b/data/rooms/domita/5133.yaml
@@ -0,0 +1,5 @@
+name: Domita — Holding Cell
+description: A dry, plain cell opens back up into the watch house. No fine or key is required to leave.
+exits:
+ up:
+ room: 5130
diff --git a/data/rooms/domita/5134.yaml b/data/rooms/domita/5134.yaml
new file mode 100644
index 0000000..de2644a
--- /dev/null
+++ b/data/rooms/domita/5134.yaml
@@ -0,0 +1,10 @@
+name: Domita — West Tram Walk
+description: Rails from a dismantled tram have been filled flush with stone. Shift workers still follow
+ their curve.
+exits:
+ south:
+ room: 5100
+ west:
+ room: 5135
+ north:
+ room: 5136
diff --git a/data/rooms/domita/5135.yaml b/data/rooms/domita/5135.yaml
new file mode 100644
index 0000000..8a8879c
--- /dev/null
+++ b/data/rooms/domita/5135.yaml
@@ -0,0 +1,5 @@
+name: Domita — West Watch Rest Room
+description: A quiet room gives road patrols somewhere to rest between rounds.
+exits:
+ east:
+ room: 5134
diff --git a/data/rooms/domita/5136.yaml b/data/rooms/domita/5136.yaml
new file mode 100644
index 0000000..0205817
--- /dev/null
+++ b/data/rooms/domita/5136.yaml
@@ -0,0 +1,9 @@
+name: Domita — West Leaseholders’ Row
+description: Identical lease notices hang on buildings of very different ages.
+exits:
+ south:
+ room: 5134
+ west:
+ room: 5137
+ north:
+ room: 5138
diff --git a/data/rooms/domita/5137.yaml b/data/rooms/domita/5137.yaml
new file mode 100644
index 0000000..2a745ef
--- /dev/null
+++ b/data/rooms/domita/5137.yaml
@@ -0,0 +1,7 @@
+name: Domita — West Night Clerk’s House
+description: A blackout curtain promises sleep despite the casino glow.
+exits:
+ east:
+ room: 5136
+mobs:
+- id: domita_resident
diff --git a/data/rooms/domita/5138.yaml b/data/rooms/domita/5138.yaml
new file mode 100644
index 0000000..d35abfd
--- /dev/null
+++ b/data/rooms/domita/5138.yaml
@@ -0,0 +1,9 @@
+name: Domita — West Service Court
+description: Laundry, coal deliveries and quiet arguments stay out of sight of the casino doors.
+exits:
+ south:
+ room: 5136
+ west:
+ room: 5139
+ north:
+ room: 5140
diff --git a/data/rooms/domita/5139.yaml b/data/rooms/domita/5139.yaml
new file mode 100644
index 0000000..2ea7050
--- /dev/null
+++ b/data/rooms/domita/5139.yaml
@@ -0,0 +1,5 @@
+name: Domita — West Ticket Printers
+description: Discarded tickets form a paper drift beneath a hand press.
+exits:
+ east:
+ room: 5138
diff --git a/data/rooms/domita/5140.yaml b/data/rooms/domita/5140.yaml
new file mode 100644
index 0000000..68fe2a0
--- /dev/null
+++ b/data/rooms/domita/5140.yaml
@@ -0,0 +1,8 @@
+name: Domita — West Garden Walk
+description: Carefully pruned ornamental shrubs conceal the ventilation grilles. Nothing here is intended
+ for harvesting.
+exits:
+ south:
+ room: 5138
+ west:
+ room: 5141
diff --git a/data/rooms/domita/5141.yaml b/data/rooms/domita/5141.yaml
new file mode 100644
index 0000000..02dcca2
--- /dev/null
+++ b/data/rooms/domita/5141.yaml
@@ -0,0 +1,5 @@
+name: Domita — West Pensioners’ Tea Room
+description: Porcelain cups clink beneath portraits of forgotten mayors.
+exits:
+ east:
+ room: 5140
diff --git a/data/rooms/domita/5142.yaml b/data/rooms/domita/5142.yaml
new file mode 100644
index 0000000..a6ac4e1
--- /dev/null
+++ b/data/rooms/domita/5142.yaml
@@ -0,0 +1,10 @@
+name: Domita — East Tram Walk
+description: Rails from a dismantled tram have been filled flush with stone. Shift workers still follow
+ their curve.
+exits:
+ south:
+ room: 5108
+ east:
+ room: 5143
+ north:
+ room: 5144
diff --git a/data/rooms/domita/5143.yaml b/data/rooms/domita/5143.yaml
new file mode 100644
index 0000000..6c01e37
--- /dev/null
+++ b/data/rooms/domita/5143.yaml
@@ -0,0 +1,5 @@
+name: Domita — East Watch Rest Room
+description: A quiet room gives road patrols somewhere to rest between rounds.
+exits:
+ west:
+ room: 5142
diff --git a/data/rooms/domita/5144.yaml b/data/rooms/domita/5144.yaml
new file mode 100644
index 0000000..f4aef52
--- /dev/null
+++ b/data/rooms/domita/5144.yaml
@@ -0,0 +1,9 @@
+name: Domita — East Leaseholders’ Row
+description: Identical lease notices hang on buildings of very different ages.
+exits:
+ south:
+ room: 5142
+ east:
+ room: 5145
+ north:
+ room: 5146
diff --git a/data/rooms/domita/5145.yaml b/data/rooms/domita/5145.yaml
new file mode 100644
index 0000000..0ed448d
--- /dev/null
+++ b/data/rooms/domita/5145.yaml
@@ -0,0 +1,7 @@
+name: Domita — East Night Clerk’s House
+description: A blackout curtain promises sleep despite the casino glow.
+exits:
+ west:
+ room: 5144
+mobs:
+- id: domita_resident
diff --git a/data/rooms/domita/5146.yaml b/data/rooms/domita/5146.yaml
new file mode 100644
index 0000000..beab2b5
--- /dev/null
+++ b/data/rooms/domita/5146.yaml
@@ -0,0 +1,9 @@
+name: Domita — East Service Court
+description: Laundry, coal deliveries and quiet arguments stay out of sight of the casino doors.
+exits:
+ south:
+ room: 5144
+ east:
+ room: 5147
+ north:
+ room: 5148
diff --git a/data/rooms/domita/5147.yaml b/data/rooms/domita/5147.yaml
new file mode 100644
index 0000000..9cb9ab0
--- /dev/null
+++ b/data/rooms/domita/5147.yaml
@@ -0,0 +1,5 @@
+name: Domita — East Ticket Printers
+description: Discarded tickets form a paper drift beneath a hand press.
+exits:
+ west:
+ room: 5146
diff --git a/data/rooms/domita/5148.yaml b/data/rooms/domita/5148.yaml
new file mode 100644
index 0000000..af064ca
--- /dev/null
+++ b/data/rooms/domita/5148.yaml
@@ -0,0 +1,10 @@
+name: Domita — East Garden Walk
+description: Carefully pruned ornamental shrubs conceal the ventilation grilles. Nothing here is intended
+ for harvesting.
+exits:
+ south:
+ room: 5146
+ east:
+ room: 5149
+ north:
+ room: 5208
diff --git a/data/rooms/domita/5149.yaml b/data/rooms/domita/5149.yaml
new file mode 100644
index 0000000..2f9e8ee
--- /dev/null
+++ b/data/rooms/domita/5149.yaml
@@ -0,0 +1,5 @@
+name: Domita — East Pensioners’ Tea Room
+description: Porcelain cups clink beneath portraits of forgotten mayors.
+exits:
+ west:
+ room: 5148
diff --git a/data/rooms/example_unused/player_housing/99999300.yaml b/data/rooms/example_unused/player_housing/99999300.yaml
deleted file mode 100644
index 64a2a25..0000000
--- a/data/rooms/example_unused/player_housing/99999300.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-id: 99999300
-name: 'Player House: Entrance Hall'
-color: ""
-description:
- - text: A cozy entrance hall with polished floors and warm lighting. A welcome mat greets visitors at the door.
-exits:
- north:
- room: 99999301
- east:
- room: 99999170
-objects:
- - id: charging_station
-item_spawns: []
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/player_housing/99999301.yaml b/data/rooms/example_unused/player_housing/99999301.yaml
deleted file mode 100644
index 19a38e9..0000000
--- a/data/rooms/example_unused/player_housing/99999301.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-name: "Player House: Workshop"
-description:
- - text: "A well-lit workshop with a sturdy workbench covered in tools and blueprints. Wood shavings litter the floor around the bench."
-exits:
- south:
- room: 99999300
-objects:
- - id: workbench
- - id: bank_booth
diff --git a/data/rooms/example_unused/town/999991.yaml b/data/rooms/example_unused/town/999991.yaml
deleted file mode 100644
index ee164f4..0000000
--- a/data/rooms/example_unused/town/999991.yaml
+++ /dev/null
@@ -1,89 +0,0 @@
-id: 999991
-name: Town Square
-color: ""
-description:
- - text: The central square of Lumbridge. A fountain gurgles peacefully in the center. Paths lead west toward the gathering grounds and east toward the production district.
-exits:
- down:
- room: 9999931
- east:
- room: 999992
- west:
- room: 9999922
- north:
- room: 99999160
-objects:
- - id: lumby_fountain
- - id: charging_station
- - id: bank_booth
- - id: aps_tower
-item_spawns:
- - id: cape_of_agility
- quantity: 1
- respawn_ticks: 60
- - id: graceful_hat
- quantity: 1
- respawn_ticks: 60
- - id: graceful_torso
- quantity: 1
- respawn_ticks: 60
- - id: graceful_legs
- quantity: 1
- respawn_ticks: 60
- - id: graceful_gloves
- quantity: 1
- respawn_ticks: 60
- - id: graceful_boots
- quantity: 1
- respawn_ticks: 60
- - id: graceful_cape
- quantity: 1
- respawn_ticks: 60
- - id: basic_deck
- quantity: 1
- respawn_ticks: 60
- - id: solar_identifier
- quantity: 1
- respawn_ticks: 60
- - id: hydro_identifier
- quantity: 1
- respawn_ticks: 60
- - id: cosmic_identifier
- quantity: 1
- respawn_ticks: 60
- - id: eco_identifier
- quantity: 1
- respawn_ticks: 60
- - id: chaos_identifier
- quantity: 1
- respawn_ticks: 60
- - id: bio_identifier
- quantity: 1
- respawn_ticks: 60
- - id: nature_identifier
- quantity: 1
- respawn_ticks: 60
- - id: law_identifier
- quantity: 1
- respawn_ticks: 60
- - id: death_identifier
- quantity: 1
- respawn_ticks: 60
- - id: blood_identifier
- quantity: 1
- respawn_ticks: 60
- - id: grimy_guam
- quantity: 5
- respawn_ticks: 60
- - id: vial_of_water
- quantity: 5
- respawn_ticks: 60
- - id: eye_of_newt
- quantity: 5
- respawn_ticks: 60
-mobs:
- - id: newbie_trainer
- - id: general_store_clerk
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/town/9999910.yaml b/data/rooms/example_unused/town/9999910.yaml
deleted file mode 100644
index 43bfbb5..0000000
--- a/data/rooms/example_unused/town/9999910.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-name: "Farming Plot"
-description:
- - text: "A small patch of tilled soil behind a weathered fence. This area is not yet accessible."
-exits:
- west:
- room: 999999
- east:
- room: 9999911
-mobs:
- - id: skeleton
- - id: skeleton
- - id: mutant_rat
diff --git a/data/rooms/example_unused/town/9999911.yaml b/data/rooms/example_unused/town/9999911.yaml
deleted file mode 100644
index 75aa59c..0000000
--- a/data/rooms/example_unused/town/9999911.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
-id: 9999911
-name: Kitchen
-color: ""
-description:
- - text: A warm kitchen with a stone hearth and wooden counters. A large iron cooking range dominates one wall, and shelves are stocked with ingredients.
-exits:
- east:
- room: 9999912
- west:
- room: 9999910
- north:
- room: 99999153
-objects:
- - id: cooking_range
-item_spawns:
- - id: bucket_of_water
- quantity: 1
- respawn_ticks: 200
- - id: pot_of_flour
- quantity: 1
- respawn_ticks: 200
-mobs:
- - id: zombie
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/town/9999912.yaml b/data/rooms/example_unused/town/9999912.yaml
deleted file mode 100644
index 0df117e..0000000
--- a/data/rooms/example_unused/town/9999912.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: "Forge"
-description:
-- text: "A blazing forge and anvil dominate this smoky workshop. The heat from the furnace is intense."
-exits:
- east:
- room: 9999913
- west:
- room: 9999911
-mobs:
-- id: weapons_smith
-objects:
-- id: furnace
-- id: anvil
-- id: bank_booth
-item_spawns:
-- id: copper_ore
- quantity: 3
- respawn_ticks: 30
-- id: tin_ore
- quantity: 3
- respawn_ticks: 30
-- id: iron_ore
- quantity: 3
- respawn_ticks: 30
-- id: coal
- quantity: 5
- respawn_ticks: 30
-- id: hammer
- quantity: 1
- respawn_ticks: 30
diff --git a/data/rooms/example_unused/town/9999913.yaml b/data/rooms/example_unused/town/9999913.yaml
deleted file mode 100644
index 318369c..0000000
--- a/data/rooms/example_unused/town/9999913.yaml
+++ /dev/null
@@ -1,48 +0,0 @@
-name: "Crafting Workshop"
-description:
- - text: "A bustling workshop filled with crafting stations. A {130}spinning wheel{/} sits in one corner, a {173}pottery wheel{/} and {196}pottery oven{/} in another. Racks of tools and raw materials line the walls. The forge is just to the west."
-exits:
- east:
- room: 9999914
- west:
- room: 9999912
-objects:
- - id: spinning_wheel
- - id: pottery_wheel
- - id: pottery_oven
- - id: sheep
- - id: clay_rock
- - id: clay_rock
-mobs:
- - id: tanner
- - id: cow
- - id: cow
- - id: cow
-item_spawns:
- - id: flax
- quantity: 5
- respawn_ticks: 60
- - id: thread
- quantity: 10
- respawn_ticks: 60
- - id: shears
- quantity: 1
- respawn_ticks: 60
- - id: needle
- quantity: 1
- respawn_ticks: 60
- - id: chisel
- quantity: 1
- respawn_ticks: 60
- - id: ring_mould
- quantity: 1
- respawn_ticks: 60
- - id: necklace_mould
- quantity: 1
- respawn_ticks: 60
- - id: amulet_mould
- quantity: 1
- respawn_ticks: 60
- - id: bracelet_mould
- quantity: 1
- respawn_ticks: 60
diff --git a/data/rooms/example_unused/town/9999914.yaml b/data/rooms/example_unused/town/9999914.yaml
deleted file mode 100644
index 671f366..0000000
--- a/data/rooms/example_unused/town/9999914.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
-id: 9999914
-name: Fletching Bench
-color: ""
-description:
- - text: A workbench covered in wood shavings, feathers, and arrowheads. Racks of unfinished bows line the walls, and a pile of bowstrings sits in the corner.
-exits:
- east:
- room: 9999915
- west:
- room: 9999913
-objects: []
-item_spawns:
- - id: bowstring
- quantity: 5
- respawn_ticks: 50
- - id: knife
- quantity: 1
- respawn_ticks: 50
- - id: chisel
- quantity: 1
- respawn_ticks: 50
-mobs:
- - id: moss_giant
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/town/9999915.yaml b/data/rooms/example_unused/town/9999915.yaml
deleted file mode 100644
index 3e5ef61..0000000
--- a/data/rooms/example_unused/town/9999915.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-id: 9999915
-name: Pharmacy Lab
-color: ""
-description:
- - text: Shelves lined with glass vials, dried herbs, and bubbling cauldrons. This area is not yet accessible.
-exits:
- east:
- room: 9999917
- west:
- room: 9999914
-objects: []
-item_spawns: []
-mobs:
- - id: lesser_drone
- - id: lesser_drone
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/town/9999916.yaml b/data/rooms/example_unused/town/9999916.yaml
deleted file mode 100644
index 6937631..0000000
--- a/data/rooms/example_unused/town/9999916.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-id: 9999916
-name: Construction Site
-color: ""
-description:
- - text: A half-built structure surrounded by planks, nails, and blueprints. A workbench stands ready for crafting. Signs point north toward the Local Neighborhood and east toward the lumberyard.
-exits:
- north:
- room: 9999918
- west:
- room: 9999917
-objects:
- - id: workbench
-item_spawns: []
-mobs:
- - id: greater_drone
- - id: estate_broker
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/town/9999917.yaml b/data/rooms/example_unused/town/9999917.yaml
deleted file mode 100644
index 1a3b899..0000000
--- a/data/rooms/example_unused/town/9999917.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-id: 9999917
-name: Bonfire
-color: ""
-description:
- - text: A ring of stones surrounds a bed of ash. A few unlit logs wait nearby. A narrow passage leads north toward what sounds like echoing footsteps and clanging metal.
-exits:
- east:
- room: 9999916
- west:
- room: 9999915
-objects: []
-item_spawns: []
-mobs:
- - id: scrap_bot
- - id: scrap_bot
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/town/9999918.yaml b/data/rooms/example_unused/town/9999918.yaml
deleted file mode 100644
index 64a00c6..0000000
--- a/data/rooms/example_unused/town/9999918.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-id: 9999918
-name: Thieves' Den
-color: ""
-description:
- - text: A shadowy hideout with lockpicks, dark cloaks, and wanted posters on the walls. This area is not yet accessible.
-exits:
- north:
- room: 9999920
- south:
- room: 9999916
-objects: []
-item_spawns: []
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/town/999992.yaml b/data/rooms/example_unused/town/999992.yaml
deleted file mode 100644
index 3ac13a1..0000000
--- a/data/rooms/example_unused/town/999992.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: "Fishing Spot"
-description:
- - text: "A quiet spot along the riverbank. The water is clear and fish can be seen swimming beneath the surface. You can cast a line here with a fishing rod and bait."
-exits:
- east:
- room: 999994
- north:
- room: 999993
- west:
- room: 999991
-objects:
- - id: bait_fishing_spot
-item_spawns:
- - id: fishing_rod
- quantity: 1
- respawn_ticks: 30
- - id: fishing_bait
- quantity: 20
- respawn_ticks: 60
diff --git a/data/rooms/example_unused/town/9999920.yaml b/data/rooms/example_unused/town/9999920.yaml
deleted file mode 100644
index eef2b5f..0000000
--- a/data/rooms/example_unused/town/9999920.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-id: 9999920
-name: Assassin's Bureau
-color: ""
-description:
- - text: A discreet office with job postings pinned to a corkboard. This area is not yet accessible.
-exits:
- south:
- room: 9999918
-objects: []
-item_spawns: []
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/town/9999922.yaml b/data/rooms/example_unused/town/9999922.yaml
deleted file mode 100644
index 90683bb..0000000
--- a/data/rooms/example_unused/town/9999922.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: "West of Town Square"
-description:
- - text: ""
-exits:
- east:
- room: 999991
- west:
- room: 9999923
diff --git a/data/rooms/example_unused/town/9999923.yaml b/data/rooms/example_unused/town/9999923.yaml
deleted file mode 100644
index 83613d2..0000000
--- a/data/rooms/example_unused/town/9999923.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: "West of West of Town Square"
-description:
- - text: "Here is a description of where we are!"
-exits:
- east:
- room: 9999922
- south:
- room: 9999924
diff --git a/data/rooms/example_unused/town/9999924.yaml b/data/rooms/example_unused/town/9999924.yaml
deleted file mode 100644
index 7d6e175..0000000
--- a/data/rooms/example_unused/town/9999924.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: "South of West of West of Town Square"
-description:
- - text: "Here is a description of where we are!"
-exits:
- north:
- room: 9999923
- east:
- room: 9999925
diff --git a/data/rooms/example_unused/town/9999925.yaml b/data/rooms/example_unused/town/9999925.yaml
deleted file mode 100644
index 741d5da..0000000
--- a/data/rooms/example_unused/town/9999925.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: "East of South of West of West of Town Square"
-description:
- - text: "Here is a description of where we are!"
-exits:
- west:
- room: 9999924
- east:
- room: 9999926
diff --git a/data/rooms/example_unused/town/9999926.yaml b/data/rooms/example_unused/town/9999926.yaml
deleted file mode 100644
index e6efc47..0000000
--- a/data/rooms/example_unused/town/9999926.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: "East of South of West of West of Town Square"
-description:
- - text: "Here is a description of where we are!"
-exits:
- west:
- room: 9999925
- south:
- room: 9999927
diff --git a/data/rooms/example_unused/town/9999927.yaml b/data/rooms/example_unused/town/9999927.yaml
deleted file mode 100644
index 5862463..0000000
--- a/data/rooms/example_unused/town/9999927.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: "East of South of West of West of Town Square"
-description:
- - text: "Here is a description of where we are!"
-exits:
- west:
- room: 9999928
- north:
- room: 9999926
diff --git a/data/rooms/example_unused/town/9999928.yaml b/data/rooms/example_unused/town/9999928.yaml
deleted file mode 100644
index a0f7734..0000000
--- a/data/rooms/example_unused/town/9999928.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-name: "East of South of West of West of Town Square"
-description:
- - text: "Here is a description of where we are!"
-exits:
- east:
- room: 9999927
diff --git a/data/rooms/example_unused/town/999993.yaml b/data/rooms/example_unused/town/999993.yaml
deleted file mode 100644
index 47a1638..0000000
--- a/data/rooms/example_unused/town/999993.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-id: 999993
-name: Fly Fishing Pool
-color: ""
-description:
- - text: A calm pool where insects hover over the water. Perfect for fly fishing.
-exits:
- south:
- room: 999992
-objects:
- - id: fly_fishing_spot
-item_spawns:
- - id: fly_fishing_rod
- quantity: 1
- respawn_ticks: 30
- - id: feather
- quantity: 15
- respawn_ticks: 60
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/town/9999931.yaml b/data/rooms/example_unused/town/9999931.yaml
deleted file mode 100644
index d0a2698..0000000
--- a/data/rooms/example_unused/town/9999931.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-id: 9999931
-name: Below Town Square
-color: ""
-description:
- - text: The central square of Lumbridge. A fountain gurgles peacefully in the center. Paths lead west toward the gathering grounds and east toward the production district.
-exits:
- up:
- room: 999991
-objects: []
-item_spawns: []
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/town/999994.yaml b/data/rooms/example_unused/town/999994.yaml
deleted file mode 100644
index 4a338f0..0000000
--- a/data/rooms/example_unused/town/999994.yaml
+++ /dev/null
@@ -1,46 +0,0 @@
-id: 999994
-name: Woodcutting Glade
-color: ""
-description:
- - text: A sunny glade at the edge of the forest. A sturdy tree stands here, perfect for practicing woodcutting. A solid rock formation near the edge of the glade looks like it could provide cover.
-exits:
- east:
- room: 999996
- north:
- room: 999995
- west:
- room: 999992
- south:
- room: 99999171
-objects:
- - id: tree
- - id: tree
- - id: tree
- - id: tree
- - id: simple_rock
- - id: tutorial_lever
-item_spawns:
- - id: bronze_axe
- quantity: 1
- respawn_ticks: 60
- - id: matches
- quantity: 100
- respawn_ticks: 120
- - id: firesteel
- quantity: 1
- respawn_ticks: 120
- - id: lighter
- quantity: 1
- respawn_ticks: 120
- - id: shortbow
- quantity: 1
- respawn_ticks: 60
- - id: bronze_arrow
- quantity: 100
- respawn_ticks: 60
-mobs:
- - id: rat
- - id: rat
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/town/999995.yaml b/data/rooms/example_unused/town/999995.yaml
deleted file mode 100644
index 092dace..0000000
--- a/data/rooms/example_unused/town/999995.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-id: 999995
-name: Oak Grove
-color: ""
-description:
- - text: A stand of young oak trees. The wood here is tougher but more valuable.
-exits:
- south:
- room: 999994
-objects:
- - id: oak_tree
-item_spawns:
- - id: iron_axe
- quantity: 1
- respawn_ticks: 60
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/town/999996.yaml b/data/rooms/example_unused/town/999996.yaml
deleted file mode 100644
index 2106b86..0000000
--- a/data/rooms/example_unused/town/999996.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-name: "Mining Pit"
-description:
- - text: "A small mining pit. The rocky walls glint with veins of copper ore."
-exits:
- east:
- room: 999998
- north:
- room: 999997
- west:
- room: 999994
-objects:
- - id: copper_rock
- - id: copper_rock
- - id: copper_rock
-item_spawns:
- - id: bronze_pickaxe
- quantity: 1
- respawn_ticks: 30
diff --git a/data/rooms/example_unused/town/999997.yaml b/data/rooms/example_unused/town/999997.yaml
deleted file mode 100644
index 2c9a091..0000000
--- a/data/rooms/example_unused/town/999997.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-id: 999997
-name: Deep Mine
-color: ""
-description:
- - text: A deeper mine shaft. Higher quality ores can be found here. This area is not yet accessible.
-exits:
- south:
- room: 999996
-objects: []
-item_spawns: []
-mobs:
- - id: goblin
- - id: goblin
- - id: bandit
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/town/999998.yaml b/data/rooms/example_unused/town/999998.yaml
deleted file mode 100644
index 81d06e1..0000000
--- a/data/rooms/example_unused/town/999998.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: "Hacking Lab"
-description:
- - text: "A dimly lit room filled with old terminals and flickering screens. Cables dangle from the ceiling, some still sparking. The air smells of ozone and burnt circuitry. A {40}basic terminal{/} against the far wall still has power."
-exits:
- east:
- room: 999999
- west:
- room: 999996
-objects:
- - id: terminal_basic
- - id: terminal_advanced
- - id: terminal_secure
- - id: netrunner
diff --git a/data/rooms/example_unused/town/999999.yaml b/data/rooms/example_unused/town/999999.yaml
deleted file mode 100644
index 1b8106e..0000000
--- a/data/rooms/example_unused/town/999999.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-name: "Scavenging Post"
-description:
- - text: "A cluttered yard full of {243}scrap{/} and discarded technology. Piles of salvageable debris are scattered across the ground. The air smells of ozone and rust."
-exits:
- east:
- room: 9999910
- west:
- room: 999998
- north:
- room: 99999150
- south:
- room: 99999151
-objects:
- - id: scrap_pile
- - id: scrap_pile
- - id: scrap_pile
- - id: solar_altar
diff --git a/data/rooms/example_unused/wilderness/99999150.yaml b/data/rooms/example_unused/wilderness/99999150.yaml
deleted file mode 100644
index 10953a3..0000000
--- a/data/rooms/example_unused/wilderness/99999150.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-id: 99999150
-name: Hydroponics Bay
-color: ""
-description:
- - text: A large enclosed area with climate-controlled growing stations. {34}Lush green patches{/} of soil are laid out in neat rows under artificial UV lamps. A {94}tool shed{/} stands near the entrance. Exits lead to specialized growing areas.
-exits:
- south:
- room: 999999
-objects:
- - id: tool_shed
-item_spawns:
- - id: rake
- quantity: 1
- respawn_ticks: 120
- - id: spade
- quantity: 1
- respawn_ticks: 120
- - id: watering_can
- quantity: 1
- respawn_ticks: 120
- - id: plant_cure
- quantity: 3
- respawn_ticks: 200
- - id: guam_seed
- quantity: 5
- respawn_ticks: 300
- - id: potato_seed
- quantity: 10
- respawn_ticks: 300
- - id: onion_seed
- quantity: 10
- respawn_ticks: 300
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/wilderness/99999151.yaml b/data/rooms/example_unused/wilderness/99999151.yaml
deleted file mode 100644
index ee09050..0000000
--- a/data/rooms/example_unused/wilderness/99999151.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-id: 99999151
-name: Herb Garden
-color: ""
-description:
- - text: A dedicated section of the hydroponics bay for growing herbs. {28}Herb patches{/} are arranged in two rows under specialized grow lights. The air here smells faintly of fresh vegetation.
-exits:
- north:
- room: 999999
- south:
- room: 99999152
-objects:
- - id: herb_patch
- - id: herb_patch
- - id: herb_patch
- - id: herb_patch
-item_spawns: []
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/wilderness/99999152.yaml b/data/rooms/example_unused/wilderness/99999152.yaml
deleted file mode 100644
index fff6341..0000000
--- a/data/rooms/example_unused/wilderness/99999152.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-id: 99999152
-name: Allotment Field
-color: ""
-description:
- - text: A section with larger soil beds for growing vegetables. {94}Allotment patches{/} stretch across the floor under warm overhead lamps. A single {213}flower patch{/} sits in the corner.
-exits:
- north:
- room: 99999151
- east:
- room: 99999161
-objects:
- - id: allotment_patch
- - id: allotment_patch
- - id: allotment_patch
- - id: flower_patch
-item_spawns: []
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/wilderness/99999153.yaml b/data/rooms/example_unused/wilderness/99999153.yaml
deleted file mode 100644
index 32b1045..0000000
--- a/data/rooms/example_unused/wilderness/99999153.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-id: 99999153
-name: Pantry
-color: ""
-description:
- - text: A cramped pantry off the kitchen. Shelves of preserved rations and cooking supplies line the walls, and the smell of dried herbs hangs in the air.
-exits:
- south:
- room: 9999911
- west:
- room: 99999154
-objects: []
-item_spawns: []
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/wilderness/99999154.yaml b/data/rooms/example_unused/wilderness/99999154.yaml
deleted file mode 100644
index 493d087..0000000
--- a/data/rooms/example_unused/wilderness/99999154.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-id: 99999154
-name: Supply Closet
-color: ""
-description:
- - text: A narrow closet stacked with crates of spare tools, rope, and salvaged parts. A flickering light strip buzzes overhead.
-exits:
- east:
- room: 99999153
-objects: []
-item_spawns: []
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/wilderness/99999160.yaml b/data/rooms/example_unused/wilderness/99999160.yaml
deleted file mode 100644
index 7b81bc3..0000000
--- a/data/rooms/example_unused/wilderness/99999160.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
-id: 99999160
-name: Market Square
-color: ""
-description:
- - text: A noisy open-air market wedged between crumbling hab-blocks. Vendors hawk salvaged tech and reconstituted food from makeshift stalls. A {220 bold}Guard{/} watches over the area with a stern expression.
-exits:
- south:
- room: 999991
- west:
- room: 99999162
- north:
- room: 99999170
-objects:
- - id: market_stall
-item_spawns: []
-mobs:
- - id: man
- wander_interval: 15
- - id: man
- wander_interval: 18
- - id: man
- wander_interval: 20
- - id: guard
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/wilderness/99999161.yaml b/data/rooms/example_unused/wilderness/99999161.yaml
deleted file mode 100644
index 6566282..0000000
--- a/data/rooms/example_unused/wilderness/99999161.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
-id: 99999161
-name: Farm Outpost
-color: ""
-description:
- - text: A cluster of hydroponic grow-pods on the asteroid's surface, shielded by a flickering atmospheric dome. Rows of bio-luminescent crops stretch into the distance.
-exits:
- west:
- room: 99999152
- east:
- room: 99999180
-objects: []
-item_spawns: []
-mobs:
- - id: farmer
- wander_rooms:
- - 99999161
- - id: farmer
- wander_rooms:
- - 99999161
- - id: bioengineer
- wander_rooms:
- - 99999161
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/wilderness/99999162.yaml b/data/rooms/example_unused/wilderness/99999162.yaml
deleted file mode 100644
index 524b14d..0000000
--- a/data/rooms/example_unused/wilderness/99999162.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-id: 99999162
-name: Detention Cell
-color: ""
-description:
- - text: A small, grimy holding cell. The walls are scratched with tally marks from previous occupants. A heavy door bars the only exit.
-exits:
- east:
- room: 99999160
-objects: []
-item_spawns: []
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/wilderness/99999170.yaml b/data/rooms/example_unused/wilderness/99999170.yaml
deleted file mode 100644
index 59bddc1..0000000
--- a/data/rooms/example_unused/wilderness/99999170.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-id: 99999170
-name: Local Neighborhood
-color: ""
-description:
- - text: A quiet cul-de-sac of modest homes, each with a small garden plot. An estate directory terminal glows in the center, listing residents and property information.
-exits:
- south:
- room: 99999160
- west:
- room: 99999300
-objects:
- - id: estate_directory
-item_spawns: []
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/wilderness/99999171.yaml b/data/rooms/example_unused/wilderness/99999171.yaml
deleted file mode 100644
index 7e5d7ab..0000000
--- a/data/rooms/example_unused/wilderness/99999171.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-id: 99999171
-name: Lumberyard
-color: ""
-description:
- - text: Stacks of fresh-cut timber fill the air with the scent of pine. A massive industrial sawmill hums in the background, operated by a burly worker.
-exits:
- north:
- room: 999994
-objects: []
-item_spawns: []
-mobs:
- - id: sawmill_operator
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/example_unused/wilderness/99999180.yaml b/data/rooms/example_unused/wilderness/99999180.yaml
deleted file mode 100644
index 3d85406..0000000
--- a/data/rooms/example_unused/wilderness/99999180.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-id: 99999180
-name: "Construction Yard Entrance"
-description:
- - text: "A fenced staging area at the edge of the terraforming works. Crates of brackets and coils of cable are stacked under a sturdy section of atmospheric dome. To the {220}north{/} the dome shielding gives out and the open solar array field begins. The farm outpost lies back to the {94}west{/}."
-exits:
- north:
- room: 99999181
- west:
- room: 99999161
diff --git a/data/rooms/example_unused/wilderness/99999181.yaml b/data/rooms/example_unused/wilderness/99999181.yaml
deleted file mode 100644
index 9253347..0000000
--- a/data/rooms/example_unused/wilderness/99999181.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-name: "Exposed Solar Array"
-description:
-- text: "A wide field of steel frames stretches under a torn section of the atmospheric dome. Raw sunlight blazes down with nothing to filter it. Half-built {220}solar panel frames{/} wait to be finished. A jagged {248}rock outcrop{/} on the south edge throws a patch of shade. The yard entrance lies back to the {34}south{/}."
-hazard: solar_radiation
-exits:
- south:
- room: 99999180
-objects:
-- id: rock_outcrop
-mobs:
-- id: solar_panel_frame
-- id: solar_panel_frame
diff --git a/data/rooms/forest/4100.yaml b/data/rooms/forest/4100.yaml
new file mode 100644
index 0000000..e489065
--- /dev/null
+++ b/data/rooms/forest/4100.yaml
@@ -0,0 +1,16 @@
+name: Western Forest — Warden’s Fork
+description: A covered map stands at a three-way fork. Numisia lies east, Tuccia south, and Domita northwest
+ by the maintained north road.
+exits:
+ east:
+ room: 7121
+ south:
+ room: 7122
+ north:
+ room: 7132
+ west:
+ room: 4101
+objects:
+- id: aps_tower
+mobs:
+- id: forest_warden
diff --git a/data/rooms/forest/4101.yaml b/data/rooms/forest/4101.yaml
new file mode 100644
index 0000000..dc81522
--- /dev/null
+++ b/data/rooms/forest/4101.yaml
@@ -0,0 +1,9 @@
+name: Western Forest — Coppice Gate
+description: A low gate opens into a managed timber trail. No aggressive creature enters the managed grove.
+exits:
+ east:
+ room: 4100
+ west:
+ room: 4102
+objects:
+- id: tree
diff --git a/data/rooms/forest/4102.yaml b/data/rooms/forest/4102.yaml
new file mode 100644
index 0000000..6efd95d
--- /dev/null
+++ b/data/rooms/forest/4102.yaml
@@ -0,0 +1,18 @@
+name: Western Forest — Oak Stand
+description: Straight oaks rise above the low coppice. Woodcutting 15. No aggressive creature enters the
+ managed grove.
+exits:
+ east:
+ room: 4101
+ west:
+ room: 4103
+ north:
+ room: 4110
+ south:
+ room: 4114
+objects:
+- id: oak_tree
+- name: danger marker
+ description: 'DANGER beyond this side trail: goblin, goblin. The public road and gathering path are
+ safe; this detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
diff --git a/data/rooms/forest/4103.yaml b/data/rooms/forest/4103.yaml
new file mode 100644
index 0000000..293be25
--- /dev/null
+++ b/data/rooms/forest/4103.yaml
@@ -0,0 +1,18 @@
+name: Western Forest — Willow Brook
+description: Roots trail into a slow stream. Woodcutting 30. No aggressive creature enters the managed
+ grove.
+exits:
+ east:
+ room: 4102
+ west:
+ room: 4104
+ north:
+ room: 4111
+ south:
+ room: 4115
+objects:
+- id: willow_tree
+- name: danger marker
+ description: 'DANGER beyond this side trail: bandit. The public road and gathering path are safe; this
+ detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
diff --git a/data/rooms/forest/4104.yaml b/data/rooms/forest/4104.yaml
new file mode 100644
index 0000000..68b0970
--- /dev/null
+++ b/data/rooms/forest/4104.yaml
@@ -0,0 +1,18 @@
+name: Western Forest — Teak Terrace
+description: Terraces hold well-spaced teak trees. Woodcutting 35. No aggressive creature enters the managed
+ grove.
+exits:
+ east:
+ room: 4103
+ west:
+ room: 4105
+ north:
+ room: 4112
+ south:
+ room: 4116
+objects:
+- id: teak_tree
+- name: danger marker
+ description: 'DANGER beyond this side trail: mutant rat. The public road and gathering path are safe;
+ this detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
diff --git a/data/rooms/forest/4105.yaml b/data/rooms/forest/4105.yaml
new file mode 100644
index 0000000..68139f7
--- /dev/null
+++ b/data/rooms/forest/4105.yaml
@@ -0,0 +1,16 @@
+name: Western Forest — Foresters’ Clearing
+description: A common-wood stand is reserved for beginners learning with friends. No aggressive creature
+ enters the managed grove.
+exits:
+ east:
+ room: 4104
+ west:
+ room: 4106
+ south:
+ room: 4117
+objects:
+- id: tree
+- name: danger marker
+ description: 'DANGER beyond this side trail: drone. The public road and gathering path are safe; this
+ detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
diff --git a/data/rooms/forest/4106.yaml b/data/rooms/forest/4106.yaml
new file mode 100644
index 0000000..815aabf
--- /dev/null
+++ b/data/rooms/forest/4106.yaml
@@ -0,0 +1,12 @@
+name: Western Forest — Brookside Oaks
+description: Young oaks follow a winding brook. Woodcutting 15. No aggressive creature enters the managed
+ grove.
+exits:
+ east:
+ room: 4105
+ west:
+ room: 4107
+ north:
+ room: 4113
+objects:
+- id: oak_tree
diff --git a/data/rooms/forest/4107.yaml b/data/rooms/forest/4107.yaml
new file mode 100644
index 0000000..5f77443
--- /dev/null
+++ b/data/rooms/forest/4107.yaml
@@ -0,0 +1,12 @@
+name: Western Forest — West Willow Reach
+description: Willows shade the westward trail. Woodcutting 30. No aggressive creature enters the managed
+ grove.
+exits:
+ east:
+ room: 4106
+ west:
+ room: 4108
+ north:
+ room: 4118
+objects:
+- id: willow_tree
diff --git a/data/rooms/forest/4108.yaml b/data/rooms/forest/4108.yaml
new file mode 100644
index 0000000..4238dd7
--- /dev/null
+++ b/data/rooms/forest/4108.yaml
@@ -0,0 +1,10 @@
+name: Western Forest — Plantation Edge
+description: Teak planted by the first settlers marks the present district boundary. Woodcutting 35. No
+ aggressive creature enters the managed grove.
+exits:
+ east:
+ room: 4107
+ west:
+ room: 4109
+objects:
+- id: teak_tree
diff --git a/data/rooms/forest/4109.yaml b/data/rooms/forest/4109.yaml
new file mode 100644
index 0000000..948e5bd
--- /dev/null
+++ b/data/rooms/forest/4109.yaml
@@ -0,0 +1,8 @@
+name: Western Forest — Western Waystation
+description: Ordinary trees line the maintained path beyond the timber stands. Future regions lie farther
+ west. No aggressive creature enters the managed grove.
+exits:
+ east:
+ room: 4108
+objects:
+- id: tree
diff --git a/data/rooms/forest/4110.yaml b/data/rooms/forest/4110.yaml
new file mode 100644
index 0000000..947a7ac
--- /dev/null
+++ b/data/rooms/forest/4110.yaml
@@ -0,0 +1,9 @@
+name: Western Forest — Charcoal Camp
+description: A public workbench and sawyer’s shelter stand outside the town boundaries.
+exits:
+ south:
+ room: 4102
+objects:
+- id: workbench
+mobs:
+- id: sawmill_operator
diff --git a/data/rooms/forest/4111.yaml b/data/rooms/forest/4111.yaml
new file mode 100644
index 0000000..3c9878d
--- /dev/null
+++ b/data/rooms/forest/4111.yaml
@@ -0,0 +1,7 @@
+name: Western Forest — River Bend
+description: A shaded river bend supports fly fishing without blocking the timber trail.
+exits:
+ south:
+ room: 4103
+objects:
+- id: fly_fishing_spot
diff --git a/data/rooms/forest/4112.yaml b/data/rooms/forest/4112.yaml
new file mode 100644
index 0000000..10955e4
--- /dev/null
+++ b/data/rooms/forest/4112.yaml
@@ -0,0 +1,7 @@
+name: Western Forest — Eco Shrine
+description: Organic circuits identify ecojunk for scavengers of level 28.
+exits:
+ south:
+ room: 4104
+objects:
+- id: eco_altar
diff --git a/data/rooms/forest/4113.yaml b/data/rooms/forest/4113.yaml
new file mode 100644
index 0000000..7a4f3e0
--- /dev/null
+++ b/data/rooms/forest/4113.yaml
@@ -0,0 +1,8 @@
+name: Western Forest — Old Field Station
+description: Roots enfold an abandoned field terminal. The training program still responds at Hacking
+ 20.
+exits:
+ south:
+ room: 4106
+objects:
+- id: terminal_advanced
diff --git a/data/rooms/forest/4114.yaml b/data/rooms/forest/4114.yaml
new file mode 100644
index 0000000..c45aaf8
--- /dev/null
+++ b/data/rooms/forest/4114.yaml
@@ -0,0 +1,11 @@
+name: Western Forest — Goblin Camp
+description: Broken baskets hang from the branches. This is an off-road combat area; hostile creatures
+ remain here.
+exits:
+ north:
+ room: 4102
+objects:
+- id: rock_outcrop
+mobs:
+- id: goblin
+- id: goblin
diff --git a/data/rooms/forest/4115.yaml b/data/rooms/forest/4115.yaml
new file mode 100644
index 0000000..341177a
--- /dev/null
+++ b/data/rooms/forest/4115.yaml
@@ -0,0 +1,10 @@
+name: Western Forest — Bandit Clearing
+description: A stolen wagon has been turned into a barricade. This is an off-road combat area; hostile
+ creatures remain here.
+exits:
+ north:
+ room: 4103
+objects:
+- id: rock_outcrop
+mobs:
+- id: bandit
diff --git a/data/rooms/forest/4116.yaml b/data/rooms/forest/4116.yaml
new file mode 100644
index 0000000..6d0cb3b
--- /dev/null
+++ b/data/rooms/forest/4116.yaml
@@ -0,0 +1,10 @@
+name: Western Forest — Rat Hollow
+description: Oversized rat tracks cross a muddy hollow. This is an off-road combat area; hostile creatures
+ remain here.
+exits:
+ north:
+ room: 4104
+objects:
+- id: rock_outcrop
+mobs:
+- id: mutant_rat
diff --git a/data/rooms/forest/4117.yaml b/data/rooms/forest/4117.yaml
new file mode 100644
index 0000000..fae76da
--- /dev/null
+++ b/data/rooms/forest/4117.yaml
@@ -0,0 +1,10 @@
+name: Western Forest — Relay Enclosure
+description: A broken fence surrounds still-active security equipment. Assassin 15; insulated gloves recommended.
+ This is an off-road combat area; hostile creatures remain here.
+exits:
+ north:
+ room: 4105
+objects:
+- id: rock_outcrop
+mobs:
+- id: drone
diff --git a/data/rooms/forest/4118.yaml b/data/rooms/forest/4118.yaml
new file mode 100644
index 0000000..9b1753e
--- /dev/null
+++ b/data/rooms/forest/4118.yaml
@@ -0,0 +1,7 @@
+name: Western Forest — Ranger Shelter
+description: An emergency charger and dry shelter mark the farthest regular patrol point.
+exits:
+ south:
+ room: 4107
+objects:
+- id: charging_station
diff --git a/data/rooms/forest/4119.yaml b/data/rooms/forest/4119.yaml
new file mode 100644
index 0000000..9bd99d6
--- /dev/null
+++ b/data/rooms/forest/4119.yaml
@@ -0,0 +1,7 @@
+name: Forest — Ranger Exercise Track
+description: A safe branch reaches the ranger training circuit.
+exits:
+ east:
+ room: 7134
+ west:
+ room: 8104
diff --git a/data/rooms/highlands/5200.yaml b/data/rooms/highlands/5200.yaml
new file mode 100644
index 0000000..d745b27
--- /dev/null
+++ b/data/rooms/highlands/5200.yaml
@@ -0,0 +1,8 @@
+name: Domita Highlands — Quarry Road
+description: A maintained quarry road serves the city’s workshops. This industrial route is not patrolled
+ by hostile machines.
+exits:
+ east:
+ room: 5100
+ west:
+ room: 5201
diff --git a/data/rooms/highlands/5201.yaml b/data/rooms/highlands/5201.yaml
new file mode 100644
index 0000000..b3271f9
--- /dev/null
+++ b/data/rooms/highlands/5201.yaml
@@ -0,0 +1,10 @@
+name: Domita Highlands — Coal Terrace
+description: A maintained quarry road serves the city’s workshops. This industrial route is not patrolled
+ by hostile machines.
+exits:
+ east:
+ room: 5200
+ west:
+ room: 5202
+objects:
+- id: coal_rock
diff --git a/data/rooms/highlands/5202.yaml b/data/rooms/highlands/5202.yaml
new file mode 100644
index 0000000..5e12ae3
--- /dev/null
+++ b/data/rooms/highlands/5202.yaml
@@ -0,0 +1,12 @@
+name: Domita Highlands — Gold Terrace
+description: A maintained quarry road serves the city’s workshops. This industrial route is not patrolled
+ by hostile machines.
+exits:
+ east:
+ room: 5201
+ west:
+ room: 5203
+ south:
+ room: 5204
+objects:
+- id: gold_rock
diff --git a/data/rooms/highlands/5203.yaml b/data/rooms/highlands/5203.yaml
new file mode 100644
index 0000000..9401bc2
--- /dev/null
+++ b/data/rooms/highlands/5203.yaml
@@ -0,0 +1,8 @@
+name: Domita Highlands — Mine Landing
+description: A maintained quarry road serves the city’s workshops. This industrial route is not patrolled
+ by hostile machines.
+exits:
+ east:
+ room: 5202
+ down:
+ room: 5205
diff --git a/data/rooms/highlands/5204.yaml b/data/rooms/highlands/5204.yaml
new file mode 100644
index 0000000..1e0d6fd
--- /dev/null
+++ b/data/rooms/highlands/5204.yaml
@@ -0,0 +1,7 @@
+name: Domita Highlands — Silver Spur
+description: A silver seam lies on a small working ledge below the gold terrace.
+exits:
+ north:
+ room: 5202
+objects:
+- id: silver_rock
diff --git a/data/rooms/highlands/5205.yaml b/data/rooms/highlands/5205.yaml
new file mode 100644
index 0000000..e794c54
--- /dev/null
+++ b/data/rooms/highlands/5205.yaml
@@ -0,0 +1,10 @@
+name: Domita Highlands — Iron Gallery
+description: Maintained ladders reach this quiet mining gallery. The ore requires skill, but the approach
+ is safe at any level.
+exits:
+ up:
+ room: 5203
+ down:
+ room: 5206
+objects:
+- id: iron_rock
diff --git a/data/rooms/highlands/5206.yaml b/data/rooms/highlands/5206.yaml
new file mode 100644
index 0000000..ee8b909
--- /dev/null
+++ b/data/rooms/highlands/5206.yaml
@@ -0,0 +1,10 @@
+name: Domita Highlands — Coal Gallery
+description: Maintained ladders reach this quiet mining gallery. The ore requires skill, but the approach
+ is safe at any level.
+exits:
+ up:
+ room: 5205
+ down:
+ room: 5207
+objects:
+- id: coal_rock
diff --git a/data/rooms/highlands/5207.yaml b/data/rooms/highlands/5207.yaml
new file mode 100644
index 0000000..57e2e36
--- /dev/null
+++ b/data/rooms/highlands/5207.yaml
@@ -0,0 +1,8 @@
+name: Domita Highlands — Gold Gallery
+description: Maintained ladders reach this quiet mining gallery. The ore requires skill, but the approach
+ is safe at any level.
+exits:
+ up:
+ room: 5206
+objects:
+- id: gold_rock
diff --git a/data/rooms/highlands/5208.yaml b/data/rooms/highlands/5208.yaml
new file mode 100644
index 0000000..a492c45
--- /dev/null
+++ b/data/rooms/highlands/5208.yaml
@@ -0,0 +1,10 @@
+name: Domita Highlands — Survey Gate
+description: The public survey road climbs beyond the city. Keep to white markers for safe travel; red
+ markers lead into combat ruins.
+exits:
+ south:
+ room: 5148
+ north:
+ room: 5209
+ east:
+ room: 5226
diff --git a/data/rooms/highlands/5209.yaml b/data/rooms/highlands/5209.yaml
new file mode 100644
index 0000000..19ceb4e
--- /dev/null
+++ b/data/rooms/highlands/5209.yaml
@@ -0,0 +1,17 @@
+name: Domita Highlands — Relay Road
+description: The public survey road climbs beyond the city. Keep to white markers for safe travel; red
+ markers lead into combat ruins.
+exits:
+ south:
+ room: 5208
+ north:
+ room: 5210
+ east:
+ room: 5214
+ west:
+ room: 5220
+objects:
+- name: danger marker
+ description: 'DANGER beyond this side trail: scrap bot. The public road and gathering path are safe;
+ this detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
diff --git a/data/rooms/highlands/5210.yaml b/data/rooms/highlands/5210.yaml
new file mode 100644
index 0000000..36a25a6
--- /dev/null
+++ b/data/rooms/highlands/5210.yaml
@@ -0,0 +1,12 @@
+name: Domita Highlands — Slate Rise
+description: The public survey road climbs beyond the city. Keep to white markers for safe travel; red
+ markers lead into combat ruins.
+exits:
+ south:
+ room: 5209
+ north:
+ room: 5211
+ east:
+ room: 5215
+ west:
+ room: 5228
diff --git a/data/rooms/highlands/5211.yaml b/data/rooms/highlands/5211.yaml
new file mode 100644
index 0000000..d871b4c
--- /dev/null
+++ b/data/rooms/highlands/5211.yaml
@@ -0,0 +1,10 @@
+name: Domita Highlands — Archive Turn
+description: The public survey road climbs beyond the city. Keep to white markers for safe travel; red
+ markers lead into combat ruins.
+exits:
+ south:
+ room: 5210
+ north:
+ room: 5212
+ east:
+ room: 5216
diff --git a/data/rooms/highlands/5212.yaml b/data/rooms/highlands/5212.yaml
new file mode 100644
index 0000000..ea1f35e
--- /dev/null
+++ b/data/rooms/highlands/5212.yaml
@@ -0,0 +1,17 @@
+name: Domita Highlands — Observatory Outlook
+description: The public survey road climbs beyond the city. Keep to white markers for safe travel; red
+ markers lead into combat ruins.
+exits:
+ south:
+ room: 5211
+ north:
+ room: 5213
+ east:
+ room: 5217
+ west:
+ room: 5225
+objects:
+- name: danger marker
+ description: 'DANGER beyond this side trail: bandit. The public road and gathering path are safe; this
+ detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
diff --git a/data/rooms/highlands/5213.yaml b/data/rooms/highlands/5213.yaml
new file mode 100644
index 0000000..4ef997a
--- /dev/null
+++ b/data/rooms/highlands/5213.yaml
@@ -0,0 +1,12 @@
+name: Domita Highlands — Northern Shelter
+description: The public survey road climbs beyond the city. Keep to white markers for safe travel; red
+ markers lead into combat ruins.
+exits:
+ south:
+ room: 5212
+ east:
+ room: 5218
+ west:
+ room: 5219
+ north:
+ room: 5227
diff --git a/data/rooms/highlands/5214.yaml b/data/rooms/highlands/5214.yaml
new file mode 100644
index 0000000..c307167
--- /dev/null
+++ b/data/rooms/highlands/5214.yaml
@@ -0,0 +1,8 @@
+name: Domita Highlands — Cosmic Array
+description: A shielded working spur leaves the safe survey road. No aggressive creatures occupy this
+ station.
+exits:
+ west:
+ room: 5209
+objects:
+- id: cosmic_altar
diff --git a/data/rooms/highlands/5215.yaml b/data/rooms/highlands/5215.yaml
new file mode 100644
index 0000000..196e1e9
--- /dev/null
+++ b/data/rooms/highlands/5215.yaml
@@ -0,0 +1,8 @@
+name: Domita Highlands — Survey Calibration Station
+description: A shielded working spur leaves the safe survey road. No aggressive creatures occupy this
+ station.
+exits:
+ west:
+ room: 5210
+objects:
+- id: survey_relay
diff --git a/data/rooms/highlands/5216.yaml b/data/rooms/highlands/5216.yaml
new file mode 100644
index 0000000..0f86e73
--- /dev/null
+++ b/data/rooms/highlands/5216.yaml
@@ -0,0 +1,8 @@
+name: Domita Highlands — Research Terminal
+description: A shielded working spur leaves the safe survey road. No aggressive creatures occupy this
+ station.
+exits:
+ west:
+ room: 5211
+objects:
+- id: terminal_secure
diff --git a/data/rooms/highlands/5217.yaml b/data/rooms/highlands/5217.yaml
new file mode 100644
index 0000000..177c760
--- /dev/null
+++ b/data/rooms/highlands/5217.yaml
@@ -0,0 +1,8 @@
+name: Domita Highlands — Observatory Calibration Station
+description: A shielded working spur leaves the safe survey road. No aggressive creatures occupy this
+ station.
+exits:
+ west:
+ room: 5212
+objects:
+- id: observatory_relay
diff --git a/data/rooms/highlands/5218.yaml b/data/rooms/highlands/5218.yaml
new file mode 100644
index 0000000..d2e4a74
--- /dev/null
+++ b/data/rooms/highlands/5218.yaml
@@ -0,0 +1,8 @@
+name: Domita Highlands — Old Solar Array
+description: A shielded working spur leaves the safe survey road. No aggressive creatures occupy this
+ station.
+exits:
+ west:
+ room: 5213
+objects:
+- id: solar_altar
diff --git a/data/rooms/highlands/5219.yaml b/data/rooms/highlands/5219.yaml
new file mode 100644
index 0000000..9b66eb3
--- /dev/null
+++ b/data/rooms/highlands/5219.yaml
@@ -0,0 +1,8 @@
+name: Domita Highlands — Ancient Scrap Yard
+description: A shielded working spur leaves the safe survey road. No aggressive creatures occupy this
+ station.
+exits:
+ east:
+ room: 5213
+objects:
+- id: scrap_pile
diff --git a/data/rooms/highlands/5220.yaml b/data/rooms/highlands/5220.yaml
new file mode 100644
index 0000000..f586bc9
--- /dev/null
+++ b/data/rooms/highlands/5220.yaml
@@ -0,0 +1,16 @@
+name: Domita Highlands — Abandoned Security Yard
+description: Old enforcement machines defend an obsolete boundary. This is an off-road combat area; hostile
+ creatures remain here.
+exits:
+ east:
+ room: 5209
+ west:
+ room: 5221
+objects:
+- id: rock_outcrop
+- name: danger marker
+ description: 'DANGER beyond this side trail: scrap bot, bandit. The public road and gathering path are
+ safe; this detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
+mobs:
+- id: scrap_bot
diff --git a/data/rooms/highlands/5221.yaml b/data/rooms/highlands/5221.yaml
new file mode 100644
index 0000000..b189be2
--- /dev/null
+++ b/data/rooms/highlands/5221.yaml
@@ -0,0 +1,17 @@
+name: Domita Highlands — Foundry Ruin
+description: The foundry’s security systems survived its workforce. This is an off-road combat area; hostile
+ creatures remain here.
+exits:
+ east:
+ room: 5220
+ west:
+ room: 5222
+objects:
+- id: rock_outcrop
+- name: danger marker
+ description: 'DANGER beyond this side trail: security turret. The public road and gathering path are
+ safe; this detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
+mobs:
+- id: scrap_bot
+- id: bandit
diff --git a/data/rooms/highlands/5222.yaml b/data/rooms/highlands/5222.yaml
new file mode 100644
index 0000000..04c2a77
--- /dev/null
+++ b/data/rooms/highlands/5222.yaml
@@ -0,0 +1,16 @@
+name: Domita Highlands — Reactor Court
+description: Heat shimmers around an ancient power conduit. This is an off-road combat area; hostile creatures
+ remain here.
+exits:
+ east:
+ room: 5221
+ west:
+ room: 5223
+objects:
+- id: rock_outcrop
+- name: danger marker
+ description: 'DANGER beyond this side trail: drone. The public road and gathering path are safe; this
+ detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
+mobs:
+- id: security_turret
diff --git a/data/rooms/highlands/5223.yaml b/data/rooms/highlands/5223.yaml
new file mode 100644
index 0000000..d397ad8
--- /dev/null
+++ b/data/rooms/highlands/5223.yaml
@@ -0,0 +1,16 @@
+name: Domita Highlands — Relay Vault
+description: A modest service drone defends the old equipment. Assassin 15; insulated gloves are recommended.
+ This is an off-road combat area; hostile creatures remain here.
+exits:
+ east:
+ room: 5222
+ west:
+ room: 5224
+objects:
+- id: rock_outcrop
+- name: danger marker
+ description: 'DANGER beyond this side trail: crawler. The public road and gathering path are safe; this
+ detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
+mobs:
+- id: drone
diff --git a/data/rooms/highlands/5224.yaml b/data/rooms/highlands/5224.yaml
new file mode 100644
index 0000000..8120074
--- /dev/null
+++ b/data/rooms/highlands/5224.yaml
@@ -0,0 +1,10 @@
+name: Domita Highlands — Collapsed Storehouse
+description: Crawlers nest under rusting storage racks. Assassin 30; acid vials are needed to finish them.
+ This is an off-road combat area; hostile creatures remain here.
+exits:
+ east:
+ room: 5223
+objects:
+- id: rock_outcrop
+mobs:
+- id: crawler
diff --git a/data/rooms/highlands/5225.yaml b/data/rooms/highlands/5225.yaml
new file mode 100644
index 0000000..0c48ace
--- /dev/null
+++ b/data/rooms/highlands/5225.yaml
@@ -0,0 +1,10 @@
+name: Domita Highlands — Observatory Breach
+description: The broken dome shelters a small gang of scavengers. Beyond the survey road, later regions
+ remain to be charted. This is an off-road combat area; hostile creatures remain here.
+exits:
+ east:
+ room: 5212
+objects:
+- id: rock_outcrop
+mobs:
+- id: bandit
diff --git a/data/rooms/highlands/5226.yaml b/data/rooms/highlands/5226.yaml
new file mode 100644
index 0000000..a4800bb
--- /dev/null
+++ b/data/rooms/highlands/5226.yaml
@@ -0,0 +1,7 @@
+name: Domita — Survey Training Track
+description: Survey crews maintain a demanding practice circuit outside the city.
+exits:
+ west:
+ room: 5208
+ east:
+ room: 8112
diff --git a/data/rooms/highlands/5227.yaml b/data/rooms/highlands/5227.yaml
new file mode 100644
index 0000000..1e4d534
--- /dev/null
+++ b/data/rooms/highlands/5227.yaml
@@ -0,0 +1,7 @@
+name: Domita — Observatory Exercise Track
+description: An exposed but safe path reaches the highest-level practice circuit.
+exits:
+ south:
+ room: 5213
+ north:
+ room: 8116
diff --git a/data/rooms/highlands/5228.yaml b/data/rooms/highlands/5228.yaml
new file mode 100644
index 0000000..e4adbdd
--- /dev/null
+++ b/data/rooms/highlands/5228.yaml
@@ -0,0 +1,7 @@
+name: Domita Foothills — Survey Repair Shelter
+description: The survey crews maintain a safe practice worksite beside the public road.
+exits:
+ east:
+ room: 5210
+mobs:
+- id: survey_frame
diff --git a/data/rooms/intro/1001.yaml b/data/rooms/intro/1001.yaml
index 3e04381..7843ad5 100644
--- a/data/rooms/intro/1001.yaml
+++ b/data/rooms/intro/1001.yaml
@@ -18,8 +18,6 @@ exits:
player_flag: 1001_touchdown
value: null
room: 1002
- east:
- room: 2001
hazard: ""
id: 1001
item_spawns: []
diff --git a/data/rooms/intro/1003.yaml b/data/rooms/intro/1003.yaml
index f82df21..9b2aeb7 100644
--- a/data/rooms/intro/1003.yaml
+++ b/data/rooms/intro/1003.yaml
@@ -6,7 +6,7 @@ exits:
north:
condition:
player_flag: 1003_talked
- room: 1004
+ room: 1133
south:
room: 1002
hazard: ""
diff --git a/data/rooms/intro/1004.yaml b/data/rooms/intro/1004.yaml
deleted file mode 100644
index 9c9de9a..0000000
--- a/data/rooms/intro/1004.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-id: 1004
-name: New Room
-color: ""
-description:
- - text: A featureless room.
-exits:
- south:
- room: 1003
-item_spawns: []
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/intro/1005.yaml b/data/rooms/intro/1005.yaml
deleted file mode 100644
index 4698ae1..0000000
--- a/data/rooms/intro/1005.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-id: 1005
-name: 'Room #1005'
-color: ""
-description: []
-exits:
- east:
- room: 1006
- west:
- room: 2001
-objects: []
-item_spawns: []
-mobs: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/intro/1006.yaml b/data/rooms/intro/1006.yaml
deleted file mode 100644
index fc40ea2..0000000
--- a/data/rooms/intro/1006.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-block_transport: false
-color: ""
-description: []
-exits:
- west:
- room: 1005
-hazard: ""
-id: 1006
-item_spawns: []
-mobs: []
-name: 'Room #1006'
-objects: []
-on_enter: []
diff --git a/data/rooms/intro/2001.yaml b/data/rooms/intro/2001.yaml
deleted file mode 100644
index 8f54228..0000000
--- a/data/rooms/intro/2001.yaml
+++ /dev/null
@@ -1,75 +0,0 @@
-block_transport: false
-casino_machines:
- - id: huff_puff_01
- game: slots
- variant: huff_and_even_more_puff
- min_bet: 1
- max_bet: 1000
- payout: 0.97
-casino_tables:
- - id: blackjack
- game: blackjack
- max_players: 6
- betting_ticks: 20
- min_bet: 1
- max_bet: 1000
- blackjack:
- decks: 8
- shuffle_at: 0.25
- blackjack_payout: 1.5
- dealer_hit_soft_17: false
- max_split_hands: 4
- resplit_aces: false
- double_after_split: true
- double_split_blackjack: true
- insurance_payout: 2
- surrender: false
- action_ticks: 20
- split_unlike_ten_values: true
- - id: baccarat
- game: baccarat
- max_players: 6
- betting_ticks: 20
- min_bet: 1
- max_bet: 1000
- baccarat:
- decks: 8
- shuffle_at: 0.25
- tie_payout: 8
- banker_payout: 0.95
-color: ""
-description:
- - text: "ADMIN TEST ROOM - this area is for development only and is not part of the live world."
- - text: "It spawns test items, including free casino chips, so developers can exercise the casino without grinding credits."
-exits:
- east:
- room: 1005
- south:
- room: 2006
- west:
- room: 1001
-hazard: ""
-id: 2001
-item_spawns:
- - id: bronze_axe
- quantity: 1
- respawn_ticks: 1
- - id: pot_of_flour
- quantity: 1
- respawn_ticks: 1
- - id: bucket_of_water
- quantity: 1
- respawn_ticks: 1
- - id: chips
- quantity: 5000
- respawn_ticks: 1
-mobs:
- - id: man
-name: Test Room
-objects:
- - description:
- - text: YOU FOUND HIM
- hidden: true
- name: hidden guy
- - id: tree
-on_enter: []
diff --git a/data/rooms/intro/2006.yaml b/data/rooms/intro/2006.yaml
deleted file mode 100644
index ccb312a..0000000
--- a/data/rooms/intro/2006.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-id: 2006
-name: Test Room
-color: ""
-description:
- - text: It's a test room
-exits:
- north:
- room: 2001
-objects: []
-item_spawns: []
-mobs: []
-on_enter: []
-hazard: ""
-block_transport: false
diff --git a/data/rooms/numisia/1100.yaml b/data/rooms/numisia/1100.yaml
new file mode 100644
index 0000000..4593ed0
--- /dev/null
+++ b/data/rooms/numisia/1100.yaml
@@ -0,0 +1,8 @@
+name: Numisia — West Gate
+description: The west road passes between worn boundary stones. Behind you, Founders Street runs past
+ separate shopfronts toward the town center.
+exits:
+ east:
+ room: 1101
+ west:
+ room: 7111
diff --git a/data/rooms/numisia/1101.yaml b/data/rooms/numisia/1101.yaml
new file mode 100644
index 0000000..6fc0c33
--- /dev/null
+++ b/data/rooms/numisia/1101.yaml
@@ -0,0 +1,14 @@
+name: Numisia — Founders Street West 3
+description: Upper windows overlook Founders Street; downstairs, merchants have propped their doors open
+ for passing trade.
+exits:
+ west:
+ room: 1100
+ east:
+ room: 1102
+ north:
+ room: 1115
+ south:
+ room: 1121
+objects:
+- id: market_stall
diff --git a/data/rooms/numisia/1102.yaml b/data/rooms/numisia/1102.yaml
new file mode 100644
index 0000000..bca49d8
--- /dev/null
+++ b/data/rooms/numisia/1102.yaml
@@ -0,0 +1,12 @@
+name: Numisia — Founders Street West 2
+description: An old drain runs beside the paving. The smell from an open shop door changes whenever the
+ wind turns.
+exits:
+ west:
+ room: 1101
+ east:
+ room: 1103
+ north:
+ room: 1116
+ south:
+ room: 1122
diff --git a/data/rooms/numisia/1103.yaml b/data/rooms/numisia/1103.yaml
new file mode 100644
index 0000000..1936d6b
--- /dev/null
+++ b/data/rooms/numisia/1103.yaml
@@ -0,0 +1,12 @@
+name: Numisia — Founders Street West 1
+description: Awnings shade this stretch of Founders Street. Each doorway belongs to a different business;
+ delivery handcarts leave a narrow path between them.
+exits:
+ west:
+ room: 1102
+ east:
+ room: 1104
+ north:
+ room: 1117
+ south:
+ room: 1123
diff --git a/data/rooms/numisia/1104.yaml b/data/rooms/numisia/1104.yaml
new file mode 100644
index 0000000..b33a1d6
--- /dev/null
+++ b/data/rooms/numisia/1104.yaml
@@ -0,0 +1,19 @@
+name: Numisia — Town Square
+description: Founders Street opens around a public notice pillar. Foot traffic divides between the shops,
+ the north avenue and the quieter houses to the south.
+exits:
+ west:
+ room: 1103
+ east:
+ room: 1105
+ north:
+ room: 1109
+ south:
+ room: 1112
+objects:
+- id: aps_tower
+- name: wayboard
+ description: 'Numisia: arrivals south; Vestalia Terra north; Brumalia east; forest west. Shops have
+ separate doors along Founders Street. Beginner quarry east, fishing south, scrap yard southeast. All
+ white-post roads are safe.'
+ inroom_description: A wayboard stands where travelers can read it.
diff --git a/data/rooms/numisia/1105.yaml b/data/rooms/numisia/1105.yaml
new file mode 100644
index 0000000..0672e54
--- /dev/null
+++ b/data/rooms/numisia/1105.yaml
@@ -0,0 +1,12 @@
+name: Numisia — Founders Street East 1
+description: Awnings shade this stretch of Founders Street. Each doorway belongs to a different business;
+ delivery handcarts leave a narrow path between them.
+exits:
+ west:
+ room: 1104
+ east:
+ room: 1106
+ north:
+ room: 1118
+ south:
+ room: 1124
diff --git a/data/rooms/numisia/1106.yaml b/data/rooms/numisia/1106.yaml
new file mode 100644
index 0000000..ec493b3
--- /dev/null
+++ b/data/rooms/numisia/1106.yaml
@@ -0,0 +1,12 @@
+name: Numisia — Founders Street East 2
+description: An old drain runs beside the paving. The smell from an open shop door changes whenever the
+ wind turns.
+exits:
+ west:
+ room: 1105
+ east:
+ room: 1107
+ north:
+ room: 1119
+ south:
+ room: 1125
diff --git a/data/rooms/numisia/1107.yaml b/data/rooms/numisia/1107.yaml
new file mode 100644
index 0000000..f942610
--- /dev/null
+++ b/data/rooms/numisia/1107.yaml
@@ -0,0 +1,12 @@
+name: Numisia — Founders Street East 3
+description: Upper windows overlook Founders Street; downstairs, merchants have propped their doors open
+ for passing trade.
+exits:
+ west:
+ room: 1106
+ east:
+ room: 1108
+ north:
+ room: 1120
+ south:
+ room: 1126
diff --git a/data/rooms/numisia/1108.yaml b/data/rooms/numisia/1108.yaml
new file mode 100644
index 0000000..68c731d
--- /dev/null
+++ b/data/rooms/numisia/1108.yaml
@@ -0,0 +1,8 @@
+name: Numisia — East Gate
+description: Cart tracks cross the eastern boundary. Lamps mark the safe road; the shops of Founders Street
+ remain within easy walking distance.
+exits:
+ west:
+ room: 1107
+ east:
+ room: 7100
diff --git a/data/rooms/numisia/1109.yaml b/data/rooms/numisia/1109.yaml
new file mode 100644
index 0000000..e5d5bb7
--- /dev/null
+++ b/data/rooms/numisia/1109.yaml
@@ -0,0 +1,8 @@
+name: Numisia — North Avenue
+description: Wide paving carries carts toward the northern boundary. A street board lists the next settlements,
+ not their recommended combat levels.
+exits:
+ south:
+ room: 1104
+ north:
+ room: 1110
diff --git a/data/rooms/numisia/1110.yaml b/data/rooms/numisia/1110.yaml
new file mode 100644
index 0000000..0ec1aca
--- /dev/null
+++ b/data/rooms/numisia/1110.yaml
@@ -0,0 +1,11 @@
+name: Numisia — Civic Walk
+description: Stone benches face municipal doorways. None of the offices charges admission.
+exits:
+ south:
+ room: 1109
+ north:
+ room: 1111
+ west:
+ room: 1127
+ east:
+ room: 1128
diff --git a/data/rooms/numisia/1111.yaml b/data/rooms/numisia/1111.yaml
new file mode 100644
index 0000000..24088a3
--- /dev/null
+++ b/data/rooms/numisia/1111.yaml
@@ -0,0 +1,8 @@
+name: Numisia — North Gate
+description: Beyond the gate the maintained road continues into open country. Dangerous side paths have
+ their own warning boards.
+exits:
+ south:
+ room: 1110
+ north:
+ room: 1300
diff --git a/data/rooms/numisia/1112.yaml b/data/rooms/numisia/1112.yaml
new file mode 100644
index 0000000..160dcf0
--- /dev/null
+++ b/data/rooms/numisia/1112.yaml
@@ -0,0 +1,8 @@
+name: Numisia — Lantern Lane
+description: Laundry strings cross above the lane, well clear of the lamps. Residents have painted their
+ doors different colors.
+exits:
+ north:
+ room: 1104
+ south:
+ room: 1113
diff --git a/data/rooms/numisia/1113.yaml b/data/rooms/numisia/1113.yaml
new file mode 100644
index 0000000..7e4b9cd
--- /dev/null
+++ b/data/rooms/numisia/1113.yaml
@@ -0,0 +1,12 @@
+name: Numisia — Residential Court
+description: A shared wash basin occupies a tiny court. Conversations drift through shutters rather than
+ out of a crowded marketplace.
+exits:
+ north:
+ room: 1112
+ south:
+ room: 1114
+ west:
+ room: 1129
+ east:
+ room: 1130
diff --git a/data/rooms/numisia/1114.yaml b/data/rooms/numisia/1114.yaml
new file mode 100644
index 0000000..c834f9b
--- /dev/null
+++ b/data/rooms/numisia/1114.yaml
@@ -0,0 +1,12 @@
+name: Numisia — South Gate
+description: The southern road leaves the houses behind. Its boundary posts are white; hazardous detours
+ are marked red.
+exits:
+ north:
+ room: 1113
+ west:
+ room: 1131
+ east:
+ room: 1132
+ south:
+ room: 1134
diff --git a/data/rooms/numisia/1115.yaml b/data/rooms/numisia/1115.yaml
new file mode 100644
index 0000000..e68b217
--- /dev/null
+++ b/data/rooms/numisia/1115.yaml
@@ -0,0 +1,7 @@
+name: Numisia — Mara’s Outfitting
+description: An axe and a small net hang above a counter assembled from shuttle seats.
+exits:
+ south:
+ room: 1101
+mobs:
+- id: numisia_outfitter
diff --git a/data/rooms/numisia/1116.yaml b/data/rooms/numisia/1116.yaml
new file mode 100644
index 0000000..7fbcf28
--- /dev/null
+++ b/data/rooms/numisia/1116.yaml
@@ -0,0 +1,9 @@
+name: Numisia — Public Smithy
+description: A hooded furnace warms one end of the room; a single anvil rings at the other. Bring ore
+ from outside the walls.
+exits:
+ south:
+ room: 1102
+objects:
+- id: furnace
+- id: anvil
diff --git a/data/rooms/numisia/1117.yaml b/data/rooms/numisia/1117.yaml
new file mode 100644
index 0000000..b06546e
--- /dev/null
+++ b/data/rooms/numisia/1117.yaml
@@ -0,0 +1,8 @@
+name: Numisia — Cooperative Bank
+description: Numbered boxes sit behind a waist-high counter. A painted sign promises the same account
+ at every branch.
+exits:
+ south:
+ room: 1103
+objects:
+- id: bank_booth
diff --git a/data/rooms/numisia/1118.yaml b/data/rooms/numisia/1118.yaml
new file mode 100644
index 0000000..a02718c
--- /dev/null
+++ b/data/rooms/numisia/1118.yaml
@@ -0,0 +1,7 @@
+name: Numisia — Neri’s Nets
+description: Loops of drying net divide the small shop into wavering curtains.
+exits:
+ south:
+ room: 1105
+mobs:
+- id: numisia_fisher
diff --git a/data/rooms/numisia/1119.yaml b/data/rooms/numisia/1119.yaml
new file mode 100644
index 0000000..522397d
--- /dev/null
+++ b/data/rooms/numisia/1119.yaml
@@ -0,0 +1,10 @@
+name: Numisia — Clay Cup Pottery
+description: Clay samples are labeled by quarry seam. The wheel and kiln are free to use.
+exits:
+ south:
+ room: 1106
+objects:
+- id: pottery_wheel
+- id: pottery_oven
+mobs:
+- id: numisia_potter
diff --git a/data/rooms/numisia/1120.yaml b/data/rooms/numisia/1120.yaml
new file mode 100644
index 0000000..c29c517
--- /dev/null
+++ b/data/rooms/numisia/1120.yaml
@@ -0,0 +1,9 @@
+name: Numisia — Sera’s Thread House
+description: Spools line the wall behind a treadle-driven spinning wheel.
+exits:
+ south:
+ room: 1107
+objects:
+- id: spinning_wheel
+mobs:
+- id: numisia_tailor
diff --git a/data/rooms/numisia/1121.yaml b/data/rooms/numisia/1121.yaml
new file mode 100644
index 0000000..064f9b4
--- /dev/null
+++ b/data/rooms/numisia/1121.yaml
@@ -0,0 +1,7 @@
+name: Numisia — Vale’s Dispensary
+description: Clear bottles catch the window light. There is room to mix herbs without blocking the counter.
+exits:
+ north:
+ room: 1101
+mobs:
+- id: numisia_chemist
diff --git a/data/rooms/numisia/1122.yaml b/data/rooms/numisia/1122.yaml
new file mode 100644
index 0000000..b7e7336
--- /dev/null
+++ b/data/rooms/numisia/1122.yaml
@@ -0,0 +1,7 @@
+name: Numisia — Public Kitchen
+description: A blackened range heats a long communal cooking bench.
+exits:
+ north:
+ room: 1102
+objects:
+- id: cooking_range
diff --git a/data/rooms/numisia/1123.yaml b/data/rooms/numisia/1123.yaml
new file mode 100644
index 0000000..defe208
--- /dev/null
+++ b/data/rooms/numisia/1123.yaml
@@ -0,0 +1,7 @@
+name: Numisia — Pella’s Pantry
+description: Flour settles into the cracks of the floorboards.
+exits:
+ north:
+ room: 1103
+mobs:
+- id: numisia_grocer
diff --git a/data/rooms/numisia/1124.yaml b/data/rooms/numisia/1124.yaml
new file mode 100644
index 0000000..bc221ba
--- /dev/null
+++ b/data/rooms/numisia/1124.yaml
@@ -0,0 +1,10 @@
+name: Numisia — Radio Repair Shop
+description: A receiver hisses softly beside a safe battery charging socket.
+exits:
+ north:
+ room: 1105
+objects:
+- id: charging_station
+- id: terminal_basic
+mobs:
+- id: numisia_engineer
diff --git a/data/rooms/numisia/1125.yaml b/data/rooms/numisia/1125.yaml
new file mode 100644
index 0000000..290dfc5
--- /dev/null
+++ b/data/rooms/numisia/1125.yaml
@@ -0,0 +1,9 @@
+name: Numisia — Ada’s Joinery
+description: Fine curls of wood cover the feet of two sturdy benches.
+exits:
+ north:
+ room: 1106
+objects:
+- id: workbench
+mobs:
+- id: numisia_carpenter
diff --git a/data/rooms/numisia/1126.yaml b/data/rooms/numisia/1126.yaml
new file mode 100644
index 0000000..182ce75
--- /dev/null
+++ b/data/rooms/numisia/1126.yaml
@@ -0,0 +1,7 @@
+name: Numisia — Contract Office
+description: A chalkboard lists small pest-control jobs and the exact places to find them.
+exits:
+ north:
+ room: 1107
+mobs:
+- id: numisia_contracts
diff --git a/data/rooms/numisia/1127.yaml b/data/rooms/numisia/1127.yaml
new file mode 100644
index 0000000..8afb78e
--- /dev/null
+++ b/data/rooms/numisia/1127.yaml
@@ -0,0 +1,7 @@
+name: Numisia — Governance and Gaming
+description: A scratched civic seal predates the casino advertisements pinned beneath it.
+exits:
+ east:
+ room: 1110
+mobs:
+- id: joanna_lucci
diff --git a/data/rooms/numisia/1128.yaml b/data/rooms/numisia/1128.yaml
new file mode 100644
index 0000000..4c7092b
--- /dev/null
+++ b/data/rooms/numisia/1128.yaml
@@ -0,0 +1,7 @@
+name: Numisia — Public Reading Room
+description: Arrival records share a shelf with manuals repaired using fishing line.
+exits:
+ west:
+ room: 1110
+mobs:
+- id: numisia_guide
diff --git a/data/rooms/numisia/1129.yaml b/data/rooms/numisia/1129.yaml
new file mode 100644
index 0000000..7313057
--- /dev/null
+++ b/data/rooms/numisia/1129.yaml
@@ -0,0 +1,7 @@
+name: Numisia — Blue Door Cottage
+description: A chipped blue cup waits beside a half-knitted scarf.
+exits:
+ east:
+ room: 1113
+mobs:
+- id: man
diff --git a/data/rooms/numisia/1130.yaml b/data/rooms/numisia/1130.yaml
new file mode 100644
index 0000000..13db02b
--- /dev/null
+++ b/data/rooms/numisia/1130.yaml
@@ -0,0 +1,7 @@
+name: Numisia — Tanner’s House
+description: A ventilated workroom opens behind a neat domestic hearth.
+exits:
+ west:
+ room: 1113
+mobs:
+- id: tanner
diff --git a/data/rooms/numisia/1131.yaml b/data/rooms/numisia/1131.yaml
new file mode 100644
index 0000000..4ea8813
--- /dev/null
+++ b/data/rooms/numisia/1131.yaml
@@ -0,0 +1,25 @@
+name: Numisia — Arrival Hostel
+description: Clean bunks surround a shelf of donated starter tools. Take what you need, then make your
+ own way.
+exits:
+ east:
+ room: 1114
+item_spawns:
+- id: bronze_pickaxe
+ quantity: 1
+ respawn_ticks: 100
+- id: bronze_axe
+ quantity: 1
+ respawn_ticks: 100
+- id: bronze_sword
+ quantity: 1
+ respawn_ticks: 100
+- id: small_fishing_net
+ quantity: 1
+ respawn_ticks: 100
+- id: matches
+ quantity: 1
+ respawn_ticks: 100
+- id: knife
+ quantity: 1
+ respawn_ticks: 100
diff --git a/data/rooms/numisia/1132.yaml b/data/rooms/numisia/1132.yaml
new file mode 100644
index 0000000..f3250bd
--- /dev/null
+++ b/data/rooms/numisia/1132.yaml
@@ -0,0 +1,7 @@
+name: Numisia — Well Court
+description: A stone basin catches water from a restored pump.
+exits:
+ west:
+ room: 1114
+objects:
+- id: lumby_fountain
diff --git a/data/rooms/numisia/1133.yaml b/data/rooms/numisia/1133.yaml
new file mode 100644
index 0000000..a750b12
--- /dev/null
+++ b/data/rooms/numisia/1133.yaml
@@ -0,0 +1,8 @@
+name: Numisia Arrival Tunnel
+description: A ventilated tunnel carries the sea air beneath the causeway. The far end is painted with
+ the Numisia civic seal.
+exits:
+ south:
+ room: 1003
+ north:
+ room: 1134
diff --git a/data/rooms/numisia/1134.yaml b/data/rooms/numisia/1134.yaml
new file mode 100644
index 0000000..1c238fa
--- /dev/null
+++ b/data/rooms/numisia/1134.yaml
@@ -0,0 +1,12 @@
+name: Numisia Causeway
+description: The causeway rises out of the water toward the town’s southern gate. A white line marks the
+ pedestrian path.
+exits:
+ south:
+ room: 1133
+ north:
+ room: 1114
+ east:
+ room: 1206
+ west:
+ room: 1209
diff --git a/data/rooms/numisia_outskirts/1200.yaml b/data/rooms/numisia_outskirts/1200.yaml
new file mode 100644
index 0000000..badf982
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1200.yaml
@@ -0,0 +1,7 @@
+name: Numisia Quarry Track
+description: A signed footpath leaves the east road for a small public quarry.
+exits:
+ south:
+ room: 7100
+ east:
+ room: 1201
diff --git a/data/rooms/numisia_outskirts/1201.yaml b/data/rooms/numisia_outskirts/1201.yaml
new file mode 100644
index 0000000..8c56fb7
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1201.yaml
@@ -0,0 +1,11 @@
+name: Copper Shelf
+description: Copper flecks shine in a low exposed face. This beginner quarry has no hostile inhabitants.
+exits:
+ west:
+ room: 1200
+ east:
+ room: 1202
+ north:
+ room: 1204
+objects:
+- id: copper_rock
diff --git a/data/rooms/numisia_outskirts/1202.yaml b/data/rooms/numisia_outskirts/1202.yaml
new file mode 100644
index 0000000..d3e184b
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1202.yaml
@@ -0,0 +1,9 @@
+name: Tin Cutting
+description: Rain has washed a pale tin seam clean.
+exits:
+ west:
+ room: 1201
+ east:
+ room: 1203
+objects:
+- id: tin_rock
diff --git a/data/rooms/numisia_outskirts/1203.yaml b/data/rooms/numisia_outskirts/1203.yaml
new file mode 100644
index 0000000..cec1a29
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1203.yaml
@@ -0,0 +1,7 @@
+name: Clay Hollow
+description: Soft earth has collected below the quarry’s stone lip.
+exits:
+ west:
+ room: 1202
+objects:
+- id: clay_rock
diff --git a/data/rooms/numisia_outskirts/1204.yaml b/data/rooms/numisia_outskirts/1204.yaml
new file mode 100644
index 0000000..ec9e935
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1204.yaml
@@ -0,0 +1,9 @@
+name: Iron Trial Face
+description: A narrow iron vein rewards miners who have reached level 15.
+exits:
+ south:
+ room: 1201
+ east:
+ room: 1205
+objects:
+- id: iron_rock
diff --git a/data/rooms/numisia_outskirts/1205.yaml b/data/rooms/numisia_outskirts/1205.yaml
new file mode 100644
index 0000000..aba7082
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1205.yaml
@@ -0,0 +1,7 @@
+name: Silver Trial Face
+description: A silver seam is marked for level 20 miners.
+exits:
+ west:
+ room: 1204
+objects:
+- id: silver_rock
diff --git a/data/rooms/numisia_outskirts/1206.yaml b/data/rooms/numisia_outskirts/1206.yaml
new file mode 100644
index 0000000..133ca62
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1206.yaml
@@ -0,0 +1,7 @@
+name: Shore Path
+description: Steps lead off the arrival causeway toward the calm nursery pools.
+exits:
+ west:
+ room: 1134
+ east:
+ room: 1207
diff --git a/data/rooms/numisia_outskirts/1207.yaml b/data/rooms/numisia_outskirts/1207.yaml
new file mode 100644
index 0000000..53cf451
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1207.yaml
@@ -0,0 +1,9 @@
+name: Nursery Pools
+description: Shallow water shelters small fish within reach of a beginner’s net.
+exits:
+ west:
+ room: 1206
+ east:
+ room: 1208
+objects:
+- id: coastal_net_spot
diff --git a/data/rooms/numisia_outskirts/1208.yaml b/data/rooms/numisia_outskirts/1208.yaml
new file mode 100644
index 0000000..f721935
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1208.yaml
@@ -0,0 +1,7 @@
+name: Sardine Rocks
+description: A low rock ledge gives bait anglers a place to sit.
+exits:
+ west:
+ room: 1207
+objects:
+- id: bait_fishing_spot
diff --git a/data/rooms/numisia_outskirts/1209.yaml b/data/rooms/numisia_outskirts/1209.yaml
new file mode 100644
index 0000000..0b14f44
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1209.yaml
@@ -0,0 +1,9 @@
+name: Common Copse
+description: A tended stand of ordinary trees lies outside the southern boundary.
+exits:
+ east:
+ room: 1134
+ west:
+ room: 1210
+objects:
+- id: tree
diff --git a/data/rooms/numisia_outskirts/1210.yaml b/data/rooms/numisia_outskirts/1210.yaml
new file mode 100644
index 0000000..a57e961
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1210.yaml
@@ -0,0 +1,8 @@
+name: Drainage Ditch
+description: Small rats pick through washed-up straw. They ignore travelers until attacked.
+exits:
+ east:
+ room: 1209
+mobs:
+- id: rat
+- id: rat
diff --git a/data/rooms/numisia_outskirts/1211.yaml b/data/rooms/numisia_outskirts/1211.yaml
new file mode 100644
index 0000000..cce8375
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1211.yaml
@@ -0,0 +1,7 @@
+name: Reclamation Yard Entrance
+description: The fenced yard sorts scrap before it can reach the sea.
+exits:
+ north:
+ room: 7100
+ east:
+ room: 1212
diff --git a/data/rooms/numisia_outskirts/1212.yaml b/data/rooms/numisia_outskirts/1212.yaml
new file mode 100644
index 0000000..b89ac0f
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1212.yaml
@@ -0,0 +1,9 @@
+name: Public Scrap Heap
+description: Clean, cold scrap is piled away from the working machinery.
+exits:
+ west:
+ room: 1211
+ east:
+ room: 1213
+objects:
+- id: scrap_pile
diff --git a/data/rooms/numisia_outskirts/1213.yaml b/data/rooms/numisia_outskirts/1213.yaml
new file mode 100644
index 0000000..a8df93c
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1213.yaml
@@ -0,0 +1,10 @@
+name: Solar Field Altar
+description: An old solar identifier array is still maintained outside town. Bring scrap and a solar identifier;
+ type id.
+exits:
+ west:
+ room: 1212
+ east:
+ room: 1214
+objects:
+- id: solar_altar
diff --git a/data/rooms/numisia_outskirts/1214.yaml b/data/rooms/numisia_outskirts/1214.yaml
new file mode 100644
index 0000000..cad040f
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1214.yaml
@@ -0,0 +1,9 @@
+name: Apprentice Relay
+description: An isolated relay provides safe hands-on Technology practice from level 1.
+exits:
+ west:
+ room: 1213
+ south:
+ room: 1215
+objects:
+- id: training_relay
diff --git a/data/rooms/numisia_outskirts/1215.yaml b/data/rooms/numisia_outskirts/1215.yaml
new file mode 100644
index 0000000..2fbc100
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1215.yaml
@@ -0,0 +1,8 @@
+name: Panel Repair Yard
+description: Unfinished frames wait for patient workers. Work on a frame for non-violent combat-skill
+ practice.
+exits:
+ north:
+ room: 1214
+mobs:
+- id: apprentice_frame
diff --git a/data/rooms/numisia_outskirts/1216.yaml b/data/rooms/numisia_outskirts/1216.yaml
new file mode 100644
index 0000000..6793626
--- /dev/null
+++ b/data/rooms/numisia_outskirts/1216.yaml
@@ -0,0 +1,7 @@
+name: Numisia — Practice Field Track
+description: A short lane leads out to the beginner agility field.
+exits:
+ west:
+ room: 1300
+ east:
+ room: 8100
diff --git a/data/rooms/roads/7100.yaml b/data/rooms/roads/7100.yaml
new file mode 100644
index 0000000..75c71d2
--- /dev/null
+++ b/data/rooms/roads/7100.yaml
@@ -0,0 +1,12 @@
+name: Brumalia Road — Numisia Milepost
+description: White boundary posts mark a maintained public road. There are no tolls or dangerous creatures
+ on the carriageway.
+exits:
+ west:
+ room: 1108
+ east:
+ room: 7101
+ north:
+ room: 1200
+ south:
+ room: 1211
diff --git a/data/rooms/roads/7101.yaml b/data/rooms/roads/7101.yaml
new file mode 100644
index 0000000..e851b66
--- /dev/null
+++ b/data/rooms/roads/7101.yaml
@@ -0,0 +1,7 @@
+name: Brumalia Road — Cart Ruts
+description: A low wall keeps livestock off the road. Beyond it, fields give way to reed beds.
+exits:
+ west:
+ room: 7100
+ east:
+ room: 7102
diff --git a/data/rooms/roads/7102.yaml b/data/rooms/roads/7102.yaml
new file mode 100644
index 0000000..b6ce86e
--- /dev/null
+++ b/data/rooms/roads/7102.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Road — White Bridge
+description: The sea breeze carries the smell of tar from Brumalia. Pedestrians have a path separate from
+ the wagons.
+exits:
+ west:
+ room: 7101
+ east:
+ room: 7103
diff --git a/data/rooms/roads/7103.yaml b/data/rooms/roads/7103.yaml
new file mode 100644
index 0000000..74f8b4c
--- /dev/null
+++ b/data/rooms/roads/7103.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Road — Sluice View
+description: White boundary posts mark a maintained public road. There are no tolls or dangerous creatures
+ on the carriageway.
+exits:
+ west:
+ room: 7102
+ east:
+ room: 7104
diff --git a/data/rooms/roads/7104.yaml b/data/rooms/roads/7104.yaml
new file mode 100644
index 0000000..d4753ca
--- /dev/null
+++ b/data/rooms/roads/7104.yaml
@@ -0,0 +1,7 @@
+name: Brumalia Road — Travelers’ Bench
+description: A low wall keeps livestock off the road. Beyond it, fields give way to reed beds.
+exits:
+ west:
+ room: 7103
+ east:
+ room: 7105
diff --git a/data/rooms/roads/7105.yaml b/data/rooms/roads/7105.yaml
new file mode 100644
index 0000000..9867a50
--- /dev/null
+++ b/data/rooms/roads/7105.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Road — Halfway Shelter
+description: The sea breeze carries the smell of tar from Brumalia. Pedestrians have a path separate from
+ the wagons.
+exits:
+ west:
+ room: 7104
+ east:
+ room: 7106
diff --git a/data/rooms/roads/7106.yaml b/data/rooms/roads/7106.yaml
new file mode 100644
index 0000000..a2b0278
--- /dev/null
+++ b/data/rooms/roads/7106.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Road — Salt Meadow
+description: White boundary posts mark a maintained public road. There are no tolls or dangerous creatures
+ on the carriageway.
+exits:
+ west:
+ room: 7105
+ east:
+ room: 7107
diff --git a/data/rooms/roads/7107.yaml b/data/rooms/roads/7107.yaml
new file mode 100644
index 0000000..7083162
--- /dev/null
+++ b/data/rooms/roads/7107.yaml
@@ -0,0 +1,7 @@
+name: Brumalia Road — Reed Culvert
+description: A low wall keeps livestock off the road. Beyond it, fields give way to reed beds.
+exits:
+ west:
+ room: 7106
+ east:
+ room: 7108
diff --git a/data/rooms/roads/7108.yaml b/data/rooms/roads/7108.yaml
new file mode 100644
index 0000000..6e9c187
--- /dev/null
+++ b/data/rooms/roads/7108.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Road — Harbor Rise
+description: The sea breeze carries the smell of tar from Brumalia. Pedestrians have a path separate from
+ the wagons.
+exits:
+ west:
+ room: 7107
+ east:
+ room: 7109
diff --git a/data/rooms/roads/7109.yaml b/data/rooms/roads/7109.yaml
new file mode 100644
index 0000000..34bee33
--- /dev/null
+++ b/data/rooms/roads/7109.yaml
@@ -0,0 +1,8 @@
+name: Brumalia Road — Signal Stone
+description: White boundary posts mark a maintained public road. There are no tolls or dangerous creatures
+ on the carriageway.
+exits:
+ west:
+ room: 7108
+ east:
+ room: 7110
diff --git a/data/rooms/roads/7110.yaml b/data/rooms/roads/7110.yaml
new file mode 100644
index 0000000..2107f0d
--- /dev/null
+++ b/data/rooms/roads/7110.yaml
@@ -0,0 +1,7 @@
+name: Brumalia Road — Brumalia Approach
+description: A low wall keeps livestock off the road. Beyond it, fields give way to reed beds.
+exits:
+ west:
+ room: 7109
+ east:
+ room: 2100
diff --git a/data/rooms/roads/7111.yaml b/data/rooms/roads/7111.yaml
new file mode 100644
index 0000000..68af94b
--- /dev/null
+++ b/data/rooms/roads/7111.yaml
@@ -0,0 +1,8 @@
+name: Forest Road — Numisia Boundary
+description: Pale posts and swept gravel distinguish the public road from the timber trails. The canopy
+ closes overhead without blocking the way.
+exits:
+ east:
+ room: 1100
+ west:
+ room: 7112
diff --git a/data/rooms/roads/7112.yaml b/data/rooms/roads/7112.yaml
new file mode 100644
index 0000000..4426a04
--- /dev/null
+++ b/data/rooms/roads/7112.yaml
@@ -0,0 +1,8 @@
+name: Forest Road — Orchard Wall
+description: A cart track runs beside the footpath. Off-road signs describe resources and warn of hostile
+ wildlife.
+exits:
+ east:
+ room: 7111
+ west:
+ room: 7113
diff --git a/data/rooms/roads/7113.yaml b/data/rooms/roads/7113.yaml
new file mode 100644
index 0000000..58eae68
--- /dev/null
+++ b/data/rooms/roads/7113.yaml
@@ -0,0 +1,8 @@
+name: Forest Road — Old Dovecote
+description: Pale posts and swept gravel distinguish the public road from the timber trails. The canopy
+ closes overhead without blocking the way.
+exits:
+ east:
+ room: 7112
+ west:
+ room: 7114
diff --git a/data/rooms/roads/7114.yaml b/data/rooms/roads/7114.yaml
new file mode 100644
index 0000000..0398a7c
--- /dev/null
+++ b/data/rooms/roads/7114.yaml
@@ -0,0 +1,8 @@
+name: Forest Road — Footbridge
+description: A cart track runs beside the footpath. Off-road signs describe resources and warn of hostile
+ wildlife.
+exits:
+ east:
+ room: 7113
+ west:
+ room: 7115
diff --git a/data/rooms/roads/7115.yaml b/data/rooms/roads/7115.yaml
new file mode 100644
index 0000000..6036687
--- /dev/null
+++ b/data/rooms/roads/7115.yaml
@@ -0,0 +1,8 @@
+name: Forest Road — Cart Shelter
+description: Pale posts and swept gravel distinguish the public road from the timber trails. The canopy
+ closes overhead without blocking the way.
+exits:
+ east:
+ room: 7114
+ west:
+ room: 7116
diff --git a/data/rooms/roads/7116.yaml b/data/rooms/roads/7116.yaml
new file mode 100644
index 0000000..9c5151b
--- /dev/null
+++ b/data/rooms/roads/7116.yaml
@@ -0,0 +1,8 @@
+name: Forest Road — Beech Shade
+description: A cart track runs beside the footpath. Off-road signs describe resources and warn of hostile
+ wildlife.
+exits:
+ east:
+ room: 7115
+ west:
+ room: 7117
diff --git a/data/rooms/roads/7117.yaml b/data/rooms/roads/7117.yaml
new file mode 100644
index 0000000..f3dc53d
--- /dev/null
+++ b/data/rooms/roads/7117.yaml
@@ -0,0 +1,8 @@
+name: Forest Road — Foresters’ Marker
+description: Pale posts and swept gravel distinguish the public road from the timber trails. The canopy
+ closes overhead without blocking the way.
+exits:
+ east:
+ room: 7116
+ west:
+ room: 7118
diff --git a/data/rooms/roads/7118.yaml b/data/rooms/roads/7118.yaml
new file mode 100644
index 0000000..fd8783f
--- /dev/null
+++ b/data/rooms/roads/7118.yaml
@@ -0,0 +1,8 @@
+name: Forest Road — Stone Drain
+description: A cart track runs beside the footpath. Off-road signs describe resources and warn of hostile
+ wildlife.
+exits:
+ east:
+ room: 7117
+ west:
+ room: 7119
diff --git a/data/rooms/roads/7119.yaml b/data/rooms/roads/7119.yaml
new file mode 100644
index 0000000..262c1ea
--- /dev/null
+++ b/data/rooms/roads/7119.yaml
@@ -0,0 +1,8 @@
+name: Forest Road — Dappled Bend
+description: Pale posts and swept gravel distinguish the public road from the timber trails. The canopy
+ closes overhead without blocking the way.
+exits:
+ east:
+ room: 7118
+ west:
+ room: 7120
diff --git a/data/rooms/roads/7120.yaml b/data/rooms/roads/7120.yaml
new file mode 100644
index 0000000..45c4d39
--- /dev/null
+++ b/data/rooms/roads/7120.yaml
@@ -0,0 +1,8 @@
+name: Forest Road — Root Bridge
+description: A cart track runs beside the footpath. Off-road signs describe resources and warn of hostile
+ wildlife.
+exits:
+ east:
+ room: 7119
+ west:
+ room: 7121
diff --git a/data/rooms/roads/7121.yaml b/data/rooms/roads/7121.yaml
new file mode 100644
index 0000000..51f96f5
--- /dev/null
+++ b/data/rooms/roads/7121.yaml
@@ -0,0 +1,8 @@
+name: Forest Road — Warden’s Approach
+description: Pale posts and swept gravel distinguish the public road from the timber trails. The canopy
+ closes overhead without blocking the way.
+exits:
+ east:
+ room: 7120
+ west:
+ room: 4100
diff --git a/data/rooms/roads/7122.yaml b/data/rooms/roads/7122.yaml
new file mode 100644
index 0000000..8c783fd
--- /dev/null
+++ b/data/rooms/roads/7122.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Road — South Fork
+description: The raised road remains dry above the marsh. Lamps and a low railing keep travelers clear
+ of the side trails.
+exits:
+ north:
+ room: 4100
+ south:
+ room: 7123
diff --git a/data/rooms/roads/7123.yaml b/data/rooms/roads/7123.yaml
new file mode 100644
index 0000000..bee89cd
--- /dev/null
+++ b/data/rooms/roads/7123.yaml
@@ -0,0 +1,7 @@
+name: Tuccia Road — Fern Cutting
+description: The safe road continues between old drainage channels. No creature patrols the carriageway.
+exits:
+ north:
+ room: 7122
+ south:
+ room: 7124
diff --git a/data/rooms/roads/7124.yaml b/data/rooms/roads/7124.yaml
new file mode 100644
index 0000000..a9d1a9d
--- /dev/null
+++ b/data/rooms/roads/7124.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Road — Dry Culvert
+description: The raised road remains dry above the marsh. Lamps and a low railing keep travelers clear
+ of the side trails.
+exits:
+ north:
+ room: 7123
+ south:
+ room: 7125
diff --git a/data/rooms/roads/7125.yaml b/data/rooms/roads/7125.yaml
new file mode 100644
index 0000000..a00f81f
--- /dev/null
+++ b/data/rooms/roads/7125.yaml
@@ -0,0 +1,7 @@
+name: Tuccia Road — Charcoal View
+description: The safe road continues between old drainage channels. No creature patrols the carriageway.
+exits:
+ north:
+ room: 7124
+ south:
+ room: 7126
diff --git a/data/rooms/roads/7126.yaml b/data/rooms/roads/7126.yaml
new file mode 100644
index 0000000..e3488f2
--- /dev/null
+++ b/data/rooms/roads/7126.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Road — Moss Bridge
+description: The raised road remains dry above the marsh. Lamps and a low railing keep travelers clear
+ of the side trails.
+exits:
+ north:
+ room: 7125
+ south:
+ room: 7127
diff --git a/data/rooms/roads/7127.yaml b/data/rooms/roads/7127.yaml
new file mode 100644
index 0000000..fbdf77b
--- /dev/null
+++ b/data/rooms/roads/7127.yaml
@@ -0,0 +1,7 @@
+name: Tuccia Road — Lantern Post
+description: The safe road continues between old drainage channels. No creature patrols the carriageway.
+exits:
+ north:
+ room: 7126
+ south:
+ room: 7128
diff --git a/data/rooms/roads/7128.yaml b/data/rooms/roads/7128.yaml
new file mode 100644
index 0000000..1804ee1
--- /dev/null
+++ b/data/rooms/roads/7128.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Road — Marsh Overlook
+description: The raised road remains dry above the marsh. Lamps and a low railing keep travelers clear
+ of the side trails.
+exits:
+ north:
+ room: 7127
+ south:
+ room: 7129
diff --git a/data/rooms/roads/7129.yaml b/data/rooms/roads/7129.yaml
new file mode 100644
index 0000000..6dfa468
--- /dev/null
+++ b/data/rooms/roads/7129.yaml
@@ -0,0 +1,7 @@
+name: Tuccia Road — Raised Causeway
+description: The safe road continues between old drainage channels. No creature patrols the carriageway.
+exits:
+ north:
+ room: 7128
+ south:
+ room: 7130
diff --git a/data/rooms/roads/7130.yaml b/data/rooms/roads/7130.yaml
new file mode 100644
index 0000000..7c39010
--- /dev/null
+++ b/data/rooms/roads/7130.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Road — Reed Wall
+description: The raised road remains dry above the marsh. Lamps and a low railing keep travelers clear
+ of the side trails.
+exits:
+ north:
+ room: 7129
+ south:
+ room: 7131
diff --git a/data/rooms/roads/7131.yaml b/data/rooms/roads/7131.yaml
new file mode 100644
index 0000000..49b174a
--- /dev/null
+++ b/data/rooms/roads/7131.yaml
@@ -0,0 +1,7 @@
+name: Tuccia Road — Tuccia Approach
+description: The safe road continues between old drainage channels. No creature patrols the carriageway.
+exits:
+ north:
+ room: 7130
+ south:
+ room: 3111
diff --git a/data/rooms/roads/7132.yaml b/data/rooms/roads/7132.yaml
new file mode 100644
index 0000000..daf9d85
--- /dev/null
+++ b/data/rooms/roads/7132.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — North Fork
+description: Gravel and white marker stones lead toward Domita. A patrol hut overlooks the road, not the
+ gathering groves.
+exits:
+ south:
+ room: 4100
+ north:
+ room: 7133
diff --git a/data/rooms/roads/7133.yaml b/data/rooms/roads/7133.yaml
new file mode 100644
index 0000000..5d489ba
--- /dev/null
+++ b/data/rooms/roads/7133.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — Deer Fence
+description: Gravel and white marker stones lead toward Domita. A patrol hut overlooks the road, not the
+ gathering groves.
+exits:
+ south:
+ room: 7132
+ north:
+ room: 7134
diff --git a/data/rooms/roads/7134.yaml b/data/rooms/roads/7134.yaml
new file mode 100644
index 0000000..e9045e4
--- /dev/null
+++ b/data/rooms/roads/7134.yaml
@@ -0,0 +1,10 @@
+name: Domita Road — Stone Shelter
+description: Gravel and white marker stones lead toward Domita. A patrol hut overlooks the road, not the
+ gathering groves.
+exits:
+ south:
+ room: 7133
+ north:
+ room: 7135
+ west:
+ room: 4119
diff --git a/data/rooms/roads/7135.yaml b/data/rooms/roads/7135.yaml
new file mode 100644
index 0000000..68f4962
--- /dev/null
+++ b/data/rooms/roads/7135.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — High Cutting
+description: Gravel and white marker stones lead toward Domita. A patrol hut overlooks the road, not the
+ gathering groves.
+exits:
+ south:
+ room: 7134
+ north:
+ room: 7136
diff --git a/data/rooms/roads/7136.yaml b/data/rooms/roads/7136.yaml
new file mode 100644
index 0000000..4fc3c21
--- /dev/null
+++ b/data/rooms/roads/7136.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — Watch Marker
+description: Gravel and white marker stones lead toward Domita. A patrol hut overlooks the road, not the
+ gathering groves.
+exits:
+ south:
+ room: 7135
+ north:
+ room: 7137
diff --git a/data/rooms/roads/7137.yaml b/data/rooms/roads/7137.yaml
new file mode 100644
index 0000000..aa6e3a5
--- /dev/null
+++ b/data/rooms/roads/7137.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — Northwest Turn
+description: Gravel and white marker stones lead toward Domita. A patrol hut overlooks the road, not the
+ gathering groves.
+exits:
+ south:
+ room: 7136
+ northwest:
+ room: 7138
diff --git a/data/rooms/roads/7138.yaml b/data/rooms/roads/7138.yaml
new file mode 100644
index 0000000..97521c6
--- /dev/null
+++ b/data/rooms/roads/7138.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — First Switchback
+description: The road climbs northwest. Domita’s casino tower grows larger at each turn; the public road
+ remains free and safe.
+exits:
+ southeast:
+ room: 7137
+ northwest:
+ room: 7139
diff --git a/data/rooms/roads/7139.yaml b/data/rooms/roads/7139.yaml
new file mode 100644
index 0000000..338ce71
--- /dev/null
+++ b/data/rooms/roads/7139.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — Slate Bridge
+description: The road climbs northwest. Domita’s casino tower grows larger at each turn; the public road
+ remains free and safe.
+exits:
+ southeast:
+ room: 7138
+ northwest:
+ room: 7140
diff --git a/data/rooms/roads/7140.yaml b/data/rooms/roads/7140.yaml
new file mode 100644
index 0000000..37fc2e2
--- /dev/null
+++ b/data/rooms/roads/7140.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — Windbreak
+description: The road climbs northwest. Domita’s casino tower grows larger at each turn; the public road
+ remains free and safe.
+exits:
+ southeast:
+ room: 7139
+ northwest:
+ room: 7141
diff --git a/data/rooms/roads/7141.yaml b/data/rooms/roads/7141.yaml
new file mode 100644
index 0000000..349fa7b
--- /dev/null
+++ b/data/rooms/roads/7141.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — Caravan Rest
+description: The road climbs northwest. Domita’s casino tower grows larger at each turn; the public road
+ remains free and safe.
+exits:
+ southeast:
+ room: 7140
+ northwest:
+ room: 7142
diff --git a/data/rooms/roads/7142.yaml b/data/rooms/roads/7142.yaml
new file mode 100644
index 0000000..c751e6b
--- /dev/null
+++ b/data/rooms/roads/7142.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — Charter Stone
+description: The road climbs northwest. Domita’s casino tower grows larger at each turn; the public road
+ remains free and safe.
+exits:
+ southeast:
+ room: 7141
+ northwest:
+ room: 7143
diff --git a/data/rooms/roads/7143.yaml b/data/rooms/roads/7143.yaml
new file mode 100644
index 0000000..85bfc7a
--- /dev/null
+++ b/data/rooms/roads/7143.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — Distant Marquee
+description: The road climbs northwest. Domita’s casino tower grows larger at each turn; the public road
+ remains free and safe.
+exits:
+ southeast:
+ room: 7142
+ northwest:
+ room: 7144
diff --git a/data/rooms/roads/7144.yaml b/data/rooms/roads/7144.yaml
new file mode 100644
index 0000000..145fe28
--- /dev/null
+++ b/data/rooms/roads/7144.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — Workers’ Shelter
+description: The road climbs northwest. Domita’s casino tower grows larger at each turn; the public road
+ remains free and safe.
+exits:
+ southeast:
+ room: 7143
+ northwest:
+ room: 7145
diff --git a/data/rooms/roads/7145.yaml b/data/rooms/roads/7145.yaml
new file mode 100644
index 0000000..1549f43
--- /dev/null
+++ b/data/rooms/roads/7145.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — Corporate Boundary
+description: The road climbs northwest. Domita’s casino tower grows larger at each turn; the public road
+ remains free and safe.
+exits:
+ southeast:
+ room: 7144
+ northwest:
+ room: 7146
diff --git a/data/rooms/roads/7146.yaml b/data/rooms/roads/7146.yaml
new file mode 100644
index 0000000..1cc2ae8
--- /dev/null
+++ b/data/rooms/roads/7146.yaml
@@ -0,0 +1,8 @@
+name: Domita Road — East Gate Approach
+description: The road climbs northwest. Domita’s casino tower grows larger at each turn; the public road
+ remains free and safe.
+exits:
+ southeast:
+ room: 7145
+ northwest:
+ room: 5108
diff --git a/data/rooms/tuccia/3100.yaml b/data/rooms/tuccia/3100.yaml
new file mode 100644
index 0000000..9a444eb
--- /dev/null
+++ b/data/rooms/tuccia/3100.yaml
@@ -0,0 +1,8 @@
+name: Tuccia — West Gate
+description: The west road passes between worn boundary stones. Behind you, Wick Street runs past separate
+ shopfronts toward the town center.
+exits:
+ east:
+ room: 3101
+ west:
+ room: 3200
diff --git a/data/rooms/tuccia/3101.yaml b/data/rooms/tuccia/3101.yaml
new file mode 100644
index 0000000..36f4eaf
--- /dev/null
+++ b/data/rooms/tuccia/3101.yaml
@@ -0,0 +1,12 @@
+name: Tuccia — Wick Street West 3
+description: Upper windows overlook Wick Street; downstairs, merchants have propped their doors open for
+ passing trade.
+exits:
+ west:
+ room: 3100
+ east:
+ room: 3102
+ north:
+ room: 3115
+ south:
+ room: 3121
diff --git a/data/rooms/tuccia/3102.yaml b/data/rooms/tuccia/3102.yaml
new file mode 100644
index 0000000..006d276
--- /dev/null
+++ b/data/rooms/tuccia/3102.yaml
@@ -0,0 +1,12 @@
+name: Tuccia — Wick Street West 2
+description: An old drain runs beside the paving. The smell from an open shop door changes whenever the
+ wind turns.
+exits:
+ west:
+ room: 3101
+ east:
+ room: 3103
+ north:
+ room: 3116
+ south:
+ room: 3122
diff --git a/data/rooms/tuccia/3103.yaml b/data/rooms/tuccia/3103.yaml
new file mode 100644
index 0000000..23bd1f6
--- /dev/null
+++ b/data/rooms/tuccia/3103.yaml
@@ -0,0 +1,12 @@
+name: Tuccia — Wick Street West 1
+description: Awnings shade this stretch of Wick Street. Each doorway belongs to a different business;
+ delivery handcarts leave a narrow path between them.
+exits:
+ west:
+ room: 3102
+ east:
+ room: 3104
+ north:
+ room: 3117
+ south:
+ room: 3123
diff --git a/data/rooms/tuccia/3104.yaml b/data/rooms/tuccia/3104.yaml
new file mode 100644
index 0000000..d14f95d
--- /dev/null
+++ b/data/rooms/tuccia/3104.yaml
@@ -0,0 +1,18 @@
+name: Tuccia — Town Square
+description: Wick Street opens around a public notice pillar. Foot traffic divides between the shops,
+ the north avenue and the quieter houses to the south.
+exits:
+ west:
+ room: 3103
+ east:
+ room: 3105
+ north:
+ room: 3109
+ south:
+ room: 3112
+objects:
+- id: aps_tower
+- name: wayboard
+ description: 'Tuccia: forest north, then Domita northwest. Wetland gathering west. The ruined chapel
+ is an optional combat detour. Contracts, housing and craft workshops line Wick Street.'
+ inroom_description: A wayboard stands where travelers can read it.
diff --git a/data/rooms/tuccia/3105.yaml b/data/rooms/tuccia/3105.yaml
new file mode 100644
index 0000000..b0d4b56
--- /dev/null
+++ b/data/rooms/tuccia/3105.yaml
@@ -0,0 +1,12 @@
+name: Tuccia — Wick Street East 1
+description: Awnings shade this stretch of Wick Street. Each doorway belongs to a different business;
+ delivery handcarts leave a narrow path between them.
+exits:
+ west:
+ room: 3104
+ east:
+ room: 3106
+ north:
+ room: 3118
+ south:
+ room: 3124
diff --git a/data/rooms/tuccia/3106.yaml b/data/rooms/tuccia/3106.yaml
new file mode 100644
index 0000000..d41aff1
--- /dev/null
+++ b/data/rooms/tuccia/3106.yaml
@@ -0,0 +1,12 @@
+name: Tuccia — Wick Street East 2
+description: An old drain runs beside the paving. The smell from an open shop door changes whenever the
+ wind turns.
+exits:
+ west:
+ room: 3105
+ east:
+ room: 3107
+ north:
+ room: 3119
+ south:
+ room: 3125
diff --git a/data/rooms/tuccia/3107.yaml b/data/rooms/tuccia/3107.yaml
new file mode 100644
index 0000000..22b862b
--- /dev/null
+++ b/data/rooms/tuccia/3107.yaml
@@ -0,0 +1,12 @@
+name: Tuccia — Wick Street East 3
+description: Upper windows overlook Wick Street; downstairs, merchants have propped their doors open for
+ passing trade.
+exits:
+ west:
+ room: 3106
+ east:
+ room: 3108
+ north:
+ room: 3120
+ south:
+ room: 3126
diff --git a/data/rooms/tuccia/3108.yaml b/data/rooms/tuccia/3108.yaml
new file mode 100644
index 0000000..853c42c
--- /dev/null
+++ b/data/rooms/tuccia/3108.yaml
@@ -0,0 +1,6 @@
+name: Tuccia — East Gate
+description: Cart tracks cross the eastern boundary. Lamps mark the safe road; the shops of Wick Street
+ remain within easy walking distance.
+exits:
+ west:
+ room: 3107
diff --git a/data/rooms/tuccia/3109.yaml b/data/rooms/tuccia/3109.yaml
new file mode 100644
index 0000000..6180700
--- /dev/null
+++ b/data/rooms/tuccia/3109.yaml
@@ -0,0 +1,8 @@
+name: Tuccia — North Avenue
+description: Wide paving carries carts toward the northern boundary. A street board lists the next settlements,
+ not their recommended combat levels.
+exits:
+ south:
+ room: 3104
+ north:
+ room: 3110
diff --git a/data/rooms/tuccia/3110.yaml b/data/rooms/tuccia/3110.yaml
new file mode 100644
index 0000000..4ac82a7
--- /dev/null
+++ b/data/rooms/tuccia/3110.yaml
@@ -0,0 +1,11 @@
+name: Tuccia — Civic Walk
+description: Stone benches face municipal doorways. None of the offices charges admission.
+exits:
+ south:
+ room: 3109
+ north:
+ room: 3111
+ west:
+ room: 3127
+ east:
+ room: 3128
diff --git a/data/rooms/tuccia/3111.yaml b/data/rooms/tuccia/3111.yaml
new file mode 100644
index 0000000..43ecab0
--- /dev/null
+++ b/data/rooms/tuccia/3111.yaml
@@ -0,0 +1,8 @@
+name: Tuccia — North Gate
+description: Beyond the gate the maintained road continues into open country. Dangerous side paths have
+ their own warning boards.
+exits:
+ south:
+ room: 3110
+ north:
+ room: 7131
diff --git a/data/rooms/tuccia/3112.yaml b/data/rooms/tuccia/3112.yaml
new file mode 100644
index 0000000..3c5beac
--- /dev/null
+++ b/data/rooms/tuccia/3112.yaml
@@ -0,0 +1,8 @@
+name: Tuccia — Lantern Lane
+description: Laundry strings cross above the lane, well clear of the lamps. Residents have painted their
+ doors different colors.
+exits:
+ north:
+ room: 3104
+ south:
+ room: 3113
diff --git a/data/rooms/tuccia/3113.yaml b/data/rooms/tuccia/3113.yaml
new file mode 100644
index 0000000..2176c32
--- /dev/null
+++ b/data/rooms/tuccia/3113.yaml
@@ -0,0 +1,12 @@
+name: Tuccia — Residential Court
+description: A shared wash basin occupies a tiny court. Conversations drift through shutters rather than
+ out of a crowded marketplace.
+exits:
+ north:
+ room: 3112
+ south:
+ room: 3114
+ west:
+ room: 3129
+ east:
+ room: 3130
diff --git a/data/rooms/tuccia/3114.yaml b/data/rooms/tuccia/3114.yaml
new file mode 100644
index 0000000..0c06bbc
--- /dev/null
+++ b/data/rooms/tuccia/3114.yaml
@@ -0,0 +1,12 @@
+name: Tuccia — South Gate
+description: The southern road leaves the houses behind. Its boundary posts are white; hazardous detours
+ are marked red.
+exits:
+ north:
+ room: 3113
+ west:
+ room: 3131
+ condition:
+ player_flag: owns_house_local_neighborhood
+ east:
+ room: 3132
diff --git a/data/rooms/tuccia/3115.yaml b/data/rooms/tuccia/3115.yaml
new file mode 100644
index 0000000..ea26b6f
--- /dev/null
+++ b/data/rooms/tuccia/3115.yaml
@@ -0,0 +1,7 @@
+name: Tuccia — Celandine’s Herbs
+description: Bundles of drying leaves hang from the ceiling, each tied with a different color.
+exits:
+ south:
+ room: 3101
+mobs:
+- id: tuccia_herbalist
diff --git a/data/rooms/tuccia/3116.yaml b/data/rooms/tuccia/3116.yaml
new file mode 100644
index 0000000..b765bba
--- /dev/null
+++ b/data/rooms/tuccia/3116.yaml
@@ -0,0 +1,7 @@
+name: Tuccia — Tuccia Savings House
+description: The bank stands on stone pilings above the damp ground.
+exits:
+ south:
+ room: 3102
+objects:
+- id: bank_booth
diff --git a/data/rooms/tuccia/3117.yaml b/data/rooms/tuccia/3117.yaml
new file mode 100644
index 0000000..7cfd9ea
--- /dev/null
+++ b/data/rooms/tuccia/3117.yaml
@@ -0,0 +1,7 @@
+name: Tuccia — Rook’s Arrow Shop
+description: A flight of feather samples hangs over the counter.
+exits:
+ south:
+ room: 3103
+mobs:
+- id: tuccia_fletcher
diff --git a/data/rooms/tuccia/3118.yaml b/data/rooms/tuccia/3118.yaml
new file mode 100644
index 0000000..1a67994
--- /dev/null
+++ b/data/rooms/tuccia/3118.yaml
@@ -0,0 +1,9 @@
+name: Tuccia — Moss’s Reclamation
+description: Sorted connectors sit in old preserve jars.
+exits:
+ south:
+ room: 3105
+objects:
+- id: terminal_advanced
+mobs:
+- id: tuccia_reclaimer
diff --git a/data/rooms/tuccia/3119.yaml b/data/rooms/tuccia/3119.yaml
new file mode 100644
index 0000000..4ca0c50
--- /dev/null
+++ b/data/rooms/tuccia/3119.yaml
@@ -0,0 +1,9 @@
+name: Tuccia — Bell’s Workshop
+description: Raised benches keep valuable lumber away from the wet floor.
+exits:
+ south:
+ room: 3106
+objects:
+- id: workbench
+mobs:
+- id: tuccia_carpenter
diff --git a/data/rooms/tuccia/3120.yaml b/data/rooms/tuccia/3120.yaml
new file mode 100644
index 0000000..6c72946
--- /dev/null
+++ b/data/rooms/tuccia/3120.yaml
@@ -0,0 +1,8 @@
+name: Tuccia — Lamplighter’s Forge
+description: Bellows breathe into a small furnace built above the flood line.
+exits:
+ south:
+ room: 3107
+objects:
+- id: furnace
+- id: anvil
diff --git a/data/rooms/tuccia/3121.yaml b/data/rooms/tuccia/3121.yaml
new file mode 100644
index 0000000..a799be8
--- /dev/null
+++ b/data/rooms/tuccia/3121.yaml
@@ -0,0 +1,7 @@
+name: Tuccia — Reedcloth Studio
+description: A spinning wheel turns under a ceiling of woven reed panels.
+exits:
+ north:
+ room: 3101
+objects:
+- id: spinning_wheel
diff --git a/data/rooms/tuccia/3122.yaml b/data/rooms/tuccia/3122.yaml
new file mode 100644
index 0000000..689a368
--- /dev/null
+++ b/data/rooms/tuccia/3122.yaml
@@ -0,0 +1,7 @@
+name: Tuccia — The Low Lantern Kitchen
+description: A copper hood gathers smoke above the public cooking range.
+exits:
+ north:
+ room: 3102
+objects:
+- id: cooking_range
diff --git a/data/rooms/tuccia/3123.yaml b/data/rooms/tuccia/3123.yaml
new file mode 100644
index 0000000..69344f3
--- /dev/null
+++ b/data/rooms/tuccia/3123.yaml
@@ -0,0 +1,7 @@
+name: Tuccia — Contract Agent’s Office
+description: Waterproof folders describe jobs in the marsh and the forest relay enclosure.
+exits:
+ north:
+ room: 3103
+mobs:
+- id: tuccia_contracts
diff --git a/data/rooms/tuccia/3124.yaml b/data/rooms/tuccia/3124.yaml
new file mode 100644
index 0000000..bcbce91
--- /dev/null
+++ b/data/rooms/tuccia/3124.yaml
@@ -0,0 +1,9 @@
+name: Tuccia — Estate Office
+description: A modest ledger records plots in the local neighborhood.
+exits:
+ north:
+ room: 3105
+objects:
+- id: estate_directory
+mobs:
+- id: tuccia_estate_broker
diff --git a/data/rooms/tuccia/3125.yaml b/data/rooms/tuccia/3125.yaml
new file mode 100644
index 0000000..14c5d63
--- /dev/null
+++ b/data/rooms/tuccia/3125.yaml
@@ -0,0 +1,8 @@
+name: Tuccia — Ceramic Stove Shop
+description: A potter’s wheel sits beside a kiln lined in green tile.
+exits:
+ north:
+ room: 3106
+objects:
+- id: pottery_wheel
+- id: pottery_oven
diff --git a/data/rooms/tuccia/3126.yaml b/data/rooms/tuccia/3126.yaml
new file mode 100644
index 0000000..9be93dc
--- /dev/null
+++ b/data/rooms/tuccia/3126.yaml
@@ -0,0 +1,7 @@
+name: Tuccia — Signal Repair
+description: A salvaged charger lights the underside of a warped worktable.
+exits:
+ north:
+ room: 3107
+objects:
+- id: charging_station
diff --git a/data/rooms/tuccia/3127.yaml b/data/rooms/tuccia/3127.yaml
new file mode 100644
index 0000000..4a1b420
--- /dev/null
+++ b/data/rooms/tuccia/3127.yaml
@@ -0,0 +1,7 @@
+name: Tuccia — Village Meeting House
+description: A roof leak has been carefully redirected into a ceremonial basin.
+exits:
+ east:
+ room: 3110
+mobs:
+- id: tuccia_resident
diff --git a/data/rooms/tuccia/3128.yaml b/data/rooms/tuccia/3128.yaml
new file mode 100644
index 0000000..c5095d7
--- /dev/null
+++ b/data/rooms/tuccia/3128.yaml
@@ -0,0 +1,5 @@
+name: Tuccia — Wick Street Archive
+description: Surveyors’ plans show a succession of canals that were never dug.
+exits:
+ west:
+ room: 3110
diff --git a/data/rooms/tuccia/3129.yaml b/data/rooms/tuccia/3129.yaml
new file mode 100644
index 0000000..71428a5
--- /dev/null
+++ b/data/rooms/tuccia/3129.yaml
@@ -0,0 +1,5 @@
+name: Tuccia — Mera’s Parlor
+description: A kettle murmurs beside a chair repaired more often than it has been replaced.
+exits:
+ east:
+ room: 3113
diff --git a/data/rooms/tuccia/3130.yaml b/data/rooms/tuccia/3130.yaml
new file mode 100644
index 0000000..51eb89a
--- /dev/null
+++ b/data/rooms/tuccia/3130.yaml
@@ -0,0 +1,7 @@
+name: Tuccia — Ferryman’s Cottage
+description: A model boat hangs over the cot.
+exits:
+ west:
+ room: 3113
+mobs:
+- id: man
diff --git a/data/rooms/tuccia/3131.yaml b/data/rooms/tuccia/3131.yaml
new file mode 100644
index 0000000..89fd0d4
--- /dev/null
+++ b/data/rooms/tuccia/3131.yaml
@@ -0,0 +1,7 @@
+name: Tuccia — Registered Home
+description: A plain entrance hall waits for its owner. The workshop is upstairs.
+exits:
+ east:
+ room: 3114
+ up:
+ room: 3133
diff --git a/data/rooms/tuccia/3132.yaml b/data/rooms/tuccia/3132.yaml
new file mode 100644
index 0000000..641c091
--- /dev/null
+++ b/data/rooms/tuccia/3132.yaml
@@ -0,0 +1,7 @@
+name: Tuccia — Rainwater Court
+description: Filtered rain fills a large covered cistern.
+exits:
+ west:
+ room: 3114
+objects:
+- id: lumby_fountain
diff --git a/data/rooms/tuccia/3133.yaml b/data/rooms/tuccia/3133.yaml
new file mode 100644
index 0000000..30e0858
--- /dev/null
+++ b/data/rooms/tuccia/3133.yaml
@@ -0,0 +1,7 @@
+name: Tuccia — Home Workshop
+description: Sunlight enters through a narrow clerestory above a private workbench.
+exits:
+ down:
+ room: 3131
+objects:
+- id: workbench
diff --git a/data/rooms/vestalia/1300.yaml b/data/rooms/vestalia/1300.yaml
new file mode 100644
index 0000000..642e0f5
--- /dev/null
+++ b/data/rooms/vestalia/1300.yaml
@@ -0,0 +1,10 @@
+name: Vestalia Terra — North Road Milepost
+description: The northern road runs between cultivated fields. Farm gates lead off the safe carriageway;
+ Numisia remains south.
+exits:
+ south:
+ room: 1111
+ north:
+ room: 1301
+ east:
+ room: 1216
diff --git a/data/rooms/vestalia/1301.yaml b/data/rooms/vestalia/1301.yaml
new file mode 100644
index 0000000..ef363e9
--- /dev/null
+++ b/data/rooms/vestalia/1301.yaml
@@ -0,0 +1,8 @@
+name: Vestalia Terra — Wheat View
+description: The northern road runs between cultivated fields. Farm gates lead off the safe carriageway;
+ Numisia remains south.
+exits:
+ south:
+ room: 1300
+ north:
+ room: 1302
diff --git a/data/rooms/vestalia/1302.yaml b/data/rooms/vestalia/1302.yaml
new file mode 100644
index 0000000..06ce209
--- /dev/null
+++ b/data/rooms/vestalia/1302.yaml
@@ -0,0 +1,12 @@
+name: Vestalia Terra — Mill Stream Bridge
+description: The northern road runs between cultivated fields. Farm gates lead off the safe carriageway;
+ Numisia remains south.
+exits:
+ south:
+ room: 1301
+ north:
+ room: 1303
+ west:
+ room: 1312
+ east:
+ room: 1313
diff --git a/data/rooms/vestalia/1303.yaml b/data/rooms/vestalia/1303.yaml
new file mode 100644
index 0000000..dbe3705
--- /dev/null
+++ b/data/rooms/vestalia/1303.yaml
@@ -0,0 +1,12 @@
+name: Vestalia Terra — Hedgerow Walk
+description: The northern road runs between cultivated fields. Farm gates lead off the safe carriageway;
+ Numisia remains south.
+exits:
+ south:
+ room: 1302
+ north:
+ room: 1304
+ west:
+ room: 1314
+ east:
+ room: 1315
diff --git a/data/rooms/vestalia/1304.yaml b/data/rooms/vestalia/1304.yaml
new file mode 100644
index 0000000..2e4f5f7
--- /dev/null
+++ b/data/rooms/vestalia/1304.yaml
@@ -0,0 +1,12 @@
+name: Vestalia Terra — Vestalia Boundary
+description: The northern road runs between cultivated fields. Farm gates lead off the safe carriageway;
+ Numisia remains south.
+exits:
+ south:
+ room: 1303
+ north:
+ room: 1305
+ west:
+ room: 1316
+ east:
+ room: 1317
diff --git a/data/rooms/vestalia/1305.yaml b/data/rooms/vestalia/1305.yaml
new file mode 100644
index 0000000..1449c43
--- /dev/null
+++ b/data/rooms/vestalia/1305.yaml
@@ -0,0 +1,12 @@
+name: Vestalia Terra — Cart Weighbridge
+description: The northern road runs between cultivated fields. Farm gates lead off the safe carriageway;
+ Numisia remains south.
+exits:
+ south:
+ room: 1304
+ north:
+ room: 1306
+ west:
+ room: 1318
+ east:
+ room: 1319
diff --git a/data/rooms/vestalia/1306.yaml b/data/rooms/vestalia/1306.yaml
new file mode 100644
index 0000000..af1fbd1
--- /dev/null
+++ b/data/rooms/vestalia/1306.yaml
@@ -0,0 +1,18 @@
+name: Vestalia Terra — Seedkeepers’ Green
+description: The northern road runs between cultivated fields. Farm gates lead off the safe carriageway;
+ Numisia remains south.
+exits:
+ south:
+ room: 1305
+ north:
+ room: 1307
+ west:
+ room: 1320
+ east:
+ room: 1321
+objects:
+- id: aps_tower
+- name: wayboard
+ description: 'Vestalia Terra: low fields south, research terraces north. Separate allotment, herb and
+ flower plots line the road. Seed shops supply all crop tiers. Sump combat is an optional eastern detour.'
+ inroom_description: A wayboard stands where travelers can read it.
diff --git a/data/rooms/vestalia/1307.yaml b/data/rooms/vestalia/1307.yaml
new file mode 100644
index 0000000..39f9d7c
--- /dev/null
+++ b/data/rooms/vestalia/1307.yaml
@@ -0,0 +1,12 @@
+name: Vestalia Terra — Granary Lane
+description: Grain wagons have right of way here, but a separate footpath keeps walkers out of the ruts.
+ Cultivated plots lie beyond the hedges.
+exits:
+ south:
+ room: 1306
+ north:
+ room: 1308
+ west:
+ room: 1322
+ east:
+ room: 1323
diff --git a/data/rooms/vestalia/1308.yaml b/data/rooms/vestalia/1308.yaml
new file mode 100644
index 0000000..3409c07
--- /dev/null
+++ b/data/rooms/vestalia/1308.yaml
@@ -0,0 +1,12 @@
+name: Vestalia Terra — Windmill Yard
+description: Grain wagons have right of way here, but a separate footpath keeps walkers out of the ruts.
+ Cultivated plots lie beyond the hedges.
+exits:
+ south:
+ room: 1307
+ north:
+ room: 1309
+ west:
+ room: 1324
+ east:
+ room: 1325
diff --git a/data/rooms/vestalia/1309.yaml b/data/rooms/vestalia/1309.yaml
new file mode 100644
index 0000000..aec11c7
--- /dev/null
+++ b/data/rooms/vestalia/1309.yaml
@@ -0,0 +1,12 @@
+name: Vestalia Terra — Research Track
+description: Grain wagons have right of way here, but a separate footpath keeps walkers out of the ruts.
+ Cultivated plots lie beyond the hedges.
+exits:
+ south:
+ room: 1308
+ north:
+ room: 1310
+ west:
+ room: 1326
+ east:
+ room: 1327
diff --git a/data/rooms/vestalia/1310.yaml b/data/rooms/vestalia/1310.yaml
new file mode 100644
index 0000000..252d24e
--- /dev/null
+++ b/data/rooms/vestalia/1310.yaml
@@ -0,0 +1,12 @@
+name: Vestalia Terra — Upper Terrace Lane
+description: Grain wagons have right of way here, but a separate footpath keeps walkers out of the ruts.
+ Cultivated plots lie beyond the hedges.
+exits:
+ south:
+ room: 1309
+ north:
+ room: 1311
+ west:
+ room: 1328
+ east:
+ room: 1329
diff --git a/data/rooms/vestalia/1311.yaml b/data/rooms/vestalia/1311.yaml
new file mode 100644
index 0000000..dd590ef
--- /dev/null
+++ b/data/rooms/vestalia/1311.yaml
@@ -0,0 +1,10 @@
+name: Vestalia Terra — Irrigation Headworks
+description: Grain wagons have right of way here, but a separate footpath keeps walkers out of the ruts.
+ Cultivated plots lie beyond the hedges.
+exits:
+ south:
+ room: 1310
+ west:
+ room: 1330
+ east:
+ room: 1331
diff --git a/data/rooms/vestalia/1312.yaml b/data/rooms/vestalia/1312.yaml
new file mode 100644
index 0000000..f74b626
--- /dev/null
+++ b/data/rooms/vestalia/1312.yaml
@@ -0,0 +1,8 @@
+name: Vestalia Terra — Sheep Paddock
+description: White wool catches on the low fence. These placid sheep can be sheared.
+exits:
+ east:
+ room: 1302
+objects:
+- id: sheep
+- id: sheep
diff --git a/data/rooms/vestalia/1313.yaml b/data/rooms/vestalia/1313.yaml
new file mode 100644
index 0000000..ce16f84
--- /dev/null
+++ b/data/rooms/vestalia/1313.yaml
@@ -0,0 +1,8 @@
+name: Vestalia Terra — Cow Pasture
+description: The small herd grazes quietly. Cows only fight if attacked.
+exits:
+ west:
+ room: 1302
+mobs:
+- id: cow
+- id: cow
diff --git a/data/rooms/vestalia/1314.yaml b/data/rooms/vestalia/1314.yaml
new file mode 100644
index 0000000..f50c02e
--- /dev/null
+++ b/data/rooms/vestalia/1314.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Flax Strip
+description: Blue flowers ripple in a long strip between two food fields.
+exits:
+ east:
+ room: 1303
+objects:
+- id: flax_bed
diff --git a/data/rooms/vestalia/1315.yaml b/data/rooms/vestalia/1315.yaml
new file mode 100644
index 0000000..9692d05
--- /dev/null
+++ b/data/rooms/vestalia/1315.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Trout Stream
+description: Fast water washes over clean gravel, ideal for fly fishing from level 20.
+exits:
+ west:
+ room: 1303
+objects:
+- id: fly_fishing_spot
diff --git a/data/rooms/vestalia/1316.yaml b/data/rooms/vestalia/1316.yaml
new file mode 100644
index 0000000..75caf66
--- /dev/null
+++ b/data/rooms/vestalia/1316.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Beginner Allotment
+description: A neat sign recommends potatoes at Farming 1. Higher seeds can use this same soil.
+exits:
+ east:
+ room: 1304
+objects:
+- id: allotment_patch
diff --git a/data/rooms/vestalia/1317.yaml b/data/rooms/vestalia/1317.yaml
new file mode 100644
index 0000000..4e1e099
--- /dev/null
+++ b/data/rooms/vestalia/1317.yaml
@@ -0,0 +1,9 @@
+name: Vestalia Terra — Guam Garden
+description: Low stakes divide the herb beds. Rake, plant, water and harvest with the appropriate tools.
+exits:
+ west:
+ room: 1304
+ east:
+ room: 1332
+objects:
+- id: herb_patch
diff --git a/data/rooms/vestalia/1318.yaml b/data/rooms/vestalia/1318.yaml
new file mode 100644
index 0000000..fc3c27f
--- /dev/null
+++ b/data/rooms/vestalia/1318.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Flower Borders
+description: Flower plots separate the vegetable beds from the lane.
+exits:
+ east:
+ room: 1305
+objects:
+- id: flower_patch
diff --git a/data/rooms/vestalia/1319.yaml b/data/rooms/vestalia/1319.yaml
new file mode 100644
index 0000000..941ef95
--- /dev/null
+++ b/data/rooms/vestalia/1319.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Field Tool Shop
+description: A tiny timber shop serves the surrounding farms, well outside the city.
+exits:
+ west:
+ room: 1305
+mobs:
+- id: vestalia_seedkeeper
diff --git a/data/rooms/vestalia/1320.yaml b/data/rooms/vestalia/1320.yaml
new file mode 100644
index 0000000..087a40d
--- /dev/null
+++ b/data/rooms/vestalia/1320.yaml
@@ -0,0 +1,9 @@
+name: Vestalia Terra — Farmhouse Kitchen
+description: A stone range warms a farmhouse shared by seasonal workers.
+exits:
+ east:
+ room: 1306
+objects:
+- id: cooking_range
+mobs:
+- id: farmer
diff --git a/data/rooms/vestalia/1321.yaml b/data/rooms/vestalia/1321.yaml
new file mode 100644
index 0000000..a322f10
--- /dev/null
+++ b/data/rooms/vestalia/1321.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Produce Weighhouse
+description: A bank counter serves farmers bringing harvests to the granary.
+exits:
+ west:
+ room: 1306
+objects:
+- id: bank_booth
diff --git a/data/rooms/vestalia/1322.yaml b/data/rooms/vestalia/1322.yaml
new file mode 100644
index 0000000..b754fa0
--- /dev/null
+++ b/data/rooms/vestalia/1322.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Root Thicket
+description: Uncultivated medicinal roots grow beyond the regular rows.
+exits:
+ east:
+ room: 1307
+objects:
+- id: reagent_thicket
diff --git a/data/rooms/vestalia/1323.yaml b/data/rooms/vestalia/1323.yaml
new file mode 100644
index 0000000..a515b13
--- /dev/null
+++ b/data/rooms/vestalia/1323.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Cabbage and Corn Field
+description: A second allotment lets farmers keep several crops growing at once.
+exits:
+ west:
+ room: 1307
+objects:
+- id: allotment_patch
diff --git a/data/rooms/vestalia/1324.yaml b/data/rooms/vestalia/1324.yaml
new file mode 100644
index 0000000..7eab3c4
--- /dev/null
+++ b/data/rooms/vestalia/1324.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Seed Research Office
+description: Seed envelopes are filed by the Farming level needed to plant them.
+exits:
+ east:
+ room: 1308
+mobs:
+- id: vestalia_botanist
diff --git a/data/rooms/vestalia/1325.yaml b/data/rooms/vestalia/1325.yaml
new file mode 100644
index 0000000..5128a6d
--- /dev/null
+++ b/data/rooms/vestalia/1325.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Hydro Field Shrine
+description: A restored water controller identifies hydrojunk at Scavenging 14.
+exits:
+ west:
+ room: 1308
+objects:
+- id: hydro_altar
diff --git a/data/rooms/vestalia/1326.yaml b/data/rooms/vestalia/1326.yaml
new file mode 100644
index 0000000..4065584
--- /dev/null
+++ b/data/rooms/vestalia/1326.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Upper Herb Terrace
+description: Rarer herbs can be cultivated here by experienced farmers.
+exits:
+ east:
+ room: 1309
+objects:
+- id: herb_patch
diff --git a/data/rooms/vestalia/1327.yaml b/data/rooms/vestalia/1327.yaml
new file mode 100644
index 0000000..0e42d3e
--- /dev/null
+++ b/data/rooms/vestalia/1327.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Irrigation Controller
+description: The safe maintenance station trains Technology from level 10.
+exits:
+ west:
+ room: 1309
+objects:
+- id: irrigation_relay
diff --git a/data/rooms/vestalia/1328.yaml b/data/rooms/vestalia/1328.yaml
new file mode 100644
index 0000000..507bd7d
--- /dev/null
+++ b/data/rooms/vestalia/1328.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Research Allotment
+description: Deep prepared soil is reserved for patient growers, not wealthy landowners.
+exits:
+ east:
+ room: 1310
+objects:
+- id: allotment_patch
diff --git a/data/rooms/vestalia/1329.yaml b/data/rooms/vestalia/1329.yaml
new file mode 100644
index 0000000..6580564
--- /dev/null
+++ b/data/rooms/vestalia/1329.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Glasshouse Garden
+description: Common flowers grow beneath repaired glass panes.
+exits:
+ west:
+ room: 1310
+objects:
+- id: flower_patch
diff --git a/data/rooms/vestalia/1330.yaml b/data/rooms/vestalia/1330.yaml
new file mode 100644
index 0000000..c1e6896
--- /dev/null
+++ b/data/rooms/vestalia/1330.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — High Herb Bed
+description: This remote bed is suitable for the same full range of herb seeds as the lower fields.
+exits:
+ east:
+ room: 1311
+objects:
+- id: herb_patch
diff --git a/data/rooms/vestalia/1331.yaml b/data/rooms/vestalia/1331.yaml
new file mode 100644
index 0000000..3ecb91f
--- /dev/null
+++ b/data/rooms/vestalia/1331.yaml
@@ -0,0 +1,7 @@
+name: Vestalia Terra — Headworks Repair
+description: A maintenance frame awaits assembly beside the water gates.
+exits:
+ west:
+ room: 1311
+mobs:
+- id: irrigation_frame
diff --git a/data/rooms/vestalia/1332.yaml b/data/rooms/vestalia/1332.yaml
new file mode 100644
index 0000000..306e1eb
--- /dev/null
+++ b/data/rooms/vestalia/1332.yaml
@@ -0,0 +1,13 @@
+name: Vestalia Terra — Sump Gate
+description: A red-edged notice warns that the drainage sump is a contract worksite. Slugs need salt for
+ the finishing blow.
+exits:
+ west:
+ room: 1317
+ east:
+ room: 1333
+objects:
+- name: wayboard
+ description: 'East: slugs (Assassin 1; salt required). Return west to the safe fields. These creatures
+ do not wander.'
+ inroom_description: A wayboard stands where travelers can read it.
diff --git a/data/rooms/vestalia/1333.yaml b/data/rooms/vestalia/1333.yaml
new file mode 100644
index 0000000..f1f93a2
--- /dev/null
+++ b/data/rooms/vestalia/1333.yaml
@@ -0,0 +1,8 @@
+name: Vestalia Terra — Slug Sump
+description: Slugs cling to the wet brickwork below the irrigation outlet.
+exits:
+ west:
+ room: 1332
+mobs:
+- id: slug
+- id: slug
diff --git a/data/rooms/wetlands/3200.yaml b/data/rooms/wetlands/3200.yaml
new file mode 100644
index 0000000..fbeb5ad
--- /dev/null
+++ b/data/rooms/wetlands/3200.yaml
@@ -0,0 +1,12 @@
+name: Tuccia Wetlands — Marsh Gatepath
+description: A raised boardwalk crosses the marsh outside Tuccia. White rails mark the safe route; hunting
+ paths leave it through red-marked gates.
+exits:
+ east:
+ room: 3100
+ west:
+ room: 3201
+ north:
+ room: 3207
+ south:
+ room: 3215
diff --git a/data/rooms/wetlands/3201.yaml b/data/rooms/wetlands/3201.yaml
new file mode 100644
index 0000000..4c5b70c
--- /dev/null
+++ b/data/rooms/wetlands/3201.yaml
@@ -0,0 +1,10 @@
+name: Tuccia Wetlands — Willow Boardwalk
+description: A raised boardwalk crosses the marsh outside Tuccia. White rails mark the safe route; hunting
+ paths leave it through red-marked gates.
+exits:
+ east:
+ room: 3200
+ west:
+ room: 3202
+ north:
+ room: 3208
diff --git a/data/rooms/wetlands/3202.yaml b/data/rooms/wetlands/3202.yaml
new file mode 100644
index 0000000..8d2d77f
--- /dev/null
+++ b/data/rooms/wetlands/3202.yaml
@@ -0,0 +1,10 @@
+name: Tuccia Wetlands — Eel Causeway
+description: A raised boardwalk crosses the marsh outside Tuccia. White rails mark the safe route; hunting
+ paths leave it through red-marked gates.
+exits:
+ east:
+ room: 3201
+ west:
+ room: 3203
+ north:
+ room: 3209
diff --git a/data/rooms/wetlands/3203.yaml b/data/rooms/wetlands/3203.yaml
new file mode 100644
index 0000000..7124f32
--- /dev/null
+++ b/data/rooms/wetlands/3203.yaml
@@ -0,0 +1,12 @@
+name: Tuccia Wetlands — Medicinal Pools
+description: A raised boardwalk crosses the marsh outside Tuccia. White rails mark the safe route; hunting
+ paths leave it through red-marked gates.
+exits:
+ east:
+ room: 3202
+ west:
+ room: 3204
+ north:
+ room: 3210
+ south:
+ room: 3214
diff --git a/data/rooms/wetlands/3204.yaml b/data/rooms/wetlands/3204.yaml
new file mode 100644
index 0000000..4a741d9
--- /dev/null
+++ b/data/rooms/wetlands/3204.yaml
@@ -0,0 +1,10 @@
+name: Tuccia Wetlands — Herbalists’ Walk
+description: A raised boardwalk crosses the marsh outside Tuccia. White rails mark the safe route; hunting
+ paths leave it through red-marked gates.
+exits:
+ east:
+ room: 3203
+ west:
+ room: 3205
+ north:
+ room: 3211
diff --git a/data/rooms/wetlands/3205.yaml b/data/rooms/wetlands/3205.yaml
new file mode 100644
index 0000000..56b0000
--- /dev/null
+++ b/data/rooms/wetlands/3205.yaml
@@ -0,0 +1,10 @@
+name: Tuccia Wetlands — Stillwater Walk
+description: A raised boardwalk crosses the marsh outside Tuccia. White rails mark the safe route; hunting
+ paths leave it through red-marked gates.
+exits:
+ east:
+ room: 3204
+ west:
+ room: 3206
+ north:
+ room: 3212
diff --git a/data/rooms/wetlands/3206.yaml b/data/rooms/wetlands/3206.yaml
new file mode 100644
index 0000000..7901032
--- /dev/null
+++ b/data/rooms/wetlands/3206.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Wetlands — Reed Pool Approach
+description: A raised boardwalk crosses the marsh outside Tuccia. White rails mark the safe route; hunting
+ paths leave it through red-marked gates.
+exits:
+ east:
+ room: 3205
+ north:
+ room: 3213
diff --git a/data/rooms/wetlands/3207.yaml b/data/rooms/wetlands/3207.yaml
new file mode 100644
index 0000000..bf024ff
--- /dev/null
+++ b/data/rooms/wetlands/3207.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Wetlands — Willow Bank
+description: A small maintained working site stands clear of the marsh trail. Skill requirements apply
+ to the activity, not to reaching it.
+exits:
+ south:
+ room: 3200
+objects:
+- id: willow_tree
diff --git a/data/rooms/wetlands/3208.yaml b/data/rooms/wetlands/3208.yaml
new file mode 100644
index 0000000..ddc4c98
--- /dev/null
+++ b/data/rooms/wetlands/3208.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Wetlands — Marsh Herb Plot
+description: A small maintained working site stands clear of the marsh trail. Skill requirements apply
+ to the activity, not to reaching it.
+exits:
+ south:
+ room: 3201
+objects:
+- id: herb_patch
diff --git a/data/rooms/wetlands/3209.yaml b/data/rooms/wetlands/3209.yaml
new file mode 100644
index 0000000..41de2c8
--- /dev/null
+++ b/data/rooms/wetlands/3209.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Wetlands — Eel Platform
+description: A small maintained working site stands clear of the marsh trail. Skill requirements apply
+ to the activity, not to reaching it.
+exits:
+ south:
+ room: 3202
+objects:
+- id: swamp_fishing_spot
diff --git a/data/rooms/wetlands/3210.yaml b/data/rooms/wetlands/3210.yaml
new file mode 100644
index 0000000..3617ef5
--- /dev/null
+++ b/data/rooms/wetlands/3210.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Wetlands — Berry Islet
+description: A small maintained working site stands clear of the marsh trail. Skill requirements apply
+ to the activity, not to reaching it.
+exits:
+ south:
+ room: 3203
+objects:
+- id: marsh_berries
diff --git a/data/rooms/wetlands/3211.yaml b/data/rooms/wetlands/3211.yaml
new file mode 100644
index 0000000..2830f87
--- /dev/null
+++ b/data/rooms/wetlands/3211.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Wetlands — Marsh Herb Nursery
+description: A small maintained working site stands clear of the marsh trail. Skill requirements apply
+ to the activity, not to reaching it.
+exits:
+ south:
+ room: 3204
+objects:
+- id: herb_patch
diff --git a/data/rooms/wetlands/3212.yaml b/data/rooms/wetlands/3212.yaml
new file mode 100644
index 0000000..b2a2c3a
--- /dev/null
+++ b/data/rooms/wetlands/3212.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Wetlands — Chaos Array
+description: A small maintained working site stands clear of the marsh trail. Skill requirements apply
+ to the activity, not to reaching it.
+exits:
+ south:
+ room: 3205
+objects:
+- id: chaos_altar
diff --git a/data/rooms/wetlands/3213.yaml b/data/rooms/wetlands/3213.yaml
new file mode 100644
index 0000000..e4a79d5
--- /dev/null
+++ b/data/rooms/wetlands/3213.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Wetlands — Reed Eel Pool
+description: A small maintained working site stands clear of the marsh trail. Skill requirements apply
+ to the activity, not to reaching it.
+exits:
+ south:
+ room: 3206
+objects:
+- id: swamp_fishing_spot
diff --git a/data/rooms/wetlands/3214.yaml b/data/rooms/wetlands/3214.yaml
new file mode 100644
index 0000000..febc2d7
--- /dev/null
+++ b/data/rooms/wetlands/3214.yaml
@@ -0,0 +1,8 @@
+name: Tuccia Wetlands — Second Herb Islet
+description: A small maintained working site stands clear of the marsh trail. Skill requirements apply
+ to the activity, not to reaching it.
+exits:
+ north:
+ room: 3203
+objects:
+- id: herb_patch
diff --git a/data/rooms/wetlands/3215.yaml b/data/rooms/wetlands/3215.yaml
new file mode 100644
index 0000000..d5af1d9
--- /dev/null
+++ b/data/rooms/wetlands/3215.yaml
@@ -0,0 +1,12 @@
+name: Tuccia Wetlands — Ruined Chapel Gate
+description: The boardwalk branches toward a roofless chapel and its dangerous crypts.
+exits:
+ north:
+ room: 3200
+ south:
+ room: 3216
+objects:
+- name: danger marker
+ description: 'DANGER beyond this side trail: crawler. The public road and gathering path are safe; this
+ detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
diff --git a/data/rooms/wetlands/3216.yaml b/data/rooms/wetlands/3216.yaml
new file mode 100644
index 0000000..46fb8fb
--- /dev/null
+++ b/data/rooms/wetlands/3216.yaml
@@ -0,0 +1,16 @@
+name: Tuccia Wetlands — Root Cellar
+description: Crawlers nest among the exposed roots. Assassin 30; use an acid vial for the finishing blow.
+ This is an off-road combat area; hostile creatures remain here.
+exits:
+ north:
+ room: 3215
+ south:
+ room: 3217
+objects:
+- id: rock_outcrop
+- name: danger marker
+ description: 'DANGER beyond this side trail: skeleton, zombie. The public road and gathering path are
+ safe; this detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
+mobs:
+- id: crawler
diff --git a/data/rooms/wetlands/3217.yaml b/data/rooms/wetlands/3217.yaml
new file mode 100644
index 0000000..130a243
--- /dev/null
+++ b/data/rooms/wetlands/3217.yaml
@@ -0,0 +1,17 @@
+name: Tuccia Wetlands — Chapel Graveyard
+description: The graves have not stayed quiet. This is an off-road combat area; hostile creatures remain
+ here.
+exits:
+ north:
+ room: 3216
+ down:
+ room: 3218
+objects:
+- id: rock_outcrop
+- name: danger marker
+ description: 'DANGER beyond this side trail: skeleton. The public road and gathering path are safe;
+ this detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
+mobs:
+- id: skeleton
+- id: zombie
diff --git a/data/rooms/wetlands/3218.yaml b/data/rooms/wetlands/3218.yaml
new file mode 100644
index 0000000..90956c8
--- /dev/null
+++ b/data/rooms/wetlands/3218.yaml
@@ -0,0 +1,16 @@
+name: Tuccia Wetlands — Lower Crypt
+description: The shallow crypt contains restless remains, not the ancient horrors rumored in distant lands.
+ This is an off-road combat area; hostile creatures remain here.
+exits:
+ up:
+ room: 3217
+ west:
+ room: 3219
+objects:
+- id: rock_outcrop
+- name: danger marker
+ description: 'DANGER beyond this side trail: zombie. The public road and gathering path are safe; this
+ detour is optional.'
+ inroom_description: A danger marker stands where travelers can read it.
+mobs:
+- id: skeleton
diff --git a/data/rooms/wetlands/3219.yaml b/data/rooms/wetlands/3219.yaml
new file mode 100644
index 0000000..11f871f
--- /dev/null
+++ b/data/rooms/wetlands/3219.yaml
@@ -0,0 +1,10 @@
+name: Tuccia Wetlands — Ossuary
+description: Bones are heaped around a fallen reliquary. This is an off-road combat area; hostile creatures
+ remain here.
+exits:
+ east:
+ room: 3218
+objects:
+- id: rock_outcrop
+mobs:
+- id: zombie
diff --git a/internal/game/casino.go b/internal/game/casino.go
index 23b6c51..698cb78 100644
--- a/internal/game/casino.go
+++ b/internal/game/casino.go
@@ -19,14 +19,34 @@ import (
type casinoWallet struct {
g *Game
p *player.Player
+ // Optional per-wallet persistence seam for fault-injection tests.
+ saveCharacter func(*player.Player) error
+}
+
+// save treats a completed replacement as applied, even if its durability is
+// uncertain. Reverting memory then would disagree with the visible file and
+// could overwrite a paid win or resurrect a resolved stake on the next save.
+// Report the storage fault, but do not tell the game to retry/refund an
+// already-applied mutation. Only pre-replacement failures require rollback.
+func (w casinoWallet) save(operation string) error {
+ save := w.saveCharacter
+ if save == nil {
+ save = w.g.AccountStore.SaveCharacter
+ }
+ err := save(w.p)
+ if errors.Is(err, persistence.ErrDurabilityUncertain) {
+ fmt.Fprintf(os.Stderr, "casino %s: %s save durability uncertain: %v — keeping applied state\n", operation, w.p.Name, err)
+ return nil
+ }
+ return err
}
// Wager debits the stake and records it in PendingWagers in the SAME atomic
// character save. The entry stays until the round resolves: a settlement
// removes the stakes it returns (PayCredits) or consumes them
// (ResolveStake/ResolveStakes), and startup refunds anything still listed
-// (see recoverPendingWagers). A failed save reverts the in-memory debit and
-// ledger entry, so a player is never charged for a stake that is not durable.
+// (see recoverPendingWagers). A pre-replacement save failure reverts the
+// debit and ledger entry; an uncertain replacement keeps both (see save).
func (w casinoWallet) Wager(amount int) (casino.Wager, error) {
if amount <= 0 {
return casino.Wager{}, casino.ErrInsufficientFunds
@@ -46,16 +66,7 @@ func (w casinoWallet) Wager(amount int) (casino.Wager, error) {
w.p.Credits -= credits
pending := player.PendingWager{ID: newPendingWagerID(), Chips: chips, Credits: credits}
w.p.PendingWagers = append(w.p.PendingWagers, pending)
- if err := w.g.AccountStore.SaveCharacter(w.p); err != nil {
- if errors.Is(err, persistence.ErrDurabilityUncertain) {
- // The character file was replaced but its directory entry may not
- // be durable. The debit and the pending entry are in the visible
- // file, so keep them: a surviving save refunds the stake at
- // startup, and a lost one means the player still has the money.
- // Either way the stake is never charged twice.
- fmt.Fprintf(os.Stderr, "casino wager: %s save durability uncertain: %v — stake kept pending\n", w.p.Name, err)
- return casino.Wager{Total: amount, Chips: chips, Credits: credits, ID: pending.ID}, nil
- }
+ if err := w.save("wager"); err != nil {
// Revert the in-memory mutation: the play must not proceed on a
// stake that could not be made durable.
if chips > 0 {
@@ -78,15 +89,15 @@ func (w casinoWallet) Wager(amount int) (casino.Wager, error) {
// passes the hand's stake IDs so the credit and the stake return are one
// atomic step; a slot win passes its triggering stake for the same reason.
// Either way a crash can never pay the payout AND refund the same stake. A
-// failed save reverts both the credit and the ledger and reports persistence
-// failure, so the caller never announces a win that is not durable.
+// pre-replacement failure reverts both the credit and the ledger and reports
+// failure. An uncertain replacement is applied and logged (see save).
func (w casinoWallet) PayCredits(amount int, stakeIDs ...string) error {
return w.payCredits(amount, stakeIDs)
}
// payCredits credits the payout and, when stakeIDs is non-empty, removes
-// those stakes from the pending ledger in the same atomic save. On any
-// failure the credit and the ledger are reverted together.
+// those stakes from the pending ledger in the same atomic save. On a
+// pre-replacement failure the credit and the ledger are reverted together.
func (w casinoWallet) payCredits(amount int, stakeIDs []string) error {
if amount <= 0 && len(stakeIDs) == 0 {
return nil
@@ -101,7 +112,7 @@ func (w casinoWallet) payCredits(amount int, stakeIDs []string) error {
removed = takePendingWagers(w.p, stakeIDs)
}
w.p.Credits = sum
- if err := w.g.AccountStore.SaveCharacter(w.p); err != nil {
+ if err := w.save("payout"); err != nil {
w.p.Credits = creditsBefore
w.p.PendingWagers = append(w.p.PendingWagers, removed...)
return casino.ErrWalletPersistence
@@ -118,7 +129,7 @@ func (w casinoWallet) ResolveStakes() {
}
before := append([]player.PendingWager(nil), w.p.PendingWagers...)
w.p.PendingWagers = nil
- if err := w.g.AccountStore.SaveCharacter(w.p); err != nil {
+ if err := w.save("resolve stakes"); err != nil {
// Keep the in-memory ledger consistent with the durable file: the
// stakes are still pending on disk, so restore them for a later
// retry or startup recovery instead of silently diverging.
@@ -139,7 +150,7 @@ func (w casinoWallet) ResolveStake(stakeID string) {
if len(removed) == 0 {
return
}
- if err := w.g.AccountStore.SaveCharacter(w.p); err != nil {
+ if err := w.save("resolve stake"); err != nil {
// The durable file still lists the stake, so restore it in memory to
// keep the two records consistent for a later retry/recovery.
w.p.PendingWagers = append(w.p.PendingWagers, removed...)
@@ -159,7 +170,7 @@ func (w casinoWallet) ResolveStakesByIDs(stakeIDs ...string) {
if len(removed) == 0 {
return
}
- if err := w.g.AccountStore.SaveCharacter(w.p); err != nil {
+ if err := w.save("resolve stakes"); err != nil {
// The durable file still lists the stakes, so restore them in memory to
// keep the two records consistent for a later retry/recovery.
w.p.PendingWagers = append(w.p.PendingWagers, removed...)
@@ -169,9 +180,9 @@ func (w casinoWallet) ResolveStakesByIDs(stakeIDs ...string) {
// RefundOutstanding returns every pending stake to the player — chips in
// kind, credits as credits — and clears the ledger in one save. It is used
-// by graceful shutdown/eviction and by a pre-deal disconnect. On a failed
-// save the in-memory return and ledger are reverted so a later attempt (or
-// startup recovery) retries cleanly.
+// by graceful shutdown/eviction and by a pre-deal disconnect. A pre-replacement
+// failure reverts the return and ledger for retry; an uncertain replacement
+// keeps both applied (see save).
func (w casinoWallet) RefundOutstanding() (chips, credits int, err error) {
before := append([]player.PendingWager(nil), w.p.PendingWagers...)
for _, pending := range before {
@@ -198,7 +209,7 @@ func (w casinoWallet) RefundOutstanding() (chips, credits int, err error) {
return 0, 0, casino.ErrWalletPersistence
}
w.p.Credits = sum
- if err := w.g.AccountStore.SaveCharacter(w.p); err != nil {
+ if err := w.save("refund"); err != nil {
w.p.Credits = creditsBefore
if chips > 0 {
w.p.RemoveItem("chips", chips)
diff --git a/internal/game/casino_durability_test.go b/internal/game/casino_durability_test.go
new file mode 100644
index 0000000..227d391
--- /dev/null
+++ b/internal/game/casino_durability_test.go
@@ -0,0 +1,135 @@
+package game
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "reflect"
+ "testing"
+
+ "thehouseoficarus/internal/casino"
+ "thehouseoficarus/internal/persistence"
+ "thehouseoficarus/internal/player"
+)
+
+// Exercise every wallet mutation with both pre-replacement and post-replacement
+// failures. The latter writes the actual character file, then reports an
+// uncertain result, matching a failed directory fsync or post-save chmod.
+func TestCasinoWalletSaveFailureConsistency(t *testing.T) {
+ type balance struct {
+ credits, chips int
+ pending map[string]player.PendingWager
+ }
+ state := func(p *player.Player) balance {
+ b := balance{credits: p.Credits, chips: countChips(p), pending: make(map[string]player.PendingWager)}
+ for _, stake := range p.PendingWagers {
+ b.pending[stake.ID] = stake
+ }
+ return b
+ }
+ tests := []struct {
+ name string
+ run func(casinoWallet) error
+ reportsError bool
+ credits, chips, stakes int
+ }{
+ {"wager", func(w casinoWallet) error {
+ _, err := w.Wager(4)
+ return err
+ }, true, 68, 0, 4},
+ {"payout", func(w casinoWallet) error { return w.PayCredits(40, "a", "b") }, true, 110, 2, 1},
+ {"unlinked payout", func(w casinoWallet) error { return w.PayCredits(20) }, true, 90, 2, 3},
+ {"resolve all", func(w casinoWallet) error { w.ResolveStakes(); return nil }, false, 70, 2, 0},
+ {"resolve one", func(w casinoWallet) error { w.ResolveStake("a"); return nil }, false, 70, 2, 2},
+ {"resolve batch", func(w casinoWallet) error { w.ResolveStakesByIDs("a", "b"); return nil }, false, 70, 2, 1},
+ {"refund", func(w casinoWallet) error {
+ chips, credits, err := w.RefundOutstanding()
+ if err == nil && (chips != 5 || credits != 30) {
+ return fmt.Errorf("refund = %d chips, %d credits; want 5, 30", chips, credits)
+ }
+ return err
+ }, true, 100, 7, 0},
+ }
+ for _, tt := range tests {
+ for _, replaced := range []bool{false, true} {
+ t.Run(fmt.Sprintf("%s/replaced=%t", tt.name, replaced), func(t *testing.T) {
+ dir := t.TempDir()
+ if err := os.MkdirAll(filepath.Join(dir, "players", "characters"), 0700); err != nil {
+ t.Fatal(err)
+ }
+ store := player.NewAccountStore(dir)
+ g := &Game{Deps: Deps{AccountStore: store}}
+ p := player.New("alice")
+ p.Credits = 70
+ p.SetInvSlot(0, &player.InventorySlot{ItemID: "chips", Quantity: 2})
+ p.PendingWagers = []player.PendingWager{
+ {ID: "a", Credits: 10, Chips: 5},
+ {ID: "b", Credits: 10},
+ {ID: "c", Credits: 10},
+ }
+ if err := store.SaveCharacter(p); err != nil {
+ t.Fatal(err)
+ }
+ before := state(p)
+ calls := 0
+ w := casinoWallet{g: g, p: p, saveCharacter: func(p *player.Player) error {
+ calls++
+ if !replaced {
+ return errors.New("injected failure before replacement")
+ }
+ if err := store.SaveCharacter(p); err != nil {
+ t.Fatal(err)
+ }
+ return fmt.Errorf("injected directory sync failure: %w", persistence.ErrDurabilityUncertain)
+ }}
+ err := tt.run(w)
+ if calls != 1 {
+ t.Fatalf("save calls = %d, want 1", calls)
+ }
+ if !replaced && tt.reportsError {
+ if !errors.Is(err, casino.ErrWalletPersistence) {
+ t.Fatalf("error = %v, want ErrWalletPersistence", err)
+ }
+ } else if err != nil {
+ t.Fatal(err)
+ }
+ if replaced {
+ if p.Credits != tt.credits || countChips(p) != tt.chips || len(p.PendingWagers) != tt.stakes {
+ t.Fatalf("applied state = %+v; want credits=%d chips=%d stakes=%d", state(p), tt.credits, tt.chips, tt.stakes)
+ }
+ } else if !reflect.DeepEqual(state(p), before) {
+ t.Fatalf("failed replacement changed money: got %+v, want %+v", state(p), before)
+ }
+ disk, err := store.LoadCharacter(p.Name)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !reflect.DeepEqual(state(p), state(disk)) {
+ t.Fatalf("memory = %+v; visible file = %+v", state(p), state(disk))
+ }
+
+ // A later ordinary save must not erase the payout or resurrect
+ // its stakes. Recovery refunds only the remaining ledger, once.
+ wantCredits, wantChips := disk.Credits, countChips(disk)
+ for _, stake := range disk.PendingWagers {
+ wantCredits += stake.Credits
+ wantChips += stake.Chips
+ }
+ if err := store.SaveCharacter(p); err != nil {
+ t.Fatal(err)
+ }
+ for i := 0; i < 2; i++ {
+ g.recoverPendingWagers()
+ disk, err = store.LoadCharacter(p.Name)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if disk.Credits != wantCredits || countChips(disk) != wantChips || len(disk.PendingWagers) != 0 {
+ t.Fatalf("recovery %d = %+v; want credits=%d chips=%d no stakes", i, state(disk), wantCredits, wantChips)
+ }
+ }
+ })
+ }
+ }
+}
diff --git a/internal/game/content_refs.go b/internal/game/content_refs.go
index d3328a1..0608f9e 100644
--- a/internal/game/content_refs.go
+++ b/internal/game/content_refs.go
@@ -11,8 +11,8 @@ package game
const (
// jailRoomID is the destination of the stall-guard's "Take me to jail"
// step in act_steal.go.
- jailRoomID = 99999162
+ jailRoomID = 5133
// estateNeighborhoodID is the local-neighborhood house room used by the
// construction/estate directory flow in cmd_estate_directory.go.
- estateNeighborhoodID = 99999300
+ estateNeighborhoodID = 3131
)
diff --git a/internal/game/vesta_world_test.go b/internal/game/vesta_world_test.go
new file mode 100644
index 0000000..50e799c
--- /dev/null
+++ b/internal/game/vesta_world_test.go
@@ -0,0 +1,379 @@
+package game
+
+import (
+ "path/filepath"
+ "strings"
+ "testing"
+
+ "thehouseoficarus/internal/item"
+ "thehouseoficarus/internal/object"
+ "thehouseoficarus/internal/validate"
+ "thehouseoficarus/internal/world"
+)
+
+// Load authored content without starting a server, migrating characters or
+// recovering the live economy journal. World-building tests must be read-only.
+func loadVesta(t *testing.T) (*Game, map[int]*world.Room, map[int]string) {
+ t.Helper()
+ dir := filepath.Join("..", "..", "data")
+ g := &Game{Deps: Deps{
+ DataDir: dir, World: world.New(dir), MobStore: world.NewMobStore(dir),
+ ObjectStore: object.NewObjectStore(dir), ItemStore: item.NewItemStore(dir),
+ CourseStore: NewCourseStore(dir),
+ }}
+ rooms := map[int]*world.Room{}
+ zones := map[int]string{}
+ for id := range g.World.RoomIndex() {
+ r, err := g.World.LoadRoom(id)
+ if err != nil {
+ t.Fatalf("room %d: %v", id, err)
+ }
+ rooms[id] = r
+ path, _ := g.World.GetRoomPath(id)
+ zones[id] = filepath.Base(filepath.Dir(path))
+ }
+ return g, rooms, zones
+}
+
+func vestaCity(zone string) bool {
+ switch zone {
+ case "numisia", "brumalia", "tuccia", "domita", "casino":
+ return true
+ }
+ return false
+}
+
+func safeVestaRooms(t *testing.T, g *Game, rooms map[int]*world.Room) map[int]bool {
+ t.Helper()
+ safe := map[int]bool{}
+ for id, r := range rooms {
+ safe[id] = r.Hazard == ""
+ for _, spawn := range r.Mobs {
+ mob, err := g.MobStore.LoadDef(spawn.ID)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if mob.Combat != nil && mob.Combat.Aggressive {
+ safe[id] = false
+ if spawn.WanderInterval != 0 || len(spawn.WanderRooms) != 0 {
+ t.Errorf("room %d: hostile %s must not wander onto safe routes", id, spawn.ID)
+ }
+ }
+ }
+ }
+ return safe
+}
+
+func vestaWalk(rooms map[int]*world.Room, safe map[int]bool, start int) map[int]bool {
+ seen := map[int]bool{start: true}
+ queue := []int{start}
+ for len(queue) > 0 {
+ id := queue[0]
+ queue = queue[1:]
+ for _, exit := range rooms[id].Exits {
+ if exit.Condition != nil || exit.Hidden || exit.AlwaysBlocked || !safe[exit.Room] || seen[exit.Room] {
+ continue
+ }
+ seen[exit.Room] = true
+ queue = append(queue, exit.Room)
+ }
+ }
+ return seen
+}
+
+func TestVestaGeographyAndSafeTravel(t *testing.T) {
+ g, rooms, zones := loadVesta(t)
+ grid := world.BuildGrid(1001, func(id int) (*world.Room, bool) {
+ r, ok := rooms[id]
+ return r, ok
+ }, nil, nil, func(conflict world.GridConflict) {
+ t.Errorf("inconsistent world grid: %+v", conflict)
+ })
+ if len(grid.Coord) != len(rooms) {
+ t.Errorf("only %d/%d rooms connected to the retained introduction", len(grid.Coord), len(rooms))
+ }
+ for _, id := range []int{1001, 1002, 1003} {
+ if rooms[id] == nil {
+ t.Fatalf("retained intro room %d missing", id)
+ }
+ }
+ for id, zone := range zones {
+ if zone == "intro" && (id < 1001 || id > 1003) || id >= 999991 {
+ t.Errorf("placeholder room %d remains", id)
+ }
+ }
+ // Map Y decreases northward. These relative positions are part of the brief.
+ num, fields := grid.Coord[1104], grid.Coord[1306]
+ brum, forest := grid.Coord[2104], grid.Coord[4100]
+ tuccia, domita := grid.Coord[3104], grid.Coord[5104]
+ if fields[1] >= num[1] || brum[0] <= num[0] || forest[0] >= num[0] || tuccia[1] <= forest[1] || domita[0] >= forest[0] || domita[1] >= forest[1] {
+ t.Fatal("region no longer follows the requested city geography")
+ }
+ safe := safeVestaRooms(t, g, rooms)
+ walkable := vestaWalk(rooms, safe, 1104)
+ counts := map[string]int{}
+ for id, zone := range zones {
+ counts[zone]++
+ if vestaCity(zone) || zone == "roads" {
+ if !safe[id] {
+ t.Errorf("%s room %d is unsafe", zone, id)
+ }
+ // The house is the only ownership-gated city interior.
+ if id != estateNeighborhoodID && rooms[id].Name != "Tuccia — Home Workshop" && !walkable[id] {
+ t.Errorf("%s room %d requires a gate or dangerous detour", zone, id)
+ }
+ }
+ }
+ for _, zone := range []string{"numisia", "brumalia", "tuccia", "domita"} {
+ if counts[zone] < 30 {
+ t.Errorf("%s needs dozens of distinct rooms, got %d", zone, counts[zone])
+ }
+ }
+ for _, id := range []int{1306, 4100, 1201, 1207, 1212, 5207} {
+ if !walkable[id] {
+ t.Errorf("rural hub/resource destination %d has no safe all-level approach", id)
+ }
+ }
+ for _, course := range g.CourseStore.AllCourses() {
+ if !walkable[course.StartRoom] {
+ t.Errorf("course %s has an unsafe or gated approach", course.ID)
+ }
+ }
+}
+
+func TestVestaEarlySkillsAndSeparateServices(t *testing.T) {
+ g, rooms, zones := loadVesta(t)
+ gathers := map[string]map[int]bool{}
+ placed := map[string]bool{}
+ stock := map[string]bool{}
+ spawns := map[string]bool{}
+ for id, r := range rooms {
+ shops := 0
+ for _, spawn := range r.Mobs {
+ spawns[spawn.ID] = true
+ mob, err := g.MobStore.LoadDef(spawn.ID)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if mob.Shop != nil {
+ shops++
+ for _, entry := range mob.Shop.Items {
+ stock[entry.ItemID] = true
+ }
+ }
+ if c := mob.Combat; c != nil {
+ s := c.Stats
+ if c.AssassinLevel > 40 || s.Attack > 40 || s.Strength > 40 || s.Defense > 40 || s.Ranged > 40 || s.Science > 40 {
+ t.Errorf("room %d: %s is beyond this starting region's combat scope", id, spawn.ID)
+ }
+ }
+ if mob.Steal != nil && mob.Steal.Level > 40 {
+ t.Errorf("room %d: %s is beyond early Thieving progression", id, spawn.ID)
+ }
+ }
+ if shops > 1 {
+ t.Errorf("room %d crams %d vendors into one shop", id, shops)
+ }
+ for _, ref := range r.Objects {
+ if ref.Local != nil {
+ continue
+ }
+ placed[ref.ID] = true
+ obj, err := g.ObjectStore.Load(ref.ID)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if obj.Gather == nil {
+ continue
+ }
+ if vestaCity(zones[id]) {
+ t.Errorf("resource %s belongs outside city room %d", ref.ID, id)
+ }
+ if gathers[obj.Gather.Skill] == nil {
+ gathers[obj.Gather.Skill] = map[int]bool{}
+ }
+ for _, drop := range obj.Gather.Drops {
+ gathers[obj.Gather.Skill][drop.Level] = true
+ if drop.Level > 40 {
+ t.Errorf("room %d: %s yields level %d resources in the starting region", id, ref.ID, drop.Level)
+ }
+ }
+ }
+ }
+ for skill, levels := range map[string][]int{
+ "woodcutting": {1, 15, 30, 35}, "mining": {1, 15, 20, 30, 40},
+ "fishing": {1, 5, 20, 28, 35, 40}, "technology": {1, 10, 20, 30, 40},
+ } {
+ for _, level := range levels {
+ if !gathers[skill][level] {
+ t.Errorf("missing %s training tier %d", skill, level)
+ }
+ }
+ }
+ for _, id := range []string{
+ "furnace", "anvil", "workbench", "spinning_wheel", "pottery_wheel", "pottery_oven", "cooking_range",
+ "allotment_patch", "herb_patch", "flower_patch", "flax_bed", "sheep", "charging_station",
+ "terminal_basic", "terminal_advanced", "terminal_secure", "scrap_pile",
+ "solar_altar", "hydro_altar", "cosmic_altar", "eco_altar", "chaos_altar", "estate_directory",
+ } {
+ if !placed[id] {
+ t.Errorf("missing reachable skill station %s", id)
+ }
+ }
+ for _, id := range []string{
+ "bronze_axe", "bronze_pickaxe", "hammer", "knife", "matches", "small_fishing_net", "fishing_rod",
+ "fly_fishing_rod", "feather", "fishing_bait", "lobster_pot", "harpoon", "saw", "shears",
+ "needle", "thread", "chisel", "rake", "spade", "watering_can", "plant_cure", "vial", "eye_of_newt",
+ "solar_identifier", "hydro_identifier", "eco_identifier", "cosmic_identifier", "chaos_identifier",
+ "biojunk", "ecojunk", "lawjunk", "naturejunk", "salt", "acid_vial", "insulated_gloves",
+ } {
+ if !stock[id] {
+ t.Errorf("no vendor supplies required skill input %s", id)
+ }
+ }
+ for _, id := range []string{"apprentice_frame", "irrigation_frame", "harbor_winch", "survey_frame", "numisia_contracts", "tuccia_contracts", "domita_contracts"} {
+ if !spawns[id] {
+ t.Errorf("missing combat/Assassin activity %s", id)
+ }
+ }
+ levels := map[int]bool{}
+ for _, course := range g.CourseStore.AllCourses() {
+ levels[course.RequiredLevel] = true
+ if course.RequiredLevel > 40 {
+ t.Errorf("%s exceeds the starting-region scope", course.ID)
+ }
+ for _, obstacle := range course.Obstacles {
+ foundExit := false
+ for _, ref := range rooms[obstacle.RoomID].Objects {
+ if ref.Local != nil {
+ continue
+ }
+ obj, _ := g.ObjectStore.Load(ref.ID)
+ for _, trigger := range obj.OnUse {
+ for _, step := range trigger.Steps {
+ foundExit = foundExit || step.Teleport == course.StartRoom
+ }
+ }
+ }
+ if !foundExit {
+ t.Errorf("%s obstacle %d has no level-independent escape", course.ID, obstacle.RoomID)
+ }
+ }
+ }
+ for _, level := range []int{1, 10, 20, 30, 40} {
+ if !levels[level] {
+ t.Errorf("missing Agility tier %d", level)
+ }
+ }
+}
+
+func TestVestaCasinoFloorsAndVariants(t *testing.T) {
+ _, rooms, zones := loadVesta(t)
+ grid := world.BuildGrid(6102, func(id int) (*world.Room, bool) {
+ r, ok := rooms[id]
+ return r, ok
+ }, nil, nil, nil)
+ games := map[string]int{}
+ floors := map[int]int{}
+ future := 0
+ soft17, surrender, singleDeck, huff, classic := false, false, false, false, false
+ for id, r := range rooms {
+ if zones[id] != "casino" {
+ if len(r.CasinoTables)+len(r.CasinoMachines) > 0 {
+ t.Errorf("unexpected casino game outside Domita's casino: %d", id)
+ }
+ continue
+ }
+ floor := grid.Coord[id][2]
+ floors[floor]++
+ if strings.Contains(r.Name, "Future ") {
+ future++
+ }
+ count := len(r.CasinoTables) + len(r.CasinoMachines)
+ if count > 1 || count > 0 && floor != 0 {
+ t.Errorf("room %d: games must have individual ground-floor salons", id)
+ }
+ for _, table := range r.CasinoTables {
+ games[string(table.Game)]++
+ if table.Game == "blackjack" {
+ soft17 = soft17 || table.Blackjack.DealerHitSoft17 != nil && *table.Blackjack.DealerHitSoft17
+ surrender = surrender || table.Blackjack.Surrender != nil && *table.Blackjack.Surrender
+ singleDeck = singleDeck || table.Blackjack.Decks == 1
+ }
+ }
+ for _, machine := range r.CasinoMachines {
+ games[string(machine.Game)]++
+ huff = huff || machine.Variant == "huff_and_even_more_puff"
+ classic = classic || machine.Variant == ""
+ }
+ }
+ if games["blackjack"] < 5 || games["baccarat"] < 3 || games["slots"] < 5 || !soft17 || !surrender || !singleDeck || !huff || !classic {
+ t.Errorf("casino variant coverage lost: %v", games)
+ }
+ if future < 15 || floors[0] < 30 || floors[1] < 15 || floors[2] < 15 || floors[3] < 15 {
+ t.Errorf("casino needs a large ground floor and substantial expansion floors: floors=%v future=%d", floors, future)
+ }
+}
+
+func TestVestaTransportAndContractReferences(t *testing.T) {
+ g, rooms, _ := loadVesta(t)
+ // The older shipped-data test does not load modules. Explicitly include
+ // them here, otherwise deleted transport destinations can silently escape CI.
+ oldMods, oldByID := AllMods, modByID
+ oldTechs, oldTechByID := AllTechs, techByID
+ t.Cleanup(func() {
+ AllMods, modByID = oldMods, oldByID
+ AllTechs, techByID = oldTechs, oldTechByID
+ })
+ if err := g.LoadMods(); err != nil {
+ t.Fatal(err)
+ }
+ if err := g.LoadTechs(); err != nil {
+ t.Fatal(err)
+ }
+ g.ValidationConfig.RootRooms = []int{1001}
+ g.CourseStore.SetWorld(g.World)
+ for _, issue := range validate.Run(g.validationSource()) {
+ if issue.Level == "ERROR" {
+ t.Errorf("%s", issue.Message)
+ }
+ }
+ walkable := vestaWalk(rooms, safeVestaRooms(t, g, rooms), 1104)
+ for _, mod := range AllMods {
+ if mod.Category == ModTransport && !walkable[mod.Destination] {
+ t.Errorf("transport %s points to an unsafe/unreachable destination %d", mod.ID, mod.Destination)
+ }
+ }
+ spawns := map[string]bool{}
+ for _, r := range rooms {
+ for _, mob := range r.Mobs {
+ spawns[mob.ID] = true
+ }
+ }
+ for _, id := range []string{"numisia_contracts", "tuccia_contracts", "domita_contracts"} {
+ mob, _ := g.MobStore.LoadDef(id)
+ assignments := 0
+ for _, node := range mob.Talk.Nodes {
+ for _, option := range node.Options {
+ if option.Action == nil {
+ continue
+ }
+ flags := option.Action.SetPlayerFlags
+ target, _ := flags["assassin_task_mob"].(string)
+ if target == "" {
+ continue
+ }
+ assignments++
+ if !spawns[target] {
+ t.Errorf("%s assigns unplaced target %s", id, target)
+ }
+ if flags["assassin_task_remaining"] != flags["assassin_task_total"] || flags["assassin_task_total"] == nil {
+ t.Errorf("%s has an incomplete contract for %s", id, target)
+ }
+ }
+ }
+ if assignments == 0 {
+ t.Errorf("%s offers no functioning contracts", id)
+ }
+ }
+}
diff --git a/internal/persistence/txn.go b/internal/persistence/txn.go
index 9939204..400d355 100644
--- a/internal/persistence/txn.go
+++ b/internal/persistence/txn.go
@@ -64,9 +64,9 @@ type Transaction struct {
ops map[string]*fileOp
order []string
journalDir string
- // dirSync makes a journal directory entry durable (nil means syncDir).
- // It is a field rather than a package-level function so a test can
- // assert that the commit point is synced and inject a sync failure.
+ // dirSync makes directory mutations durable (nil means syncDir).
+ // Per-transaction so tests can check ordering and inject failures
+ // without changing a package-global hook.
dirSync func(string) error
}
@@ -82,12 +82,31 @@ func syncDir(dir string) error {
return d.Sync()
}
-// syncJournalDir syncs the transaction's journal directory.
-func (t *Transaction) syncJournalDir() error {
+func (t *Transaction) syncDirectory(dir string) error {
if t.dirSync != nil {
- return t.dirSync(t.journalDir)
+ return t.dirSync(dir)
}
- return syncDir(t.journalDir)
+ return syncDir(dir)
+}
+
+// removeFileDurable also syncs an already-absent file's parent: recovery may
+// be retrying a deletion whose previous directory sync failed. A missing
+// parent needs no sync because this transaction does not create directories.
+func (t *Transaction) removeFileDurable(path string) error {
+ err := os.Remove(path)
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+ dir := filepath.Dir(path)
+ if os.IsNotExist(err) {
+ if _, statErr := os.Stat(dir); os.IsNotExist(statErr) {
+ return nil
+ }
+ }
+ if err := t.syncDirectory(dir); err != nil {
+ return fmt.Errorf("sync directory %s after delete: %w", dir, err)
+ }
+ return nil
}
// removeJournalDurable unlinks a journal and syncs its directory, so the
@@ -101,7 +120,7 @@ func (t *Transaction) removeJournalDurable(path string) error {
for attempt := 0; attempt < journalRemoveAttempts; attempt++ {
removeErr = os.Remove(path)
if removeErr == nil || os.IsNotExist(removeErr) {
- if err := t.syncJournalDir(); err != nil {
+ if err := t.syncDirectory(t.journalDir); err != nil {
return fmt.Errorf("journal %s removed but its directory could not be synced (a crash may resurrect the journal and roll the transaction back): %w", path, err)
}
return nil
@@ -291,7 +310,7 @@ func (t *Transaction) apply() error {
return fmt.Errorf("write %s: %w", op.Path, err)
}
case kindDelete:
- if err := os.Remove(op.Path); err != nil && !os.IsNotExist(err) {
+ if err := t.removeFileDurable(op.Path); err != nil {
return fmt.Errorf("delete %s: %w", op.Path, err)
}
case kindMove:
@@ -306,6 +325,17 @@ func (t *Transaction) apply() error {
if err := os.Rename(op.Path, op.MoveTo); err != nil {
return fmt.Errorf("move %s: %w", op.Path, err)
}
+ // A cross-directory rename changes both directory entries. Make
+ // both durable before the recovery journal can be retired.
+ srcDir, dstDir := filepath.Dir(op.Path), filepath.Dir(op.MoveTo)
+ if err := t.syncDirectory(srcDir); err != nil {
+ return fmt.Errorf("sync move source directory %s: %w", srcDir, err)
+ }
+ if dstDir != srcDir {
+ if err := t.syncDirectory(dstDir); err != nil {
+ return fmt.Errorf("sync move destination directory %s: %w", dstDir, err)
+ }
+ }
case kindMoveTarget:
// Content replace after the move delivered the source bytes.
if op.NewExists {
@@ -333,21 +363,13 @@ func (t *Transaction) rollback() error {
if op.OldExists {
return WriteFile(path, op.Old, os.FileMode(op.OldMode))
}
- return os.Remove(path)
+ return t.removeFileDurable(path)
}
switch op.Kind {
- case kindMove, kindMoveTarget:
- if err := restore(op.Path); err != nil && !os.IsNotExist(err) {
- record(fmt.Errorf("restore %s: %w", op.Path, err))
- }
- case kindReplace:
+ case kindMove, kindMoveTarget, kindReplace, kindDelete:
if err := restore(op.Path); err != nil {
record(fmt.Errorf("restore %s: %w", op.Path, err))
}
- case kindDelete:
- if err := restore(op.Path); err != nil && !os.IsNotExist(err) {
- record(fmt.Errorf("restore %s: %w", op.Path, err))
- }
}
}
return firstErr
diff --git a/internal/persistence/txn_directory_durability_test.go b/internal/persistence/txn_directory_durability_test.go
new file mode 100644
index 0000000..134580e
--- /dev/null
+++ b/internal/persistence/txn_directory_durability_test.go
@@ -0,0 +1,175 @@
+package persistence
+
+import (
+ "errors"
+ "os"
+ "path/filepath"
+ "reflect"
+ "strings"
+ "testing"
+)
+
+func TestTransactionSyncsChangedDirectoriesBeforeCommit(t *testing.T) {
+ for _, operation := range []string{"delete", "move same directory", "move across directories"} {
+ t.Run(operation, func(t *testing.T) {
+ dir := t.TempDir()
+ journalDir := filepath.Join(dir, ".journal")
+ srcDir := filepath.Join(dir, "source")
+ dstDir := srcDir
+ if operation == "move across directories" {
+ dstDir = filepath.Join(dir, "destination")
+ }
+ src, dst := filepath.Join(srcDir, "a.yaml"), filepath.Join(dstDir, "b.yaml")
+ writeTestFile(t, src, "source")
+ writeTestFile(t, dst, "destination")
+ txn := NewTransaction(journalDir)
+ var err error
+ if operation == "delete" {
+ err = txn.Delete(src)
+ } else {
+ err = txn.Move(src, dst)
+ }
+ if err != nil {
+ t.Fatal(err)
+ }
+ var synced []string
+ txn.dirSync = func(d string) error {
+ entries, err := ListJournalFiles(journalDir)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if d != journalDir && len(entries) != 1 {
+ t.Fatal("journal retired before data directory sync")
+ }
+ if d == journalDir && len(entries) != 0 {
+ t.Fatal("commit point did not remove journal")
+ }
+ if _, err := os.Stat(src); !os.IsNotExist(err) {
+ t.Fatalf("sync must follow deletion/rename: %v", err)
+ }
+ synced = append(synced, d)
+ return syncDir(d)
+ }
+ if err := txn.Commit(); err != nil {
+ t.Fatal(err)
+ }
+ want := []string{srcDir}
+ if dstDir != srcDir {
+ want = append(want, dstDir)
+ }
+ want = append(want, journalDir)
+ if !reflect.DeepEqual(synced, want) {
+ t.Fatalf("sync order = %v, want %v", synced, want)
+ }
+ if operation != "delete" && readTestFile(t, dst) != "source" {
+ t.Fatal("move did not replace destination")
+ }
+ })
+ }
+}
+
+func TestTransactionDataSyncFailureRollsBack(t *testing.T) {
+ for _, failAt := range []string{"delete", "move source", "move destination"} {
+ t.Run(failAt, func(t *testing.T) {
+ dir := t.TempDir()
+ journalDir := filepath.Join(dir, ".journal")
+ srcDir, dstDir := filepath.Join(dir, "source"), filepath.Join(dir, "destination")
+ src, dst := filepath.Join(srcDir, "a.yaml"), filepath.Join(dstDir, "b.yaml")
+ writeTestFile(t, src, "source")
+ writeTestFile(t, dst, "destination")
+ txn := NewTransaction(journalDir)
+ var err error
+ if failAt == "delete" {
+ err = txn.Delete(src)
+ } else {
+ err = txn.Move(src, dst)
+ }
+ if err != nil {
+ t.Fatal(err)
+ }
+ failed := false
+ fault := errors.New("injected data directory sync failure")
+ txn.dirSync = func(d string) error {
+ failDir := srcDir
+ if failAt == "move destination" {
+ failDir = dstDir
+ }
+ if d == failDir {
+ failed = true
+ return fault
+ }
+ // Restoring existing before-images uses WriteFile, which
+ // already syncs their directories before journal removal.
+ if d == journalDir && (readTestFile(t, src) != "source" || readTestFile(t, dst) != "destination") {
+ t.Fatal("journal retired before rollback restored files")
+ }
+ return syncDir(d)
+ }
+ if err := txn.Commit(); !errors.Is(err, fault) || !failed {
+ t.Fatalf("commit error = %v, fault injected = %t", err, failed)
+ }
+ entries, err := ListJournalFiles(journalDir)
+ if err != nil || len(entries) != 0 {
+ t.Fatalf("successful rollback should retire journal: %v, %v", entries, err)
+ }
+ })
+ }
+}
+
+func TestRollbackDeletionSyncFailureRetainsJournalAndRetries(t *testing.T) {
+ dir := t.TempDir()
+ journalDir := filepath.Join(dir, ".journal")
+ createdDir, failDir := filepath.Join(dir, "created"), filepath.Join(dir, "fail")
+ if err := os.Mkdir(createdDir, 0700); err != nil {
+ t.Fatal(err)
+ }
+ created, deleted := filepath.Join(createdDir, "new.yaml"), filepath.Join(failDir, "old.yaml")
+ writeTestFile(t, deleted, "before")
+ txn := NewTransaction(journalDir)
+ if err := txn.Replace(created, []byte("new"), 0600); err != nil {
+ t.Fatal(err)
+ }
+ if err := txn.Delete(deleted); err != nil {
+ t.Fatal(err)
+ }
+ var synced []string
+ txn.dirSync = func(d string) error {
+ synced = append(synced, d)
+ return errors.New("injected directory sync failure")
+ }
+ if err := txn.Commit(); err == nil || !strings.Contains(err.Error(), "rollback failed") {
+ t.Fatalf("expected apply and rollback sync failures, got %v", err)
+ }
+ if !reflect.DeepEqual(synced, []string{failDir, createdDir}) {
+ t.Fatalf("syncs = %v; missing rollback deletion barrier", synced)
+ }
+ if _, err := os.Stat(created); !os.IsNotExist(err) {
+ t.Fatalf("rollback should have removed created file: %v", err)
+ }
+ if entries, err := ListJournalFiles(journalDir); err != nil || len(entries) != 1 {
+ t.Fatalf("failed rollback must retain journal: %v, %v", entries, err)
+ }
+
+ // Retry the same rollback with the file already absent: skipping its
+ // directory sync would incorrectly retire an undurable deletion.
+ synced = nil
+ txn.dirSync = func(d string) error {
+ synced = append(synced, d)
+ return syncDir(d)
+ }
+ if err := txn.rollback(); err != nil {
+ t.Fatal(err)
+ }
+ if !reflect.DeepEqual(synced, []string{createdDir}) {
+ t.Fatalf("retry syncs = %v, want %s", synced, createdDir)
+ }
+ if err := Recover(journalDir); err != nil {
+ t.Fatal(err)
+ }
+ if readTestFile(t, deleted) != "before" {
+ t.Fatal("recovery did not restore deleted file")
+ }
+ if entries, err := ListJournalFiles(journalDir); err != nil || len(entries) != 0 {
+ t.Fatalf("recovery did not retire journal: %v, %v", entries, err)
+ }
+}