Concepts → Luck and streak protection
·
Luck pools and streak protection — variance reduction without changing the mean
Hard West has an explicit Luck Bar. XCOM 2 has a hidden streak protection mechanic. Both share the same mathematical structure: cross-attempt state that modulates per-attempt hit chance based on prior outcomes. The user-visible effect: variance shrinks without the mean changing in the limit. The engine models both via a state-carrying Markov walk over the per-attempt distribution.
The core idea: state breaks independence
In the standard probability model, every attack roll is independent. P(hit) is fixed; whether the prior shot hit or missed has no bearing on the current one. Convolution of N independent attempts gives the chain damage distribution.
Streak protection / Luck pools break that. The per-attempt P(hit) depends on cumulative state — typically:
- Streak protection (XCOM 2-style): consecutive misses boost the next shot's hit chance. Hit resets the streak; another miss advances it.
- Luck pool (Hard West-style): a pool of "luck" that depletes on hits and refills on misses. Higher pool = bigger boost to the next attempt.
Both produce the same user-visible outcome: misses are anti-correlated with future misses. You can't realistically miss six 70% shots in a row — the engine pushes you back toward your "fair" hit rate.
The math: state-carrying Markov walk
Each attack expression carries a streak rule that defines:
- An initial state (e.g., "no misses yet" or "full luck pool")
- A modulate function:
(state, base_P_hit) → adjusted_P_hit - A transition function:
(state, outcome) → next_state
The engine evaluates the chain as a Markov walk over a joint
(state, cumulative_damage) distribution. Per
strike, branch into hit / crit / miss outcomes weighted by
the modulated per-state probabilities; transition state per
outcome; aggregate. Marginalize over end-state for the damage
PMF.
This is exact (not Monte Carlo) — the Markov chain over a bounded state space (Luck pool 0..=5, miss streak 0..=N) evaluates in closed form for any N strikes.
The user-visible contract: variance reduction
The mean damage stays the same (linearity of expectation; the modulator preserves expected value in equilibrium). What shrinks is variance — specifically the probability of "all misses." For a 5-attempt chain at 50% hit chance:
| Chain | Mean | P(all-miss) | Strike URL |
|---|---|---|---|
| Independent (no state) | ~25 | ~3.1% (0.5⁵) | /strike/1d10~hit50attacks5 |
| Streak protection | ~27 | much lower (state boosts later attempts) | /strike/1d10~hit50attacks5streak |
| Luck pool (starts full) | ~35 | much lower (first attempt at 75% from full pool) | /strike/1d10~hit50attacks5luck |
The "luck" version's higher mean isn't the modulator "cheating" — it's that LuckPool starts at full pool (max boost on the first attempt), which biases the chain mean up. Streak protection starts neutral (no boost on first attempt) and only kicks in after misses, so its mean stays close to independent.
The variance reduction is the user-visible feature both modulators provide: the "all-miss" tail of the distribution shrinks substantially in both cases.
Engine grammar
Two postfix keywords on attack chains:
<attack> @ hit P% attacks N streak
Adds XCOM 2-style streak protection — no boost on a fresh
streak; +15% per consecutive miss thereafter, ramping
linearly through 8 streak states (0, 15, 30, 45, 60, 75, 90,
100%) and clamped at +100. The engine ships the Commander-
difficulty rate (+15); Veteran/Rookie use +10 per miss,
Legend uses 0 (no protection) per the same INI. Source:
community datamining of XComGameCore.ini's
MissStreakChanceAdjustment=15 for Commander —
Firaxis hasn't officially documented the formula. The
"shots ≥ 50% hit chance" gate the real game applies IS
modeled (see min_hit_chance_bps: 5000 on the
streak preset); shots below 50% roll without the boost.
<attack> @ hit P% attacks N luck
Adds Hard West-style Luck pool — pool of 5 capacity, +5% per pool unit (full pool = +25% boost on next attempt), each hit consumes 1 luck, each miss refunds 1. Approximate Hard West shape; exact game formula isn't officially documented.
Build planning: when does streak protection matter?
The variance reduction matters most when:
- You need a guaranteed kill window: clearing a turn-critical objective where 1-2 misses cascade into a wipe. Independent chains might whiff; streak protection bounds the worst case.
- Chain length is moderate (3-7 attacks): too few attempts and state doesn't have time to evolve; too many and the variance reduction relative to the long-run mean becomes a smaller fraction.
- Base hit chance is in the 30-70% range: below 30% even streak protection can't save you; above 70% the mean is already high and miss streaks are rare anyway.
Streak protection / Luck doesn't change the mean (much). What it changes is the SHAPE of the damage distribution — fewer catastrophic-miss outcomes, slightly more typical-roll outcomes. For tactical games where one bad turn is the difference between winning and losing, that shape matters.
Composition with other engine primitives
The streak/luck modulators compose with two of the engine's multi-attempt primitives. Both compositions use the same joint-state-space Markov walk machinery the standalone chain uses; what changes is which other state axis is in the cross product.
-
Composition with cascade chain: shipped.
attacks N luck cascade [HP1, HP2, …] onkill <attack>and the streak variant both work. The cascade state machine (target index, target HP, attack budget, pending bonus, depth cap) joins the modulator state into a single(CascadeState, StreakState)memo key; per-attack hit chance is looked up on the streak axis, and each outcome transitions both axes. Lets you model "what if XCOM had GWM-on-kill" or any kill-cascade with streak protection layered on. -
Composition with rounds_to_kill: shipped.
Multi-round encounters now thread the modulator state across
round boundaries. End-of-round-N state distribution becomes
the start state for round N+1, instead of resetting to the
modulator's initial each round. The marginal-distribution
path overstated Hard West luck-pool damage in round 2+ by
refilling the pool each round; the joint
(state, cum_damage)Markov chain is the honest model.
State persists within an encounter (the multi-round Markov threads streak / pool state across round boundaries) and resets at the encounter boundary — the right model for the vast majority of tactical game encounters, where each combat starts fresh. Per-mission Luck persistence across multiple encounters is a separate layer that wraps the per-encounter output; cross-mission carry composes by chaining encounters together with the end-state distribution as the start state for the next.
About the parameter values
Hard West's exact Luck consumption and refund formulas aren't
published in any official source. Community datamining of
XCOM 2's ConfigCharacter.ini reveals the streak
boost parameters but not the precise activation thresholds.
The presets here capture the structural shape of both
mechanics — pool depletes / refills, streak boosts after
misses — using documented community values.
The math substrate (state-carrying Markov walk) is exact. Per-game preset values can be substituted via the standard modulator parameters when a verified source is available.