Add time-of-day system with tests

This commit is contained in:
Jared Miller 2026-02-14 15:46:34 -05:00
parent 4d44c4aadd
commit 32f52ef704
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C
2 changed files with 126 additions and 0 deletions

70
src/mudlib/timeofday.py Normal file
View file

@ -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)]

56
tests/test_timeofday.py Normal file
View file

@ -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