Guide
Game friendly fire systems explained
Harbor Siege's medic class shipped with a single boolean:
friendly_fire = false. Direct rifle shots could not hurt allies.
Rocket launchers, flashbang concussions, and burning oil puddles still applied
full splash to anyone in radius — including medics channeling a revive three
meters from the blast. After two weeks, 41% of medic mains stopped queuing for
co-op raids. Support tickets blamed “broken netcode” because kill
feeds showed no attacker name on splash deaths. The refactor introduced a
layered friendly-fire policy: direct weapon hits blocked, ability
splash at 35% reduced damage with clear attribution, and a 1.2-second rez
immunity bubble. Medic queue time dropped 22% and squad wipes from self-grenades
fell 31%.
A friendly fire (FF) system decides whether damage, knockback, debuffs, and forced movement from one player or ally NPC can affect teammates. It sits at the intersection of combat math, team identity, and social trust. Turning FF off entirely feels safe but can make grenades and area spells absurd; turning it on without telegraphs breeds griefing and accidental team kills. This guide covers FF policy taxonomy, where filters belong in the damage pipeline, grenade and AoE collateral rules, knockback and rez edge cases, UI and kill-feed attribution, multiplayer authority, the Harbor Siege medic refactor, a technique decision table, pitfalls, and a production checklist. Pair with area-of-effect systems, grenades and throwables, and co-op design for the full team-combat stack.
FF policy taxonomy
A single global on/off flag rarely survives production. Most shipped games mix policies by damage source, game mode, and role:
| Policy | Behavior | Typical use |
|---|---|---|
| FF off (full block) | Allied entities immune to ally-sourced damage and debuffs | Casual PvE, hero shooters, family modes |
| FF on (full damage) | Allies take 100% from ally hits, splash, and DoT | Hardcore realism, some PvP sandboxes |
| Scaled FF | Reduced damage or debuff duration on allies | Tactical co-op, extraction shooters |
| Source-split | Direct hits blocked; splash or environmental still applies | Ability-heavy RPGs, siege modes |
| Role carve-outs | Medics, summons, or pets exempt or differently ruled | Class-based co-op, MOBA adjacency |
| Mode override | FF rules change per playlist or difficulty | Ranked vs casual, weekly mutators |
Document policies per DamageSource tag, not per weapon ID.
“Rocket splash” and “rifle bullet” should share a
pipeline stage even if tuning differs.
Damage pipeline placement
FF checks belong after hit validation and before mitigation so logs stay honest. A typical server-side order:
- Hit resolve — raycast or overlap confirms target entity.
- Team filter — compare
instigator_team_idvstarget_team_id; apply policy table. - Immunity gates — rez bubble, spawn protection, cinematic i-frames.
- Mitigation — armor, resist, shields (see damage mitigation).
- Apply and broadcast — HP delta, knockback impulse, status stacks.
If FF blocks damage, still log a blocked_friendly event at verbose
level for QA. Silent drops make “why didn't my nade hurt the boss
add?” bugs impossible to trace.
Knockback and displacement need explicit policy. Blocking HP damage but applying full knockback sends allies off cliffs — a common oversight when FF is “off.” Either zero ally knockback or scale it with the same FF table.
Grenades, AoE, and DoT collateral
Splash damage is where FF policy matters most. Players aim at enemy clusters knowing allies may stand nearby. Rules to define upfront:
- Radius falloff on allies — same curve as enemies or steeper reduction at center?
- Self-damage — separate from FF; many games allow 50% self-splash to punish careless throws.
- Persistent zones — fire patches and poison clouds must declare owner team; allies entering may take reduced tick or none.
- Chain and pierce — lightning that jumps between targets should not retarget allies if FF blocks direct ally hits.
- Healing overlap — healing AoE on damaged allies is fine; damaging AoE that also heals creates ambiguous net effects.
Telegraph ally-safe zones in UI when FF is source-split: outline color, reduced particle intensity on friendly ground decals, or a brief “allies immune to direct fire” tooltip on weapon inspect.
Attribution, UI, and social systems
When FF is on or scaled, players need to know who hurt whom:
- Kill feed — prefix team kills with ally icon; show weapon or ability name on splash.
- Damage numbers — use a distinct color for ally-sourced hits (see floating combat text).
- Death recap — list last five damage sources with team flag; critical for appeal flows.
- Scoreboard — track team damage dealt and accidental kills separately from enemy kills.
- Griefing tools — vote-kick thresholds, FF strike counters, or auto-mute after repeated ally kills in PvP-adjacent modes.
If splash kills show blank attacker, players assume cheats. Always propagate
instigator_id through AoE spawn even when damage is reduced.
Multiplayer and rez edge cases
Co-op FF bugs cluster around revive and downed states:
- Downed bleedout — can allies finish a downed teammate with FF on? Usually no; downed should be non-damageable by allies.
- Revive channel — interrupt rules: does ally splash cancel medic rez? If yes, medics need immunity or players avoid support roles.
- Rez inside hazard — FF-off does not stop environmental damage; eject or grant brief i-frames (see revive systems).
- Late join — sync team roster before first shot; temp allies during handoff need stable team IDs.
- Summons and pets — inherit owner team; pet splash should follow owner FF policy.
Harbor Siege medic refactor (case study)
Before the patch, medics died to own-team flashbangs while reviving because concussion damage used the environmental tag without instigator team. The fix had four parts:
- Policy table asset — rows per
DamageKind(direct, splash, DoT, displacement) with ally multiplier and knockback scale. - Rez immunity component — 1.2s on revive start; blocks ally splash and knockback only, not enemy fire.
- Attribution pass — every AoE spawner stores
instigator_team_id; kill feed shows ally icon on team splash kills. - Loadout telegraph — grenade reticle turns amber when an ally stands inside blast radius at full throw strength.
Playtest metric: “medic deaths during ally ability windup” dropped from 18% of squad wipes to 6%. Players still had to position around rockets — scaled splash remained — but support role frustration fell sharply.
Technique decision table
| Approach | Best when | Weak when |
|---|---|---|
| FF fully off | Casual co-op, young audiences, ability-spam PvE | Grenades feel consequence-free; realism seekers bounce |
| FF fully on | Hardcore tactical, emergent tension, PvP training | Pub groups grief; new players quit after first team kill |
| Scaled splash only | Siege shooters, extraction co-op, RPG raids | Needs strong UI or players still blame RNG |
| Role immunity windows | Revive-heavy, medic/support-centric design | Exploitable if immunity extends to enemy overlap bugs |
| Mode-specific FF | Same codebase, ranked vs casual playlists | Players confused when rules change between queues |
| No FF system (implicit off) | Solo-only or pure PvP with no teams | Any future co-op feature ships blind |
Common pitfalls
- One bool for everything — splash and direct fire need separate policy rows.
- FF off but knockback on — allies launch off ledges without HP loss.
- Missing instigator on DoT zones — kill feed shows environment for player-owned fire.
- Healing nades damage allies — polarity flag per projectile, not team check alone.
- Downed allies damageable — teammates finish bleedout with accidental spray.
- Pet team desync — summon damages owner after zone transition.
- Client-only FF filter — desync and cheat surface; server must authorize.
- Silent block — player fires full mag at ally, no feedback, assumes broken gun.
Production checklist
FriendlyFirePolicytable keyed by damage kind and game mode.- Team filter stage in server damage pipeline before mitigation.
- Knockback and displacement follow same ally multipliers as HP.
- AoE spawners store instigator team and player ID for attribution.
- Self-damage rules documented per throwable and ability.
- Downed and revive states define ally damage immunity explicitly.
- Rez or channel immunity windows tuned and visible in patch notes.
- Kill feed, death recap, and damage numbers distinguish ally sources.
- Scoreboard tracks team damage and accidental kills separately.
- Grenade reticle or ground decal warns when allies in blast radius.
- QA matrix: splash on rez, pet chain, late join, FF mode toggle.
- Verbose logging for blocked friendly hits in dev builds.
Key takeaways
- Friendly fire is a policy matrix, not a single checkbox — direct, splash, DoT, and knockback need separate rows.
- Filter on the server after hit confirm and before mitigation so combat logs stay trustworthy.
- Splash without attribution feels like cheating; always propagate instigator through AoE.
- Support roles need immunity or scaled splash around revive channels or players abandon the class.
- UI must explain blocked or reduced ally damage — silent FF-off frustrates more than teaches.
Related reading
- Game area-of-effect systems explained — blast shapes and overlap queries
- Game grenade and throwable systems explained — fuse, arc, and splash tuning
- Game hitbox and hurtbox systems explained — where hits are validated
- Game co-op design explained — squad roles and trust pacing