Modifiers

A modifier is the game's own buff, debuff and state marker system. Stuns, silences, shields, speed boosts, "is in the shop", "is carrying the idol" and the thing that makes a team change actually network are all modifiers. Applying one is a single call, and most of what goes wrong is in the four failure modes at the bottom of this page.

Adding a modifier

The full signature from the official docs:

// every argument after the name is optional
entity.AddModifier("modifier_citadel_stunned", KeyValues3? kv, caster, ability, team);

In practice there are two shapes worth using.

Plain, with your own timer for the duration

// This is the shape to prefer. It needs no extra type, and the duration is exactly
// what you asked for whatever the modifier's own default happens to be.
pawn.AddModifier("modifier_citadel_cursed");
Timer.Once(3000.Milliseconds(), () => {
    try {
        var p = Players.FromSlot(slot)?.GetHeroPawn()?.As<CCitadelPlayerPawn>();
        if (p != null && p.IsValid) p.RemoveModifier("modifier_citadel_cursed");
    } catch { }
});

Re-reading the pawn from the controller inside the timer rather than capturing it is deliberate. Writing to a pawn handle captured earlier is how a Bedwars player once ended up stuck out of the world with no log line to show for it.

With a duration keyvalue

using var kv = new KeyValues3();
kv.SetFloat("duration", 3.0f);
pawn.AddModifier("modifier_citadel_knockdown", kv);
Not every modifier reads duration

duration is confirmed on modifier_citadel_knockdown. Others want different fields (power, a target, an ability reference), and a modifier that does not read your keyvalue will use its own default without complaining. If the length matters, own it with a timer and treat the keyvalue as a nicety.

Removing a modifier

entity.RemoveModifier("modifier_citadel_stunned");   // by name
entity.RemoveModifier(modifierRef);                    // by reference

Removing a modifier that is not applied is harmless. That is what makes the timer pattern above safe: if the modifier expired on its own first, your removal is a no-op.

Reading what is applied

entity.ModifierProp.HasModifier("modifier_citadel_cursed");   // bool
entity.ModifierProp.Modifiers;                                // enumerate them all
entity.ModifierProp.SetModifierState(EModifierState.X, true);
Always read it back when it matters

AddModifier returning without throwing is not the same as the modifier landing. A name the engine does not recognise can simply do nothing at all. If your gamemode depends on the modifier being on, check HasModifier immediately afterwards and log the answer. Otherwise your log will cheerfully claim a state that was never applied.

Catching a modifier as it is applied

This hook is more useful than it looks, and it is how BattleBox detects a punch without classifying a single melee. A punchable powerup grants a modifier the instant it breaks, so the modifier arriving is the signal that a punch landed.

public override HookResult OnAddModifier(AddModifierEvent args) {
    string name = args.ModifierVData.Name ?? "";
    var owner = args.ModifierProperty.Owner;     // who it is landing on
    // return HookResult.Stop to REFUSE it, so the buff is never actually gained
    return HookResult.Continue;
}
The grant and refuse loop, measured in a real game

A powerup pickup does not grant one modifier. It grants four, and only one of them means anything:

gun_powerup_pickup/near_rejuv                    // hidden proximity aura, radius 300
gun_powerup_pickup/near_rejuv/target_near_item   // the same aura, per target
gun_powerup_pickup/modifier_check_nearby_player_parry
gun_powerup_pickup/gun_powerup_pickup            // THE REWARD, only when it breaks

The aura fires roughly every 15 milliseconds just from standing nearby. Returning Stop for all of them created a grant and refuse loop. The reward is the one where the text before the slash equals the text after it, so that is the only shape to match:

int sl = name.IndexOf('/');
if (sl > 0 && name.IndexOf('/', sl + 1) < 0) {
    string a = name.Substring(0, sl), b = name.Substring(sl + 1);
    if (a == b && a.EndsWith("_powerup_pickup")) { /* a punch landed */ }
}

From the console, without a plugin

modifier_create modifier_citadel_disarmed

// with a source path, a target and parameters
modifier_create upgrade_capacitor/modifier_weapon_capacitor_slow player {"duration" "5"}

Useful for finding out whether a modifier does what you think before you write any code. Also worth knowing: modifier_dump_list is a real cvar and will list them.

The four ways this fails quietly

SymptomCauseWhat to do
Nothing happens, no errorThe name does not exist in this buildHasModifier straight after. A typo is indistinguishable from a no-op otherwise.
It lasts the wrong length of timeThe modifier ignored your durationEnforce it with Timer.Once plus RemoveModifier.
It is applied, nothing visible changesYou picked a _tracker or _desc nameThose are UI-only. See the naming rules below.
It fires thousands of timesYou hooked an aura, not an eventMatch the exact modifier name you want, never a prefix.

Naming rules that save you a test

The ones worth knowing

Grouped by what you would reach for them for. Every name is in the full list below.

Stopping a player doing things

NameEffect
modifier_citadel_stunnedClassic stun. Blocks movement and actions.
modifier_citadel_silencedBlocks abilities. The game's own display name is "Silenced".
modifier_citadel_disarmedBlocks weapon attacks. Display name "Disarmed". Proven in a community Manhunt mode.
modifier_citadel_cursedDisplay name "Cursed". BattleBox puts this on a revived player for three seconds.
modifier_citadel_rootStops movement but allows attacking, unlike stunned.
modifier_citadel_pre_match_waitValve's own pre-match freeze. The right tool for a countdown phase.
modifier_citadel_dazedDaze.
modifier_citadel_knockdownKnockdown. Confirmed to read a duration keyvalue.
modifier_citadel_kelvin_frozenKelvin dome freeze. Very strong, may include invulnerability.
modifier_citadel_mutedBlocks voice chat.

Defence

NameEffect
modifier_citadel_metal_skinNear invulnerability.
modifier_citadel_barrierShield.
modifier_citadel_tech_shieldSpirit shield. Display name "Spirit Shield".
modifier_citadel_damage_reductionGeneric percentage reduction.
modifier_citadel_reflect_shieldReflect.
modifier_citadel_crystal_shieldShield, Ice source.

Movement and stats

NameEffect
modifier_citadel_speed_boostSpeed up.
modifier_citadel_lineslow / _slowtargetSlow.
modifier_citadel_damageboostDamage up.
modifier_citadel_rapid_fireFire rate up.
modifier_citadel_bullet_flurryBullet flurry.
modifier_citadel_dodgingDodge state.

State markers you can read instead of computing

These are the cheap way to know something about a player without a per-tick distance check.

NameMeans
modifier_citadel_in_shopThey are in the shop.
modifier_citadel_in_fountainThey are in the regen zone.
modifier_citadel_in_hideout_zoneThey are in the Hideout map zone.
modifier_citadel_holding_golden_idolThey are carrying the urn.
modifier_citadel_revealed_on_mapThey are visible to enemies on the minimap.
modifier_citadel_sprint_start / _sprint_endSprint state transitions.

The one that is not really a modifier

citadel_change_team

pawn.AddModifier("citadel_change_team") is the only known safe way to move a live player between engine teams 2 and 3, and each application flips the pawn between them rather than setting a side. Writing pawn.TeamNum instead changes the number server-side and never tells the clients, which makes bullets pass through enemies. Full detail in Recipes.

All 125 names

Scanned out of the install on 2026-04-21. This is a string scan of the game files, so it is complete for names that appear as literal strings and may miss any that are constructed at runtime. A name being here means it exists in the build; it does not promise it does something useful when applied cold.

modifier_citadel_accuracy_tracker
modifier_citadel_afterburn_buildup
modifier_citadel_archer_air_raid
modifier_citadel_archer_guided_arrow
modifier_citadel_architect_lock_on
modifier_citadel_assassinate_target
modifier_citadel_ballista_ammo_pack_pickup_timer
modifier_citadel_ballista_fusion_bomb_plant
modifier_citadel_ballista_fusion_bomb_slow
modifier_citadel_banished
modifier_citadel_barrier
modifier_citadel_bolo
modifier_citadel_bubble
modifier_citadel_bull_charging
modifier_citadel_bull_leap
modifier_citadel_bullet_flurry
modifier_citadel_capture_point_meteor
modifier_citadel_capture_zipline_timer
modifier_citadel_charging
modifier_citadel_chrono_pulse_grenade_debuff
modifier_citadel_chrono_swap_buff
modifier_citadel_chrono_swap_debuff
modifier_citadel_chrono_time_wall_effect
modifier_citadel_containment_victim
modifier_citadel_crystal_shield
modifier_citadel_cursed
modifier_citadel_damage_reduction
modifier_citadel_damageboost
modifier_citadel_dazed
modifier_citadel_death_tax
modifier_citadel_death_tax_tech_amp
modifier_citadel_delayed_catapult_launch
modifier_citadel_delayed_stun
modifier_citadel_disarm_proc
modifier_citadel_disarm_proc_buildup
modifier_citadel_disarmed
modifier_citadel_disarmed_icebeam
modifier_citadel_disruptive_charge
modifier_citadel_dodging
modifier_citadel_dps_tracker
modifier_citadel_drone_spotted_enemy
modifier_citadel_drone_spotted_enemy_desc
modifier_citadel_duo_energy_link
modifier_citadel_duo_energy_link_duration
modifier_citadel_duo_fusion_scalpel_target
modifier_citadel_enemy_uppercutted
modifier_citadel_grapplehook_wall_hanging
modifier_citadel_gravity_lasso_enemy
modifier_citadel_gravity_lasso_self
modifier_citadel_hijack_weapon_jammer_proc
modifier_citadel_hijack_weapon_jammer_proc_desc
modifier_citadel_holding_golden_idol
modifier_citadel_holding_golden_idol_revealed
modifier_citadel_holding_golden_idol_visible
modifier_citadel_hornet_chain_connection
modifier_citadel_hornet_crit_stacking_damage_buff
modifier_citadel_hornet_crit_vulnerability
modifier_citadel_hornet_sting_debuff
modifier_citadel_hornetleap
modifier_citadel_hornetmark
modifier_citadel_idol_pickup_disabled
modifier_citadel_immobilize_trap_immobilize
modifier_citadel_immobilize_trap_immobilize_debuff
modifier_citadel_in_fountain
modifier_citadel_in_shop
modifier_citadel_incendiaryprojectile_burn
modifier_citadel_kelvin_frozen
modifier_citadel_knockdown
modifier_citadel_knockdown_stumble
modifier_citadel_lightningball
modifier_citadel_lineslow
modifier_citadel_mechaguy_echo
modifier_citadel_mechaguy_echo_slow
modifier_citadel_mechaguy_retaliate
modifier_citadel_metal_skin
modifier_citadel_muted
modifier_citadel_pestilence_infection_buildup
modifier_citadel_phalanx_reflect
modifier_citadel_pre_match_wait
modifier_citadel_projectmind
modifier_citadel_psychiclift
modifier_citadel_psychiclift_self
modifier_citadel_quarantine
modifier_citadel_rapid_fire
modifier_citadel_reflect_shield
modifier_citadel_respawn_credit
modifier_citadel_returning_golden_idol
modifier_citadel_revealed_on_map
modifier_citadel_root
modifier_citadel_rootgrenade
modifier_citadel_shiv_dagger
modifier_citadel_shiv_dash
modifier_citadel_shiv_dash_impact_slow
modifier_citadel_silenced
modifier_citadel_sleep_bomb
modifier_citadel_sleep_dagger_asleep
modifier_citadel_sleep_dagger_postsleep
modifier_citadel_slowtarget
modifier_citadel_smoke_bomb_in_smoke
modifier_citadel_smoke_bomb_invis
modifier_citadel_spade_card
modifier_citadel_spade_card_cooldown
modifier_citadel_spade_card_regen
modifier_citadel_spade_hattrick_tracker
modifier_citadel_spade_pupeteer_puppet
modifier_citadel_spade_rupture
modifier_citadel_spade_sleeve_toss_card_draw
modifier_citadel_spade_translocate
modifier_citadel_spade_vanishing_act
modifier_citadel_speed_boost
modifier_citadel_sprint_end
modifier_citadel_sprint_start
modifier_citadel_staticcharge
modifier_citadel_sticky_bomb_attached
modifier_citadel_stunned
modifier_citadel_surveillance_drone_alive
modifier_citadel_tech_shield
modifier_citadel_tempest_weathermaker_lightning_incoming
modifier_citadel_tempest_weathermaker_lightning_incoming_remain_covered
modifier_citadel_tempest_weathermaker_lightning_incoming_seek_shelter
modifier_citadel_tengu_stone_form
modifier_citadel_tethered
modifier_citadel_throw_sand_debuff
modifier_citadel_unstick
modifier_citadel_wing_blast_push
Names that are not in this list but are real

The scan only covered modifier_citadel_*. Two other families exist and both matter: citadel_change_team (no modifier_ prefix at all), and the modifier_citadel_powerup_* rewards that punchable powerups grant, namely _powerup_movement, _powerup_survival, _powerup_gun and _powerup_casting. Item modifiers use modifier_item_* and upgrade_* namespaces instead.

Verifying a name yourself

The game's own localisation file is the last word on whether a status exists and what it is called in the UI:

grep -n "modifier_citadel_cursed" \
  09_research_log/github_clones/GameTracking-Deadlock/game/citadel/resource/\
localization/citadel_attributes/citadel_attributes_english.txt

// 88:  "modifier_citadel_cursed"    "Cursed"

A name in citadel_attributes_english.txt has a player-visible status. A name that only turns up in a binary string scan exists but may be internal.