Scheduled events
An event is a scheduled, bounded, audited change to a live game world. You write it once as a sequence of phases, publish a version of it, put it on the calendar, and it runs — at four in the morning if that is when you scheduled it, with nobody watching.
That last clause is the whole reason this feature is shaped the way it is. Everything below that looks like extra ceremony — the switchboard, the caps, the dry run, the ledger — is there because the thing being automated is somebody’s game world, and the person who authored the change is asleep when it happens.
Core owns the engine; the installed module owns the meaning. Core decides whether an action is permitted, when it runs, in what order, how many times, within what budget, what it created and who is told. The module says which verbs exist and performs them. Core never learns a game word: every label you see in the step editor came from the module that registered it.
Where it is
Section titled “Where it is”Admin → Events, its own group in the sidebar:
| Row | Who sees it |
|---|---|
| Events — the definitions, and their runs | Admin, editor, moderator |
| Calendar — month and list view, with series | Admin, editor, moderator |
| Actions — what this deployment permits, and the caps | Admin only |
| My participation — your own attendance | Everyone |
Reading is staff-wide on purpose. A moderator’s power over this feature is the run console — the screen you open when an event is doing something wrong at two in the morning — and hiding it from the one role that exists for incident response would be a strange way to build an incident tool. The narrower gates are on the actions, not the rows: authoring is admin and editor, publishing a version and starting a run are admin only, and all of it is enforced on the server rather than by hiding a button.
Authoring
Section titled “Authoring”A definition is the thing that gets listed, searched, scheduled and audited: a title, a slug, a storyline, a schedule, and an ordered list of phases. Each phase holds steps, and a step is one action with its parameters.
A phase advances on a condition — after a duration, or when something happens in the game a given number of times. The vocabulary of “something that happens” is the trigger catalog the installed module already ships, so a module gains phase conditions by declaring one more entry in a list it already had.
Versions are immutable, and a run pins one
Section titled “Versions are immutable, and a run pins one”Publishing takes a snapshot. The run that starts on Saturday holds the version that was published, not the one you edited on Friday — which is what makes a run reproducible and an audit answerable after a change. A running event cannot be edited; you edit the definition, publish a new version, and the next run picks it up.
Nothing is enabled until you enable it
Section titled “Nothing is enabled until you enable it”Admin → Events → Actions lists every action the installed modules registered, and everything above a notification arrives switched off. Installing a module must never start doing things to your world.
Each row has two controls: whether the action is permitted on this deployment at all, and its
per-run caps — how much of a budget dimension one run may consume. Dimensions are
declared by the module (uo.creatures, uo.bosses, uo.rewards and so on), and consumption
is counted in the database with a conditional update, not checked in application code.
That distinction matters more than it sounds. A stolen admin session has already passed every
role check there is; it still cannot exceed the cap, because the cap is a condition on the
UPDATE that spends the budget.
Dry run before anything unattended
Section titled “Dry run before anything unattended”Verify materialises the whole plan without touching the world: every step is dispatched with a verify flag, and you get back what would happen and what it would cost against the caps, in the module’s own words. Refusals show up here, before the calendar entry exists.
A definition that has never been verified is exactly the one worth not scheduling. Verifying is cheap, and it is the last point a human sees the plan.
Running one
Section titled “Running one”Runs start on the schedule, or by hand. A series groups definitions into an arc, so a three-part story reads as one thing on the calendar rather than three unrelated entries.
The run console shows live status, the steps and their attempts, the budget consumed against each cap, any failures, and the cleanup. Its controls are:
- Pause and resume — resume carries a run past any settled step, including one that failed or was refused.
- Skip, retry and confirm a single step. Confirm is how a human-cue step advances: the run posts the instruction, waits, and moves on when somebody says they did it.
- Advance a phase by hand.
- Cancel, with or without cleanup.
Every one of those is logged with the person who did it.
What an event does to a world, and how it is undone
Section titled “What an event does to a world, and how it is undone”Two different things, and the difference is the whole safety story.
What it owns. Creatures, bosses, oracle NPCs, decoration, a temporary gate — things the run created. Each one is written to a resource ledger as it is made, with the run and step that made it.
What it borrows. A spawner’s respawn timer, a starting skill cap, a seasonal flag — values that already existed and are being changed for the duration. Those are leases: the game keeps the original, the site records both halves, and the lease carries its own deadline.
The game server has its own switches
Section titled “The game server has its own switches”They live on the shard host, outside the site’s reach, and the site cannot turn them on.
EventsEnabled is off by default, and it is a different switch from AdminWriteEnabled.
Turning the admin plane on is consenting to staff moderation driven from a screen somebody is
looking at. Turning this on is consenting to the site changing and watching your world
unattended. One switch could not honestly express both.
Beside it sit the game’s own ceilings — how many creatures one call may spawn, how long a gate may stand, how much one run may own in total, how often the world may be saved. They refuse rather than clamp, for the same reason the caps do: a quietly shortened request leaves the two halves disagreeing about what actually happened. See Bridge.cfg for every key.
What players see
Section titled “What players see”The public calendar at /site/events carries what is scheduled, what is happening now, what
finished recently, and published results. A run that was cancelled says so — “Did not
happen” — rather than quietly disappearing.
Listing is separate from publishing. A definition has its own listed switch, because publishing is what makes an event runnable and a surprise invasion should not have to be advertised a fortnight in advance in order to be allowed to happen. Unlisting hides the definition, its runs and its results from the public pages and from a participant’s own history; it hides nothing from staff.
Where a module can tell who took part, a run can keep a participation ledger — scores and ranks, published as a results table when the run finishes. Ranks are computed at publication and stored, so somebody added afterwards does not silently renumber a table people have already read. A signed-in person sees their own attendance under their account, and staff see theirs on the same screen.
When something goes wrong
Section titled “When something goes wrong”degradedis notfailed. If the game server disappears mid-run, the run degrades, world-changing steps park unattempted, and it recovers when the connection does. The public page does not say so — that is operator information.refusedmeans a bound said no, and it is reported with the numbers.- The run log answers “why did phase 3 not start?” as a query, not by reading a wall of text. It is kept for 90 days after a run reaches a terminal state — and a run still in flight keeps every line it has, however old, because the question it answers is still open.
- Cleanup can be re-run from the run console if a teardown was interrupted.
Where the record is
Section titled “Where the record is”website/EVENTS.md
is the design of record — the model, the data, the security argument and what was deliberately
left out.
website/MODULE_API.md
is the contract a module registers its verbs against, and
link/ADMIN_CONTROLS.md
is what the site may ask a game to do at all.
For how the engine is put together, see Events architecture.