Audience: Foundry module developers augmenting SoHL actor/item behavior broadly — across many items or actors — without modifying SoHL source.
SoHL fires cancellable Foundry hooks around each phase of its data-preparation
lifecycle. From a module you can listen to augment behavior, or return false
from a pre* hook to replace a phase. For behavior on one specific item,
prefer a Script Action instead — see
Macros and Actions.
This page is the module-author entry point; the details live with the code that defines them:
- The hook contract — the hook names, cancellable semantics, arguments, and
worked
Hooks.on(...)examples (listen and cancel) — is documented on SohlActor, which fires the hooks during data preparation. - The type strings in the hook names (
sohl.<itemType>.…andsohl.actor.<actorType>.…) are ITEM_KIND and ACTOR_KIND. - The phase model — the three phases (
initialize→evaluate→finalize) and the barrier guarantees — is in SohlLogic; for the concept overview see Phase-batched lifecycle.
Minimal example
Hook names are sohl.<itemType>.<phase> (and sohl.actor.<actorType>.<phase>),
where <phase> is preInitialize/postInitialize, preEvaluate/postEvaluate,
or preFinalize/postFinalize.
// Augment: run after every mystical ability finishes evaluating.
Hooks.on("sohl.mysticalability.postEvaluate", (item, ctx) => {
// item = the mysticalability item; ctx = SohlActionContext
// read/adjust derived state here (not persisted)
});
// Replace: cancel the default initialize phase for a specific item.
Hooks.on("sohl.mysticalability.preInitialize", (item, ctx) => {
if (item.system.shortcode !== "curse") return; // leave others alone
// ...do the replacement work...
return false; // returning false from a pre* hook cancels the phase
});
For persistent writes, guard them (next section). For a fuller worked example including a world-setting toggle, see House Rules Cookbook — Recipe 2.
Guarding persistent side effects
When a hook writes persistent state (documents, world settings), gate it behind a world-setting toggle and a GM-only check, so it runs under a single authority rather than once per connected client. See the worked recipe in House Rules Cookbook — guard pattern.
See also
- Macros and Actions — per-item behavior instead of type-wide.
- Extension Points — choosing an extension scope.
- SohlLogic — the phase model and rationale.
- Writing Modules — building the module these hooks live in.