# Changelog — StixsworldHD Ungodly AI Overhaul (HYPERCHARGE: Unboxed +DLC) ## v1.8.0 Deeper enemy coverage and finer game-mode control. ### Enemies - **Spinner-type simple enemies** now get their own movement tuned (`npc_actor_move_speed_mult` -> `MoveSpeed`, `npc_actor_spin_speed_mult` -> `SpinSpeed`). Previously simple NPCs only got perception/chase-time; spinners were leaving their movement on the table. Other simple NPCs that don't have these fields are unaffected (guarded). - **Optional enemy escalation (`enemy_dda_*`, OFF by default):** a dynamic difficulty director *for enemies*. When enabled, each enemy gets a one-time bonus at spawn scaled by the friendly director's live intensity, folded onto enemy sight range + movement speed. Enemies that appear while a match is hot are tougher than those that appear while it's calm; an `enemy_dda_invert` option turns it into a rubber-band that pushes hardest on dominant players. Snapshotted once per enemy (no per-tick work, never compounds), uses the universal intensity so it escalates in every mode, and stays neutral (x1.0) until the director has produced a reading. ### Game modes - **Per-side mode filters:** new `bot_mode_filter` and `enemy_mode_filter` refine the global `mode_filter` independently for the friendly and enemy sides, so you can (for example) enhance enemies in every mode but only buff teammates in co-op, or the reverse. Both default to `"all"` and gate their side's controller/pawn passes, simple-NPC enhancement, pickups/battery seeking, bot profiles, and the director's bot scaling. - Config key count is now 150 (was 142), 1:1 `config.lua` <-> `DEFAULTS` parity; banner bumped to v1.8.0 and now reports enemy escalation and both per-side filters. - Verified in a dedicated harness: spinner MoveSpeed/SpinSpeed scaling via the real NPC hook, enemy escalation producing the expected x1.5 bonus at intensity 0.5 (on top of the static multipliers) and neutral when off, and the per-side filters gating each side independently (bot excluded while enemy enhanced, and vice-versa). Full prior suite still passes. ## v1.7.0 A smarter difficulty director plus real quality-of-life for live tuning. - **Richer difficulty-director signals:** - `dda_metric_players_weight` (+ `dda_full_team_size`): fewer humans alive => more teammate assist, normalised against the team size. A solo player gets maximum backup; a full team gets none from this signal. Defaults on at a modest weight; auto-skips if the player count can't be read (e.g. at a menu), so it never guesses. - `dda_metric_time_weight` (+ `dda_time_ramp_seconds`): an optional time-survived ramp that gradually raises teammate capability over a match — ideal for endless modes like Survival. Off by default (opt-in). - The director now blends up to **five** signals (Core power, enemy pressure, player health, player count, time), each independently weighted, on top of the v1.6.0 intensity floor/ceiling. - **Live config hot-reload:** new `reload_key` (and optional `auto_reload_seconds` timer) re-reads `config.lua` from disk without a game restart and updates the live config **in place**, so the difficulty director and every newly-spawned toy immediately use the new values (toys already in play keep what they had). A syntax error in an edited config on reload is caught and the last good values are kept. - **Diagnostics:** new `status_key` prints a one-shot live status line to the UE4SS console — current mode, difficulty, director skill/intensity, player count, and per-category enhancement counts. - All three new keys (`toggle_key` joins them) are opt-in and default to `nil`/off. Config key count is now 142, 1:1 `config.lua` <-> `DEFAULTS` parity; banner bumped to v1.7.0 and now prints the director's signal weights and the auto-reload interval. - Verified in a dedicated harness: player-count metric (solo => max assist, full team => none, unknown => skipped), time-ramp metric (monotonic rise to the cap), and live reload (auto-reload firing on schedule, in-place mutation taking effect mid-session, and a broken-config reload safely keeping the last good values). Full prior suite still passes. ## v1.6.0 A broad "all around" deepening pass — the biggest addition closes the friendly-pathfinding gap. - **Friendly bot pathfinding & behaviour (new section 2h — `bot_path_*`):** teammate bots are `AUBAIController`s with the same `PathFollowingJumpingComponent` and behaviour flags as enemies, so they now get the full enemy-grade navigation engine: block-detection + auto-repath, teleport-when-blocked failsafe, moving-target interception (`bOffsetMoveTargetBasedOnVelocity`), keep-pathing while launched/falling, preserved nav-links, `bAllowStrafe`, `bJumpOnLanding`, `bSkipExtraLOSChecks`, and longer `LoseEnemyAfterTime`. Applied once per bot controller via the existing dispatch (idempotent). - **Deeper bot profile competence:** added `MoveDecelScale` (crisper stops/turns), `StepHeight` and `StepAngle` (climb taller/steeper), a widened `Hostility_PreyHealth` band (finish more wounded foes), and folded `Hostility_EnemyFlashlightMultiplier` into the objective target-priority group. - **Enemy sensing completeness:** enemy sensing now also asserts `bHearNoises` and `bSeeEnemies` (alongside the existing `bSeePawns`) for fuller awareness. - **Difficulty director polish:** new `dda_intensity_floor` / `dda_intensity_ceiling` clamp the live intensity, so you can guarantee a baseline level of teammate assist (floor) or cap how hard the director ramps (ceiling). - Config key count is now 137 (was 117), 1:1 `config.lua` ↔ `DEFAULTS` parity; banner bumped to v1.6.0 and now reports `bot_path`. - Verified in a dedicated harness: bot controller pathfinding (block detection, interception, teleport, strafe, jump-on-landing, pursuit), the new profile levers, and the DDA intensity floor holding a baseline skill with no danger present. Full prior suite still passes. ## v1.5.0 Ungodly enhanced **all game modes support** and **all enemy type support**. ### All game modes - **Mode detection + filter:** reads `CurrentGameMode` from the local player controller (Waves=0 / Survival=1 / FreeRoam=2 / Deathmatch=3 / Plague=4 / Zones=5 / SpinnerArena=6 / TankBattle=7 / CTB=8). New `mode_filter` (config section 1b) defaults to `"all"`; set a comma-separated list to restrict the mod to chosen modes. The director loop and all five spawn hooks are gated by the filter (it never blocks when the mode can't yet be determined). - **Universal difficulty signal:** the dynamic difficulty director now also reads local player health (`dda_metric_player_health_weight`) via `UHealthComponent:GetHealthPercent`, so it has a danger signal in **every** mode — including modes with no Core, where the core-power signal is simply skipped. Core / enemy-pressure / player-health weights are all independently tunable. - Wave-only features (building, battery seeking, Core defending) already degrade gracefully in modes that lack buildables / batteries / a Core, thanks to the guarded helpers. ### All enemy types - **Flying / floating enemies** (`AUBFlyingPawn` and any pawn whose movement is a `UFlyingPawnMovement` / `UFloatingPawnMovement` rather than `CharacterMovement`) are now enhanced: the enemy pawn pass detects the absence of `CharacterMovement` and boosts the flying movement component instead (`MaxSpeed`, plus `Acceleration`/`Deceleration`/ `TurningBoost` when present). New config section 6b — `enemy_fly_*`. - Verified coverage of the full enemy hierarchy: all hostile controllers including `AUBAIControllerSimple` (caught by the existing `AUBAIController` hook), all `AUBCharacter` enemies including `AUBCharacterShield`, `AUBCharacterBreakable` and `…BreakableMulti`, and all `AUBNPCActor` simple enemies (`AUBBouncyBall`, `AUBSpinner`, `AUBNPCActorBreakable`). The particle-swarm actor is a non-AI spline hazard and is intentionally left alone. Human players remain untouched in every mode. - Config key count is now 117 (was 111), 1:1 `config.lua` ↔ `DEFAULTS` parity; banner bumped to v1.5.0 and now reports `mode_filter`. - Verified in a dedicated harness: flying-enemy movement boost, mode-filter gating (excluded mode = no changes, allowed mode = enhanced), and the player-health difficulty signal raising bot skill in a Core-less mode. ## v1.4.0 Added an ungodly, madly, vastly enhanced **real-time dynamic difficulty director** (config section 2g — `dda_*`) that scales bot Skill within a per-vanilla-difficulty band. - **Difficulty detection:** reads `CurrentDifficulty` from the local player controller (Easy=0 / Normal=1 / Hard=2 / Nightmare=3), with a configurable fallback. - **Per-difficulty skill bands:** independent `min`/`max` Skill for Easy/Normal/Hard/Nightmare (`dda_*_skill_min`/`max`) plus an absolute clamp (`dda_skill_clamp_min`/`max`). Skill is a raw `uint8` on `UBotProfile`, written as an absolute value every tick (never multiplied). - **Live intensity metric:** derived from Core power remaining (`AUBCore` → `UPowerComponent:GetPowerPercent`) and active enemy pressure (tracked controllers + NPC actors, self-calibrating peak), with per-signal weights and an `dda_invert` option. - **Smoothing:** `dda_smoothing` eases Skill toward its target; re-initialises to the band midpoint on first run and whenever the difficulty band changes. - **Competence-follows-skill (default on):** modulates `AimSpeedMul`, `AimAccuracy`, `ControlRotationInterpEnemy` (higher-is-better) and `SenseInterval` (inverse) by a multiplier that slides between `dda_competence_min`/`max` across the band. Computed from a one-time baseline captured *after* the static enhancement pass, so it never drifts or compounds. - Runs inside the existing director loop after the profile/controller sweeps; responsiveness is governed by `director_interval_ms` + `dda_smoothing`. - Config key count is now 111 (was 91), 1:1 `config.lua` ↔ `DEFAULTS` parity; version banner bumped to v1.4.0 with a dynamic-difficulty status line. - Verified in a dedicated harness: difficulty→band selection, danger-driven skill scaling (high danger → band max, calm → band min), competence modulation (aim up / sense down), re-banding on difficulty change, and no compounding across 200 ticks. ## v1.3.0 Added an ungodly, madly, vastly enhanced **friendly-bot battery-seeking** system (config section 2f — `bot_battery_*`). - **Battery seeking / objective delivery:** clears `bBotsIgnorePickup` on objective batteries (`AUBBattery` and its flag variants) so bots actively seek batteries and carry them to the Core to power it. Master switch `bot_battery_enhance`, with `bot_battery_unignore` for the un-ignore action. - Runs **independently of `bot_seek_scope`**, so battery seeking stays on even when generic pickup seeking is set to credits-only. - Batteries are `AUBPickup`-derived, so the generic pickup handler now explicitly **cedes batteries** to this dedicated feature: with the feature off, batteries are left alone (verified — disabling it leaves batteries ignored while other pickups still seek). This also corrects the v1.2.0 note that implied batteries were untouched. - New `/Script/Unboxed.UBBattery` construction hook plus the director sweep (5 hooks total), with a cached `AUBBattery` class resolver and name-based fallback detection. - Config key count is now 91 (was 89), 1:1 `config.lua` ↔ `DEFAULTS` parity; status logging now reports the bot-seekable-battery count; version banner bumped to v1.3.0. ## v1.2.0 **Infinite credits is no longer enabled by default** (`bot_builder_infinite_credits` now `false`), so bots earn credits the intended way. Added three new friendly-bot competency systems plus the credit-seeking that funds them. - **Defending / objective prioritization** (config section 2c — `bot_defend_*`, `bot_objective_*`): widens the Core-defense perimeter (`Hostility_CoreDistance`), speeds reaction to fresh wave spawns (`Hostility_SpawnDelay`), boosts priority on battery-carrying enemies (`Hostility_EnemyBatteryCarrierMultiplier`), sharpens high-value target selection (instigator/context/winner/better-weapon/more-attachments/player multipliers), and shortens `RePickupItemDelay` so bots recover dropped objective items fast. Master switch `bot_defend_enhance`. - **Item / weapon handling** (config section 2d — `bot_weapon_*`): sharper grab-while-dodging (`DodgePickupMovement`) and an optional bottomless-ammo flag (`IsMaxAmmo`, `bot_weapon_infinite_ammo`, OFF by default). Weapon swapping and reload-cancelling continue to come from clearing the handicap flags. Master switch `bot_weapon_enhance`. - **Pickup / credit seeking** (config section 2e — `bot_seek_*`): clears `bBotsIgnorePickup` on AUBPickup-derived pickups so bots actively seek turret credits, ammo, health, weapons, attachments, weapon sets and jetpacks. `bot_seek_scope` selects `"all"` or `"credits"` (credit-only focus). Implemented via a new `/Script/Unboxed.UBPickup` construction hook plus the director sweep; batteries (a separate objective-item base) are intentionally untouched. Master switch `bot_seek_enhance`. - Added `IsMaxAmmo` (bit 0) to the EBotFlags table. - Config key count is now 89 (was 77), with 1:1 `config.lua` ↔ built-in `DEFAULTS` parity. - New `/Script/Unboxed.UBPickup` spawn hook (4 hooks total); status logging now reports the bot-seekable-pickup count; version banner bumped to v1.2.0. - Verified: defending/objective multipliers, credits-and-ammo-off-by-default, pickup seeking in both scopes, and the infinite-ammo toggle, all in the off-engine harness suite. ## v1.1.0 Added an ungodly, madly, vastly enhanced **friendly-bot building / defense competency** system (config section 2b — `bot_builder_*`). - **Category enables guaranteed:** ensures `Buildable_Defence` (barricade), `Buildable_Trap`, and `Buildable_Turret` are enabled on every bot profile (raise-only — never reduces a bot that already builds more). `bot_builder_ensure_enabled`. - **Full buildable catalog unlocked:** reads every profile's `Buildables_Defence/Trap/Turret` subtype lists, unions them, and grants the complete shipped set to all profiles so every bot can build every barricade/trap/turret type any profile could. All indices come from real shipped data (no invalid buildables); the union is rebuilt each sweep so late-loading profiles widen the catalog for everyone. Best-effort + fully guarded so it degrades gracefully on engine builds that don't support array replacement. `bot_builder_unlock_all_buildables`. - **Unlimited build credits keystone:** sets the `InfiniteCredits` bot flag so bots can afford to build, repair, and upgrade defenses relentlessly. `bot_builder_infinite_credits` (also still enabled by `bot_set_infinite_credits`). - **Advanced count override:** `bot_builder_category_amount` forces each category-enable byte to an exact value for users who determine it acts as a per-category structure count. - Master switch `bot_builder_enhance` for the whole feature. - Builder pass runs separately from the once-only multiplier pass: category enables apply once per profile, the catalog re-applies only when it grows, and everything is idempotent (verified: repeated sweeps change nothing; late-loaded profiles propagate correctly). - Config key count is now 77 (was 72), with 1:1 `config.lua` ↔ built-in `DEFAULTS` parity. - Version banner bumped to v1.1.0; status logging now reports the builder count. ## v1.0.0 Initial release. ### Friendly bot AI — behaviour - Aim acquisition / tracking speed scaling (AimSpeedMul, AimSpeedVel). - Aim precision scaling (AimAccuracy). - Control-rotation interpolation scaling toward targets (ControlRotationInterp + Enemy). - Combat flags: enable NoRecoil, NoSpread, HasAntiAir; clear all developer handicap flags (NoLeadTarget, NoAimTarget, NoTargetDodge, NoDodge, NoMelee, NoPreyOnWeak, NoDamageDodge, NoDamageDodgeJump, NoChangeWeapon, NoReloadSwap); optional InfiniteCredits. - Perception: faster sense interval, wider vision angle, longer target memory, longer voice-command hearing range. - Hostility/target-priority awareness band widening. - Optional Skill override and low-health-threshold scaling (off / neutral by default). ### Friendly bot AI — pathfinding / mobility - Movement, acceleration, and air-control input-scaling (MoveSpeedScale/AccelScale/AirScale). - Jump velocity, dodge distance, dodge-jump chance, damage-dodge movement/jump, dodge recovery. - Faster reaction delays (DoubleJump/DamageDodge/AimTargetDodge/Vault). - Optional per-bot-body movement tuning (speed cap, acceleration, air control, step height), applied only to bot bodies — never to human players. ### Enemy AI — perception - Sight radius, hearing thresholds (incl. LOS hearing), sensing interval, and peripheral vision angle scaling (vision capped at 180°). ### Enemy AI — behaviour & persistence - Longer loss-of-sight pursuit time. - Keep pathing while launched and while falling. - Jump-on-landing chaining, strafing while engaging, faster target lock (skip extra LOS). ### Enemy AI — pathfinding engine - Block (stuck) detection with configurable distance/interval/sample window. - Teleport-when-blocked last-resort un-stick. - Target velocity prediction / interception (lead moving targets). - Preserve nav-links when momentarily falling. - Optional path-point acceptance-radius scaling (only when the map set a non-zero override). - Optional, off-by-default route diversity via varied navigation-query filters (rand/fixed pools, jump-filter variant, configurable count). ### Enemy AI — body / traversal - Walk speed, acceleration, air control, step height, jump velocity, yaw rotation rate, optional braking scaling, optional double-jump count and steeper walkable-floor angle. ### Simple enemies (UBNPCActor: bouncy balls, swarmers) - Sense-component radius/interval/vision scaling and longer chase timer. ### Engineering - Single fully-documented `config.lua` control surface with min/max ranges on every value. - Built-in DEFAULTS fallback in `main.lua` (1:1 key parity with `config.lua`), so the mod runs even if the config is missing or corrupt. - Event-driven: each entity enhanced exactly once at construction; ~1 Hz guarded safety sweep; dead-reference pruning; no per-frame AI logic. - Multiplier-based (baseline-agnostic) buffs that never compound and preserve per-difficulty tuning; humans never modified. - Every property write / function call individually guarded for cross-version and cross-DLC resilience; survives UE4SS hot-reload via a generation token.