Search by

tilttek / seasonal-events

phil

Seasons and their events for gamification: a season once or each year by an RFC 5545 rule in its timezone, the quests, items and decorations it brings while it lasts, multipliers of gains only on events announced ahead, a port to read what is on, and bridges to tilttek/quests and tilttek/collections

Package info

github.com/TiltTek/seasonal-events

Homepage

pkg:composer/tilttek/seasonal-events

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

0.1.0-alpha 2026-11-13 14:27 UTC

This package is auto-updated.

Last update: 2026-11-13 22:47:54 UTC


README

Seasons and their events: the quests, items and decorations of a period, in the site's timezone, coming back each year.

tilttek/seasonal-events keeps the seasons of a site — a winter festival, a spooky season, a harvest feast — and the events inside them. A season comes once, between two dates, or each year for a number of days from a date an RFC 5545 yearly rule gives: the 15th of December, the fourth Thursday of November. Its days are counted in its timezone, from midnight on the wall clock, across changes of time. A season brings quests, items and decorations while it lasts; an event inside it adds its own for some of its days, and may multiply the gains of a ledger — only when it is announced at least a day ahead, so that nothing multiplies by surprise and the highest multiplier applies when events meet. Each time a season comes has a code, the date of its first day, so that what a member earns in it is told apart from the next year.

The other packages read what is on through one port, ActiveContent: the quests open now, the items offered, the decorations shown, the multiplier of a ledger. They never read the seasons themselves, and the library depends on none of them: optional bridges open a tilttek/quests quest with a season and list the tilttek/collections items it brings, when those packages are installed.

It is for a community or a game that wants seasonal content without hand-switching it on and off: the seasons are declared ahead, in code, a configuration or a database, and answer for any moment. There is no season pass to buy and no item that never comes back: a season that comes each year brings its items again.

It is a plain PHP library whose dependencies are phil/recurrence, which reads the yearly rules, phil/resource, the references of quests, items and decorations, and psr/clock. It keeps no state between two questions.

Status

Part State
SeasonSchedule: once, or each year by an RFC 5545 yearly rule, in a timezone, up to 183 days Implemented and tested
Season, SeasonalEvent, Content, ContentKind, Multiplier: what a season and its events bring Implemented and tested
SeasonalEvents, Snapshot, ActiveSeason, ActiveEvent, Period: what is on at a moment, and what is announced Implemented and tested
ActiveContent: the port other packages read Implemented and tested
SeasonCatalogue, InMemorySeasonCatalogue, SeasonReader: seasons from code or plain arrays, and back Implemented and tested
Bridges to tilttek/quests and tilttek/collections Implemented and tested
Exceptions under one SeasonalEventsException interface Implemented and tested

Documentation

Document What it covers
Installation Requirements, installing and wiring the library.
Seasons and events Schedules, timezones, recurrence, contents, events, announcements and multipliers.
What is on The questions of a moment, the snapshot, the announced events and the port ActiveContent.
Definitions Seasons written as plain arrays — a configuration, JSON or YAML — read and written back.
Bridges Quests, collections, and an advent calendar during a season.
Extension points What an application gives the library: the catalogue, the clock.
Testing The library's tests, fuzzing and benchmarks, and how to test code that reads the seasons.
Reference Every type of the library, with its role.

Quick start

composer require tilttek/seasonal-events
use Symfony\Component\Clock\Clock;
use Tilttek\SeasonalEvents\{Content, Multiplier, Season, SeasonalEvent, SeasonalEvents, SeasonSchedule};
use Tilttek\SeasonalEvents\Store\InMemorySeasonCatalogue;

$winter = new Season(
    'winter-festival',
    SeasonSchedule::yearly('America/Toronto', '2026-12-15', 23),
    [Content::quest('quest:winter-hunt'), Content::decoration('decoration:snowflakes')],
    [new SeasonalEvent('gift-week', fromDay: 8, days: 7, contents: [Content::item('item:wrapped-die')], multiplier: new Multiplier('points', 200), announceDays: 7)],
);

$seasons = new SeasonalEvents(new InMemorySeasonCatalogue([$winter]), new Clock());

$seasons->at()->decorations();          // [decoration:snowflakes] while the festival is on
$seasons->multiplier('points')?->apply(10); // 20 during the gift week

Requirements

PHP 8.5 or later.

Contributing

Contributions are welcome on the PHIL monorepo: read the contribution guide and the code of conduct. Report a vulnerability privately, as the security policy explains, never in a public issue.

License

MIT, © Philippe Gamache, doing business as Le Gnome Archiviste; a Tilttek project. See LICENSE.