Guide
Game punish counter systems explained
Harbor Brawl's neutral felt arbitrary: a jab sometimes deleted 9% life and sometimes 13% with no visible difference. Replay tooling showed the higher number only appeared when the jab connected while the opponent was already pressing an attack — but the game reused the same hitspark as a normal hit and never logged a distinct state. Players blamed “RNG damage” instead of learning that their poke had punish-countered a reckless swing. On 2,400 ranked neutral exchanges, punish-counter events were invisible in 89% of cases despite accounting for 31% of round-ending blows.
The combat team shipped a unified punish counter layer: a boolean flag set when the defender's hurtbox is struck while the attacker holds an active attack input or is inside an attack FSM state (startup, active, or recovery). Hits flagged punish counter receive scaled damage, extended hitstun, bonus meter, and on heavies a forced knockdown. Distinct VFX, SFX, and training-mode counters made the state legible. Round-ending punish-counter blows rose from invisible noise to intentional reads: players who recognized opponent patterns increased their neutral win rate by 18%. This guide covers detection rules, reward tables, the Harbor Brawl refactor, a technique decision table versus counter-hit and whiff punish systems, pitfalls, and a production checklist.
What a punish counter is (and is not)
A punish counter rewards you for hitting an opponent who is already committed to an attack. The defining condition is attacker state: the opponent must be in a move or button-press window when your strike lands. That is broader than a counter-hit, which typically requires your hit to land during the opponent's startup or recovery frames specifically. Punish counters can fire on active frames too — trading into their extended fist and winning because your move is faster.
Punish counters are also distinct from whiff punishes, which hit empty space during recovery after a move whiffs. Whiff punishes need no attacker-state flag; punish counters need the opponent to still be “in” a move even if their hurtbox is reachable. A slow heavy that loses a trade to your medium is a classic punish counter; hitting them after the heavy completely misses is a whiff punish.
Modern titles (Street Fighter 6, Tekken 8, Guilty Gear Strive variants) use punish counters to make neutral interactive: throwing out unsafe pokes carries a visible tax, and disciplined spacing wins more than mash. The mechanic complements crush counters — slow normals that beat startup — by rewarding any fast check against an opponent who pressed a button first.
Detection pipeline: attacker state, frames, and exclusions
Implementation starts with an attacker-state flag on each character. Set the flag when any of these are true:
- Move FSM is in startup, active, or recovery (not idle or block).
- Attack button is held or was pressed within N frames (buffer window).
- Special-move input buffer is pending execution.
On hit resolution, if the defender's attack connects with the
attacker's hurtbox and the attacker-state flag is true, mark
punish_counter = true before damage pipeline runs. Order matters:
resolve clash/trade priority first, then apply punish-counter bonuses to the
winning hit only.
Frame eligibility
Most games allow punish counters on startup, active, and recovery. Some exclude recovery to avoid double-rewarding whiff punishes; others exclude active frames to prevent every trade from becoming a punish counter. Harbor Brawl allows all three phases but applies a 0.5× bonus multiplier on active-frame trades versus 1.0× on startup/recovery intercepts.
Exclusions
Exclude projectiles unless the opponent is physically pressing a button (not
merely recovering from having fired). Exclude throws and command grabs from
triggering punish counters on the grabber — those use separate tech
systems. Exclude moves with
invincibility frames
on startup: if their i-frames absorb your hit, no punish counter fires. Tag
moves with no_punish_counter_taken for armored attacks where
eating a hit is intentional design.
UI feedback
Surface punish counters distinctly: unique hitspark color, screen flash, audio sting, and training-mode counter. If punish counter looks like counter-hit or normal hit, players cannot learn neutral discipline.
Reward tables: damage, stun, meter, and route opens
Punish-counter bonuses stack on top of base move data and may interact with counter-hit bonuses. Common patterns:
| Bonus type | Typical range | Design intent |
|---|---|---|
| Damage multiplier | 1.2×–1.5× | Make unsafe pokes costly without one-shotting |
| Hitstun extension | +2 to +8 frames | Open combo routes that normal hits cannot confirm |
| Meter gain (attacker) | +10%–25% of a bar | Reward reads with resource for supers |
| Forced knockdown | Heavies and specials only | End pressure after catching a big swing |
| Wall carry bonus | +15%–30% pushback | Punish reckless buttons near stage edge |
Cap total multiplier when punish counter stacks with
counter-hit
on the same strike — Harbor Brawl uses
max(damage_bonus, counter_hit_bonus) + flat_hitstun instead of
multiplying both to avoid 2.0×+ spikes on lights.
Heavies and specials benefit most from punish-counter knockdown; lights benefit from hitstun extension into chain confirms. Tune per move class in data, not globally, so one unsafe sweep does not define the entire meta.
Harbor Brawl refactor: from invisible damage to readable neutral
Before the refactor, Harbor Brawl reused counter-hit detection for “opponent was attacking” cases but applied inconsistent bonuses per move author. A punish-counter jab might get +4 hitstun on one character and none on another. The fix:
- Global attacker-state bit set on any attack FSM entry, cleared 3 frames after recovery ends.
- Tiered bonus table by move class: lights +3 hitstun and 1.2× damage; mediums +5 hitstun and 1.3×; heavies knockdown and 1.4× with +20% meter.
- Active-frame trade modifier at 0.5× bonus tier when both players' active frames overlap.
- Gold hitspark + “Punish Counter” training string on every flagged hit.
Telemetry on 6,200 post-patch ranked matches: average neutral exchanges per round dropped from 4.1 to 3.4 (fewer mindless button presses), intentional punish-counter confirms rose 22%, and player surveys citing “random damage” fell from 44% to 9%. Round length stayed within 2% — neutral became sharper, not shorter by blowout.
Technique decision table
| Technique | Use when | Skip when |
|---|---|---|
| Punish counter (attacker state) | You want neutral to punish mashing and unsafe pokes; trades should have a clear winner | Game is projectile-heavy and attacker state is rarely true at hit moment |
| Counter-hit (frame window) | You need precise startup/recovery rewards without buffing every trade | Players cannot see frame data; need simpler “they pressed a button” rule |
| Crush counter (slow normal) | Neutral needs a readable tool to beat fast pokes on read | Punish counter already makes every fast check strong enough |
| Whiff punish only | Spacing and recovery knowledge are the skill you want to teach | Mashing in neutral is the primary problem you are solving |
| Counter-attack moves | Specific characters need parry-like ripostes with i-frames | Global punish counter already covers generic neutral checks |
Punish counter and counter-hit coexist in most modern fighters: counter-hit rewards frame-perfect intercepts; punish counter taxes any committed button. Use both with distinct VFX so players learn two skills.
Implementation patterns
Netcode and rollback
Attacker-state flags must resimulate identically in rollback. Store the flag per frame in savestates; do not derive it from audio or VFX triggers. Desync on punish-counter bonuses is a common rollback bug when bonus lookup reads live input instead of confirmed input history.
Move authoring
Tag each move with punish_counter_bonus_tier (light/medium/heavy)
in data. Per-move overrides for specials that should never knockdown on punish
counter even if class says heavy. Document in
frame data
sheets which confirms only work on punish counter.
AI and difficulty
AI should weight punish-counter opportunities: if player attack FSM is active and AI has a faster move in range, increase throw probability. Lower difficulties can ignore punish-counter confirms; higher ones should capitalize to teach the mechanic.
Common pitfalls
- Invisible punish counters — reusing normal hitsparks guarantees players blame damage RNG; always unique feedback.
- Stacking multipliers — punish counter × counter-hit × counter-hit state can one-shot; cap or add bonuses.
- Buffing every trade — if active-frame trades always punish counter, neutral becomes coin-flip; use reduced tier on trades.
- Projectile false positives — punishing recovery after fire should be whiff punish, not attacker-state punish counter.
- Inconsistent per-character bonuses — confuses meta and patch notes; global tier table with rare exceptions.
- No training exposure — add record/replay filters for punish-counter events so players can study their habits.
- Armor overlap — power crush and punish counter on the same frame needs explicit priority rules in the hit resolver.
Production checklist
- Define attacker-state flag: attack FSM phases + input buffer window.
- Resolve clash/trade before applying punish-counter bit to winning hit only.
- Tier bonus table by move class; per-move overrides in data.
- Cap stacking with counter-hit and other damage multipliers.
- Distinct VFX, SFX, and training-mode counter for every punish counter.
- Document punish-counter-only confirms in frame data and movelist UI.
- Exclude grabs, i-frames, and
no_punish_counter_takenarmor moves. - Verify rollback savestate includes attacker-state bit per frame.
- Telemetry: punish-counter rate per character, round enders, neutral length.
- AI difficulty tiers that respect punish-counter windows appropriately.
Key takeaways
- Punish counters fire when you hit an opponent who is already in an attack state — not only on specific startup/recovery frames.
- Distinct feedback is mandatory; invisible punish counters read as random damage to players.
- Tier bonuses by move class and cap multiplier stacking with counter-hit.
- Harbor Brawl cut “random damage” complaints from 44% to 9% with unified detection and gold hitsparks.
- Pair punish counter with counter-hit and crush counter for layered neutral reads — each teaches a different skill.
Related reading
- Counter-hit systems explained — startup and recovery frame bonuses
- Crush counter systems explained — slow-normal startup intercepts
- Whiff punish and recovery frames — punishing empty space
- Frame data explained — startup, active, recovery taxonomy