Tape to Tape Wiki All games ☕ Tip on Ko-fi

Goalies#

Goalie attributes, how they turn into movement, and how the game decides between a save, a goal, a rebound and a catch.


1. Goalie attributes (GoaltenderData)#

Field Range UI name (EGoalieStat) What it drives (verified)
skill −100 – 100 (in match clamped 0–200) Overall (inferred: OVR = skill) Base save chance (§4)
catchingSkill 0 – 100 Catching Chance to hold the puck instead of giving a rebound (§6)
standingSpeed 0 – 200 Standing Standing max speed and acceleration; max speed while carrying the puck
butterflySpeed 0 – 200 Butterfly Butterfly max speed and acceleration; acceleration while carrying the puck
controlSkill 0 – 100 Control Butterfly slide friction
recoverySkill 0 – 100 Recovery Speed of save-recovery animations
passPower 0 – 100 Pass Power Pass strength
shotPower 0 – 100 Shot Power Goalie shot and lob strength
pokecheckSkill 0 – 100 PokeCheck Pokecheck lunge speed
depth 0 – 100 Depth How far out of the net the goalie plays; coverage
passReadSkill 0 – 1 – Quick pass-read (only on difficulties that enable it)
gloveSkill, blockerSkill, fiveHoleSkill 0 – 100, hidden Glove/Blocker/FiveHole No gameplay use found (legacy)

Across the 50 goalie assets, typical values are skill ~80–95 (mean 69 because some joke goalies have −100), catching ~74, standing/butterfly ~82, depth 16–100 (mean 32), and goalie shot power 25–100 (mean 44).

In-match modifiers exist for only five goalie values. Skaters.GoaltenderStats has Func<int,int> lists overallSkillEvent, overallRecoveryEvent, overallStandingSpeed, overallDepth and overallButterflySpeed. Goalie talents and relics such as Goalie Speed and Enraged can only change these five. Every other field is read raw.

Source: Data.GoaltenderData, Data.EGoalieStat, Skaters.GoaltenderStats, loc v2/player-customization/goalie_stat/*.


2. Movement and size formulas#

t = clamp01(stat/100) unless noted. "Lerp" is linear and "SmoothStep" is Unity's Mathf.SmoothStep.

Value Stat used Formula Range
Standing max speed standingSpeed (+mods, clamp 0–200) Lerp(1.5, 6.0, t) 1.5 → 6.0
Standing acceleration standingSpeed (+mods) Lerp(6, 9, t) 6 → 9
Butterfly max speed and acceleration butterflySpeed (+mods) Lerp(3.5, 6.0, t) 3.5 → 6.0
Max speed with puck, standing / butterfly standingSpeed (raw, clamp 0–100) SmoothStep(1.6, 3.0, t) / SmoothStep(1.1, 1.8, t)
Accel with puck, standing / butterfly butterflySpeed (raw) SmoothStep(19, 32, t) / SmoothStep(12.8, 22.4, t)
Fetch max speed (GetMaxSpeedFetch) – max(6, standingMaxSpeed), +6 with a certain talent (type unresolved)
Pass power, standing / butterfly passPower SmoothStep(18, 30, t) / SmoothStep(14, 25, t); −7 without a stick
Shot power shotPower Lerp(22, 42, t) + 0 × hold 22 → 42
Lob shotPower Lerp(2, 9, t) + 2 × holdLerp (the asset's minLobPower = 9/maxLobPower = 2 are swapped by name)
Pokecheck speed pokecheckSkill Lerp(3, 6, 3t² − 2t³) 3 → 6
Max distance in front of net depth (+mods; +50 in one game mode) Lerp(1.25, 4.75, t); min distance is a constant 1.5
Coverage (GetCoverage) depth (+mods) 0.6 + 0.05 × (1 − t) 0.65 → 0.60
Butterfly friction controlSkill Lerp(f(0.25), f(0.35), t), with f(p) = butterflyAccel·p / (0.5·|g|)
Save recovery time scale recoverySkill (+mods) typeFactor × t (table below)

Standing and butterfly speed stop helping at 100. The stat is clamped to 0–200, but the formula input t is clamped to 0–1, so values above 100 add nothing. Enraged's +80 Standing only matters for goalies below 100.

Save recovery typeFactor by save type:

SaveType factor
Pad 1.65
Blocker/Glove Butterfly (when in butterfly), Soccer Kick 1.2
Butterfly 1.1
Gobble 1.0
Blocker/Glove Standing (when standing) 0.5
Desperate, Pad Stacker 0.3
Above The Net 0.25
others 0

Unused helpers in GoaltenderStatsUtil. It also defines GetBlockerSize/GetGloveSize (SmoothStep 0.5 → 1.2), GetRecoveryTimeAfterSave = (0.05 + 0.45·clamp01((puckSpeed−10)/80)) / (1 + 2t), and GetRecoveryMaxSpeedAfterSave = 3 − 2.5t. No direct callers were found, so they may be unused or inlined (inferred).

Pads (collider sizes, inferred): smallest / small / regular = 0.45 / 0.65 / 1.36 for the north goalie and 0.50 / 0.95 / 0.86 for the south goalie (Team.isNorth). ResetPadsSize restores them after a save. Goalie skins, pads and helmets are otherwise cosmetic.

Source: Skaters.GoaltenderStats::*, Skaters.GoaltenderStatsUtil::* (data goaltenderStatUtil), Goaltender.Goaltender::GetMaxSpeed/GetAcceleration/GetMaxSpeedFetch.


3. Current skill: fatigue and clutch#

Goaltender.GetCurrentSkill() adjusts skill (after modifiers, clamped 0–200) each shot:

  • CPU goalie (team has no human Players): loses 1 skill per shot on net since the last goal it conceded, down to a floor of 85% of its skill: current = max(round(0.85·skill), skill − shotsSinceLastGoal). The counter resets when a goal is scored. In practice, peppering a CPU goalie with shots wears it down by up to 15%.
  • Human goalie: gets +15 skill in clutch spots. One is a first-to-N game when the opponent needs only one more goal (opponent goals = MaxGoal − 1). The other is a second, time-based end-condition case (exact condition inferred).

Source: Goaltender.Goaltender::GetCurrentSkill, .ctor (skillToLosePerSave = 1), OnShotOnNet, OnTeamScore.


4. Save chance (ShotQualityCalculator.CalculateShotQuality)#

When a shot is on net, the game computes a save chance in percent for the goalie.

Step 1: distance and time#

  • d = distance from the shot release point to the centre of the goalie's net. Long distances are compressed: if d > 15, then d = max(15, d − 20).
  • t = d / max(shotSpeed, 1), the time the puck takes to reach the net.

Step 2: base from skill#

base = skill ≤ 10 ?  skill + 30  :  75 + 0.2·skill

For example, skill 50 → 85, skill 80 → 91, skill 95 → 94.

Step 3: shot modifier = time term + distance term#

Time to net t Time term
≤ 0.05 s −15 … −10 (linear)
0.05–0.10 s −10 … −5
0.10–0.20 s −5 … 0
> 0.20 s 0 … +5 (reaches +5 at 0.40 s)
Distance d Distance term
< 6 −14 … 0 (14·d/6 − 14)
6 – 12 0
> 12 0 … +5 (reaches +5 at d = 25)

CalculateAngleBonus (up to +12 for a straight-on angle) is computed, but its result is discarded, so shot angle has no effect on the save chance.

Step 4: difficulty bonus#

Difficulty CPU goalie Human goalie
Training −10 +12
Veteran +9 +6
Pro +6 +8
Nightmare +12 +3

These come from cpuGoalieSaveChanceBonus / humanGoalieSaveChanceBonus.

Step 5: human-goalie soft-goal prevention#

Human goalies only. If the shot is slow or from far away, the save chance is raised to at least 70 + 0.25·skill. The trigger is any of: t > 0.4 & d > 12, t > 0.5 & d > 8, a low angle factor, and so on.

Step 6: situational adjustments#

Condition Effect
One-timer vs a CPU goalie + cpuGoalieOneTimerSaveBonus (Nightmare +5, otherwise 0)
Critical shot (ShootingArg.isCritical) −25
Shot has the Curve Ball talent −10
Human goalie Run through a contrast curve that spreads mid values apart (below)
CPU goalie, shot t > 0.35 s and d > 12 Chance 0.03 − 0.025·(skill/100) to halve the save chance ("random soft goal")
CPU goalie, otherwise 0.1% chance to multiply by 0.6
Hard blue-line shot − 12 × hard-shot strength (0–1)
Shootout mode (inferred mode id) ×0.55
Final clamp Human goalie 5–100, CPU goalie 5–99

Human-goalie contrast curve (ApplyHumanGoalieContrast), input → output:

in <50 50 60 70 80 88 90 95 100
out ×0.72 36 50 63 74 88 94 99 100

Source: Skaters.ShotQualityCalculator::CalculateShotQuality/CalculateSaveChance/CalculateBaseFromSkill/CalculateShotModifier/ApplyDifficulty/ApplyHumanGoalieContrast/ApplyOpponentVariance/EnforceSoftGoalPrevention; consts CriticalBonus 25, CurveBallBonus 10, ShootoutSaveChanceMultiplier 0.55, HardBlueLineSavePenaltyMax 12; Data.DifficultyLevel data.


5. Save or goal (SavingState.OnEnter)#

Starting from the save chance q:

  1. Butterfly penalty. If the goalie is in butterfly and q ≤ 90: q ×= 0.96 (×0.975 for the home team in game type 1).
  2. Goal pacing. GoalPacingSystem counts consecutive saves per goalie. Past a threshold, q drops (only applied while q < 95, floor 5):
Threshold Penalty per extra save Max penalty
CPU goalie 4 (Training/Pro) or 5 (Veteran/Nightmare) −4 −25
Human goalie 6 −3 −20
  1. Recent save. If the goalie made a save less than 3 s ago and q < 95: q −= 3, so rebounds are slightly easier to score.
  2. Roll. goal = Random.Range(1, 101) > q. The goal is cancelled (forced save) if any of these hold: - the goalie is Enraged (status tag 3), which means an enraged goalie never lets a goal in; - the shot has overrideSave; - the game mode forbids goals (mode id 3); - Save protection (human goalie vs CPU shooter): the CPU's first shot of the game is always saved, and after the CPU scores, the next 3 CPU shots are always saved (FORCED_SAVES_AFTER_GOAL = 3); - in one specific home-team mode, a slow shot (puck speed ≤ 50) from ≥ 9 units out is always saved.
  3. Forced rebound flag (ShouldFailWithRebound), only on saves. It is set when all three hold: - q ≤ 93 + 2·hardShotStrength; - the puck speed is ≥ 40 or the time to impact is ≤ 0.22 s; - Random(0,1) ≤ clamp01(0.6 + 0.1·hardShotStrength) (0.2 + … in one home-team mode).

Critical shots that are saved always set this flag.

Source: Goaltender.GoaltenderStates.SavingState::OnEnter, Goaltender.GoalPacingSystem::GetSavePenalty, Goaltender.GoalieSaveProtection::ShouldForceSave/OnGoalScored/RegisterSave.


6. Catch vs rebound (SavingState.HandlePossession)#

When the puck touches the goalie on a save, and the shot was not critical, the game rolls r = Random(0,1) against a catch chance:

c = 0.7·(catchingSkill/100) + 0.3·(q/100)
if puckSpeed > 70:              c = min(c, 0.10)
if (an internal flag):           c ×= 0.5
if shot released within 6 units: c ×= 0.3 + 0.7·(dist/6)
if CPU goalie:                   c = max(0, 1 − 1.5·(1 − c))    // harsher for the CPU
  • If r ≤ c, the goalie holds the puck: a gobble, or a glove/blocker freeze (MoutardeGobble/MoutardeGloveBlocker).
  • Otherwise the puck rebounds off the pad, blocker or body.
  • Desperate, Pad-Stacker and Above-The-Net saves never freeze the puck off a blocker or body contact.

Worked example: a CPU goalie with 80 catching facing a q = 90 shot gets c = 0.83 before the CPU adjustment and 0.745 after. A 75-speed slapshot caps the chance at 0.10, and the CPU adjustment then brings it to 0.

Source: Goaltender.GoaltenderStates.SavingState::HandlePossession (reads GoaltenderData.catchingSkill at +0x144).


7. Enraged goalie#

The EnragedEffect status (10 s) gives a goalie:

Bonus Value
Skill +80
Standing speed +80
Butterfly speed +30
Depth +30
Save roll always saves (§5 step 4)

The keyword text reads "quicker and reacts faster". Visually, the goalie's face catches fire. Sources include the Goalie Enraged On Goal / On Shot / On Breakaway / First 30 Sec / Last 30 Sec relics and talents.

Source: Rogue.EnragedStatusEffect data (goalieSkillBonus 80, goalieStandingBonus 80, goalieButterflyBonus 30, goalieDepthBonus 30, duration 10), Rogue.EnragedStatusEffectController::AddGoalie*Bonus, SavingState::OnEnter (HasTag(Enraged)).


8. Other difficulty-driven goalie behaviour#

DifficultyLevel field Training Veteran Pro Nightmare
goaliePokecheckDistance (min–max) × mult 0.5–1.75 ×0.5 ×1.0 ×1.0 ×1.0
goaliePokecheckForce (min–max) × mult 0.4–0.7 ×0.5 ×1.0 ×1.0 ×1.0
enableGoalieQuickPassRead no no no yes
pass reaction delay (quick / default) 0.25 0.25 0.25 0.10 if passReadSkill > 0
pass glide entry delay (quick / default) 0.10 0.10 0.10 0.0 if quick read
goaliePassInterceptChance 0.10 0.25 0.45 0.65

Source: Data.DifficultyLevel data, Skaters.GoaltenderStats::HasQuickPassRead/GetPassReactionDelay/GetPassGlideEntryDelay.