From 656693cc84d59ca151a56d1c6e070d733576fe6d Mon Sep 17 00:00:00 2001 From: rope Date: Sun, 18 Oct 2026 22:41:11 +0100 Subject: [PATCH] Council sells useless stockpile items into the treasury Co-Authored-By: Claude Opus 5.5 --- game.py | 21 ++++++++++++++++++++- tests/test_game.py | 11 +++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/game.py b/game.py index 5187793..fac4b93 100644 --- a/game.py +++ b/game.py @@ -379,7 +379,7 @@ RAID_TRAITS = ["lightly armoured, heavy on archers", "mounted and fast, few bows # --- world --------------------------------------------------------------- -WORLD_VERSION = 3 +WORLD_VERSION = 4 def new_world(now: float, speed: float = 1.0) -> dict: @@ -429,9 +429,28 @@ def migrate(world: dict) -> dict: player.setdefault("hp", max_hp(player)) player.setdefault("hp_at", now) world["version"] = 3 + if world["version"] < 4: + _sell_useless_stock(world, world["city"]["last_tick"]) + world["version"] = 4 return world +def _sell_useless_stock(world: dict, now: float) -> None: + """The council sells what the city can't use, into the treasury.""" + city = world["city"] + sold = {item: qty for item, qty in city["stockpile"].items() if item in ITEMS and not city_uses(item)} + if not sold: + return + gold = sum(qty * ITEMS[item]["value"] for item, qty in sold.items()) + for item in sold: + del city["stockpile"][item] + city["treasury"] += gold + names = [amount(i, q) for i, q in sold.items()] + names = ", ".join(names[:-1]) + " and " + names[-1] if len(names) > 1 else names[0] + log(world, now, "city", f"The council sold {names} " + f"from the stockpile for {gold:,} gold") + + def speed(world: dict) -> float: return world["config"]["speed"] diff --git a/tests/test_game.py b/tests/test_game.py index 68d4037..629e776 100644 --- a/tests/test_game.py +++ b/tests/test_game.py @@ -265,6 +265,17 @@ class CityTest(unittest.TestCase): self.assertEqual(world["city"]["queue"], []) self.assertEqual(world["city"]["buildings"]["walls"]["fund"], {}) + def test_v3_worlds_sell_useless_stock_into_the_treasury(self): + world = world_with() + world["version"] = 3 + world["city"]["stockpile"] = {"copper_ore": 8, "raw_meat": 1, "bricks": 500, "bread": 30} + world["city"]["treasury"] = 10 + game.migrate(world) + self.assertEqual(world["city"]["stockpile"], {"bricks": 500, "bread": 30}) + self.assertEqual(world["city"]["treasury"], 10 + 8 * 2 + 1 * 2) + self.assertEqual(world["ledger"][-1]["text"], + "The council sold 8 copper ore and 1 raw meat from the stockpile for 18 gold") + def test_population_view_explains_growth(self): world = world_with() view = game.population_view(world)