Skip to content

V13.5.0 API and Experimental Morale

Choose a tag to compare

@GnollStack GnollStack released this 28 Feb 05:47
· 35 commits to main since this release

Squad Combat Initiative v13.5.0

Foundry VTT Compatibility: v13+
D&D 5e System: 5.1.0+, verified 5.2.5

This release introduces a experimental and optional Squad Morale System, exposes a fully documented public API for macro developers, and includes vital bug fixes and internal refactoring for better stability.

What's New

  • Experimental Squad Morale System: A fully opt-in morale mechanic for group combat. Each living member rolls individually against a dynamic DC, with automatic application of the Frightened (or custom Fleeing) condition on failure.
    • Roll formula: 1d20 + WIS Modifier + floor(CR) + Mob Confidence vs DC 10 + Casualty Penalty
    • Mob Confidence gives a bonus based on how many squad members are still standing (+1 per N living members, configurable per group).
    • Casualty Penalty counts both dead (HP = 0) members and any combatants deleted from combat mid-fight.
    • Discipline Levels per group: Expendable (disadvantage), Standard (normal), Elite (advantage), Fearless (immune).
    • Disabled by default — zero impact on existing workflows unless you turn it on.
  • Manual morale button: A white flag icon ( 🏳️ ) on each group header triggers a check on demand. Only appears when the morale system is enabled.
  • 50% casualty auto-prompt: When a group's living members drop to a configurable threshold (default 50%) of their starting size, the GM receives a private whisper with a clickable [Roll Morale] button. Fires once per group per combat to avoid spam.
  • Discipline level selection: Added to both the Create Group dialog and the Edit Group context menu. Standard is the default, so existing groups are unaffected.
  • Formatted morale chat card: GM-only output showing the DC, all modifier breakdowns, discipline level, roll formula, a passed/failed summary, and a per-combatant table with individual rolls and results. Green rows held; red rows broke.

New Settings

Five new settings under Configure Settings → Squad Combat Initiative, all gated behind the master toggle:

Setting Default Description
Enable Morale System Off Master switch — all morale features are hidden when disabled
Auto-Prompt Threshold 50% Casualty % that triggers the GM whisper
Failure Status Effect Frightened Apply dnd5e's built-in Frightened or a custom Fleeing effect
Mob Confidence Divisor 3 +1 bonus per this many living members; can be overridden per group
Effect Duration (rounds) 0 0 = permanent until removed manually

Public API

Squad Combat Initiative now exposes a fully documented public API, enabling macros, scripts, and other modules to programmatically control groups solving #3.

Access the API:

const api = game.modules.get("squad-combat-initiative").api;

Wait for API ready:

Hooks.on("squad-combat-initiative.apiReady", (api) => {
  // API is available
});

New Methods & Constants:

  • rollMorale(combat, groupId) — trigger a morale check programmatically
  • getLivingMembers(combat, groupId) — get combatants with HP > 0
  • getDeadMembers(combat, groupId) — get combatants with HP = 0
  • getCasualtyCount(combat, groupId) — dead + deleted member total
  • DISCIPLINE — enum constant ( EXPENDABLE, STANDARD, ELITE, FEARLESS )

Bug Fixes

  • Context menu breaks after turn changes — Right-clicking group headers stopped working after onUpdateCombat fired (e.g., when advancing to the next combatant's turn). The ContextMenu was attached to the inner <ol> element, which Foundry's render cycle can replace. It is now attached to the application's persistent root element, ensuring the context menu survives all re-renders.

Internal Refactoring

All group management operations previously scattered across inline event handlers and dialog callbacks have been extracted into named static methods on GroupManager. The following UI handlers now delegate to shared methods:

  • Reset button → GroupManager.resetGroupInitiative()
  • Visibility toggle → GroupManager.toggleGroupVisibility()
  • Inline initiative edit → GroupManager.setGroupInitiative()
  • "Add Group" dialog → GroupManager.createGroup()
  • Context menu "Edit Group" → GroupManager.editGroup()
  • Context menu "Set Group Initiative" → GroupManager.setGroupInitiative()

Note: This refactor has no behavior changes — all existing UI functionality works identically.

The morale system is off by default. Existing groups and combats are completely unaffected unless you enable it in settings.