Tape to Tape Wiki All games ☕ Support me

Shooting#

How shots are produced: shot types, how Shot Power becomes puck speed, how Accuracy becomes aim error, close-range and long-range rules, one-timers, bats and deflections.

Stats are normally 0–100 but can exceed 100 with bonuses.


1. Shot types#

Skaters.ShotType:

Value Name Produced by
0 Wristshot Tap shoot (SkaterAbility::WristShot)
1 Slapshot Hold and release shoot (SkaterAbility::SlapShot, the _Slapshot coroutine)
2 Redirect Deflections / headshot redirects
3 Bat Swinging at an airborne puck (SkaterAbility::Bat)
4 Throw Thrown puck (ThrowPuck)
5 OneTimer One-timer (tracking/events; one-timer slapshots roll crits as Slapshot)
6 Yoyo One-timer of a Yo-Yo ability puck

Glossary (in-game): Wrist shot: "A quick shot performed by tapping the shot button. Less powerful than a slapshot." Slapshot: "hold the shot button to wind up, release to fire." One-Timer: "Shooting a pass the moment it arrives… Not considered a slapshot."

Game restrictions (State.GameRestriction) can disable shots: NoWristShot, NoSlapshot, NoBatting. Trying a restricted wrist shot makes the skater stagger instead (WristShot → Forward::Staggered).

Source: Skaters.ShotType, SkaterAbility::WristShot, SkaterAbility::VerifyRestriction.


2. Shot Power → puck speed#

All formulas use the skater's total Shot Power (ForwardStats::GetTotalShotPowerStats, which includes bonuses and curses such as CursedNoodle). x = max(0, ShotPower) / 100.

Shot Formula (verified) Stat 0 25 50 75 100 150 200
Wrist shot max(10, 15 + 35·x^0.55) 15.0 31.3 38.9 44.9 50.0 58.7 66.2
Backhand wrist max(8, 12 + 27·x^0.55), stat capped to 0–300 12.0 24.6 30.4 35.0 39.0 45.7 51.5
Slapshot max(13, 20 + 50·x^0.55) 20.0 43.3 54.2 62.7 70.0 82.5 93.2
Bat 12 + 27·x^0.55 12.0 24.6 30.4 35.0 39.0 45.7 51.5

(x^0.55 is a Mathf.Pow call with exponent 0.55. Values are puck speed in world units per second (inferred unit).) The max() floors never take effect for non-negative stats.

Diminishing returns: going from 0 to 50 Shot Power gains more speed than going from 50 to 100.

ShotPowerOverride (set by some power-ups) replaces the slapshot power when present.

2.1 Modifiers applied at release#

Order for a wrist shot (GetWristShotDirection): 1. Base power: forehand formula, or the backhand formula when SkatingAnimation::IsBackhand (the shot direction falls in the backhand arc). 2. If critical: +CritPower (+50 base, see critical-shots.md) and +10 accuracy. 3. Close-range reduction, if power ≥ 15: t = clamp01((7.25 − distToNet) / 5), then power = max(15, power − power·0.2·t). At up to 2.25 units from the net, wrist shots lose 20% (but not below 15).

Order for a slapshot (<_Slapshot>::MoveNext): 1. Base power: ShotPowerOverride or GetSlapShotPower(). 2. If critical: +CritPower. 3. If one-timer: +Random.Range(0, 15). 4. Close-range reduction, if power ≥ 20: power = max(20, power − power·0.5·t) with the same t. Point-blank slapshots lose up to 50%.

Wind-up time does not scale base slapshot power in the code examined. holdTime is used by Charge Shot (forced crit at full charge) and passed to power-ups (GetPowerupsInShots(holdTime, …)).

After the direction is built, release-time power-up hooks can still change the shot: ApplyWetNoodleDebuff, ApplyYipsDebuff, ApplySandShotDebuff, ApplyFairwayShotBoost, ApplyNoSlapshotPenalty, AimAtPost, plus golf-ball multipliers (GolfBallShotSpeedMultiplier = 0.8).

Source: Skaters.StatsUtil::GetWristShotPower/GetSlapshotPower/GetBackhandPower/GetBattingPower, ForwardStats::GetWristShotPower/GetSlapShotPower/GetBattingPower, SkaterAbility::GetWristShotDirection, SkaterAbility/<_Slapshot>d__100::MoveNext.


3. Accuracy → aim error#

3.1 Effective accuracy per shot type#

Shot Accuracy fed to the aim randomizer
Wrist shot (< 24 units from net) Accuracy (+10 if crit)
Wrist shot (≥ 24 units, SkatingConfiguration.distanceToManualShot = 24) 0 (long shot, see §4)
Slapshot (< 24 units) round(85 · (Accuracy/100)^1.5) (+10 if crit)
Slapshot (≥ 24 units) 0, plus a random yaw of ±10° (unless the shooter uses AimMode.Pattern)

Slapshot accuracy curve (before the crit bonus):

Accuracy stat 25 50 75 100
Slapshot effective accuracy 11 30 55 85

At equal stats, slapshots are far less accurate than wrist shots. For one-timer slapshots, an unidentified team relic adds (Speed − ForwardData base speed) to Accuracy before this curve (inferred).

3.2 Aim randomization (Skaters.ShotAccuracy::RandomizeShot)#

  1. Tier lookup: index = clamp(RoundToInt(acc/10) − 1, 0, 9) into GameManager.shotAccuracyDatas (Data.ShotAccuracyData). All tiers share one DistributionCurve.
Tier asset maxX (horizontal) maxY (vertical)
shotAccuracy1 0.50 0.55
shotAccuracy2 0.48 0.53
shotAccuracy3 0.46 0.50
shotAccuracy4 0.44 0.48
shotAccuracy5 0.42 0.45
shotAccuracy6 0.39 0.42
shotAccuracy7 0.35 0.38
shotAccuracy8 0.30 0.33
shotAccuracy9 0.24 0.26
shotAccuracy10 0.18 0.20

(The list is assumed to run tier 1→10 in GameManager order (inferred).)

  1. Distance factor: d = clamp01((distToNet − 3) / 13). distMult = lerp(0.5, 1.4 − 0.35·a, d) with a = clamp01(acc/100). Close shots get half the spread. Far shots get up to 1.4× (low accuracy) or 1.05× (100 accuracy).
  2. Angle factor: angleMult = 1 + 2.5 · clamp01((angleDot − 0.9) / −0.75). Straight-on shots (angleDot ≥ 0.9) get 1×, sharp-angle shots up to 3.5×.
  3. Error magnitudes: horizontal ≈ distMult · maxX · angleMult · curve.Random(). Vertical uses maxY, with the angle factor applied at half strength ((angleMult−1)·0.5 + 1).
  4. Toward-center bias: towardCenter = 0.45 + 0.3 · clamp01(acc/90)^0.8, blended toward 0.5 at bad angles. This is the chance that a miss is pulled toward the middle of the net instead of wide. Aims within ±0.15 (horizontal) or ±0.3 (vertical) of center pick a random side.
  5. Near-perfect shot chance: before the normal error, a roll Random.value < P gives an almost-perfect shot (only ±0.03 jitter): P = ((0.2 + 0.5·a) · lerp(1 − 0.6·d, 1, 0.7·a) + 0.6·clamp01((8 − dist)/5)) · angleTerm angleTerm = 0.9·clamp01((angleDot − 0.15)/0.75) + c (c ≈ 0.1, unresolved constant) (inferred)
  6. Post handling: AvoidPostTarget / AvoidSidePostPath keep the result out of a band around the posts (MinPostAvoidanceBand 0.25–MaxPostAvoidanceBand 0.35, PostAvoidanceInsideChance 0.8). Near the net (NoMissAboveNetDistance = 3) shots aren't sent over the crossbar (CrossbarClampInset 0.1) (constants verified, exact branch logic inferred).

A "perfect" aim (isPerfectShot = true, accuracy 100) skips the randomizer. The game uses it to compute the ideal direction first.

Stray Shot talent: shots are sent to CalculateWildMissTarget when Random.value < missChance. The data has missChance = 0.7, while the tooltip says 90%. It also gives +200 Shot Power.

Source: ShotAccuracy::RandomizeShot, GetSpreadFactor (0.5 − 0.45a), GetTowardCenterChance, GetNearPerfectChance, AdjustForLeftRightShot/HighLowShot, Data.ShotAccuracyData, SkaterAbility::GetShotDirectionFromController/GetAimPosition.

3.3 Aim cones (StatsUtil)#

StatsUtil defines max aim angles that grow with a stat (statUtil asset):

Formula Stat 0 50 100
Wrist shot max angle 10 + 0.75·stat 10° 47.5° 85°
Slapshot max angle 5 + 0.45·stat 5° 27.5° 50°

ForwardStats::GetMaxSlapshotAngle(accuracy) uses the slapshot formula. No direct callers were found for these getters, so how they are used in gameplay is unverified (inferred: limits how far off the skater's facing a shot can be aimed).

3.4 Forehand / backhand arcs#

SkatingAnimations.ShotQuadrantSettings splits the shot direction, relative to the skater, into Backhand / Alt Forehand / Forehand arcs. Default boundaries: altForehandStart −151.1°, forehandStart −24.1°, forehandEnd 46.6°, with per-direction overrides (e.g. East −174.9/−20/40.5, South −129.8/−24.1/71.0). Shots in the backhand arc use backhand power and cannot crit unless the skater has a crit-modifier source.


4. Long shots, dump-ins and close-range clamps#

Rule Detail
Dump-in A wrist shot from a human-controlled skater counts as a dump-in when IsOutOfZoneShot, the shot is not a headshot, and the skater has had the puck ≥ 0.15 s (FirstTouchShotWindow; first-touch shots are exempt). It uses GetDumpInDirection (consts: speed ×1.2, min speed 28, peak height 2.25–3.5, max angle 65°)
Long wrist shot (≥ 24 units) Accuracy 0. Unless AimMode.Pattern, horizontal speed is clamped to Random(25, 35), vertical set to Random(6, 12), yaw rotated Random(−2°, 2°)
Long slapshot (≥ 24 units) Accuracy 0 and Random(−10°, 10°) yaw. Out-of-zone slapshots that aren't IsLongRangeShotExempt get a further 10°–18° yaw (OutOfZoneSlapshotMinYaw 10, OutOfZoneSlapshotYaw 18) (inferred direction)
Low-speed vertical clamp If the resulting shot speed < 19, the vertical velocity is clamped to [−10, 7] (both wrist and slap)
Goal-line clamp ShotGoalLineClampBuffer = 0.2: the aim point is kept 0.2 inside the goal line (GetShotDirectionFromController)
Close-shot vertical cap MaxCloseShotVerticalSpeed = 14 when flight time < CloseShotFlightTimeThreshold 0.16 s (constants only)
Open net OpenNetAim retargets when the opposing net is abandoned (AbandonedNetGoalieDistance = 4)

5. One-timers#

  • A one-timer is a slapshot taken on a pass as it arrives (SlapShot(..., oneTimer: true)).
  • Power: +Random.Range(0, 15) speed on top of the slapshot formula.
  • Crit roll as Slapshot. The OneTimer shot type is not passed, so Sweet Spot does nothing here (see critical-shots.md).
  • The goalie has less time to set up. DifficultyManager.GetCpuGoalieOneTimerSaveBonus exists for CPU goalies (not traced).
  • Yo-Yo one-timers use shot type Yoyo. At Yo-Yo Lv2 they are forced crits, and with oneTimerSelfSonicSlap they set off a Sonic Slap with radius 8.

6. Bat shots#

SkaterAbility::Bat (glossary: "knock a flying puck out of the air"):

  • Power 12 + 27·x^0.55 (batting power), accuracy = Accuracy stat, aimed with ShotType.Bat.
  • Mis-hit roll (puck above a height threshold, aim not Pattern): if Random.value > 0.25 and Random(0,100) > Accuracy, the bat pops up: horizontal speed Random(2.5, 14), vertical Random(5, 25). Mis-hit chance ≈ 0.75 × (1 − Accuracy/100).
  • Another branch uses 1.4 × batting power with a perfect aim (trigger condition not traced). A third branch bats the puck as a pass, using pass power plus a random insideUnitCircle offset.
  • Bats never roll for a crit.

7. Deflections / redirects#

  • Glossary: "Changes the direction of a shot already in progress. Automatically occurs when a teammate is between the puck and the net during a shot."
  • Deflections are tracked as touches (State.TouchType: TipDeflect, HeadshotDeflect, BodyDeflect) and count toward goal and assist credit (LastTouches::OnDeflect).
  • Puck.RedirectShotGraceTime = 0.1 s (constant only). Headshot redirects use SkaterAbility::_Headshot(direction, redirect) and ShotType.Redirect.
  • Redirects do not roll for a crit.

8. Sticks#

  • Glossary: a skater without a stick can't shoot or pass until they get one. Spare sticks (Extra Stick) are used first when disarmed.
  • SkaterAbility::BreakStick / LoseStick(direction, xzForce, yForce, …) handle broken and lost sticks. Crit knockouts call Knockout(..., willLoseStick: true).
  • Glass Cannon (ShatterStrike): stick breaks on non-crit shots.

9. Posts and the goalie#

  • Glossary: "Shots that hit the post without going in the net stay in play." GoalPost raises post events (PuckOnPostEventArgs), used by relics such as FalseGoalOnPostController.
  • Goalie save chance is computed in ShotQualityCalculator::CalculateShotQuality (goalie skill, distance, angle, time remaining, difficulty). Shot modifiers seen there: crit −25, CurveBallBonus 10, shootout ×0.55, hard blue-line shots (speed 50–65) up to −12 save chance and up to +0.1 rebound chance. Goaltending has its own page.

Source: Skaters.ShotQualityCalculator constants and CalculateShotQuality.

Comments