From 70246f78eabebe434b01e2b2129dad3c44d486e9 Mon Sep 17 00:00:00 2001 From: rope Date: Mon, 19 Oct 2026 09:42:36 +0100 Subject: [PATCH] Count days and seasons by calendar day Co-Authored-By: Claude Opus 5.5 --- app.py | 2 +- game.py | 17 ++++++++++++++--- tests/test_game.py | 8 ++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/app.py b/app.py index 126c6f4..78a7011 100644 --- a/app.py +++ b/app.py @@ -149,7 +149,7 @@ def city_view(world: dict, now: float) -> dict: "merchant_until": city.get("merchant_until", 0), "repelled": city["repelled"], "defence": game.defence(world), - "day": int((now - world["created"]) * game.speed(world) // game.DAY) + 1, + "day": game.calendar_day(world, now) + 1, } diff --git a/game.py b/game.py index 21b39ab..7751b97 100644 --- a/game.py +++ b/game.py @@ -10,6 +10,7 @@ from __future__ import annotations import math import random +from datetime import date HOUR = 3600 DAY = 24 * HOUR @@ -1881,11 +1882,21 @@ FORTUNES = {"merchant": [12] * 4, "refugees": [10] * 4, "master": [16] * 4, "har TRACK_HOURS = {"minor": (48, 96), "hardship": (48, 96), "fortune": (36, 72)} +def calendar_day(world: dict, now: float) -> int: + """Days since the world began, counting midnights in the server's timezone (0 on the first day). + + A sped-up dev world has no calendar to speak of, so it counts 24-hour stretches instead. + """ + if speed(world) != 1: + return int((now - world["created"]) * speed(world) // DAY) + return (date.fromtimestamp(now) - date.fromtimestamp(world["created"])).days + + def season(world: dict, now: float) -> dict: - day = (now - world["created"]) * speed(world) / DAY - index = int(day // SEASON_DAYS) % len(SEASONS) + day = calendar_day(world, now) + index = day // SEASON_DAYS % len(SEASONS) name, icon = SEASONS[index] - return {"index": index, "name": name, "icon": icon, "day": int(day % SEASON_DAYS) + 1} + return {"index": index, "name": name, "icon": icon, "day": day % SEASON_DAYS + 1} def _pick(weights: dict, rng: random.Random) -> str: diff --git a/tests/test_game.py b/tests/test_game.py index 5b80b9a..1fdcd23 100644 --- a/tests/test_game.py +++ b/tests/test_game.py @@ -848,6 +848,14 @@ class HappeningsTest(unittest.TestCase): self.assertEqual(game.season(self.world, T0 + 8 * game.DAY)["name"], "Summer") self.assertEqual(game.season(self.world, T0 + 22 * game.DAY)["name"], "Winter") + def test_days_count_midnights_not_24_hour_stretches(self): + from datetime import datetime + late = datetime(2026, 10, 18, 23, 0).timestamp() + world = game.new_world(late) + self.assertEqual(game.calendar_day(world, late + 1800), 0) # 23:30 the same evening + self.assertEqual(game.calendar_day(world, late + 2 * 3600), 1) # 01:00 the next morning + self.assertEqual(game.season(world, late + 2 * 3600)["day"], 2) + def test_weather_changes_skill_speed(self): p = self.world["players"]["ann"] farm = game.ACTION_BY_ID["farm_wheat"]