From 32f52ef7044b06c9086b658c94ae629d9ac4b157 Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Sat, 14 Feb 2026 15:46:34 -0500 Subject: [PATCH] Add time-of-day system with tests --- src/mudlib/timeofday.py | 70 +++++++++++++++++++++++++++++++++++++++++ tests/test_timeofday.py | 56 +++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 src/mudlib/timeofday.py create mode 100644 tests/test_timeofday.py diff --git a/src/mudlib/timeofday.py b/src/mudlib/timeofday.py new file mode 100644 index 0000000..a1b17c8 --- /dev/null +++ b/src/mudlib/timeofday.py @@ -0,0 +1,70 @@ +"""Time-of-day periods and atmospheric descriptions.""" + +from __future__ import annotations + + +def get_time_period(hour: int) -> str: + """Map a game hour (0-23) to a time period. + + Args: + hour: Game hour (0-23) + + Returns: + Time period: "dawn", "day", "dusk", or "night" + """ + if 5 <= hour <= 6: + return "dawn" + elif 7 <= hour <= 17: + return "day" + elif 18 <= hour <= 19: + return "dusk" + else: + return "night" + + +def get_sky_description(hour: int) -> str: + """Return an atmospheric one-liner for the current time of day. + + Args: + hour: Game hour (0-23) + + Returns: + Short atmospheric description based on time of day + """ + period = get_time_period(hour) + + # multiple variants per period, pick based on hour for determinism + descriptions = { + "dawn": [ + "pale light seeps across the horizon", + "the first rays of dawn touch the sky", + ], + "day": [ + "the sun hangs high overhead", + "bright daylight illuminates everything", + "warm light fills the air", + "midday light is at its strongest", + "golden afternoon light slants across the land", + "the day is bright and warm", + "light glints off distant surfaces", + "the sun begins its slow descent", + "late afternoon shadows grow longer", + "the sun drifts toward the western horizon", + "the day's light begins to soften", + ], + "dusk": [ + "the sky burns orange and violet", + "twilight deepens across the landscape", + ], + "night": [ + "stars wheel slowly overhead", + "darkness blankets the world", + "the night is deep and still", + "moonlight casts pale shadows", + "the hours before dawn stretch long and dark", + ], + } + + variants = descriptions[period] + # use hour to pick variant deterministically + return variants[hour % len(variants)] diff --git a/tests/test_timeofday.py b/tests/test_timeofday.py new file mode 100644 index 0000000..62e6b48 --- /dev/null +++ b/tests/test_timeofday.py @@ -0,0 +1,56 @@ +"""Tests for time-of-day system.""" + +from mudlib.timeofday import get_sky_description, get_time_period + + +def test_get_time_period_dawn(): + assert get_time_period(5) == "dawn" + assert get_time_period(6) == "dawn" + + +def test_get_time_period_day(): + assert get_time_period(7) == "day" + assert get_time_period(12) == "day" + assert get_time_period(17) == "day" + + +def test_get_time_period_dusk(): + assert get_time_period(18) == "dusk" + assert get_time_period(19) == "dusk" + + +def test_get_time_period_night(): + assert get_time_period(20) == "night" + assert get_time_period(21) == "night" + assert get_time_period(23) == "night" + assert get_time_period(0) == "night" + assert get_time_period(1) == "night" + assert get_time_period(4) == "night" + + +def test_get_sky_description_returns_non_empty(): + for hour in range(24): + desc = get_sky_description(hour) + assert desc, f"hour {hour} returned empty description" + assert isinstance(desc, str) + + +def test_get_sky_description_differs_by_period(): + dawn_desc = get_sky_description(5) + day_desc = get_sky_description(12) + dusk_desc = get_sky_description(18) + night_desc = get_sky_description(0) + + # each period should have different descriptions + descriptions = {dawn_desc, day_desc, dusk_desc, night_desc} + assert len(descriptions) == 4, "periods should have distinct descriptions" + + +def test_get_sky_description_edge_cases(): + # boundaries between periods + assert get_sky_description(0) # night start + assert get_sky_description(5) # dawn start + assert get_sky_description(7) # day start + assert get_sky_description(18) # dusk start + assert get_sky_description(20) # night start + assert get_sky_description(23) # night end