================================================================================
  UNGODLY AI  v2.17.0
  Ungodly Madly Vastly Enhanced AI & Pathfinding Overhaul for EASY RED 2
  by StixsworldHD (StixsmasterHD4k)
================================================================================

  Target game ..... Easy Red 2 v2.0.6 (all DLC supported: Normandy, Stalingrad,
                    Ardennes, Iwo Jima & Bougainville, Kwajalein, Tinian, Guam,
                    Anzio & Nettuno, Sicilia, Fall of Berlin, ...)
  Framework ....... BepInEx 6 Bleeding Edge, IL2CPP x64
  Multiplayer ..... 100% compatible - see "MULTIPLAYER" below
  Engine facts .... every hook verified against the game's own v2.0.6 code
                    (IL2CPP disassembly + interop reverse engineering)

--------------------------------------------------------------------------------
 WHAT THIS MOD DOES (short version)
--------------------------------------------------------------------------------
 * Bots THINK up to 16x more often. Vanilla runs exactly ONE soldier brain per
   rendered frame for the whole battlefield; on a 200-bot map each bot only
   re-evaluates once every ~3+ seconds. UngodlyAI multiplies the game's own
   scheduler under a hard CPU budget so your FPS is always protected.
 * The global pathfinder budget (vanilla: hardcoded 3 ms shared by EVERY unit)
   is configurable - orders and routes are delivered on demand.
 * Dynamic route refresh: vanilla re-paths every 14-18 s no matter what.
   UngodlyAI: fast combat clock (default 1.5-3 s) while a bot has a target or
   is being suppressed, moderate calm clock (6-10 s) otherwise. Bots actually
   chase you, react to collapsing flanks, and scramble for cover NOW.
 * Stuck-bot rescue: no more squads grinding into hedgerows. Fresh path first,
   then a short human-looking sidestep. No teleport crutches needed -
   and the infamous multiplayer "bot blinked 20 m" teleport is blocked.
 * Human combat feel: per-soldier hidden skill (rookies fumble, aces snap-fire),
   first-contact surprise, first-shots-go-wide aim settling, leading error vs
   sprinting targets, range falloff, suppression that really works - all layered
   ON TOP of a faithful reimplementation of the vanilla difficulty formula, so
   your in-game Difficulty sliders keep their exact meaning.
 * Longer spot memory & alert states, grenade discipline, wider squad spacing.
 * OBJECTIVE PRIORITIZATION (v2.0.0): vanilla task-picking, decoded from the
   disassembly, sends every attacking squad to the single NEAREST objective
   (conga armies) and every defending squad to a RANDOM one (wandering while
   the front collapses). UngodlyAI replaces it with a scored strategic brain:
   distance-weighted, crowd-balanced across objectives, contested points pull
   reinforcements, defenders use the same smart scoring - plus periodic
   re-evaluation so the front line actually FLOWS. Scripted mission orders
   and player squads are never touched.
 * SQUAD COMMAND BRAIN (v2.0.0): coordinated assault CHARGES onto contested
   points instead of one-by-one trickles, defensive GARRISON holds on freshly
   captured ground, automatic REGROUP of scattered survivors out of contact,
   and context-aware FORMATIONS (column marching, line closing, spread under
   fire) - all issued through the game's own squad-order API with its native
   network sync.
 * RADIO & FIRE SUPPORT (v2.0.0): verified - vanilla AI squads NEVER call
   artillery; only players and scripts do, while the radioman-answer behavior
   and the batteries sit unused. Now AI squad leaders with a living radioman
   genuinely use the radio: HE fire missions when pinned, SMOKE screens ahead
   of objective assaults, tank/AT support on spotted armor - via the exact
   pipeline a human player triggers, radioman confirmation and all.
 * TACTICAL STANCE DISCIPLINE (v2.0.0): vanilla stances ignore range entirely
   (fixed 4-in-5 crouch, prone only above 50 suppression). Now CQB fights stay
   ON THE FEET for mobility, long-range firefights go low by soldier skill,
   and the suppression-prone threshold is tunable.
 * ITEM INTELLIGENCE (v2.1.0): decoded from the disassembly - vanilla AI item
   handling is literally two hardcoded "switch to slot 1" calls. Bleeding bots
   NEVER use the bandages they carry (zero AI callers of the bandage API), AT
   grenades only fly on generic random rolls, smoke is decorative, bipods
   deploy by accident. Now owned bots genuinely use their kit: the wounded
   bandage themselves after a human fumble delay (when it's safe enough), AT
   units and sappers commit AT grenades on armor inside real range, pinned
   soldiers pop panic smoke on the threat axis, and stationary gunners set up
   their bipods - all via the game's own item APIs (animations, consumption
   and network sync untouched).
 * CLASS AWARENESS (v2.1.0): the game's own role flags finally MEAN something.
   Medics get a guaranteed treatment heartbeat whenever a squadmate is down
   (vanilla routine, extra cadence - casualties get reached fast). Marksmen
   fight like marksmen: patient deliberate trigger timing that the aim-settle
   model turns lethal, plus early prone in long-range duels. Radiomen keep
   tight formation on the leader so your AI fire-support calls get confirmed
   quickly. AT units and sappers hunt armor (see above).
 * VAULTING (v2.2.0): verified in the disassembly - the game ships a complete,
   network-synced vault system (obstacle check, landing math, animation,
   online replication) whose only callers are the player's input, the HUD
   prompt, mission scripting and the network receiver. Vanilla AI has never
   once hopped a sandbag. Now owned AI soldiers vault exactly like players:
   the stuck-rescue system tries "can I just hop this?" BEFORE falling back
   to repath/sidestep, moving bots probe for vaultable obstacles mid-stride,
   and CHARGING bots probe three times as often - bayonet charges pour OVER
   sandbag lines and trench lips in one continuous motion. Suppression-prone
   soldiers, deployed gunners and bots mid-animation never attempt it, an
   eagerness roll keeps squads organic (some hop, some jog around), and every
   vault self-replicates through the vanilla sync path.
 * ENVIRONMENTAL AWARENESS (v2.3.0): verified in the disassembly - the AI
   vision formula is 'pose tier x equipment camo' and NOTHING else. Night,
   fog, snowfall, overcast and smoke do not exist to AI eyes: bots spot you
   at 300 m through a moonless blizzard and track you perfectly through the
   smoke you paid a grenade for. Now the world matters: darkness, fog, snow
   and cloud cover shrink every AI's spotting distance through the game's own
   camo-distance hook (all vanilla spotting logic intact), and SMOKE finally
   works both ways - thrown smoke & phosphorus grenades register a sight
   blocker at their actual rest position, artillery smoke at its impact
   point, AI sight lines through a live cloud simply fail (memory decays
   naturally), and shots fired blind into smoke go satisfyingly wild. Player
   spotting is untouched - your own eyes decide what you see.
 * UNGODLYBALLISTICS SYNERGY (v2.4.0): auto-detects StixsworldHD's
   UngodlyBallistics mod at runtime (soft link - never a hard dependency,
   everything here runs identically without it). Compatibility was audited
   against the UngodlyBallistics v3.0.0 source: the two mods' Harmony patch
   sets are fully DISJOINT, and UB's impact chain deliberately drives the
   vanilla damage path that this mod's artillery-smoke hook lives on, so all
   16 prior systems work byte-identically alongside it. When linked, UB's
   simulated physics feed the AI: soldiers mis-hold for UB's Photon-seeded
   WIND by skill (aces read and correct most of the crosswind, rookies eat
   it; UB's gust noise stays organically uncompensated on top), and this
   mod's artificial long-range error steps back so UB's real drag physics
   create the honest misses. Link status shows live on the Accuracy tab and
   the Overview footer.
 * MAP WEAPONS (v2.5.0): verified in the disassembly - every emplaced gun on
   every map (sandbag MGs, AT guns, howitzers, AA mounts) is a stationary
   Vehicle with turret seats, the game ships a COMPLETE turret gunner AI
   (target search, traverse, engagement, even radio-mission execution) that
   activates the moment any AI sits down, and the vehicle itself is a valid
   AI walk-and-board destination... yet nothing in vanilla ever SENDS a
   soldier to one. Guns sit empty all battle unless a crew literally spawned
   on them. Now owned AI squads actively crew the map: defenders man nearby
   empty guns through the game's own walk-up-board-sync pipeline (the exact
   call the Lua scripting API uses), armor sightings trigger urgent AT-gun
   scrambles at extended radius, specialists (medics/radiomen/marksmen) and
   the squad leader are never pulled off their jobs, a claim system stops
   three squads racing one gun, and vanilla's own dismount logic pulls crews
   off when the squad receives a move order.
 * BATTLEFIELD LOOTING (v2.6.0): the supply loop-closer. This mod taught the
   AI to SPEND its kit like humans - bandaging, AT grenades on armor, panic
   smoke - but vanilla offers no way to ever RESTOCK, and nothing in vanilla
   makes an AI take anything from anyone. Verified: every dead soldier keeps
   a fully valid inventory, and the game's own take-from-inventory transfer
   (the same flow its player interaction system is built on) sits ready. Now
   owned bots with a genuine NEED walk to a nearby fallen soldier and take
   exactly what they lack: a bleeding rifleman whose bandages ran dry finds
   a body, takes the dressing, and patches himself up on the spot; AT units
   who spent their charge restock and stay dangerous; missing smoke gets
   replaced. Runs start and abort on safety (no visible target, suppression
   under a ceiling), timeout after 14 s, never happen mid-charge, and only
   strict needs qualify - nothing is hoarded.
 * TAKE COVER & SCREENING SMOKE (v2.7.0): verified - vanilla has NO code path
   where a leader reacts to his squad being mauled by ordering cover, and
   members receiving ANY cover/waypoint order may sit on a repath timer up to
   18 SECONDS before their pathfinder even looks at the new destination. Now:
   owned AI leaders call a genuine "TAKE COVER!" when the squad takes sudden
   effective fire or loses a man - the squad scatters into surrounding cover
   via the game's own order, weathers the worst, then resumes the attack with
   a fresh approach. Members act on cover / waypoint / charge orders the
   INSTANT they land (their repath timer is zeroed) - and because the player
   command wheel routes through the same functions, a HUMAN squad leader's
   take-cover command now also snaps their own AI squadmates into motion.
   And squads screen their own maneuvers with hand smoke: an engaged carrier
   pops smoke on the threat axis when advancing onto an objective under fire
   or as part of the take-cover scatter ("SMOKE! COVER!") - and thanks to the
   v2.3.0 occlusion system, that cloud genuinely BLINDS the AI shooting at
   them.
 * COVER FIGHTING (v2.8.0): two facts verified in the disassembly - every
   cover point on every map carries a HAND-AUTHORED firing pose
   (CombatCover.suggestedPose: crouch behind the sandbags, stand at the
   window) plus a firing arc that the AI pose logic never reads, and the
   CombatCover class appears exactly ZERO times in the entire AI brain. No
   peek logic, no duck logic, no cover-fighting of any kind exists in
   vanilla - a covered bot stands there per generic pose rules firing
   continuously until somebody dies. Now owned AI at cover fight like
   humans: rise into the mapper's intended firing pose, hold a skill-scaled
   fire window (deployed MGs hold much longer - they are the base of fire),
   drop behind the cover for a suppression-scaled beat, rise again with a
   genuine re-acquisition penalty on every peek - and accurate return fire
   slams them down EARLY mid-window. A small braced-aim bonus applies while
   exposed, suppressive fire finally buys the attacker something tangible
   (longer ducks), and the vault system never abandons a working cover
   fight.
 * COUNTERATTACK (v2.9.0): verified - when the enemy captures an objective a
   faction held, vanilla does NOTHING special: defenders keep picking RANDOM
   objectives (that is literally the vanilla defender logic), no code
   detects the loss, and any recapture is a statistical accident. Now losing
   a point is a detected EVENT for the owned side: the secured-faction flip
   is caught within seconds, the freshly-lost objective spikes in every
   squad's task scoring with a bonus that decays across a configurable
   memory window, the nearest uncommitted squads are IMMEDIATELY re-tasked
   into a counterattack wave (per-objective cooldown, never drafting player
   squads, contested defenses, or depleted squads), and squads assaulting
   recently-lost ground push straight onto the point harder - hit them
   before they dig in, exactly like a human commander. Watch a line objective
   fall and the sector pivots to take it back.
 * CLOSE QUARTERS & MELEE (v2.10.0): decoded from the disassembly - vanilla
   AI melee requires the ATTACKER'S OWN suppression above 20 (the strike is
   literally coded as a panic move; a calm soldier standing nose-to-nose
   never uses the blade), then a 34% random roll, evaluated only on the slow
   one-brain-per-frame tick. Result: two bots hosing the walls around each
   other at two meters, bayonets forever sheathed. Now owned AI fight close
   like humans: any bot with a visible enemy at blade range strikes reliably
   through the game's own synced melee (calm or panicked), CHARGING bots get
   extra reach so bayonet charges finally END in bayonet strikes - over the
   sandbags and into the trench, blades first - trigger delays inside CQB
   range run on adrenaline (snap factor + halved surprise window), and a
   hard aim-error ceiling inside 8 meters means a man-sized target at point
   blank is treated like one, whatever smoke, suppression or panic says.
 * SMOKE DOCTRINE (v2.11.0): real infantry burn smoke CONSTANTLY - before
   crossings, over casualties, on the point - and until now every hand-smoke
   behavior here was tuned conservatively. This update adds a global
   frequency dial (SmokeDoctrine, default 1.6: it divides the per-squad
   screening cooldown, divides the panic-smoke re-roll damp and multiplies
   its trigger chance) plus three NEW human occasions: PRE-EMPTIVE crossing
   smoke - a squad advancing with fresh contact but not yet suppressed
   screens BEFORE the crossing turns into a bloodbath (the single biggest
   realism gain: humans smoke first, bleed later); screening continues
   INSIDE contested objectives while the fight for the point rages; and
   when the medic is dispatched to a wounded member, an engaged carrier
   screens the casualty area - covering the corpsman's run. The looting
   system keeps carriers restocked from the fallen, so high doctrine stays
   sustainable all battle, and the v2.3.0 occlusion system makes every one
   of these clouds genuinely blind the AI firing through them.
 * AIR COMBAT (v2.12.0): the disassembly shows the game ships a real flight
   brain (AIPlane: bomb-run states, a dive system keyed to each aircraft's
   hand-authored dive angle, dogfight fight-modes, air-target selection) -
   with placid decisions and one glaring hole: ZERO defensive logic exists.
   No plane in vanilla has ever evaded anything. Now locally-piloted AI
   aircraft fly like they mean it: bomb-run dives run STEEPER (multiplying
   each plane's authored angle, capped at 82 degrees; gun strafes keep
   their vanilla 12-degree cap), pull-outs press 30% LOWER before release
   (hard 25 m floor), dogfight maneuver decisions re-roll on a faster human
   tempo, FIGHTERS detecting an enemy aircraft closing in their rear cone
   fly genuine BREAK TURNS (rolling, jinking evasive input blended into
   their steering - dive exits are never interrupted, bombers stay on their
   runs), fighters tasked onto ground targets while enemy aircraft are
   visible swap to the air war first, and MACHINE-GUN runs finally DIVE:
   vanilla hard-caps every gun-only attack at a 12-degree glide, and
   StrafeDiveAngle (default 30) turns strafes into genuine diving gun runs
   that recover through the same dive-exit machinery as full bomb dives. Only inputs are shaped - all flight
   physics, damage and sync stay vanilla, gated on the machine that
   simulates each pilot.
 * ARMOR & TRANSPORT (v2.13.0): the disassembly gave up two beauties. First:
   the vehicle driver AI tracks the squad aboard it (squadInside) and
   automatically drives toward that squad's task destination - the game can
   already CHAUFFEUR a squad to its objective - yet nothing in vanilla ever
   tells a squad on foot to USE an empty transport; trucks sit parked while
   infantry walks 300 m under fire. Second: vanilla recovery for a wedged
   AI vehicle is literally a TELEPORT (ExecuteUnstuckTeleport) - the tank
   blinks out of the hedge. Now owned squads whose objective is far mount a
   nearby empty transport of their faction (the game's own seat logic fills
   the driver position, the driver AI carries them to the task, vanilla
   dismount unloads them there); stuck locally-driven vehicles REVERSE out
   (a destination behind the hull, driven by the game's own driving logic,
   up to ReverseTries times) before any teleport is permitted; every
   locally-crewed TURRET brain runs its decision clocks faster - target
   refresh, fire windows AND the game's own AP/HE ammo re-evaluation, which
   exists but idles on a lazy clock; and turrets on armored fighting
   vehicles that are busy machine-gunning infantry swap to a visible enemy
   VEHICLE inside 450 m (validated through the turret's own line-of-sight
   check) - a tank commander does not strafe riflemen while enemy armor
   crosses his front.
 * COVER & TRANSPORT REFINEMENT (v2.14.0): both young systems audited against
   the game's own APIs and their real usage gaps closed. COVER: the
   peek-and-duck system only ran on ASSIGNED cover destinations - but battle
   constantly leaves bots standing beside authored cover nobody assigned
   them to. Now they ADOPT any adjacent cover point (battlefield cover grid,
   8 m cells, per-bot 3 s memo), every adopted or snapped cover must pass
   the game's OWN composite availability check - the mapper's firing ARC,
   live occupancy and destruction state in one call that v2.8.0 never
   consulted (no more peeking a wall that faces away from the threat) - and
   a single suppressed bot now dives for valid cover within reach on its own
   initiative, the individual survival reflex squad orders cannot provide.
   TRANSPORT: v2.13.0 requested the driver seat be filled before anyone had
   physically boarded, so squads could sit in a parked truck forever - a
   1.5 s watchdog now re-invokes the game's own crew-reseating once riders
   are actually seated until the wheel is manned; the mount gate no longer
   requires a spotless order history (stale old business frees the bus);
   seat counts are re-verified fresh at mount time instead of trusting the
   5 s cache; and a riding squad that comes under real fire BAILS OUT
   through the game's own crew-retreat and fights from the ground, with
   arrival closing the ride cleanly.
 * TANK BATTLES & AIR DEFENSE (v2.15.0): three fronts at once. TANKS now
   duel like tankers: an owned tank engaging enemy armor fights in the
   short-halt rhythm (halt for steady gunnery, roll a beat, halt again -
   purely by steering the hull's own destination), refuses to keep closing
   inside a standoff range instead of driving onto the enemy's muzzle, and
   its turret COMMITS to the armor target it is working instead of
   ping-ponging every refresh. AIR DEFENSE wakes up twice over: the game's
   own ammo census (Turret.CheckBullets) identifies TIME-FUSE FLAK turrets,
   which now LOCK onto enemy aircraft inside 900 m (any vehicle turret
   pot-shots planes pressing inside 250 m) - and, verified, the turret
   brain contains ZERO lead prediction, so gunners aimed at where a
   400 km/h aircraft WAS; the air scan's half-second velocity estimates now
   feed a computed LEAD POINT straight into the turret's own aim rotation.
   Tracers finally cross the nose. And the sky ANSWERS: every detected
   attacker (an enemy plane with a live attack target - the dive bomber
   mid-plunge, the strafer on his run) is handed to the nearest FREE owned
   fighter inside the intercept radius as its new target - dive bombers get
   bounced mid-run, escorts earn their pay.
 * ALL-SYSTEMS REFINEMENT (v2.16.0): one genuine polish for every pillar of
   the mod. ACCURACY - fire is WALKED onto the target: staying engaged on
   the same enemy tightens error over the first seconds (resets on every
   switch and every peek; never inside the point-blank ceiling). RADIO - a
   danger-close check: no HE or armor-support mission is transmitted with a
   known friendly squad inside the veto radius (smoke is exempt - smoke on
   friendlies is doctrine, not fratricide). MEDIC - the wounded step behind
   valid authored cover within reach BEFORE kneeling to treat when it's
   loud. COUNTERATTACK - the instant wave passes over pinned squads
   (average suppression above 40 stays put) and every drafted squad turns
   toward the lost point BEHIND a requested screening smoke. VAULTING -
   landing from a vault flows straight onto adjacent arc-valid cover,
   chaining v2.2.0 into v2.14.0. MELEE - a landed strike opens a fast
   follow-up window: the second blow comes 55% quicker, pressing the
   wounded opponent. VEHICLES - unstuck reversing alternates its line left
   and right of straight astern instead of backing into the same rut
   twice. Eight refinements, every one riding the game's own verified
   machinery.
 * SPAWN LOGISTICS (v2.17.0): the motor-pool reflex. The section-26 mount-up
   brain works through the normal squad review with its order-history gates
   and cooldowns - a FRESHLY SPAWNED squad could walk half the map before
   its turn came up, right past the trucks parked at its own spawn. Now
   every squad newly detected by the strategic cache (battle start AND
   every reinforcement wave, via a persistent first-seen memory that
   survives the cache rebuilds) gets a dedicated spawn window: it scans for
   a suitable empty transport IMMEDIATELY with a wider motor-pool search
   radius, bypassing the order-history gate and the per-squad transport
   cooldown entirely, retrying every 4 seconds inside the window - and each
   miss nudges the vehicle cache to rescan, because reinforcement vehicles
   spawn alongside reinforcement squads and a 5-second-old cache does not
   know them yet. Its own objective-distance threshold keeps spawn
   logistics sane independent of how aggressive general transport use is
   tuned. Fresh troops ride to the front instead of hiking to it.
 * In-game GUI (default F6) with a SOLID readable background, every setting as
   a slider with live values, plain-English explanations of what each value
   does in gameplay terms, one-click presets, live MP/performance stats.
 * 202 documented config entries with min/max ranges - the .cfg carries the same
   explanations, so you can tune from a text editor too. Everything applies
   LIVE, no restart needed.

--------------------------------------------------------------------------------
 INSTALLATION
--------------------------------------------------------------------------------
 STEP 1 - Install BepInEx 6 Bleeding Edge (IL2CPP x64) into Easy Red 2
   1. Download the latest "BepInEx-Unity.IL2CPP-win-x64-6.0.0-be.###" zip from
      https://builds.bepinex.dev/projects/bepinex_be
      (this mod was built against BE 785; any recent BE build works)
   2. Extract it DIRECTLY into your game folder, e.g.
        C:\Program Files (x86)\Steam\steamapps\common\Easy Red 2\
      After extracting you must see, next to "Easy Red 2.exe":
        BepInEx\   dotnet\   .doorstop_version   winhttp.dll   doorstop_config.ini
   3. Start the game ONCE and wait. First run takes a few extra minutes while
      BepInEx generates interop assemblies for the game (a console window may
      appear). When the main menu loads, quit.

 STEP 2 - Install UngodlyAI
   1. Open this mod zip.
   2. Drag its "BepInEx" folder onto your game folder (merge when asked).
      That places:
        BepInEx\plugins\StixsworldHD.EasyRed2.UngodlyAI.dll
   3. Launch the game. Done.

 STEP 3 - Verify (optional)
   * In-game, press F6 -> the UngodlyAI window opens.
   * Or check BepInEx\LogOutput.log for:
       "UngodlyAI - Ungodly Madly Vastly Enhanced AI & Pathfinding Overhaul v2.17.0"
       "Harmony patch groups: 9 applied, 0 failed."

--------------------------------------------------------------------------------
 IN-GAME GUI (default key: F6, rebindable)
--------------------------------------------------------------------------------
   * Solid opaque window - readable mid-firefight. Drag it by the title bar.
   * Scroll long tabs with the mouse wheel, or drag the scrollbar on the right
     (clicking the empty track pages up/down).
   * Rebind the toggle key from Squad & MP -> "PRESS TO REBIND..." - just hit
     the key you want (Escape cancels).
   * Tabs: Overview / Brain / Pathfind / Reaction / Accuracy / Behavior /
     Strategy / Radio+Tac / Kit+Class / Squad&MP.
   * Hover ANY control -> the bottom panel explains in gamer terms exactly what
     it changes, what raising vs lowering does, and its allowed range.
   * Overview tab has one-click presets:
       BALANCED (mod defaults) | CINEMATIC CO-OP | HARDCORE VETERANS | POTATO SAVER
   * Footer shows live status: Offline/Host/Client, bots owned by your PC,
     extra brain ticks + their real ms cost, and stuck-rescue counters.
   * SAVE TO FILE writes the cfg; all changes apply live either way.

--------------------------------------------------------------------------------
 MULTIPLAYER - HOW IT STAYS 100% SAFE
--------------------------------------------------------------------------------
 Easy Red 2 bots are simulated on exactly ONE machine each - the Photon owner
 of that unit (the host for world bots, each player for their own squad bots).
 The game's own AI entry point checks this ownership every tick.

 UngodlyAI applies every behavior change ONLY inside the simulation of bots
 YOUR machine owns, using the game's own ownership gate. Other players simply
 receive the normal Photon position/state sync they always did. Consequences:
   * No desync is possible by construction - you are tuning the inputs of the
     one authoritative simulation, not forking it.
   * Mixed lobbies work: modded host + vanilla clients, vanilla host + modded
     clients, any combination. Others just see smarter (or dumber - your
     choice) soldiers from the machines that run the mod.
   * As a CLIENT you enhance your own squad's bots (Photon assigns them to
     you). As HOST you enhance all world-spawned bots. The GUI footer shows
     exactly how many bots your PC currently owns.
   * The vanilla online-teleport cheat (bots skipping ahead in plain view) is
     blocked by default (AiTeleportPolicy = BlockInMultiplayer).

--------------------------------------------------------------------------------
 PERFORMANCE
--------------------------------------------------------------------------------
 * Extra AI thinking is governed by BrainFrameBudgetMs (default 1.5 ms/frame)
   with a Stopwatch hard-stop - the mod can never spiral your frametime.
 * The stuck watchdog is time-sliced (default 12 bots/frame) and the whole
   per-soldier state store is allocation-free on hot paths.
 * Weak CPU? Open the GUI -> Overview -> POTATO SAVER, or lower
   BrainTicksPerFrame / budgets manually. Even BrainTicksPerFrame=3 is a
   night-and-day improvement over vanilla.

--------------------------------------------------------------------------------
 UNINSTALL / DISABLE
--------------------------------------------------------------------------------
 * Temporary A/B test: set [1. Master] EnableMod = false (or untick systems in
   the GUI) - the mod loads but touches nothing.
 * Full removal: delete BepInEx\plugins\StixsworldHD.EasyRed2.UngodlyAI.dll
   (and optionally the cfg). BepInEx itself is removed by deleting winhttp.dll.

--------------------------------------------------------------------------------
 TROUBLESHOOTING
--------------------------------------------------------------------------------
 * "Nothing happens / no F6 window"
     - Confirm BepInEx actually runs: BepInEx\LogOutput.log must exist and
       grow. If not, re-check STEP 1 (files must sit NEXT to the game exe;
       x64 IL2CPP build, not Mono).
     - Search the log for "UngodlyAI". "9 applied, 0 failed" = all good.
 * "A patch group reports FAILED after a game update"
     - Each of the 5 patch groups is independently guarded; the rest keep
       working. A game patch that renames a method disables only that group.
       Grab an updated mod build, or play with the remaining systems.
 * Ranges: every slider hard-clamps to its documented min/max. Out-of-range
   values hand-typed into the cfg are clamped by BepInEx on load.
 * Log lines prefixed "Brain tick paused 5s" are the built-in circuit breaker
   reacting to a scene teardown mid-frame - harmless, auto-recovers.
 * A healthy v2.17.0 load logs ZERO mod-related warnings. If you see
   "[Warning:Il2CppInterop] Class::Init signatures have been exhausted, using
   a substitute!" - that line is printed by the BepInEx/Il2CppInterop CORE
   during startup, BEFORE any plugin loads (it also appears with an empty
   plugins folder). It is BepInEx resolving an internal engine signature for
   this Unity version, is expected on BE builds, and is harmless. It does not
   come from - and cannot be silenced by - this mod.

--------------------------------------------------------------------------------
 CHANGELOG
--------------------------------------------------------------------------------
 v2.17.0  -  THE SPAWN LOGISTICS UPDATE
   * NEW: spawn detection. The strategic cache keeps a persistent
     first-seen timestamp per squad (surviving its 2 s rebuilds); every
     squad carries FirstSeenAt, marking battle-start squads and every
     reinforcement wave the moment they appear.
   * NEW: the spawn-ride reflex. Inside SpawnRideWindow of first sighting,
     a foot squad whose objective is beyond SpawnRideMinDistance hails the
     motor pool immediately: the mount attempt uses the wider
     SpawnRideSearchRadius, bypasses the section-27 order-history gate and
     the per-squad TransportCooldown, and retries every 4 s inside the
     window. Successful spawn rides use the exact v2.13-v2.14 pipeline
     (walk-and-board, driver insurance, ride management, ambush dismount).
   * NEW: rescan nudge. A failed spawn-ride attempt zeroes the vehicle
     cache timer - reinforcement vehicles spawn alongside reinforcement
     squads, and the very next brain pass sees them.
   * 4 new config entries (202 total across 30 sections), a SPAWN
     LOGISTICS section on the Squad & MP tab, and a spawn-rides counter on
     the Overview armor & transport line.
 v2.16.0  -  THE ALL-SYSTEMS REFINEMENT UPDATE
   * ACCURACY: SustainedFireCorrection - continuous engagement on one
     target linearly tightens aim error from 2 s to 6 s of contact (max
     cut configurable, default 12%), reset by target switches and cover
     peeks, inert inside the 8 m point-blank ceiling.
   * RADIO: RadioDangerClose - before any HE/armor-support transmission,
     the strike point is checked against every same-faction squad position
     from the strategic cache; any friendly inside the radius vetoes the
     call (15 s damp, danger-close counter on the radio stats line).
     Smoke missions are exempt.
   * MEDIC: BandageInCover - a maturing self-bandage under suppression >=
     30 first moves the bot to arc-valid authored cover within 5 m (the
     v2.14.0 cover grid), then the fumble window re-arms and treatment
     happens behind the wall.
   * COUNTERATTACK: SmartWaveDraft - the squad cache now carries per-squad
     average suppression; wave drafting skips squads above 40.
     CounterattackSmoke - every drafted squad immediately requests a
     screening smoke through the section-24 doctrine entry point.
   * VAULTING: VaultIntoCover - both vault paths stamp the bot; within 3 s
     of landing, a bot with a live target adopts arc-valid cover inside
     3.5 m (one attempt per vault).
   * MELEE: MeleeFinisher - a strike landed within the last 4 s cuts the
     next melee recovery to 45% - strike, press, finish.
   * VEHICLES: ReverseSteerVariance - successive unstuck reversals offset
     4.5 m alternately left/right of straight astern.
   * 8 new config entries (198 total across 29 sections), an ALL-SYSTEMS
     REFINEMENT section on the Squad & MP tab, and new counters (danger-
     close vetoes, bandage-in-cover, vault->cover) on the Overview tab.
 v2.15.0  -  THE TANK BATTLES & AIR DEFENSE UPDATE
   * NEW: short-halt tank duels. A 0.8 s hull pass over the vehicle cache
     drives the classic rhythm for owned tanks with a visible ARMOR target
     inside 400 m: halt (destination pinned to own position) for
     TankHaltSeconds of steady gunnery, roll ~3 s, halt again - and inside
     TankStandoff the hull refuses to keep closing at all. Game driving,
     gunnery and sync untouched.
   * NEW: target stickiness. FindBestTarget keeps a per-turret armor-target
     memory: while the committed target stays visible (the turret's own
     CanSee) and younger than TargetStickiness, refresh cannot ping-pong
     the gun elsewhere - crews finish the kill they are working.
   * NEW: flak wake-up. Turret.CheckBullets (the game's own ammo census,
     virtual per turret type) identifies time-fuse-flak carriers; a flak
     turret with an enemy aircraft inside 900 m and in its own line of
     sight locks onto it over everything, and any vehicle turret engages
     planes pressing inside 250 m. Aircraft positions/factions come from
     the air scan's new twice-a-second sky snapshot.
   * NEW: computed AA lead. Verified: TurretAI contains zero lead
     prediction. The sky snapshot now carries half-second velocity
     estimates per aircraft; the gunner heartbeat computes a lead point
     (typical AA muzzle velocity model x AALeadScale) and the turret's own
     LookRotation is steered onto it while the solution is fresh.
   * NEW: interception vectoring. Enemy planes with a LIVE attack target
     are detected as raiders; the nearest free owned fighter inside
     InterceptRadius receives the raider as its targetToAttack (8 s
     per-fighter damp) - the v2.12.0 dogfight systems fly the bounce from
     there.
   * 9 new config entries (190 total across 28 sections), a TANK BATTLES &
     AIR DEFENSE section on the Squad & MP tab, halt/lock/lead/intercept
     counters on the Overview tab.
 v2.14.1  -  TRANSPORT RANGE TWEAK
   * TransportMinDistance may now go as low as 10 m (was 80 m floor) - at
     the bottom of the range squads motorize practically every move; the
     per-squad TransportCooldown and the ride-management logic from v2.14.0
     are what keep the mount/dismount churn sane on dense maps. Default
     stays 120 m; the config description and GUI slider honor the new
     range. No other changes.
 v2.14.0  -  THE COVER & TRANSPORT REFINEMENT UPDATE
   * NEW: cover adoption. A battlefield cover grid (12 s scan of all
     authored CombatCover points into 8 m spatial cells) lets any owned bot
     with a target adopt UNASSIGNED cover within arm's reach - the full
     v2.8.0 peek-fire-duck cycle, authored pose and braced-aim bonus now
     engage wherever cover actually is, tracked through a per-bot 3 s memo.
   * NEW: arc discipline. Adopted and snapped covers are validated through
     the game's own CombatCover.IsCoverAvailable(shootDirection, faction) -
     the mapper's firing arc, occupancy and destruction in one virtual call
     (trench and vehicle-connected variants apply their own rules). v2.8.0
     never consulted it; bots would fight the wrong side of the sandbags.
   * NEW: individual cover snap. An owned bot whose suppression passes
     CoverSnapSuppression with a live target moves itself to the nearest
     valid cover inside CoverSnapRadius (8 s per-bot damp; never while
     charging, meleeing, riding, or already in a cover fight).
   * FIXED: transport driver insurance. The v2.13.0 reseat fired at ORDER
     time, before riders had physically boarded, so the game could find
     nobody to promote to driver and the squad idled in a parked truck. A
     1.5 s watchdog now monitors each pending mount and re-invokes
     SwitchSeatAi once riders are seated until the driver position fills
     (35 s expiry), with seat counts re-verified fresh at mount time.
   * NEW: ride management. Arrival at the destination closes the ride and
     frees the squad for normal tasking; TransportAmbushDismount bails the
     squad out through the game's own RetreatCrew when average suppression
     passes 35 under live contact - no more dying in the back of a calm
     truck.
   * NEW: stale-order gate. Mounting no longer demands a spotless order
     history - any special order older than TransportStaleOrderSeconds
     frees the squad to ride, multiplying real-world transport usage.
   * 8 new config entries (181 total across 27 sections), a COVER &
     TRANSPORT REFINEMENT section on the Squad & MP tab, cover-snap and
     insurance/dismount counters on the Overview tab.
 v2.13.0  -  THE ARMOR & TRANSPORT UPDATE
   * NEW: transport mount-up. Verified: AIVehicle tracks squadInside and
     auto-drives toward the aboard squad's task destination, and
     AIVehicle.SwitchSeatAi is the game's own crew-reseating call - the
     chauffeur existed, nobody ever hailed it. A 5 s battlefield scan
     caches movable ground vehicles (free seats, free driver position,
     faction); an owned foot-squad with no fresher business, not under
     fire, and an objective beyond TransportMinDistance walks up and
     boards the nearest suitable empty transport (v2.5.0 walk-and-board
     pipeline), the driver seat is filled through the game's own logic,
     and the squad rides to its task. Per-squad TransportCooldown, 40 s
     per-vehicle claims, players never drafted.
   * NEW: reverse-first unstuck. Verified: vanilla recovery is
     ExecuteUnstuckTeleport - a blink. The prefix orders a genuine REVERSE
     (destination ~14 m behind the hull) up to ReverseTries times; only
     spent attempts let the teleport through as last resort, and freeing
     the vehicle (ResetUnstuckChecks) clears the count.
   * NEW: turret tempo. The turret gunner brain re-arms target-refresh,
     fire-check AND ammo-switch clocks on lazy intervals inside AutoPilot;
     remainders are rescaled by TurretTempo for locally-simulated gunners -
     the game's own AP/HE shell selection finally re-evaluates at combat
     speed.
   * NEW: armor-first targeting. FindBestTarget on a turret whose parent
     is a locally-driven ARMORED vehicle swaps an infantry target for the
     nearest visible enemy vehicle inside 450 m, validated through the
     turret's own CanSee. (The turret-to-gun data link is not exposed, so
     the rule is gated to AFV-mounted turrets rather than per-weapon
     ballistics - emplaced guns and infantry AT reflexes are untouched.)
   * 8 new config entries (173 total across 26 sections), an ARMOR &
     TRANSPORT section on the Squad & MP tab, live armor/transport
     counters on the Overview tab, and a new 9th Harmony patch group
     ("Armor & Transport").
 v2.12.0  -  THE AIR COMBAT UPDATE
   * NEW: dive-bombing doctrine. GetCurrentAttackDiveAngle returns each
     plane's authored dive value only when bombs are aboard (verified:
     gun-only attacks cap at 12 degrees); DiveSteepnessMult multiplies the
     bomb-run angle (cap 82) and PullOutFloorScale presses the GetDiveData
     altitude floor lower (hard 25 m minimum) - committed plunges, later
     releases, tighter hits.
   * NEW: dogfight tempo. The fight-mode timer the flight brain arms inside
     its own Update is rescaled for locally-piloted fighters with an air
     target - maneuver decisions come DogfightTempo times faster, ending
     the long straight-line chases.
   * NEW: break on six. A half-second air scan marks locally-piloted
     fighters with an enemy plane closing inside their rear cone (behind
     and pointed at them within 420 m); while marked, a rolling/jinking
     break blends into the Rotate steering input. Verified: the vanilla
     flight brain contains no defensive reaction of any kind. Dive exits
     are never interrupted; bombers are never diverted from their runs.
   * NEW: fighters hunt aircraft. DoAttackTarget on an owned fighter swaps
     a ground target for GetBestAircraftVisibleEnemy when one exists - air
     superiority first.
   * NEW: diving machine-gun runs. Verified: GetCurrentAttackDiveAngle
     hard-caps every gun-only attack at 12 degrees. StrafeDiveAngle
     (12-60, default 30) raises the gun-run path into a genuine diving
     attack, with recovery through the same exit machinery (and altitude
     floor) as bomb dives; a separate gun-dive counter joins the Overview
     air-combat stats.
   * 8 new config entries (165 total across 25 sections), an AIR COMBAT
     section on the Behavior tab, live air-combat counters on the Overview
     tab, and a new 8th Harmony patch group ("Air Combat").
 v2.11.2  -  THE ORPHANED CLASS FIX (critical - resurrects smoke AND AT)
   * FIXED: smoke still absent after v2.11.1. The v2.11.1 clock/handshake
     fixes were real bugs, but a deeper one sat under them, and the hunt
     finally reached the mod's oldest assumption: a full reference census
     of the decompiled game shows that the classes VirtualSmokeGrenade and
     VirtualATGrenade are ORPHANS - they exist in the assembly, but NOTHING
     in the entire game ever constructs or casts them. Runtime throwables
     are plain VirtualThrowable instances whose identity lives in DATA: the
     authored prefab's ItemGrenade.grenadeType (infantryGrenate=0,
     smokeGrenade=1, ATGrenade=2, phosporusGrenade=3). Every
     TryCast<VirtualSmokeGrenade> and TryCast<VirtualATGrenade> in the kit
     and corpse scanners has therefore returned null for every item in the
     game since v2.1.0: panic smoke, screening smoke, smoke looting AND the
     entire AT-grenade-vs-armor system were structurally dead - no clock or
     chance setting could ever have mattered. (Self-bandaging always worked
     because VirtualBandages is real: the game's own UseBandages signature
     demands that exact type - which is also why bandage behaviors were
     visible while smoke never was.)
   * NEW ARCHITECTURE: a data-truth classifier. VirtualItem.GetItemPrefab()
     returns the authored prefab WITHOUT instantiating anything; the
     classifier reads the prefab's hand-authored grenadeType once per
     item_id and caches it forever (phosphorus counts as smoke, matching
     the cloud-registration system). Kit slots and corpse-supply slots are
     retyped to the base VirtualItem (Throw and PickUpItemFromInventory
     both take the base type, so every downstream call is unchanged).
   * RESURRECTED: panic smoke (13), screening smoke in all its occasions
     (20/24), smoke looting (19), AT-grenade-vs-armor (13) and AT-grenade
     looting (19) - the complete smoke doctrine and anti-armor reflex now
     run on the game's own item data for the first time.
   * No new settings; no other systems touched.
 v2.11.1  -  THE SMOKE STARVATION FIX (critical)
   * FIXED: smoke grenades barely appeared no matter how the v2.11.0 knobs
     were set. Root cause hunted through both this mod's own code and the
     game's Throw pipeline:
     (1) THE SHARED 18-SECOND GRENADE CLOCK. Every hand-thrown item -
     frag, AT, smoke - armed the same per-bot cooldown, and every smoke
     path required that clock to be COLD. The vanilla brain rolls frag
     throws constantly in combat, and this mod's own brain-tick boost
     multiplies those roll opportunities several times over, so in any real
     firefight the shared clock was hot on virtually every engaged carrier,
     virtually all the time. Smoke needed an 18-second no-grenade window
     that combat never provides. This is why no smoke setting helped.
     (2) The grenade-discipline prefix (built to thin vanilla's random frag
     spam) also applied its use-percent roll to the mod's own COMMANDED
     throws, and callers armed squad cooldowns and counted stats without
     knowing whether the throw had been eaten - a blocked screen burned the
     squad's entire smoke window with nothing in the air.
     (3) The game's Soldier.Throw silently refuses when its own animation
     gate (CanPlaySpecialAnim) or a vehicle seat says no - refusals looked
     identical to successes.
   * NEW ARCHITECTURE: tactical smoke now rides a DEDICATED per-bot lane
     (its own short cooldown) that frag throws can never starve; all
     commanded throws (screening smoke, panic smoke, AT-on-armor) go
     through a proactive handshake that bypasses the frag-discipline roll
     and the shared clock; the game's own CanPlaySpecialAnim is
     pre-flighted so an engine refusal becomes a cheap retry (next pass /
     next carrier) instead of a burned window; and every cooldown and every
     stat counter now arms ONLY on an accepted throw. AT engagements still
     arm the shared clock on success (75%) so overall grenade rhythm stays
     human; vanilla-initiated random throws keep the exact same discipline
     as before.
   * Result: smoke frequency now actually obeys sections 13, 20 and 24.
     No new settings; no other systems touched.
 v2.11.0  -  THE SMOKE DOCTRINE UPDATE
   * NEW: SmokeDoctrine - one dial for how often ALL hand smoke flies
     (default 1.6x the pre-2.11 rhythm): divides the section-20 per-squad
     screening cooldown (floor 8 s), divides the section-13 panic re-roll
     damp (floor 5 s) and multiplies the panic chance (cap 100%), and
     multiplies the new early-smoke chance.
   * NEW: EarlySmoke - pre-emptive crossing screens. A squad advancing on
     its objective with CONTACT made but suppression still low pops smoke
     immediately (EarlySmokeChance x doctrine) instead of waiting to be
     pinned - smoke first, bleed later.
   * NEW: SmokeInsideContested - screening no longer stops at the task-area
     perimeter; squads fighting ON a contested point keep cutting sight
     lines.
   * NEW: MedicCoverSmoke - the medic heartbeat (section 14) now requests a
     screen over the casualty area when dispatching the corpsman, honoring
     all squad/bot cooldowns via a new doctrine entry point.
   * Synergy notes: the loot system (19) restocks thrown smoke from the
     fallen, and every cloud registers in the occlusion system (16), so
     higher frequency is both sustainable and mechanically real.
   * 5 new config entries (157 total across 24 sections) and a SMOKE
     DOCTRINE section on the Strategy tab.
 v2.10.0  -  THE CLOSE QUARTERS UPDATE
   * NEW: reliable melee. Verified vanilla gating: Soldier.Melee() fires
     from the AI only when suppressionValue > 20 AND a Random.Range(0,100)
     > 65 roll passes, on the slow brain tick - a panic spasm, not a
     weapon. The kit brain now drives the game's own synced Melee() for any
     owned bot with a visible enemy inside MeleeRange (per-bot
     MeleeCooldown, never mid-animation or mid-swing), and ChargeMelee
     grants charging bots +30% commit reach - assaults crest the wall and
     finish with the blade.
   * NEW: CQB instinct. Inside CQBStandDistance the reaction model runs on
     adrenaline: trigger delays x CQBSnapFactor and the first-contact
     surprise window is halved - room fights are instant, instinctive
     exchanges instead of long-range duels played at three meters.
   * NEW: point-blank ceiling. Total aim error is hard-capped
     (PointBlankErrCap) inside 8 m - suppression, smoke and panic still
     matter everywhere else, but nobody empties a magazine past a man-sized
     target at spitting distance.
   * 7 new config entries (152 total across 23 sections), a CLOSE QUARTERS
     & MELEE section on the Reaction tab, and melee counters (with charging
     strikes broken out) on the Overview kit-brain line.
 v2.9.0  -  THE COUNTERATTACK UPDATE
   * NEW: objective loss detection. The objective cache now carries a
     persistent per-objective memory (keyed by task identity, surviving the
     2 s cache rebuilds): a secured-faction flip A -> B is recorded as a
     LOSS for A with a timestamp, exposed to every strategic system.
   * NEW: retake scoring. Task scoring multiplies a freshly-lost
     objective's score by up to (1 + RetakePriority) for squads of the
     losing faction, decaying linearly across RetakeMemorySeconds - lost
     ground outbids routine tasking while the wound is fresh.
   * NEW: instant counterattack wave. Within seconds of the flip, the
     nearest CounterattackSquads eligible owned squads (same faction, no
     player, 3+ alive, inside CounterattackRadius, not already tasked
     there) are re-tasked on the spot and their approach-commitment gates
     cleared - the riposte starts before the enemy digs in. One wave per
     loss per CounterattackCooldown.
   * NEW: retake aggression. Squads whose current task is a
     recently-lost objective gain RetakeDirectPushBonus extra percentage
     points of direct-push chance - counterattacks drive AT the point
     rather than taking the scenic flank.
   * 7 new config entries (145 total across 22 sections), a COUNTERATTACK
     section on the Strategy tab, and wave/retask counters in the Overview
     strategic stats.
 v2.8.0  -  THE COVER FIGHTING UPDATE
   * NEW: peek-fire-duck cycles. When an owned AI's destination is a
     CombatCover, it is beside it, and it has a target beyond CQB range, a
     per-bot phase machine runs inside the pose hook: EXPOSED in the cover's
     authored suggestedPose for FireWindowSeconds x (0.7-1.3 by hidden
     skill), then DUCKED one level below it (stand->crouch, crouch->prone;
     prone covers hold steady) for DuckSecondsBase x (1 + suppression/100 x
     DuckSuppressionScale). Every rise resets the aim-settle clock, so each
     peek is a real re-acquisition. A suppression JUMP of
     SuppressionSpikeDuck while exposed forces an immediate duck - effective
     return fire visibly puts heads down.
   * NEW: authored cover poses honored. The mapper-placed firing pose that
     ships unread in every map now drives the exposed phase
     (UseAuthoredCoverPose).
   * NEW: braced fire. CoverBracedBonus (default 0.85x error) while exposed
     at cover; deployed bipods multiply the fire window (BipodExposureMult
     2x) and shorten ducks 40% - machine guns behave like the base of fire.
   * Cover fights are protected: the proactive vault probe never fires
     during one, and the suppression-prone override still outranks
     everything at extreme suppression.
   * 8 new config entries (138 total across 21 sections), a COVER FIGHTING
     section on the Radio+Tac tab, and peek-cycle counters in the Overview
     strategic stats.
 v2.7.0  -  THE TAKE COVER UPDATE
   * NEW: reactive take-cover. Leaders of owned AI squads issue the game's
     own hold/cover order at their position when average squad suppression
     crosses TakeCoverSuppression or a member drops while under fire
     (TakeCoverOnCasualty). The squad holds for TakeCoverHoldSeconds (early
     release when the fire slackens), during which assault/retask churn is
     suspended; on release the approach-commitment gate is cleared so the
     push resumes promptly with a fresh approach. Never triggers mid-charge
     or once inside the objective area.
   * NEW: instant order response. Postfixes on SendUnitsToCovers /
     GiveWaypointToUnits / SendUnitsToCharge zero every owned AI member's
     repath timer the moment a destination-assigning order lands - killing
     the vanilla up-to-18-second order lag. Applies equally to AI-leader
     orders, mission scripting, and a human player's command wheel on their
     own squad (InvokeOrder routes through the same functions).
   * NEW: leader-directed screening smoke. Distinct from panic smoke (13)
     and artillery smoke (11): when a squad advances onto its objective
     under fire, or as part of the take-cover scatter, an ENGAGED member
     carrying smoke throws it onto the threat axis (throws land at his
     current target), where the v2.3.0 occlusion system makes it a real AI
     vision blocker. Per-squad SquadSmokeCooldown on top of the per-bot
     grenade cooldown.
   * 10 new config entries (130 total across 20 sections), a TAKE COVER &
     SCREENING section on the Strategy tab, and covers/screens counters in
     the Overview strategic stats.
 v2.6.0  -  THE LOOTING UPDATE
   * NEW: battlefield looting. Verified chain: Creature.inventory persists on
     corpses; supplies live in the same wearedItems slots the v2.1.0 kit
     scanner classifies (with VirtualItemStackable.GetStackCount exposing
     empty bandage rolls); Soldier.PickUpItemFromInventory(item, source, slot)
     is the game's own transfer with pickup animation. Vanilla never invokes
     any of it for AI.
   * Strict needs only: bleeding + no usable bandage (top priority, and the
     bot bandages immediately after the take); AT unit/sapper with no AT
     grenade; missing smoke; missing frag (off by default - it reads greedy).
     A corpse cache refreshes every LootScanSeconds; per-corpse supplies are
     scanned lazily and re-checked at the moment of the take, so two bots
     racing one body resolve cleanly.
   * Human discipline: loot runs start AND abort on safety (no visible
     target, suppression under LootMaxSuppression, never while charging),
     time out after 14 s, use direct movement with a fresh path restored on
     abort, and the vault system happily hops walls en route to a body.
   * MP note: the taker is always an owned soldier, so the transfer executes
     inside the one authoritative simulation of that unit like every other
     system here; no dedicated corpse-pickup RPC exists in the game, so a
     remote client may briefly render an already-taken item on a body -
     cosmetic only, no gameplay state diverges.
   * 9 new config entries (120 total across 19 sections), a BATTLEFIELD
     LOOTING section on the Kit+Class tab, and live loot counters on the
     Overview tab.
 v2.5.0  -  THE MAP WEAPONS UPDATE
   * NEW: emplacement crewing. Reverse-engineering established the full chain:
     stationary guns are Vehicles (non-MovableVehicle) with turret seats
     (Vehicle.SeatIsTurret / Seats.hasUnitSet); Vehicle implements
     AiDestination, so Soldier.CoverPosition(vehicle) is the game's own
     walk-up-and-board pipeline (pathing, enter animation, seat assignment,
     SyncUnitOnVehicle replication) - the exact call the game's Lua
     scripting uses; and TurretAI.AutoPilot is a complete gunner brain that
     engages the moment an AI is seated. Vanilla never invokes any of it for
     map guns.
   * Defending/garrisoning owned squads send one suitable member (never the
     leader; never medics/radiomen/marksmen with CrewExcludesSupport) to the
     nearest free own-or-neutral-faction gun inside MannedSearchRadius; a
     spotted enemy VEHICLE makes it urgent (ATGunUrgency, +50% radius, no
     defensive-posture requirement). Per-gun claims prevent crew pile-ups,
     MaxCrewPerSquad caps rifle-strength loss, the regroup system keeps its
     hands off a crewman walking to his gun, and vanilla's move-order
     dismount logic returns crews to the squad when it pushes on.
   * 6 new config entries (111 total across 18 sections), a MAP WEAPONS
     section on the Kit+Class tab, and a live guns-cached/manned counter on
     the Overview tab. Same ownership-gated, vanilla-synced-API-only MP
     architecture as every other system.
 v2.4.0  -  THE BALLISTICS LINK
   * NEW: full compatibility + synergy with UngodlyBallistics (audited against
     its v3.0.0 source). Verified: zero overlapping Harmony targets between
     the two mods; UB's BulletInstance.OnHit prefix is a void passthrough
     that runs the vanilla impact chain including Bullet.BulletDamage, so
     UngodlyAI's artillery-smoke registration works identically under UB.
   * NEW: wind-aware marksmanship. UB simulates deterministic, Photon-room-
     seeded wind; UngodlyAI reads the TRUE steady direction from UB's own
     state (works in random-direction rooms too) via a reflection soft-link
     and pushes AI shots off-hold by crosswind x distance x (1 - skill x
     WindSkillCompensation). Aces read the wind; rookies spray downwind.
     UB's gust noise stays organically uncompensated on top.
   * NEW: UBRangeSynergy - while UB is linked, UngodlyAI's own artificial
     RangeErrorPer100m term is scaled (default 0.5) so UB's genuine drag and
     velocity-decay physics create the long-range misses instead of stacking
     two penalties.
   * 4 new config entries (105 total across 17 sections), a BALLISTICS
     SYNERGY section with live link status on the Accuracy tab, and a link
     line on the Overview tab. Detection is logged at startup.
   * Without UngodlyBallistics installed the link stays dormant and nothing
     changes - no hard dependency was added.
 v2.3.0  -  THE ENVIRONMENT UPDATE
   * NEW: Environmental vision. The verified vanilla camo-distance formula
     (pose tier 300/220/50/37 m x equipment camo, zero environmental terms)
     is now multiplied by a live factor computed once a second from the
     game's own day/night + weather singleton: isNight (NightVisionFactor),
     fogAmount, snowAmount and cloudsAmount each with their own impact
     slider. Applied via postfixes on the Soldier / Vehicle / Creature
     camo-distance hooks the game itself queries, so every vanilla spotting
     rule keeps working - just with honest eyes.
   * NEW: Smoke occlusion. Thrown smoke & phosphorus grenades are tracked by
     a cheap periodic scan and register a sight-blocking cloud at their
     ACTUAL rest position on detonation (grenades destroyed between scans
     register at their last seen spot - watertight). Artillery smoke shells
     register at their impact point via the game's own BulletData.IsSmoke
     flag. An owned AI whose sight line to a target crosses a live cloud
     cannot make the spot (TrySpot is gated), its target memory decays
     naturally, and continued memory-fire through smoke gets a
     SmokeBlindFireError aim penalty. AI's own v2.0.0 smoke screens now
     genuinely protect the squads that call them.
   * 10 new config entries (101 total across 16 sections), an ENVIRONMENT &
     SMOKE section on the Behavior tab, and a live environment line (current
     vision factor, active clouds, spots blocked) on the Overview tab.
   * All prior systems untouched; same ownership-gated MP-safety
     architecture. Player vision and player spotting are never modified.
 v2.2.0  -  THE VAULTING UPDATE
   * NEW: AI vaulting. The game's own Soldier.CanVault / Soldier.Vault pair
     (which validates internally and replicates itself via SyncVault when the
     owning Syncher is online) is now driven for every AI soldier this machine
     owns - vanilla AI never called either function.
   * Stuck-rescue integration: when a bot is caught grinding an obstacle, the
     rescue ladder now asks the vault check FIRST; a successful hop counts as
     progress and no repath/sidestep is spent. The most robotic moment in the
     game becomes the most human one.
   * Proactive vaulting: moving bots probe on a per-bot clock (VaultProbe-
     Seconds) and hop qualifying obstacles mid-stride; charging bots probe 3x
     as often (ChargeVaultBoost) so assaults flow over defensive lines.
   * Human guards: no vault attempts while suppression-prone, mid body
     animation, or on a deployed bipod; VaultEagerness leaves a few soldiers
     jogging around the gap like real people; per-bot VaultCooldownSeconds
     prevents bunny-hop loops on double-sided obstacles.
   * 7 new config entries (91 total across 15 sections), a VAULTING section
     on the Pathfind tab, and stuck-rescue/proactive vault counters on the
     Overview tab. All prior systems untouched; identical MP-safety
     architecture (ownership gate + the game's own self-syncing action).
 v2.1.2  -  THE DESTINATION FIX (critical)
   * FIXED: AI still drifted AWAY from objectives after v2.1.1. Deep-dive into
     SoldierAI.UpdatePath's disassembly revealed the true root cause - and it
     was ours, present since v1.0.0: GetSpacingFromSquad(), despite its name,
     does NOT return a relative formation offset. It returns the soldier's
     FINAL ABSOLUTE WORLD DESTINATION, which UpdatePath feeds directly into
     the pathfinder as the goal position. Our formation-spread feature was
     therefore multiplying WORLD COORDINATES by 1.15 - displacing every single
     AI destination on the map roughly 15% radially away from the world
     origin - and v2.1.0's radioman factor (x0.65) literally sent radiomen
     marching toward the map origin. v2.1.1's approach-commitment fix was
     correct and stays, but it also unmasked this deeper systematic drift.
   * The spacing hook is rewritten to do what it always claimed: it now scales
     only the OFFSET around the squad leader's position, only while the squad
     is in plain FOLLOW formation (ordered destinations - hold positions,
     flank waypoints, charges - are absolute goals and are never touched), and
     a 60 m sanity clamp ignores anything that is not a genuine formation-slot
     vector. FormationSpreadScale and RadiomanSticksToLeader now behave
     exactly as documented, and every AI path destination in the game is
     finally bit-identical to what the game's own order logic computed.
   * Also confirmed while in there: the mod's dynamic-repath system sits on
     the correct engine field (pathRefreshTime, offset 0x68) - repathing was
     never part of the drift.
   * No new settings; no other systems touched.
 v2.1.1  -  THE OBJECTIVE-ORBIT FIX
   * FIXED: AI squads swung very wide around objectives as if avoiding them.
     Root cause (traced in the disassembly): every attack order the game
     issues rolls a random +/-45 degree approach - about a third go straight
     at the point, two thirds swing to a FLANK waypoint placed at 70% of the
     remaining distance, rotated off-axis. The order function has no cooldown
     of its own; it relied on the slow vanilla leader tick. UngodlyAI's brain-
     tick boost was re-rolling that approach several times per second, so
     squads endlessly weaved between fresh left/right flank waypoints and
     orbited the objective without ever committing. The game even arms a
     15s/60s order-commitment timer that the re-rolls trampled.
   * NEW: Approach Commitment - squads now commit to each rolled approach for
     ApproachCommitSeconds (default 8s; the game's own running-order timer is
     respected on top), and ObjectiveDirectPushPercent (default 55%) biases
     fresh approaches into a tight hold order RIGHT ON the point, with the
     remainder keeping the vanilla flank hook (flanks are good - they were
     just happening constantly).
   * FIXED: v2.1.0's own contributions to the width - the garrison hold used
     a cover-search dispersion of 0.9x the objective radius (parking defenders
     in a ring OUTSIDE big invasion-phase zones; now clamped to 10-20 m inside
     the area), assault charges fanned similarly wide (endpoints now land
     inside the point), and Smart Formations scattered squads into 'spread' on
     mere visual contact (now only genuine suppression does; closing on the
     objective forms a line).
   * NEW: RadioFactionCooldown - a faction-wide gap between AI fire missions,
     so ten squads on personal cooldowns can no longer ripple a near-constant
     barrage onto the front line.
   * 3 new config entries (84 total), new Strategy/Radio+Tac GUI rows, and
     push/flank counters in the Overview strategic stats.
 v2.1.0  -  THE KIT & CLASS UPDATE
   * NEW: Item Intelligence. Verified: vanilla AI item logic is two hardcoded
     SwitchTo(slot 1) calls and nothing else - Soldier.UseBandages has ZERO AI
     callers. Added, all through vanilla item APIs on owned bots only:
     self-bandaging with a human fumble delay and a suppression gate; proactive
     AT-grenade engagement of armor by AT units/sappers (respects the section-6
     grenade cooldown); panic smoke on the threat axis when pinned hard in the
     open; forced bipod-deploy checks for stationary gunners with a target.
   * NEW: Class Awareness. Medic response heartbeat (extra invocations of the
     vanilla MedicRoutine while a squadmate is injured); marksman doctrine
     (MarksmanPatience trigger timing + early prone in long-range duels,
     stacking with the humanized accuracy model); radioman keeps ~35% tighter
     spacing to the leader (fast confirmation of the v2.0.0 AI radio calls).
   * 16 new config entries (81 total across 14 sections), new Kit+Class GUI
     tab, new kit-brain live counters on the Overview tab.
   * All prior systems unchanged; identical MP-safety architecture (ownership
     gate + vanilla synced APIs only).
 v2.0.0  -  THE STRATEGIC UPDATE
   * NEW: Objective Prioritization. Squad.CalculateSquadTask (decoded from the
     v2.0.6 disassembly: attackers = closest objective only, defenders =
     literally random) is replaced for AI-owned squads by a scored selection
     over the game's own objective registry: distance-weighted, squad-count
     balanced (BalanceSquadsPerObjective), contested-point reinforcement, smart
     defender tasking, periodic strategic re-evaluation. Scripted 'closer'/
     'random' picks from missions are respected unless you opt in to override.
   * NEW: Squad Command Brain - coordinated assault charges onto contested
     objectives, garrison holds on captured ground, regrouping of scattered
     squads, context-aware formations. Issued exclusively through the vanilla
     squad-order API (HoldArea / SendUnitsToCharge / FollowLeader) which
     carries its own network sync.
   * NEW: Radio & Fire Support - AI squads with a living radioman now call HE
     barrages when pinned, smoke ahead of assaults and tank/AT support on
     armor, through the untouched vanilla radio pipeline (GiveRadioRequest ->
     radioman walks to a radio and confirms -> batteries fire). Per-squad
     cooldowns, call chance and triggers are all configurable. Verified: no
     vanilla code path ever let AI initiate these.
   * NEW: Tactical Stance Discipline - range-aware posture layered on the
     vanilla GetFavouriteFightingPose hook: CQB stays standing, long range
     goes low by skill, tunable suppression-prone threshold.
   * 23 new config entries (65 total across 12 sections), two new GUI tabs
     (Strategy, Radio+Tac), new live strategic counters on the Overview tab.
   * All v1.x systems unchanged. MP safety identical: every new behavior is
     gated on squad-leader ownership (the game's own Photon authority) and
     uses only order/radio calls that vanilla itself syncs.
 v1.0.2
   * Fixed: the configuration window opened as an empty gray box (only the
     title bar rendered). Root cause: Easy Red 2's IL2CPP build STRIPS part of
     Unity's IMGUI module. The GUILayout auto-layout family used by the window
     body still exists in the BepInEx interop assemblies (so the mod compiled),
     but its engine-side implementation is partially absent from
     GameAssembly.dll - the first stripped call threw during the layout pass
     every frame, aborting everything after the title.
   * The entire window was rebuilt on the fixed-rectangle GUI.* subset that was
     verified member-by-member to survive in ER2's GameAssembly (Box, Label,
     Button, styled HorizontalSlider, BeginGroup/EndGroup clipping). Because
     GUI.BeginScrollView and GUI.TextField are also stripped from the game,
     scrolling is now a built-in scrollbar (mouse wheel + draggable thumb +
     track paging) and the hotkey field became a press-to-capture rebind
     button. Hover explanations now run on raw Input instead of IMGUI events.
   * Added: if any GUI exception ever occurs again, it is logged ONCE at Error
     level with a full stack trace AND shown as a red banner inside the window
     itself - no more silent blank windows.
   * All features preserved: 7 tabs, all 202 settings with live sliders and
     min/max display, hover explanations, one-click presets, window dragging,
     live MP/performance footer. No gameplay or config format changes.
 v1.0.1
   * Fixed: 4 Il2CppInterop startup warnings ("has unsupported parameter
     ConfigEntry`1[...]") emitted while registering the GUI component. The
     GUI's internal slider/toggle/enum row helpers take managed BepInEx
     ConfigEntry<T> parameters, which the IL2CPP class injector cannot marshal
     when building native thunks; they are now marked [HideFromIl2Cpp] so the
     injector skips them. They were only ever invoked from managed code inside
     OnGUI, so behavior is byte-identical - the log is simply clean now.
   * No gameplay, config, or feature changes. All 42 settings, the GUI, the
     presets and every AI system are untouched.
 v1.0.0
   * Initial release.

--------------------------------------------------------------------------------
 FILES IN THIS RELEASE
--------------------------------------------------------------------------------
   BepInEx\plugins\StixsworldHD.EasyRed2.UngodlyAI.dll   the mod
   README_INSTALL.txt                                     this file

 Reverse-engineering, design & code: StixsworldHD (StixsmasterHD4k)
 Built from a full Ghidra decompile of Easy Red 2 v2.0.6 + BepInEx interop dumps.
================================================================================
