Shattered Codex

Wiki

Modules/SC - More Activities

SC - More Activities

Foundry v13-v14System D&D 5eFree

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 dnd5e activity 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

  1. In Foundry VTT, open Add-on Modules.
  2. Choose Install Module.
  3. Paste this manifest URL:
code
https://github.com/Shattered-Codex/sc-more-activities/releases/latest/download/module.json
  1. Install the module.
  2. Enable SC - More Activities in your world.
  3. Install and enable libWrapper if you want the recommended compatibility layer.

Compatibility:

  • Foundry VTT v13 to v14
  • system: dnd5e
  • dnd5e compatibility declared in module.json: minimum 5.0.0, verified 5.3.0
  • localization: English and Brazilian Portuguese

Important behavior:

  • the module exits early outside dnd5e worlds
  • native dnd5e activities remain available
  • the module relies on items and sheets that already support the dnd5e activity 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-activities activity 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

ActivityUse it forMain configurationImportant notes
SC SoundPlay 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 MacroRun 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 HookEmit 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 ChainExecute 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 ContestResolve 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 GrantGrant 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 AdvancementTrigger 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 TeleportChoose 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 MovementPush 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 WallCreate 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.

SC Advancement
Use a source item that already contains dnd5e advancements, then select the advancement entries this activity can trigger.
1 / 10

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 menuScopeWhat it does
Debug loggingClientLogs lifecycle and diagnostic messages to the browser console for your user.
Migration backup retentionWorld, GMControls how many migration backups are stored in world settings. Default: 3. Range: 1 to 10.
Activity catalogWorld, GMOpens the registered activity catalog and diagnostics window.
More Activities migrationWorld, GMOpens the preview, apply, export, and restore workflow for legacy more-activities data.
Preview colorsClientOpens the per-user color configuration for teleport, movement, and wall overlays.
DocumentationWorld, GMOpens the wiki page for this module from inside Foundry.
Support the developerWorld, GMOpens 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 color and Border color controls
  • 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:

  1. Keep the legacy module enabled only long enough to inspect or migrate old data.
  2. Open More Activities migration from module settings.
  3. Run Preview first.
  4. Review convertible and blocked entries.
  5. Use Apply migration only after the preview looks correct.
  6. Export the preview or final report if you need a record.
  7. 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-activities module 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")?.api
  • globalThis.ShatteredCodex.activities for the published activities API

Main lifecycle hooks:

  • sc-more-activities.registerActivities
  • sc-more-activities.registryLocked
  • sc-more-activities.apiReady
  • sc-more-activities.activityRegistered
  • sc-more-activities.activityAvailabilityChanged
  • sc-more-activities.activityUseStart
  • sc-more-activities.activityUseComplete
  • sc-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:

  • moduleId
  • type
  • label
  • hint
  • icon
  • documentClass

Your documentClass must provide:

  • static metadata.type that matches the registered type
  • static availableForItem(...)
  • static localize(...)

Minimal example:

js
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-slot
  • sc-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

FileRole 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:

js
import { ScMoreActivitiesIntegration } from "./core/integrations/sc-more-activities/ScMoreActivitiesIntegration.js";
 
ScMoreActivitiesIntegration.register();

That register() method does two jobs:

  1. It listens to sc-more-activities.registerActivities.
  2. It registers a query handler during init so 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:

js
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 flow
  • groupId, groupLabel, and groupOrder create a module-specific activity group in the create dialog
  • dataModel, sheetClass, and templates turn the type into a configurable authoring experience instead of a bare runtime document
  • ownership.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:

js
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:

  1. Extend dnd5e.documents.activity.ActivityMixin(...).
  2. Put the registered type id into static metadata.type.
  3. Route availability through availableForItem(...).
  4. Call super.use(...) first.
  5. 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.operation
  • slot.name
  • slot.color
  • slot.cursorImage
  • slot.description
  • slot.condition
  • slot.targetCondition
  • slot.hidden
  • slot.deleteGemOnRemoval
  • slot.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:

js
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:

  1. Builds a request payload with activityUuid, itemUuid, operation, and requestUserId.
  2. Executes directly when the current user is a GM or already has socket-edit permission.
  3. Falls back to an active GM query using a registered query id when direct execution is not allowed.
  4. 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:

code
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.hbs

Build it in this order:

  1. Register an integration class from scripts/main.js.
  2. Listen to sc-more-activities.registerActivities.
  3. Call activitiesApi.registerType(...).
  4. Create a document class with metadata, availableForItem(...), and use(...).
  5. Add a data model for your stored fields.
  6. Add a sheet class and Handlebars template for configuration.
  7. Move the actual side effects into a service class.
  8. 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 dnd5e system.
  • 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.