3 KiB
Event reasons (camera + orange dossier)
A/B layers
| Layer | What | Gate |
|---|---|---|
| B ticker | Activity / Life / chronicle prose for live ids | Always may write when the game fires |
| A story camera | Interest candidates, orange reason, camera cuts | EventCatalog.IsCameraWorthy only |
Happiness: Presentation.Signal = A; Ambient / Aggregate = B-only.
Discrete / status / WorldLog: CreatesInterest = A gate.
InterestDirector only ranks A candidates. It does not author inventory.
Character fill runs only when the pending EventLed queue is empty, and uses an empty Label (task chip only).
Orange dossier reason = the owning A event’s Label while the scene is active (InterestDirector.TryGetOwnedReasonCandidate).
Quiet grace / inactive dwell clears the reason even if focus has not switched yet.
Drops (ambient, createsInterest=false, identity filter, below margin, …) go to InterestDropLog.
EventReason
IdleSpectator/Events/EventReason.cs is the sole Label factory for camera candidates.
It lives in the Events module with catalogs (not in the director).
Feeds call typed helpers (Fight, BuildingEat, SeekingLover, …) or Apply(template, a, b, id).
Events module layout
| Path | Role |
|---|---|
Events/EventCatalog.cs (+ Catalogs/EventCatalog.*.cs) |
One inventory - nested domains + IsCameraWorthy |
Events/Feeds/ |
Build + register A candidates from catalog dials |
Events/Patches/ |
Harmony hooks → feeds / Activity |
Events/EventReason.cs |
Orange reason sentences |
Events/EventFeedUtil.cs |
Shared Register path |
Events/InterestDropLog.cs |
Why a beat stayed B or missed A |
Events/DiscreteEventEntry.cs |
Shared catalog row shape |
Rules:
- Sentence form with names:
{a} is fighting {b},{a} is eating a beehive,{a} is seeking a lover. - Set
RelatedUnitwhen the sentence names a second party. - Never invent stranger subjects for unit-led events.
- Never use engine jargon that misstates the action.
Removed crumbs
Do not author these as orange reasons:
In action- bare
Duel/Fight (N)without a named sentence - identity titles (
King of X,Leader of X,Lone beetle) Consumes a building/Damages a building: {a}crumb form
Strength dial (Layer A only)
CreatesInterest / Signal gates whether an id registers for the camera; EventStrength ranks among A.
Instant cut-in when next.TotalScore >= current + cutInMargin (sticky scenes use stickyCutInMargin).
See scoring-model.json.
Dossier display
UnitDossier.EventLabelBeat keeps EventReason / Name verb … sentences.
It rejects identity/weak crumbs and scrubs living stranger names (ReasonNamesStranger / LeadsWithForeignName).
Active EventLed A scenes should not silently blank a valid Label.
See also
event-audit.md- sources, MaxWatch, A demotion setevent-prose-audit.md- prose vs game call sitesscoring-model.md- score weights