Outward
Install with App

Details

Latest version
0.1.6
Last Updated
First Uploaded
Downloads
713
Likes
0
Size
154KB
Dependants

AggroKit changelog

0.1.6 — 2026-09-05

  • ForgeKit 0.4.13 / DonorKit 0.1.9 / SpawnKit 0.6.1: session-3 fixes
  • packaging: raise ForgeKit dep pins to 0.4.12 and StoryKit to 0.1.8 (fresh-install floor)
  • Spawn gate abstraction: Lifecycle.IsGameplayLive, StoryKit SpawnPolicy + posture census, WalkSpeed default

0.1.5 — 2026-08-28

  • Fix stale dependency pins across the fleet; DonorKit 0.1.7
  • Cross-area pet orphan fix + three combat-staging diagnostics
  • attack staging verb (alias aggroonto) — attack <victim> [attacker] [holdSeconds]: make a nearby creature fight a chosen VICTIM, not just the player. Victim is a name substring, uid:xxxx, me, or pet/ally (the nearest player-faction AI that is not you — a companion anchor, hireling or summon; AggroKit stays pet-agnostic). Attacker defaults to the nearest non-player-faction AI in 40 m. It installs a PAIR targetability override only when the faction matrix would veto the lock, alerts the attacker's squad the way a vanilla detection does, and SUSTAINS the pin for holdSeconds (default 20, 0 = one-shot) through TauntController, which re-asserts every 0.3 s and so out-paces AISCombat's 0.5 s re-poll and the 50 % ChanceToSwitchTargetOnHurt steal. Motivation: a live session's one-shot staging left a hostile 2.4 m from a companion still fighting the player, with nothing in the log to say why.
  • Every force reports a REASONAggroTools.ForceTargetDetailed returns an AttackOutcome (NoAttacker, NoVictim, AttackerHasNoTargeting, VictimNotAlive, VictimHasNoLockingPoint, BlockedByOverride, NoCombatState, LockDidNotHold, Locked) and AttackPlan.Describe turns it into a remedy sentence. attack and forcetarget both print N retargeted plus the reason, at Message on success and Warning on failure — so a zero can never be read as silence again. AggroTools.ForceTarget itself is unchanged and stays the boolean recipe consumers call.
  • New pure helpers on AggroTools: FindCharacter (victims need not have a CharacterAI), FindAlly, FindHostile. AttackPlan (outcome ladder + argument grammar) is System-only and unit-tested in tests/AggroKit.Tests/AttackPlanTests.cs.
  • ak_cmd.txt runs the WHOLE file (allLines: true), like every other channel in the family, and honours # comments. It was the last "first non-blank line only" channel: a batched two-line file silently discarded its second line with nothing in the log to say so.
  • Additive only — COMPAT_SINCE stays 0.1.3.

0.1.4 — 2026-08-23

  • Truce breakers can be resolved LIVEAggroTruce.Hold gains an overload taking a dealer-UID predicate that TruceTable consults at BREAK time; the UID snapshot stays as the fallback. A consumer whose breaker is a live thing (Beastwhispering's pet anchor, which does not exist yet when the failed-tame truce is armed) registers the predicate instead. (static analysis AO5-1/AO5-7)

  • AggroTruce.Enforceable — false when [Fixes] EnablePatches was off at boot, i.e. when a held truce is bookkeeping only because none of the blocking prefixes were installed. Hold warns once instead of asserting a peace that does not exist. (AO5-2)

  • AggroTools.ForceTarget now RELEASES a live truce on the pair it forces (reason forcetarget) rather than overriding it silently; it never refuses on a truce. (AO5-5, Cobalt's ruling)

  • Owner retags are never silent: OwnerTable.Own reports the owner it displaced, TruceTable.Record carries DisplacedOwner, and OverrideTable gains an additive OnRetag sink. (AO5-8)

  • TauntController warns once per hold when its re-assert cannot land, with the fields that separate the causes, instead of failing silently for the hold's whole duration. (AO5-9)

  • Truce hygiene: the gone-subject strike table is cleared on Tick's idle early-return. (AO5-6)

  • Protected characters (AggroTools.Protect(target, owner) / Unprotect / IsProtected, dev verbs protect / unprotect): a TargetableOverrides "targetable=false" entry is now honoured at AI acquisition too — prefixes on AICEnemyDetection.Detected / CharHurt and AISCombat.SetPreferredTarget refuse a blocked target (the faction-keyed scan could not be asked per Character, so before this a blocked target FLAPPED instead of staying at peace) — and at skill/status sub-effects (SubEffect.IsTargetable postfix). ForceTarget refuses a blocked pair. Protect also releases every AI lock already held on the target. Resolution order pair > for-all

    vanilla is pure (OverrideTable, unit-tested); ClearForAllOwnedBy is the owner-checked clear. Built for the road merchant the pet's anchor bit on 2026-08-22. Known hole: RaycastProjectile volleys (faction-keyed).

  • AggroTruce — a timed, pair-keyed truce: one AI tolerates one character (no scan or squad acquisition; calmed once if already locked), broken the moment that character — or a consumer-named extra breaker such as a pet's anchor — hits it, at which point vanilla aggro runs untouched. The CharHurt/Defense prefixes break it BEFORE the original runs; Detected/SetPreferredTarget read it after the global veto. Pure TruceTable bookkeeping, unit-tested. Built for Beastwhispering's failed-tame outcome.

  • AggroTools.AlertSquad(ai, target) — the squad half of a vanilla detection (AISquad.AddTarget), kept separate from ForceTarget so TauntController's re-assert never spams it.

  • Verbs truce [seconds] [name|nearest], truceoff [name|nearest|all], truces; status and restore know about truces; the scene-load sweep clears dev-staged truces only.

0.1.3 — 2026-08-19

  • Merge branch 'fix/sa-0815-leafkits' into feature/pet-self-feed
  • Static-analysis wave F3c: leaf-kit fixes (A7-1/2/4/8/9/13/14/15/16/20/23/24/25/27)
  • Test debt (F4): model every project in the dependency gate, AggroKit's first tests, UsageSpec corpus coverage
  • Coercion wave: every ForgeKit integration completes cleanly through the TUI seam
  • Forge shell fixes: SSH commands via bash -c (fish login shell); set/cfgdump on every channel mod
  • Forge shell: catalog dump + response protocol + set/cfgdump in ForgeKit; forge CLI/REPL + completion packs; wiki-enriched name db

0.1.2 — 2026-08-11

Prompted by a player report that bisected a vanilla-content bug down to AggroKit. The report did not hold up — AggroKit patches nothing on the path it was blamed for — but answering it took five passes over the decompiled game, because AggroKit was effectively unfalsifiable in the field. This release is about that, plus the one real defect the investigation found.

  • [Fixes] BlockSquadSelfTarget now defaults OFF. It was the mod's only unconditional change to vanilla AI, and it is implemented as a skipping Harmony prefix — which under HarmonyX suppresses every other mod's prefix on AISCombat.SetPreferredTarget as well as the original. The case it guards is unreachable in vanilla (both callers filter to allies, and an ally is never a valid target), so it was paying a cross-mod cost for a benefit that cannot be demonstrated. Still available for anyone who actually hits the fake-combat stall.
  • New [Fixes] EnablePatches master switch (default on). Disables every Harmony patch AggroKit installs while keeping the library primitives and the ak_cmd.txt dev verbs working — so AggroKit can be ruled in or out of a mod-conflict bisection without uninstalling it. Five patch classes previously had no gate at all.
  • AggroKit now says what it patched. A boot-time census of the vanilla methods actually patched (read back from the Harmony instance, not a hand-maintained list) plus the resolved gate values, both also surfaced by the status verb.
  • The self-target block reports when it fires, bounded per session — previously it was silent unless the dev-only ring buffer was enabled, which it never is in a shipped install.
  • HarmonyPriority(Priority.Last) on the three prefixes that can skip the original, so when AggroKit suppresses a method, other mods' patches have already had their say.
  • The IsTargetable postfix — the one patch body doing real work with no try/catch — now routes throws to the same bounded Swallowed reporter as every other patch body.
  • The self-test is now gate-aware: it asserts each patch's installed state matches its config rather than asserting it is installed, so EnablePatches = false no longer reads as a failure. It also cross-checks the census against the gates.
  • Docs: the README, wiki page and Thunderstore description no longer describe an "always-on" fix, and both now document EnablePatches.

Also in this release:

  • AggroKit: trim manifest description to Thunderstore's 250-char limit
  • Merge branch 'main' into fix/sa-0808-kits
  • Static-analysis 2026-08-08 wave D-kits: P2-13/P2-15 + the kit P3 group
  • Static-analysis 2026-08-08 wave 0: nine P1/P2 fixes
  • W4: fixes for everything D1 found, plus the join-race P1
  • AggroKit: fake-null cleanup for the aggro taps and taunt forensics
  • A1: the fake-null accessors, and every Plugin.cs cleared
  • A0 pilot: the fake-null rewrite recipe, proven on one file

0.1.1 — 2026-08-02

  • Logging: answer "why did nothing happen?" without needing LogVerbose on in advance
  • Cleanup: one anchor-collect loop, one ownership side-table
  • Docs sweep: archive, condense, and validate the whole documentation tree
Thunderstore development is made possible with ads. Please consider making an exception to your adblock.