AggroKit
Reusable aggro/threat control tooling for Outward BepInEx mods: per-pair targetability gates, detection veto/redirect, taunt and force-target primitives. Inert until a mod uses it — a library dependency, installed automatically.AggroKit
📖 Full documentation: AggroKit wiki page
Reusable aggro/threat-control tooling for people writing BepInEx 5 mods for Outward: Definitive Edition. It doesn't add anything a player sees on its own — it's a library dependency other mods (CompanionKit, and anything built on top of it) pull in, and other modders are welcome to build on it too.
Requires: BepInEx 5 (Outward's Mono branch — see Compatibility below) + ForgeKit (hard dependency, installed automatically).
What's in it
| Piece | What it gives you |
|---|---|
AggroTools |
Patch-free primitives for reading/adjusting engine aggro state without a Harmony patch of your own. |
TargetableOverrides |
A per-pair targetability gate — make one specific character untargetable to one specific other character, without touching the game's global targeting rules. |
AggroEvents |
Observability hooks (opt-in, off by default) plus an opt-in squad-self-target guard (also off by default — see BlockSquadSelfTarget). |
Installing (for players)
Drop the AggroKit folder into BepInEx/plugins/. It has no effect by itself — install it
because another mod you're using declares it as a dependency.
Configuration
BepInEx/config/cobalt.aggrokit.cfg (generated on first launch):
[Dev]
## Poll BepInEx/config/ak_cmd.txt for dev commands (aggrodump/forcetarget/taunt/calm/...).
EnableCommandFile = true
## Whether DumpKey logs an aggro dump of all AI characters near the player.
EnableDumpKey = true
## Key that logs an aggro dump of all AI characters near the player (needs EnableDumpKey=true).
# Default value: F3
DumpKey = F3
[Research]
## Re-arm AggroEvents' purely-observational Harmony taps that record the event buffer. OFF by
## default so these hot AI-tick paths stay un-patched. With EnablePatches on, the detection-side
## control patches and the targetability override gate are installed regardless of this key — they're
## inert until a verb activates them.
EnableObservation = false
[Fixes]
## Master switch for EVERY Harmony patch AggroKit installs. Off = it patches nothing at all, while
## the library calls and the ak_cmd.txt verbs keep working — so AggroKit can be ruled in or out of a
## mod-conflict bisection without uninstalling it. Applied at load; changing it needs a relaunch.
EnablePatches = true
## Opt-in fix for a squad-contagion self-target assignment in AISCombat.SetPreferredTarget.
## DEFAULT OFF: the case is unreachable in vanilla, and the block is a skipping Harmony prefix, which
## also suppresses any other mod's prefix on the same method. Read live — no relaunch needed.
BlockSquadSelfTarget = false
Dev verbs
AggroKit polls BepInEx/config/ak_cmd.txt (write a line, it runs on the next poll — works while
the game is paused). [Dev] EnableCommandFile = false turns the channel off.
| Verb | What it does |
|---|---|
aggrodump [radius] |
Aggro dump of every AI near the player, plus the player's targetability state |
aistates [name|nearest] |
Dump one AI's state machine |
aggrolog [n|on|off|clear] |
The [AGGRO] event buffer |
watch <name|nearest|off> |
Watch an AI's (state, target) changes |
forcetarget [name|nearest] |
Force an AI onto the player, and auto-watch it |
feud <A> <B> [nooverride|both] |
Make any two AIs fight each other |
taunt [radius] / calm [radius] |
Pull every AI in radius onto the player / calm them |
untargetable / targetable |
Toggle the player's QuestNonTargetable |
undetectable / detectable |
Toggle the player's DetectabilityMult |
shieldme / unshieldme |
Toggle incoming-aggro shielding on the player |
stealthme [off] |
Veto AI detection of the player |
decoy <name>|off |
Redirect detections of the player onto another AI |
noaggro [off] |
The player's hits generate no aggro |
clearoverrides |
Clear all targetability overrides |
status |
One glance: player flags, overrides, controls, watches, aggrolog |
restore |
Undo everything — targetable + detectable, all overrides/controls/watches cleared |
selftest |
Zero-interaction environment checks ([SELFTEST] PASS/FAIL … DONE) |
The [Dev] DumpKey bind (default F3) runs aggrodump without the channel. Keys are a
cross-mod resource in this workspace — AggroKit claims its bind through ForgeKit.Keybinds so a
collision with another mod is reported rather than silently firing both.
Using it (for modders)
<!-- your .csproj -->
<ProjectReference Include="path\to\AggroKit\AggroKit.csproj" Private="false" />
[BepInPlugin(GUID, NAME, VERSION)]
[BepInDependency(AggroKit.Plugin.GUID)]
public class Plugin : BaseUnityPlugin
{
// AggroTools / TargetableOverrides / AggroEvents are static entry points —
// call them directly once AggroKit has loaded (declare it as a dependency above).
}
Private="false" matters — it stops MSBuild from copying a second AggroKit.dll into your
mod's own output folder. The kit ships from its own BepInEx/plugins/AggroKit/ folder; your mod
just references it and declares the dependency so BepInEx loads it first.
Compatibility
Outward must be on its Mono Steam beta branch, not the default IL2CPP build — like every
BepInEx 5 mod for this game. If your game runs but no BepInEx mods load and there's no crash log,
this is almost always why (Properties → Betas → select mono in Steam).
License
Apache License 2.0 — see LICENSE in the repository root. You may use, modify, and redistribute
this kit (including in commercial mods) provided you keep the copyright/license notice; see the
license text for the full terms.
