Module Creator
Examples: Dice Tray and Action Dock
Compare the live host runtime, interactive contract preview, and representative host exhibits in Module Lab.
Dice Tray: concrete scaffold and host runtime
The CLI scaffold is the concrete Dice & Chat package. Fabled's first-party Dice Tray uses the same model: an account target contributes a Chat composer panel and global command, requests dice.roll.self, optionally requests chat.post.self, and points to reviewed action/frame/locale assets.
- The package supplies a dice expression, visibility choice, die buttons, presets, and localized labels.
- The allowlisted fabled.dice-tray.v1 renderer belongs to Fabled; the module does not ship arbitrary React UI.
- The host checks the exact action descriptor, performs the native roll, owns the result and 3D presentation, and applies audience rules.
- Module Lab previews Fabled's repository-bundled canonical Dice Tray fixture in development. It cannot load an arbitrary project path, or install, activate, approve, or publish a package.
Action Dock: interactive contract preview
The fabled-labs.token-action-hud package targets vtt and previews a compact selection overlay for the controlled token. It contributes a userCampaign compact-mode setting and uses reviewed Action Dock descriptors that remain inert like other assets until the production VTT renderer contract is admitted.
| Capability | Why the preview asks for it | Consent |
|---|---|---|
| tokens.read.controlled | Read the safe view of the token controlled by the user | campaign and user |
| framework.invoke.controlled | Invoke a reviewed controlled-token action | campaign and user |
| events.observe.declared | Observe declared selection and turn-state changes | campaign |
| dice.roll.self (optional) | Roll for a reviewed action when the user invokes it | user |
The preview demonstrates permission-filtered context, stale-state rejection, idempotent command dispatch, localization, and scoped settings while Fabled keeps action authority. A schema-valid manifest is only the package boundary; the unavailable production renderer contract still stops admission outside the Lab.
Welcome Command and Character Sheet: host exhibits
Module Lab also includes two representative host exhibits, not full package demos. Welcome Command mirrors an owner-managed campaign module whose Spotlight command produces an ordinary Chat result and disappears after disable. Character Sheet mirrors a marker-only reviewed contribution to Fabled's canonical FramePreview, with VIEW denial and safe-mode teardown keeping character data inside the host.
Spell effects: source CLI candidate
npm run modules:cli -- module init arcane-arsenal --template spell-effects --publisher-id my-studio --publisher-name "My Studio"The scaffold includes six examples: arcane_bolt, dragon_fire, frost_breath, toxic_breath, sword_swing, and melee_hit. The matching source host accepts 12 presets in total, also including lightning_arc, meteor_strike, frost_nova, void_vortex, radiant_sigil, and thorn_burst. Recipes choose fixed colors, intensity, and a duration of 300–2200 ms through the same seven-key fabled.vtt-effect.v1 contract. They provide visuals only: no arbitrary shaders, layers, damage, healing, resource costs, or imported spell mechanics.
After review and installation of the exact release, the campaign owner activates the module in Campaign → Modules. In the VTT, an authorized GM uses the Target tool to select 1–8 existing tokens, opens a different source token context menu, expands Arcane Arsenal, and chooses a recipe. Fabled validates the cast and broadcasts the authoritative effect. Disabling removes the menu and prevents new casts; effects already admitted finish within 2200 ms.
The reusable pattern
- Declare intent in the manifest and exact JSON assets.
- Ask for the minimum capabilities and consent scopes.
- Let Fabled own renderers, context filtering, authoritative mutations, and results.
- Validate and inspect locally, then submit immutable evidence for review.
- Expect disable, replacement, revocation, and safe mode to tear contributions down cleanly.