Settlers scale with empty homes: fast catch-up, slowing near full

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-10-19 20:35:15 +01:00
parent 8fbab37a56
commit 632a12e8bc
3 changed files with 11 additions and 10 deletions

View file

@ -35,8 +35,8 @@ Alpha. One season, bandit raids plus two friendly events, six buildings.
Construction also saws planks, which higher building levels need, and Construction also saws planks, which higher building levels need, and
builds fittings from them: one-off upgrades a building takes once it's high builds fittings from them: one-off upgrades a building takes once it's high
enough (shelving, a well pump, weapon racks, enchanted chests…). Population eats food, enough (shelving, a well pump, weapon racks, enchanted chests…). Population eats food,
pays taxes, and fills the houses (empty homes draw settlers, about a pays taxes, and fills the houses (empty homes draw settlers, half of
quarter of all homes a day, plus slow family growth); it promotes the settlement them a day, so it slows as the houses fill, plus slow family growth); it promotes the settlement
(hamlet, village at 40, town at 90, city at 150), which raises building (hamlet, village at 40, town at 90, city at 150), which raises building
level caps and gives everyone bank slots. level caps and gives everyone bank slots.
- **Prayer:** enemies drop bones; burying them gives prayer points and - **Prayer:** enemies drop bones; burying them gives prayer points and

View file

@ -482,9 +482,9 @@ TIERS = [
{"name": "City", "pop": 150, "cap": 99, "houses": 8}, {"name": "City", "pop": 150, "cap": 99, "houses": 8},
] ]
TIER_SLOTS = 2 TIER_SLOTS = 2
# Growth: empty homes draw settlers (a share of all the homes, every day, while # Growth: empty homes draw settlers, fast while many stand empty and slower as
# any stand empty), and families grow a little on their own. # they fill, and families grow a little on their own however full the city is.
SETTLERS_PER_HOME = 0.25 SETTLERS_PER_EMPTY_HOME = 0.5
FAMILY_GROWTH = 0.05 FAMILY_GROWTH = 0.05
RAID_GROUPS = ["the Red Hand", "the Hollow Crows", "the Blackwater gang", "the Ashen Wolves", RAID_GROUPS = ["the Red Hand", "the Hollow Crows", "the Blackwater gang", "the Ashen Wolves",
@ -1437,7 +1437,7 @@ def _start_next(world: dict, now: float) -> None:
def growth_per_day(world: dict) -> float: def growth_per_day(world: dict) -> float:
"""New townsfolk a day while there's room: settlers for the homes, plus families.""" """New townsfolk a day while there's room: settlers for the homes, plus families."""
pop = world["city"]["population"] pop = world["city"]["population"]
growth = SETTLERS_PER_HOME * housing(world) + FAMILY_GROWTH * pop growth = SETTLERS_PER_EMPTY_HOME * max(0.0, housing(world) - pop) + FAMILY_GROWTH * pop
return growth * city_rate(world, "growth") * (1.25 if fitted(world, "furniture") else 1) return growth * city_rate(world, "growth") * (1.25 if fitted(world, "furniture") else 1)

View file

@ -315,13 +315,14 @@ class CityTest(unittest.TestCase):
city["population"] = 22.0 city["population"] = 22.0
city["buildings"]["houses"]["level"] = 2 city["buildings"]["houses"]["level"] = 2
city["stockpile"] = {"bread": 10_000} city["stockpile"] = {"bread": 10_000}
self.assertAlmostEqual(game.growth_per_day(world), 0.25 * 65 + 0.05 * 22) self.assertAlmostEqual(game.growth_per_day(world), 0.5 * 43 + 0.05 * 22)
for _hour in range(24): for _hour in range(24):
game._city_hour(world, T0) game._city_hour(world, T0)
self.assertGreater(city["population"], 38) self.assertGreater(city["population"], 38)
for _hour in range(48): # Slower as the homes fill, but never down to nothing.
game._city_hour(world, T0) self.assertLess(game.growth_per_day(world), 0.5 * 43)
self.assertEqual(city["population"], 65) city["population"] = 64.0
self.assertAlmostEqual(game.growth_per_day(world), 0.5 + 3.2)
def test_fed_city_grows_to_housing_and_pays_tax(self): def test_fed_city_grows_to_housing_and_pays_tax(self):
world = world_with() world = world_with()