Modifiers
Namespace:
DeadworksManaged.Api
Modifiers are buffs/debuffs applied to entities. They can alter gameplay states, apply visual effects, and control movement.
Adding Modifiers
Use CBaseEntity.AddModifier() with a VData name and KeyValues3 parameters:
using var kv = new KeyValues3();
kv.SetFloat("duration", 3.0f);
pawn.AddModifier("modifier_citadel_knockdown", kv);
AddModifier Parameters
entity.AddModifier(
string name, // Modifier VData name (e.g. "modifier_citadel_knockdown")
KeyValues3? kv, // Parameters (duration, etc.) (optional)
CBaseEntity? caster, // Entity that applied the modifier (optional)
CBaseEntity? ability, // Ability that caused the modifier (optional)
int team
);
KeyValues3
Wraps a native KeyValues3 handle. Create, set typed members, pass to AddModifier, then dispose.
Important: Always Dispose
// Using statement ensures proper cleanup
using var kv = new KeyValues3();
kv.SetFloat("duration", 5.0f);
kv.SetString("effect", "burning");
pawn.AddModifier("my_modifier", kv);
// kv is automatically disposed here
Properties
| Property | Type | Description |
|---|---|---|
IsValid | bool | true if underlying native handle is alive |
Setter Methods
| Method | Description |
|---|---|
SetString(string key, string value) | Set a string value |
SetBool(string key, bool value) | Set a boolean value |
SetInt(string key, int value) | Set a signed 32-bit integer |
SetUInt(string key, uint value) | Set an unsigned 32-bit integer |
SetInt64(string key, long value) | Set a signed 64-bit integer |
SetUInt64(string key, ulong value) | Set an unsigned 64-bit integer |
SetFloat(string key, float value) | Set a single-precision float |
SetDouble(string key, double value) | Set a double-precision float |
SetVector(string key, Vector3 value) | Set a 3D vector |
CModifierProperty
Manages modifier state bits and active modifier instances on an entity. Access via entity.ModifierProp.
// Enable unlimited air jumps
pawn.ModifierProp.SetModifierState(EModifierState.UnlimitedAirJumps, true);
pawn.ModifierProp.SetModifierState(EModifierState.UnlimitedAirDashes, true);
// Check a state
bool hasState = pawn.ModifierProp.HasModifierState(EModifierState.UnlimitedAirJumps);
// Disable
pawn.ModifierProp.SetModifierState(EModifierState.UnlimitedAirJumps, false);
// Enumerate active modifiers
foreach (var mod in pawn.ModifierProp.Modifiers)
Console.WriteLine(mod.SubclassVData?.Name);
// Check by name
if (pawn.ModifierProp.HasModifier("modifier_citadel_knockdown")) { /* ... */ }
| Method / Property | Returns | Description |
|---|---|---|
SetModifierState(EModifierState, bool) | void | Sets or clears a modifier state bit |
HasModifierState(EModifierState) | bool | Returns true if state bit is set |
HasModifier(string name) | bool | Returns true if the entity has an active modifier with the given subclass VData name |
Modifiers | IReadOnlyList<CBaseModifier> | All active modifier instances on the entity |
Removing a modifier
Remove is a method on the entity itself, not on ModifierProp:
// By name — removes the first instance matching that VData name
pawn.RemoveModifier("modifier_citadel_knockdown");
// By instance — use when you held on to a CBaseModifier from AddModifier
var mod = pawn.AddModifier("modifier_...", kv);
pawn.RemoveModifier(mod);
EModifierState
Enum containing all modifier state flags (302 values). Key examples:
| Value | Description |
|---|---|
UnlimitedAirJumps | Allow unlimited air jumps |
UnlimitedAirDashes | Allow unlimited air dashes |
| (many more) | Covers movement, visibility, combat, hero-specific states |
CBaseModifier
Wraps a native CBaseModifier instance — a buff/debuff applied to an entity. Returned by AddModifier.
EKnockDownTypes
Knockdown animation type applied to a hero.
Common Modifier Patterns
Knockdown with Duration
using var kv = new KeyValues3();
kv.SetFloat("duration", 3.0f);
pawn.AddModifier("modifier_citadel_knockdown", kv);
Toggling Movement States
// Enable
var mp = pawn.ModifierProp;
mp.SetModifierState(EModifierState.UnlimitedAirJumps, true);
mp.SetModifierState(EModifierState.UnlimitedAirDashes, true);
// After duration, disable
Timer.Once(20.Seconds(), () =>
{
mp.SetModifierState(EModifierState.UnlimitedAirJumps, false);
mp.SetModifierState(EModifierState.UnlimitedAirDashes, false);
});
AddAbility + AddModifier Pattern
Many game modifiers read properties from their parent ability (e.g., ModelScaleGrowth, ActiveMoveSpeedPenalty). To apply these modifiers with full functionality, you must first add the ability, then pass the returned ability entity as the 4th parameter to AddModifier:
// 1. Add the item ability — returns the ability entity
var ability = pawn.AddAbility("upgrade_shrink_ray", 0);
if (ability == null) return;
// 2. Apply modifier, passing the ability so it can read VData properties
using var kv = new KeyValues3();
kv.SetFloat("duration", 30.0f);
pawn.AddModifier("modifier_shrink_ray", kv, pawn, ability);
// 3. Remove the ability after the modifier is applied
pawn.RemoveAbility("upgrade_shrink_ray");
EModifierState Reference
State behavior is inconsistent — some flags are honored by the client, others are only meaningful when set by internal C++ modifier code. When in doubt, try setting the flag every tick (from OnGameFrame or a 1-tick timer): several states that "don't work" when set once do work when sustained.
Examples
| Raw Value | Name | Description |
|---|---|---|
| 11 | Immobilized | Prevents all movement |
| 38 | AdditionalAirMoves | Extra air moves |
| 39 | UnlimitedAirDashes | Allow unlimited air dashes |
| 40 | UnlimitedAirJumps | Allow unlimited air jumps |
| 68 | VisibleToEnemy | Reveal on the minimap to the enemy team. Must be set every tick to stay reliable for human players (bots work with a single call). |
| 69 | InfiniteClip | Infinite ammo, no reload needed |
| 115 | UnitStatusHealthHidden | Hides the healthbar above the hero. Set every tick. |
| 116 | UnitStatusHidden | Hides the whole unit status / nameplate panel. Set every tick. |
| 118 | FriendlyFireEnabled | Enables friendly-fire for bullet damage only. Abilities and melee still ignore teammates; see the FFA recipe in team-and-hero-management. |
The Discord dump has several cases of "doesn't work" turning into "works when set every tick." Before writing off a state, try:
public override void OnGameFrame(bool simulating, bool firstTick, bool lastTick)
{
if (!simulating) return;
foreach (var pawn in Players.GetAllPawns())
pawn.ModifierProp?.SetModifierState(EModifierState.VisibleToEnemy, true);
}
You can also cast raw integer values to EModifierState for states not in the managed enum:
pawn.ModifierProp?.SetModifierState((EModifierState)69, true); // InfiniteClip
EModifierState has 302 values total. The raw values follow the MODIFIER_STATE_ prefix pattern from VData (e.g., MODIFIER_STATE_INFINITE_CLIP = 69).
Discovering Modifier Names
Deadlock has hundreds of modifiers. Useful sources:
modifier_dump_listin the server console — lists currently-known modifiers. Results can vary between invocations; if it looks short, run it again after a map fully loads.modifier_dump— lists modifiers currently active on an entity. Useful for discovering subclassed modifiers.- Deadlock modding modifier list — community-maintained dump.
scripts/modifiers.vdata(extracted frompak01_dir.vpk) — the authoritative standalone modifier definitions.scripts/abilities.vdata— abilities contain inline modifier subclasses underModifiersblocks. These are referenced asupgrade_<item>/modifier_<name>in VData but you callAddModifierwith just the bare modifier name.
Tools for browsing the VDATA: source2viewer-cli (decompile and grep), and s2v.app (web browser for game files).
See Also
- Entities —
AddModifieronCBaseEntity - Players —
ModifierProponCCitadelPlayerPawn - Timers — Timed modifier application
- Roll The Dice Example — Modifier effects in practice