Skip to content

feat: automate Shock Roll consequences - #22

Open
Solarion63 wants to merge 40 commits into
feature/foundry-v14-masterfrom
feat/automated-shock-effects
Open

feat: automate Shock Roll consequences#22
Solarion63 wants to merge 40 commits into
feature/foundry-v14-masterfrom
feat/automated-shock-effects

Conversation

@Solarion63

@Solarion63 Solarion63 commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Summary

Adds optional HârnMaster Shock Roll consequence automation for Foundry VTT v14.

Behavior

  • Adds world setting Automate Shock Effects (default off).
  • Preserves the legacy Shock Roll when the setting is disabled.
  • Routes combat-card Shock buttons, Actor-sheet Shock rolls, and the public game.hm3.macros.shockRoll API through one canonical workflow when enabled.
  • Uses Universal Penalty d6 vs Endurance for Shock tests.
  • Treats zero Universal Penalty as an automatic success rather than attempting a 0d6 roll.
  • On an initial failed Shock Roll, applies system-managed Unconscious and Prone effects.
  • Managed Unconscious, Prone, and Shocked effects explicitly use Foundry v14's showIcon = ALWAYS behavior so their status indicators appear on tokens.
  • In combat, recovery from unconsciousness is tied to subsequent combat turns.
  • For an unconscious actor with no non-GM OWNER, the authoritative active GM automatically makes the Shock Recovery Roll when that actor's turn begins.
  • For an unconscious actor with one or more player owners, the authoritative active GM whispers a one-per-turn Shock Recovery Required chat card to those owners and all GMs. The card contains a button for the player to make the recovery roll.
  • If combat ends while a character is still unconscious from Shock, or an initial Shock failure occurs outside combat, the system rolls the core-rule 2d6 minute unconscious duration once and schedules recovery against Foundry world time.
  • When that non-crisis duration expires, NPCs automatically regain consciousness and make the required follow-up Shock Roll. Player-owned actors instead receive a private reminder card with a button to make the follow-up roll.
  • Shock recovery cards now include a GM-only Clear Shock Recovery action so an automated unconscious state can be explicitly cancelled when necessary.
  • Removing the Unconscious status manually also prevents the hidden Shock workflow state from continuing to behave as unconscious.
  • A successful consciousness recovery immediately requires the core-rule follow-up Shock Roll.
  • Failure of that follow-up creates a Shock injury with Injury Level 0 and Heal Rate 5 (H5) and applies a Shocked effect.
  • Actual four-hour recovery after entering Shock remains intentionally deferred to the next focused change. The Shock injury notes state that recovery is tested every four hours.

Architecture

  • shock-rules.js: pure, testable Shock state/outcome rules and out-of-combat timing calculation.
  • shock-service.js: Actor flags, managed Active Effects, H5 Shock injury persistence, and recovery-state cleanup.
  • shock-workflow-v14.js: v14 roll orchestration, consequence presentation, and 2d6 non-crisis recovery scheduling.
  • shock-api-v14.js: preserves the historical public macro API while routing it through the optional workflow.
  • shock-turn-v14.js: authoritative-GM combat-turn dispatcher for NPC automatic recovery and player reminder delivery.
  • shock-out-of-combat-v14.js: authoritative-GM world-time dispatcher for non-crisis recovery and post-combat scheduling.

The workflow only removes Unconscious effects that it created itself. Prone is deliberately retained after consciousness returns or an automated Shock recovery state is cleared.

Validation

  • Adds Shock rules regression tests, including 2d6 recovery timing arithmetic.
  • Extends validate.yml to verify syntax, required files, API load order, Shock workflow wiring, combat-turn automation, out-of-combat world-time automation, and chat actions.

Runtime test plan

  1. With Automate Shock Effects disabled, verify combat-card and Actor-sheet Shock Rolls behave exactly as before.
  2. Enable the setting. Use an actor with Universal Penalty 0 and confirm Shock automatically succeeds without a 0d6 error.
  3. Force an initial failed Shock Roll and confirm Unconscious + Prone are applied and both token indicators are visible.
  4. For a non-player-owned unconscious actor, advance combat to that actor's subsequent turn and confirm the Shock Recovery Roll happens automatically exactly once.
  5. For a player-owned unconscious actor, advance combat to that actor's subsequent turn and confirm one private Shock Recovery Required card is whispered to the player owner(s) and GMs, with no automatic roll.
  6. Click the player's combat reminder and confirm it makes the Shock Recovery Roll for the correct actor.
  7. End combat while an actor is still unconscious. Confirm the system rolls a single 2d6-minute unconscious duration and records an out-of-combat recovery schedule.
  8. Advance world time to just before the due time and confirm no recovery occurs.
  9. Advance world time to/through the due time: an NPC should automatically regain consciousness and make the follow-up Shock Roll; a player-owned actor should receive one private follow-up reminder instead.
  10. Click the player's out-of-combat reminder and confirm the actor regains consciousness, Unconscious is removed, Prone remains, and the required follow-up Shock Roll occurs.
  11. Use Clear Shock Recovery while an actor is unconscious and confirm the managed Unconscious state and pending recovery schedule are cleared while Prone remains.
  12. Manually remove the Unconscious effect from the Actor and confirm subsequent world-time/combat-turn updates do not continue treating the Actor as unconscious.
  13. Pass the follow-up and confirm no Shock injury is created.
  14. Repeat and fail the follow-up; confirm a single Shock injury exists with IL 0 / H5 and the Shocked token indicator is visible.
  15. Verify another Shock Roll while already in actual Shock is blocked with a clear warning.
  16. Verify game.hm3.macros.shockRoll(false, actor) follows the same setting-controlled workflow.
  17. Verify normal Stumble/Fumble combat-card consequences remain unchanged.

Do not merge until the exact final head SHA passes CI and Foundry 14.365 runtime testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant