Agenda
Plans with people at a place and a time, shared by every mod: checked for clashes, kept in the save, reserved in the NPCs' routines, shown in the agenda.
A mod that makes plans (an outing, a meeting, a class, a club night) books them into the shared agenda rather than keeping its own diary. Every mod then sees the same day: the player cannot be booked into two places at once, a contact into two outings, or a coffee at a cafe that is closed. The player sees them all behind the calendar on the map's rail, with where, with whom, how far and when.
lualocal M = "ynl_Nightlife"
local r = Agenda:propose(M, "dinner_" .. person:id(), {
title = "Dinner with " .. person:name(),
people = { person }, -- Actors, People references or ids
inHours = 24, -- or at = an absolute time (Events:now() counts the same hours)
duration = 2,
tags = { "restaurant" }, -- any venue of these types...
-- building = id, or here = true: ...or this exact building
accepted = true, -- false (the default): an invitation waiting for Agenda:respond
})
if not r.ok then
Game:Narrate(r.reason) -- "Noor is at work then.", "That overlaps "Coffee with Lena"."...
end
Checks
Agenda:propose refuses, with a reason to show, when:
- the player has another plan at that time (any mod's);
- someone in
peopleis no longer a contact (blocked or deleted), already has plans then, or is at work then (their routine; passignoreRoutine = trueif your story gave them the time off); - none of the
tagsis open at that hour (opening hours fromMap/amenities.json); - the building is in another city, or the player could not get there in time from where they are.
Agenda:check(options) answers the same question without booking: nil, or the reason.
Life of a plan
| State | Meaning |
|---|---|
invited |
Proposed, waiting for Agenda:respond(mod, key, accept [, reason]). Unanswered when its window opens, it is declined ("no answer"). |
accepted |
On. From early hours before the start (default 1) to late hours after it (default 3) is its window. |
completed |
You called Agenda:complete(mod, key), typically in the scene where it happens. |
missed |
The window closed while it was still accepted. |
cancelled |
You called Agenda:cancel(mod, key, reason), or someone in it was blocked or deleted ("unavailable"). |
declined |
Refused through respond, or never answered. |
- While the window is open, each person in the plan is reserved at the venue in the NPC routines: that is where the game places them, instead of their schedule. Completing, cancelling or missing the plan, or turning your mod off, releases them.
- One hour before, the player gets a reminder notification, and one when it is missed, both linking to the agenda. Pass
notify = falseif your mod sends its own (ul_Phone does). Agenda:isHere(mod, key)is true when the player is at the place (the building, or a venue of one of the tags) inside the window: check it before running the meeting.- Every change is an
agendaChangedevent:Events:on(M, "agendaChanged", function(mod, key, state) ... end). - A suggestion in dialogue is not a plan: only what is in the agenda reserves anyone.
Moving your own saved plans in
A mod that kept plans in its own variables migrates them once, with migrate = true: the plan goes in as it was agreed, without the checks (it was valid when it was made), and the person is not asked again. Look it up with Agenda:get first so migrating twice does nothing. See ul_Phone's P.migrate for a complete example.
| Method | Does |
|---|---|
Agenda:propose(mod, key, options) |
Books; { ok, id } or { ok = false, reason }. |
Agenda:check(options) |
nil, or why it would be refused. |
Agenda:respond(mod, key, accept [, reason]) |
Answers an invitation. |
Agenda:cancel(mod, key [, reason]) |
Cancels an invited or accepted plan. |
Agenda:complete(mod, key) |
Marks an accepted plan done. |
Agenda:get(mod, key) |
The plan as a table (title, state, at, duration, people, tags, building, place, reason, here), or nil. |
Agenda:list([mod]) |
Active plans soonest first, then ended ones. |
Agenda:isHere(mod, key) |
The player is there, in the window. |
Agenda:here() |
{ id, name, tag } of the building the player is in, nil outdoors. |
Agenda:version() |
The API version, 1. |