feat(events): the five world verbs an author sees (Phase 12a) #31
Reference in New Issue
Block a user
No description provided.
Delete Branch "feature/events-p12a-world-verbs"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Events Phase 12a, module half. One of four:
servuo-plugins(servuo-plugins#23),link(link#38),Module-uo,docs(docs#221) — all ontoedge. Spec of record:docs/link/v7.md.What an author gains
uo.creature.spawn,uo.boss.spawn,uo.npc.place,uo.gate.open,uo.decor.place. Five actions because five is what an author has; one sharedperform/revert/reconcilebecause on the wire they are one thing.Five new budget dimensions —
uo.creatures,uo.bosses,uo.npcs,uo.decor,uo.gate.minutes— all declared by this module (org lead, 2026-09-07). Core meters whatever dimensions a module declares and holds no UO knowledge, which is the whole of whatMODULE_APImeans by game-agnostic. A gate is priced in minutes rather than in gates: one standing all day and twelve standing five minutes each are not the same imposition on a world, and a count would price them identically.MODULE_API_VERSIONdoes not move. Budget dimensions and option sources are things a module declares through an API that already exists.reconcile()asks, and this is the one place in the file that mustA crier line lives in shard memory, so a changed
bootIdis proof it is gone — that is whatreconcileByBootIdexists for. A spawned creature is in the world save and survives the restart the stamp would report it lost by. So the world verbs askworld.owned, and anything not listed is gone — safe only because the shard's registry and the objects it describes are written by the same save.Teardown reports
goneas success andrefusedas failed. A creature a player killed is the point of having spawned it, and a run that endedincompletebecause its event worked would be a report nobody could read.refusedmeans the shard denies this run ever owned the serial: nothing will delete it through this path, so the row must land unresolved with a reason rather than be quietly marked reverted.The decoration index
The atlas gains one, parsed from the shard's own
Data/Decoration/**/*.cfg. 120 files, read recursively — the real tree nests two deep (Magincia/Trammel,Stygian Abyss/Ter Mur,Old/Britannia) and a flat read would index a fraction of it while looking like it worked, the failure being a dropdown quietly missing whole expansions. 313 distinct types on this tree.The decor verb resolves through it rather than passing a type name straight to the shard, which does two things at once: it keeps the verb to this shard's own decoration vocabulary (tighter than "any item that is not a container"), and it fetches the item id —
Staticalone accounts for 5031 placements under 1992 different graphics, so for that class the graphic is the identity and a bare type name places the wrong thing. 131 of the 313 types carry more than one id.PARSER_VERSION→ 3, so an already-imported tree is re-read rather than skipped on an unchanged hash.Two defects the build found in code that had already shipped
uo.options.creaturesanswered with something the shard cannot use. It shipped in Phase 9, before anything consumed it, carrying the atlas slug — unique, stable, and not a thing the shard can build, because a creature is constructed from a ServUO class name andorc-bruteis not one. The atlas'snameis the raw type token from the spawn files (displayNamepicks the best-attested spelling), so the fix was to stop discarding the half that works. Safe to change because Phase 12a is the source's first consumer; the file said so when it shipped.uo.npc.placecould not be performed from its own required params. Both ends refuse an oracle with neither a greeting nor a line — it would stand there in silence — but both fields were declared optional, so a cross-field "at least one of these" rule sat where no authoring form could render it as valid. The greeting is nowrequired, which says the same thing in the contract core reads as data; theperform()check remains, for the field holding nothing but spaces.It was caught by the existing dry-run sweep — the test that performs every action with only its required params — which is a better argument for that test than anything written about it when it shipped.
Checks
npm test: 605 pass, 0 fail (was 598).check:importsandcheck:bundleclean.check:swaggerreports the fragment stale — it is already stale onedge(verified by stashing this branch's changes and re-running), and this phase adds no route, so it is left alone rather than regenerated inside an unrelated change.🤖 Generated with Claude Code
https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4