SC - More Activities
SC - More Activities
Overview
SC - More Activities extends the native D&D 5e activity system in
Foundry VTT. It does not replace the standard dnd5e activity workflow. It
adds new activity types, a Shattered Codex-owned registration layer, a grouped
activity creation dialog, GM-facing diagnostics, and explicit migration tools
for worlds moving away from the legacy more-activities module.
The module is built for two different jobs:
- GMs who want more activity types without maintaining custom patches
- module authors who want to register custom
dnd5eactivity types through a stable public API
At release, the module ships with 10 built-in SC activity types and a registry flow that can also expose third-party activity types in the same creation UI.
Installation
- In Foundry VTT, open Add-on Modules.
- Choose Install Module.
- Paste this manifest URL:
https://github.com/Shattered-Codex/sc-more-activities/releases/latest/download/module.json- Install the module.
- Enable SC - More Activities in your world.
- Install and enable
libWrapperif you want the recommended compatibility layer.
Compatibility:
- Foundry VTT
v13tov14 - system:
dnd5e dnd5ecompatibility declared inmodule.json: minimum5.0.0, verified5.3.0- localization: English and Brazilian Portuguese
Important behavior:
- the module exits early outside
dnd5eworlds - native
dnd5eactivities remain available - the module relies on items and sheets that already support the
dnd5eactivity workflow
What It Adds
- 10 built-in Shattered Codex activity types for automation, support, progression, inventory, and canvas workflows
- a public registration hook and API for Shattered Codex modules and third-party modules
- a grouped activity creation dialog that separates D&D 5e, Shattered Codex, and External activity groups
- a GM Activity Catalog with diagnostics, filters, and enable or disable controls
- explicit migration tools for legacy
more-activitiesactivity data - per-user preview color settings for teleport, movement, and wall overlays
- module settings shortcuts for the wiki, support links, catalog, migration tools, and preview colors
Built-In Activity Types
| Activity | Use it for | Main configuration | Important notes |
|---|---|---|---|
| SC Sound | Play an audio file after the activity is used. | Audio file, Playback, and Volume. | Broadcasting to Everyone requires a GM. Non-GM use falls back to local playback. |
| SC Macro | Run a selected world macro or inline code stored on the activity. | Macro source, World macro, and Inline code. | Inline code runs only for GMs. World macros still respect the user's macro permissions. |
| SC Hook | Emit a hook or call a whitelisted callback exposed by another module. | Dispatch mode, Hook name, Callback module, and Callback id. | This is primarily an integration and developer workflow, not a player-facing automation shortcut. |
| SC Chain | Execute other activities from the same item in order. | Activity ids, Depth limit, Continue after failure, and Stop when canceled. | Includes loop detection and nested-depth protection. |
| SC Contest | Resolve a contested roll between the activity user and a defender. | Defender, Tie rule, and roll configuration for both sides. | The defender can be the selected target or the same actor. Custom formulas are supported. |
| SC Grant | Grant configured items to the activity actor or to a targeted actor. | Recipient, granted item UUIDs, and Quantity. | Using the target flow requires exactly one target token with a valid actor. |
| SC Advancement | Trigger selected dnd5e advancement entries from a source item. | Source item and selected Advancement Entries. | The actor must own the source item at use time. |
| SC Teleport | Choose teleport targets and place their destination on the canvas. | Targets, Maximum targets, Allow self, Target range, Teleport range, destination source, offsets, and arrangement controls. | Scene movement is GM-mediated. Destination placement can be limited by range. |
| SC Movement | Push or pull tokens from the activity actor with a preview workflow. | Targets, Maximum targets, Snap to grid, Movement type, Distance, and Range limit. | Scene movement is GM-mediated and respects the configured range limit. |
| SC Wall | Create walls by placing points directly on the canvas. | Wall type, Placement range, wall limits, panel settings, facing, and block properties. | Can be restricted to GM-only creation or allow player requests through an active GM. |
The built-in activities are registered under the Shattered Codex group in the activity creation dialog, but the catalog still tracks their category and source metadata separately.
Activity Creation Flow
SC - More Activities keeps the normal dnd5e activity workflow intact and
extends the creation dialog instead of replacing it.
When supported activity types are present, the dialog is grouped into:
- D&D 5e for native activity types
- Shattered Codex for the built-in SC activity set
- External for third-party modules that register through the SC registry
This matters for both users and builders:
- GMs can distinguish native types from SC or third-party additions
- module authors can register external activity groups without writing directly
into
CONFIG.DND5E.activityTypes - disabled activity types are filtered out of creation and blocked from use
The creation dialog keeps native D&D 5e types visible, then adds a separate Shattered Codex group for the built-in SC activity set.
Module Settings
From Configure Settings > Module Settings > SC - More Activities, the module adds visible settings and menus for both GM administration and personal preview preferences.
| Setting or menu | Scope | What it does |
|---|---|---|
| Debug logging | Client | Logs lifecycle and diagnostic messages to the browser console for your user. |
| Migration backup retention | World, GM | Controls how many migration backups are stored in world settings. Default: 3. Range: 1 to 10. |
| Activity catalog | World, GM | Opens the registered activity catalog and diagnostics window. |
| More Activities migration | World, GM | Opens the preview, apply, export, and restore workflow for legacy more-activities data. |
| Preview colors | Client | Opens the per-user color configuration for teleport, movement, and wall overlays. |
| Documentation | World, GM | Opens the wiki page for this module from inside Foundry. |
| Support the developer | World, GM | Opens the Shattered Codex Patreon support link. |
The module also stores hidden world or client data for disabled activity types, preview colors, and migration backups. Those are managed through the UI and are not intended for direct manual editing.
Activity Catalog
The Activity Catalog is the GM-facing control center for registered activity types.
It includes:
- summary cards for Registered, D&D Ready, Rejected, and Warnings
- filters for search, category, status, and availability
- separate sections for Registered Activities, Rejected Registrations, and Warnings
- actions to Refresh, Copy report, Clear filters, and open Migration
Availability states are important:
- Active means the activity type is available for creation and use
- Disabled means the GM has blocked that type for the world
- Unavailable means the type is not in a state that can be enabled for use
Only activity types that successfully reach the D&D-ready state can be toggled for world use. This makes the catalog useful both as a user control panel and as a diagnostic report for module integrations.
The catalog combines registration state, lifecycle metadata, capability markers, and per-type availability controls in one GM-facing window.
Preview Colors
The Preview colors menu is a client-scoped preference, so each user can pick their own overlay colors without changing the world for everyone else.
It is used by the canvas-oriented workflows:
- SC Teleport
- SC Movement
- SC Wall
The menu includes:
- separate sections for Teleport, Movement, and Wall
Fill colorandBorder colorcontrols- a Live Preview area
- reset and save actions
These colors affect preview overlays only. They are not an activity authoring setting and they do not change the underlying activity data.
Preview colors are saved per user, so one GM can change overlay colors without changing the world for everyone else.
Migration from More Activities
SC - More Activities ships with an explicit migration flow for the legacy
more-activities module.
The migration window is GM-only and split into four tabs:
- Overview
- Preview
- Apply
- Backups
Recommended workflow:
- Keep the legacy module enabled only long enough to inspect or migrate old data.
- Open More Activities migration from module settings.
- Run Preview first.
- Review convertible and blocked entries.
- Use Apply migration only after the preview looks correct.
- Export the preview or final report if you need a record.
- Use Restore latest backup if you need to roll back the last migration.
Important limits:
- migration does not run automatically
- a preview is required before apply
- migration backups are stored in world settings
- some blocked or partially compatible legacy entries may still need manual cleanup after conversion
- the module warns when the legacy
more-activitiesmodule is still active
The preview report makes it clear which legacy entries can be converted, which SC type they map to, and what still needs manual review.
Developer Registration API
If you are building another module, register activity types through the SC
registry instead of mutating CONFIG.DND5E.activityTypes directly.
Public API access:
game.modules.get("sc-more-activities")?.apiglobalThis.ShatteredCodex.activitiesfor the published activities API
Main lifecycle hooks:
sc-more-activities.registerActivitiessc-more-activities.registryLockedsc-more-activities.apiReadysc-more-activities.activityRegisteredsc-more-activities.activityAvailabilityChangedsc-more-activities.activityUseStartsc-more-activities.activityUseCompletesc-more-activities.activityUseError
Registration timing:
- register during
Hooks.on("sc-more-activities.registerActivities", ...) - late registrations are rejected after the registry locks during initialization
- if you need the final published API object, listen for
sc-more-activities.apiReady
Minimum registration contract:
moduleIdtypelabelhinticondocumentClass
Your documentClass must provide:
static metadata.typethat matches the registered typestatic availableForItem(...)static localize(...)
Minimal example:
Hooks.on("sc-more-activities.registerActivities", (activities) => {
activities.registerType({
moduleId: "my-module",
type: "my-module-ignite",
label: "MYMODULE.Activity.Ignite.Label",
hint: "MYMODULE.Activity.Ignite.Hint",
icon: "modules/my-module/icons/ignite.svg",
documentClass: MyIgniteActivity,
});
});The public activities API also exposes helper methods such as:
listTypes()listTypeAvailability()setTypeEnabled(type, enabled)getRegistrationReport()createActivityOnItem(item, type, data, options)
Developer Example: SC Simple Sockets
If you want a concrete external-module example, SC - Simple Sockets is the best reference currently in the Shattered Codex module set.
It does not patch sc-more-activities directly. Instead, it keeps the entire
integration inside its own module and registers two external activity types when
both modules are active:
sc-socket-slotsc-socket-extraction
This example focuses on sc-socket-slot, because it shows the full lifecycle
for a custom activity type.
What Files The Example Uses
| File | Role in the integration |
|---|---|
| `scripts/main.js` | Imports the integration and calls `ScMoreActivitiesIntegration.register()` during module startup. |
| `scripts/core/integrations/sc-more-activities/ScMoreActivitiesConstants.js` | Defines hook names, type ids, group metadata, query id, timeout, and icon paths. |
| `scripts/core/integrations/sc-more-activities/ScMoreActivitiesIntegration.js` | Listens to the registration hook, registers types, exposes GM-mediated query handlers, and dispatches socket mutations. |
| `scripts/core/integrations/sc-more-activities/activities/socket-slot/ScMoreActivitiesSocketSlotActivity.js` | Defines the activity document class and its `use()` behavior. |
| `scripts/core/integrations/sc-more-activities/activities/socket-slot/ScMoreActivitiesSocketSlotActivityData.js` | Defines the activity schema stored on the item. |
| `scripts/core/integrations/sc-more-activities/activities/socket-slot/ScMoreActivitiesSocketSlotActivitySheet.js` | Extends the activity sheet and prepares UI context for the custom effect tab. |
| `scripts/core/integrations/sc-more-activities/activities/socket-slot/ScMoreActivitiesSocketSlotActivityService.js` | Runs the real workflow after `super.use()` succeeds. |
| `templates/integrations/sc-more-activities/socket-slot-effect.hbs` | Renders the custom form fields shown on the activity sheet. |
How The Bootstrap Works
SC - Simple Sockets loads the integration from its own scripts/main.js and
registers it at startup:
import { ScMoreActivitiesIntegration } from "./core/integrations/sc-more-activities/ScMoreActivitiesIntegration.js";
ScMoreActivitiesIntegration.register();That register() method does two jobs:
- It listens to
sc-more-activities.registerActivities. - It registers a query handler during
initso socket mutations can be routed through an active GM when needed.
This is important because the integration owns both the activity definition and the mutation flow. The external module is responsible for its own runtime behavior.
The Real Registration Call
Inside ScMoreActivitiesIntegration.js, SC - Simple Sockets registers
sc-socket-slot like this:
return activitiesApi.registerType({
moduleId: Constants.MODULE_ID,
type: SC_MORE_ACTIVITIES_ACTIVITY_TYPES.SOCKET_SLOT,
label: "SCSockets.Integrations.ScMoreActivities.SocketSlot.Title",
hint: "SCSockets.Integrations.ScMoreActivities.SocketSlot.Hint",
icon: SC_MORE_ACTIVITIES_ICONS.SOCKET_SLOT,
documentClass: ScMoreActivitiesSocketSlotActivity,
dataModel: ScMoreActivitiesSocketSlotActivityData,
sheetClass: ScMoreActivitiesSocketSlotActivitySheet,
configurable: true,
category: "sockets",
ui: {
scope: "external",
group: "sockets",
groupId: SC_MORE_ACTIVITIES_GROUP.id,
groupLabel: SC_MORE_ACTIVITIES_GROUP.label,
groupIcon: SC_MORE_ACTIVITIES_GROUP.icon,
groupOrder: SC_MORE_ACTIVITIES_GROUP.order,
order: 140
},
tags: ["sockets", "slot", "inventory"],
compatibility: {
dnd5e: "5.x",
scMoreActivities: { moduleId: "sc-more-activities", required: true },
scSimpleSockets: { moduleId: "sc-simple-sockets", required: true }
},
templates: [
"modules/sc-simple-sockets/templates/integrations/sc-more-activities/socket-slot-effect.hbs"
],
ownership: {
execute: "item-owner",
hostItem: "activity-item",
mutation: "gm-mediated"
},
source: Constants.MODULE_ID
});Why this registration is useful:
ui.scope: "external"places the type in the external registration flowgroupId,groupLabel, andgroupOrdercreate a module-specific activity group in the create dialogdataModel,sheetClass, andtemplatesturn the type into a configurable authoring experience instead of a bare runtime documentownership.mutation: "gm-mediated"matches the real workflow, because socket mutations may need GM execution
The Activity Class
The activity class extends the standard dnd5e activity mixin and connects the
registered type id to the custom schema, metadata, availability check, and
runtime execution:
export class ScMoreActivitiesSocketSlotActivity extends dnd5e.documents.activity.ActivityMixin(
ScMoreActivitiesSocketSlotActivityData
) {
static metadata = Object.freeze(
foundry.utils.mergeObject(super.metadata, {
type: SC_MORE_ACTIVITIES_ACTIVITY_TYPES.SOCKET_SLOT,
img: SC_MORE_ACTIVITIES_ICONS.SOCKET_SLOT,
title: "SCSockets.Integrations.ScMoreActivities.SocketSlot.Title",
hint: "SCSockets.Integrations.ScMoreActivities.SocketSlot.Hint",
sheetClass: ScMoreActivitiesSocketSlotActivitySheet
}, { inplace: false })
);
static availableForItem(item, ...args) {
const base = typeof super.availableForItem === "function"
? super.availableForItem(item, ...args)
: true;
return base && ScMoreActivitiesIntegration.isTypeEnabled(
SC_MORE_ACTIVITIES_ACTIVITY_TYPES.SOCKET_SLOT
);
}
async use(usage = {}, dialog = {}, message = {}) {
const results = await super.use(usage, dialog, message);
if (results === undefined) return results;
return ScMoreActivitiesSocketSlotActivityService.execute(this, { usage, dialog, message, results });
}
}The pattern to copy into your own module is:
- Extend
dnd5e.documents.activity.ActivityMixin(...). - Put the registered type id into
static metadata.type. - Route availability through
availableForItem(...). - Call
super.use(...)first. - Hand off the actual side effects to a dedicated service class.
The Data Model
ScMoreActivitiesSocketSlotActivityData extends
dnd5e.dataModels.activity.BaseActivityData and stores all custom fields under
slot.
Real schema fields in the example include:
slot.operationslot.nameslot.colorslot.cursorImageslot.descriptionslot.conditionslot.targetConditionslot.hiddenslot.deleteGemOnRemovalslot.ignoreMaxSockets
That structure is worth copying because it keeps custom activity state grouped under one schema branch instead of scattering unrelated top-level fields.
The Sheet and Template
ScMoreActivitiesSocketSlotActivitySheet extends
dnd5e.applications.activity.ActivitySheet and injects a custom effect-part
template:
static PARTS = {
...super.PARTS,
effect: {
template: TEMPLATE_PATH,
templates: [...super.PARTS.effect.templates]
}
};That template is
templates/integrations/sc-more-activities/socket-slot-effect.hbs, and it
renders the actual authoring controls for:
- slot operation
- slot name and color
- cursor image
- description
- condition code
- target condition code
- behavior toggles such as hidden, delete on removal, and ignore socket limit
Use this pattern when your custom activity needs real item-authoring UI instead of a small number of primitive fields.
The Runtime Service
The actual socket behavior does not live in the activity class. It lives in
ScMoreActivitiesSocketSlotActivityService.
That service decides whether the configured operation is:
- add a slot to a selected item
- remove one empty slot from the host item
The service also validates the target condition, launches the slot-picker UI
when needed, and hands the mutation back to ScMoreActivitiesIntegration.
That separation matters:
- the activity class stays small and predictable
- the data model only describes stored state
- the service owns workflow branching, validation, dialogs, and user feedback
How GM-Mediated Execution Works
SC - Simple Sockets is a strong example because it shows how to handle
mutations that may require GM authority.
Inside ScMoreActivitiesIntegration.js, the integration:
- Builds a request payload with
activityUuid,itemUuid,operation, andrequestUserId. - Executes directly when the current user is a GM or already has socket-edit permission.
- Falls back to an active GM query using a registered query id when direct execution is not allowed.
- Resolves the request on the GM side and turns the result into a normalized success or failure object.
This is the concrete pattern to follow when your custom activity mutates actors, items, scenes, or other documents that should not be changed blindly by every player client.
Minimal Blueprint For Your Own Module
If you are building a new external activity, the smallest practical file set is:
scripts/main.js
scripts/integrations/sc-more-activities/MyIntegration.js
scripts/integrations/sc-more-activities/MyActivity.js
scripts/integrations/sc-more-activities/MyActivityData.js
scripts/integrations/sc-more-activities/MyActivitySheet.js
scripts/integrations/sc-more-activities/MyActivityService.js
templates/integrations/sc-more-activities/my-activity-effect.hbsBuild it in this order:
- Register an integration class from
scripts/main.js. - Listen to
sc-more-activities.registerActivities. - Call
activitiesApi.registerType(...). - Create a document class with
metadata,availableForItem(...), anduse(...). - Add a data model for your stored fields.
- Add a sheet class and Handlebars template for configuration.
- Move the actual side effects into a service class.
- Add GM-mediated dispatch only if your workflow really needs it.
When To Copy This Pattern
Use the sc-simple-sockets structure when your activity:
- needs custom authoring fields
- performs complex runtime logic after
super.use(...) - may require GM-mediated document changes
- belongs to a module-specific activity group in the create dialog
- should stay fully owned by the integrating module instead of by
sc-more-activities
Notes and Limits
- This module supports only the
dnd5esystem. - It extends native activities instead of replacing them.
- World macros, inline code, hooks, and callbacks still follow their own permission and ownership limits.
- Canvas actions such as teleport, movement, and wall placement rely on GM-mediated scene updates.
- The migration workflow is explicit by design, which is safer than an automatic conversion but still requires review before apply.