dMUD Seasonal Event System
Added: June 2026 — commits
b03682a6(core),3deed0af(per-system integration),3d8f05ff(character pass) Core module:dmud/seasonal.go(new module, intentionally isolated fromevents.gocore churn)
A time-aware seasonal layer for dMUD that drives festivals, weather, seasonal NPC spawns, and seasonal stat/equipment bonuses. Built as a sibling module to the existing event system so the legacy events.go switch remains untouched.
🌍 Seasons
Season detection uses meteorological windows (not astronomical):
| Season | Window (approx) |
|---|---|
| Spring | March–May |
| Summer | June–August |
| Autumn | September–November |
| Winter | December–February |
API:
GetCurrentSeason()— current season enumGetSeasonForTime(t time.Time)— season for arbitrary timestampGetSeasonInfo(season)— metadata record fromSeasonInforegistry
🎪 Festivals
Time-boxed windows with their own NPCs/lore/effects:
| Festival | Period |
|---|---|
halloween |
Oct–early Nov |
midsummer |
June–July |
harvest |
September |
wintersfeast |
December–January |
springbloom |
April–May |
IsFestivalActive(name) returns true inside the active window; FestivalInfo returns the metadata record.
🌧️ Weather
WeatherState enum: clear / rain / snow / thunder / fog
Helpers:
FormatSeasonBanner(season)/FormatWeatherBanner(weather)— ANSI-coloured banners for the terminal
🎯 Stat Bonuses (Character Pass — commit 3d8f05ff)
SeasonalStatBonus table gives per-season fishing/mining/woodcutting XP bonuses:
| Helper | Returns |
|---|---|
GetSeasonalStatBonus(season, skill) |
Bonus multiplier for one skill in one season |
GetActiveSeasonalBonuses() |
All active bonuses (season + festival stacking) |
The character pass also adds seasonal equipment effects — equipment items can carry season-triggered modifiers (e.g. a midsummer sword granting bonus fishing XP only during midsummer).
🔁 Event System Integration (events.go)
Commit b03682a6 extended events.go without disrupting the existing dispatcher:
- New
EventTypevalues:seasonal,seasonal_start,seasonal_end,weather,festival(andrandom, which was defined but previously undistributed). Eventstruct gained optional fields:Season,Weather,Festival,BonusXP,StatSkill,StatBonus, parsed from INI.- Dispatchers added to
checkEvents:handleSeasonal,handleFestival,handleWeather,handleRandom. - New actions:
give_xp,apply_seasonal_bonus,set_weather.
🧩 Per-System Integration (commit 3deed0af)
Seasonal logic is surfaced per-room/per-NPC so individual rooms and NPC Lua scripts can react:
- Rooms can declare seasonal behaviour via INI.
- NPC Lua scripts gain
get_game_time/get_time_of_day(already present from previous NPC-events pass) and the new seasonal context. - Spawning:
seasonalNPCsregistry — adding a seasonal NPC requires only a registry entry + a Lua script (no Go changes).
🧹 Holiday End Event Fix
Commit 9fe6c6be stopped holiday_end events from re-triggering every minute. The previous loop reset its own cooldown marker each tick, causing a flood of post-holiday announcements.
📁 Key Files
| File | Purpose |
|---|---|
dmud/seasonal.go |
Season / festival / weather / stat-bonus registry, helpers |
dmud/events.go |
New event types + dispatchers + new actions |
dmud/data/rooms/*.ini |
Rooms with seasonal hooks (e.g. ambient time-aware rooms) |
dmud/data/scripts/*.lua |
on_time_change, on_seasonal_start, on_festival, on_weather handlers |
🧪 Test Bot Coverage
Per AGENTS.md guidance, the headless test bot (cmd/dmud-bot/) must gain phase assertions for:
- Season detection (current season matches meteorological window)
- Festival activation window
- Holiday-end event not re-triggering
apply_seasonal_bonusaction applying StatSkill/StatBonus to the user
🔗 Related
- dMUD Overview
- Scripting & Quests — NPC Lua event handlers
- dMUD Enhancement — Vision + economy