Skip to content

Chapter 54 — Companion Interception

Companion interception determines whether an ally steps in to absorb an attack aimed at a protected target (the player or a backline entity). The scored formula replaces the old flat 20 + instinct * 2 with a multi-factor calculation driven by reaction speed, composure, health, morale, combat state, and role.

  1. An attack hits and damage is calculated.
  2. The target qualifies for interception (player, or backline when engagement-core is loaded).
  3. Eligible allies in the same zone are checked in order. An ally is eligible when: alive, same zone, isAlly() returns true, not FLEEING, and either ENGAGED or the target is the player.
  4. Each ally rolls against their interception chance. First ally to pass absorbs the damage.
defaultInterceptChance(ally, target, world, statMapping)
ComponentFormulaRange
Base8fixed
Reaction speedfloor(instinct * 2.5)0-25
Composuremax(0, floor((will - 3) * 1.5))0+
Healthfloor(hpRatio * 8)0-8
Critical HP-15 when HP < 25%0 or -15
Moralefloor((morale - 50) * 0.15)-7 to +6
FLEEINGhard block (returns 0)0
OFF_BALANCE-100 or -10
GUARDED+80 or +8
Role bonusper-tag table below-12 to +15
Clampmax(5, min(90, total))5-90

At default stats (instinct=5, will=3, full HP, morale=70, no status, no role), the formula produces 31% — within 1 point of the old flat 30%.

TagBonusRationale
role:bodyguard+15Dedicated protector
role:sentinel+8Defensive specialist
role:brute+5Physically imposing
role:elite+5Trained fighter
companion:fighter+8Combat companion
role:minion-5Expendable
companion:scout-5Not built for tanking
companion:smuggler-5Self-preservation instinct
role:skirmisher-8Hit-and-run style
companion:healer-8Avoids frontline
role:backliner-10Stays behind
companion:diplomat-10Non-combatant
companion:scholar-10Non-combatant
role:coward-12Self-preserving

Combat role tags (role:*) take priority over companion tags (companion:*). If neither is present, the role bonus is 0.

Factor variations from baseline (instinct=5, will=3, full HP, morale=70):

ScenarioOldNew
Baseline3031
instinct=73436
instinct=104044
will=53034
HP=50%3027
HP < 25% (critical)309
morale=303025
morale=903037
FLEEING300
OFF_BALANCE3021
GUARDED3039
role:bodyguard3046
role:coward3019

Extreme combinations:

ScenarioChance
Bodyguard, guarded, will=6, morale=90, instinct=772
Coward, half HP, morale=20, OFF_BALANCE5 (clamp)

A FLEEING ally never intercepts. This is enforced in two places:

  1. Ally eligibility filter — FLEEING allies are excluded before rolling.
  2. Formula — returns 0 if the ally has FLEEING status (defense in depth).

When engagement-core is loaded, withEngagement() wraps the formula:

  • PROTECTED targets get an additional +15 to their allies’ interception chance.
  • The wrapper calls defaultInterceptChance (not a flat fallback).
  • Total is clamped to [5, 90].

The combat-state-narration module listens for combat.companion.intercepted and generates narrator-channel text:

  • Standard: “steps in front of {target}, taking the blow”
  • Heroic (HP < 30% before interception): “staggers forward to shield {target}, barely standing”

Heroic interceptions get priority: 'high'.

The combat intent scorer estimates interception cover for each enemy:

  • Allies with role:bodyguard or role:sentinel contribute 15 cover.
  • role:brute or role:elite contribute 8.
  • role:coward or role:backliner contribute 2.
  • Default allies contribute 5.
  • FLEEING allies are excluded.

The AI applies a penalty of -min(10, floor(cover * 0.6)) to attack scores against well-covered targets, preferring to target enemies with weaker interception support.

Pack authors can fully replace the interception formula:

createCombatCore({
interceptChance: (ally, target, world) => {
// Custom logic
return 50;
},
});

When interceptChance is provided, the default scored formula is bypassed entirely. The engagement-core PROTECTED bonus still stacks on top.

To create companion archetypes with distinct interception behavior:

# Loyal bodyguard — high interception, protects at all costs
entities:
- id: iron-shield
tags: [ally, role:bodyguard]
stats: { vigor: 6, instinct: 7, will: 5 }
# Interception: ~60% (bodyguard + high instinct + high will)
# Scholar companion — avoids frontline, rarely intercepts
- id: sage
tags: [ally, companion:scholar]
stats: { vigor: 3, instinct: 4, will: 6 }
# Interception: ~14% (scholar penalty + low instinct)
# Wounded veteran — intercepts heroically at low HP
- id: old-knight
tags: [ally, role:sentinel]
stats: { vigor: 5, instinct: 5, will: 7 }
# At full HP: ~45%. At critical HP: heroic narration fires.