Skip to content

Changelog

Kanisuko edited this page May 25, 2026 · 11 revisions

Changelog


0.4.0 — 2026-05-25

Lifecycle System

v0.4.0 introduces a first-class lifecycle system for mods. By passing an IModLifecycle implementation to ModRegistry.Register(), your mod's callbacks are automatically wired into the EventBus — no manual EventBus.Register() call required.

ModRegistry.Register(new ModInfo("MyMod", "1.0.0", "desc"), new MyLifecycle());

The IModLifecycle interface defines six callbacks:

Callback When it fires
OnEnabled() Immediately after successful registration
OnDisabled() Reserved for future use
OnWorldLoaded(WorldLoadedEvent) World fully initialized, Body safe to access
OnLayerLoaded(LayerLoadedEvent) Every layer (biome) finishes generating
OnWorldUnloading(WorldUnloadingEvent) Before layer transition or save-and-exit
OnWorldDestroyed(WorldDestroyedEvent) WorldGeneration.OnDestroy() completes

ModLifecycleBase provides default empty implementations of all six callbacks. Inherit from it and override only what you need.


New Events

Three new pre-defined game events are now built into ScavLib and triggered automatically via Harmony:

LayerLoadedEvent

Fired every time a layer (biome) finishes generating and is playable, including the very first layer of a session.

Property Type Description
BiomeDepth int Depth of the layer that just loaded. 0 = first layer.
IsFirstLoad bool true only on the first layer of the session.

WorldUnloadingEvent

Fired before WorldGeneration.Clear() runs, giving you a last chance to read player and world state safely.

Property Type Description
CurrentBiomeDepth int The depth being torn down.
NextBiomeDepth int The depth to be generated next, or -1 on save-and-exit.
IsExitToMenu bool Convenience: true if NextBiomeDepth < 0.

WorldDestroyedEvent

Fired after WorldGeneration.OnDestroy() completes. Use for global cleanup that must survive layer transitions.

Property Type Description
LastBiomeDepth int Last known biome depth before destruction. May be -1.
WasSaveAndExit bool true if triggered by save-and-exit.

ModInfo — Dependency Declaration

ModInfo now accepts an optional dependencies parameter listing the names of mods this mod depends on. Missing dependencies are logged as warnings at registration time (advisory only — load order is still enforced by BepInEx [BepInDependency]).

new ModInfo("MyMod", "1.0.0", "desc", "Author", "ScavLib", "OtherMod")

scavlib status now displays declared dependencies after the mod entry:

ScavLib Activated.
Version: 0.4.0
Registered Mods: [
  MyMod v1.0.0 by Author [F] Deps: [ScavLib, OtherMod]
]

The [F] tag indicates the mod was registered with an IModLifecycle object.


Breaking Changes

None. All additions are purely additive. Existing 0.3.x mod code compiles against 0.4.0 without modification.


0.3.0 — 2026-05-24

PlayerUtil — Full Body Coverage

PlayerUtil has been expanded to cover virtually every writable field on the player Body component, up from the ~15 methods in 0.2.3. The new additions are organized into named sections within the source file:

  • Circulation / BloodBloodViscosity BloodVesselSize FibrillationProgress HeartRatePressureOffset FibrillationForced HasPulmonaryEmbolism StrokeAmount
  • AdrenalineAdrenaline CurAdrenaline
  • Infection / Toxicology / SepsisSepticShock SicknessAmount VenomTotal VenomCurrent
  • BleedingInternalBleeding Hemothorax
  • Neurology / PsychologyShock PainShock TraumaAmount RadiationSickness HorrifiedLevel FocusedLevel BrainGrowSickness
  • Happiness / WeightHappinessBase WeightOffset
  • External ConditionsWetness Dirtyness SnowAmount HearingLoss
  • ClawsClawHealth ClawRegrowTime
  • ImmunityImmunity AntibioticImmunityTime
  • StimulantsCaffeinated
  • AppearanceDisfigured EyeGone BothEyesGone
  • SleepSleeping BadSleepAmount
  • Read-only derived propertiesAveragePain TotalBleedSpeed IsBreathing IsInWater HasScubaGear IsStanding IsCrouching IsOnHardStimulants UsedNeuralBooster

Each writable field provides both a Get read and a SetRaw direct-field write with Mathf.Clamp protection. The two-path convention (recommended writes vs. Raw writes) introduced in 0.2.0 is preserved throughout.


PlayerUtil.Thresholds — Expanded Constants

PlayerUtil.Thresholds has been expanded from ~50 to 60+ named constants, now covering every threshold used by the game's moodle system:

Category Constants added
Blood pressure CRITICAL_LOW LOW_1~3 HIGH_1~3 CRITICAL_HIGH
Bleeding speed CRITICAL HEAVY MEDIUM
Internal bleeding CRITICAL
Hemothorax PRESENT HEAVY
Stroke CRITICAL
Happiness Full 8-tier scale (MISERABLEHAPPY_4)
Weight offset Full 8-tier scale (UNDERWEIGHT_4OVERWEIGHT_4)

All values were extracted directly from MoodleManager.AddAllMoodles() and match the thresholds used by the game's own UI.


LimbUtil — Aggregate Queries

LimbUtil gains several new aggregate query methods:

  • HasBrokenBone()true if any non-dismembered limb is broken
  • HasDislocation()true if any non-dismembered limb is dislocated
  • HasInfection()true if any non-dismembered limb has an active infection
  • HasDismemberment()true if any limb has been dismembered
  • GetMaxInfection() — highest infection amount across all limbs (0 ~ 100)
  • GetAveragePain() — mirrors Body.averagePain
  • GetTotalBleedSpeed() — total bleed speed across all limbs

Bug Fixes

  • PlayerUtil.HealAll() — Now also resets shock, adrenaline, curAdrenaline, painShock, traumaAmount, wetness, dirtyness, hearingLoss, hasPulmonaryEmbolism, venomCurrent, venomTotal, internalBleeding, hemothorax, and clawHealth — fields that were silently left dirty in 0.2.x.

Breaking Changes

None. All additions are purely additive. Existing 0.2.x mod code compiles against 0.3.0 without modification.


0.2.3

Bug Fixes

  • PlayerUtil — Fixed wrong namespace (ScavLib_API.utilScavLib.util) and wrong access modifier (internal classpublic static class). The class was previously invisible to all external mods.
  • ItemPickupPatch — Removed unused bool force parameter from the Postfix signature to eliminate unnecessary Harmony reflection binding.
  • CommandRegistryPatch — Added [HarmonyPriority(Priority.High)] to guarantee commands are registered before WorldLoadedEvent fires.

Added

  • PlayerUtil — 9 new methods:
    • GiveItem(string id) — Spawn item at player feet and auto-pickup
    • TakeItem(string id) — Drop first matching item from inventory
    • HasItem(string id) — Check surface inventory by ID
    • GetAllItems() — Get all slot inventory items
    • IsAlive() / IsConscious() / IsDying() — State queries
    • GetHunger() / GetThirst() — Vital reads

0.2.2

Bug Fixes

  • MenuManager — Fixed menu windows not rendering. Migrated MenuManager from a standalone DontDestroyOnLoad GameObject to a MonoBehaviour renderer attached to PlayerCamera. Removed the now-unused MenuWindowStyle enum.

0.2.1

Bug Fixes

  • PlayerUtil — Fixed Body.PickUpItem call signature: parameter type corrected from Item it to Item item.

0.2.0 — 2026-05-23

New Modules

  • PlayerUtil — Vital sign reads, state queries, recommended writes, raw writes, inventory shortcuts, and PlayerUtil.Thresholds (~50 named constants from the game's moodle system).
  • SkillUtil — Typed SkillType enum, level/XP reads, XP writes, raw level set, global XpMultiplier.
  • ItemUtil — World-space item scanning, safe condition modification, favourite toggling, safe destruction, global registry queries.
  • CustomItemRegistry — Register custom ItemInfo definitions into Item.GlobalItems with automatic injection timing.

Event System

  • Added pre-defined game events: WorldLoadedEvent, ItemPickedUpEvent, ItemDroppedEvent — triggered automatically via Harmony, no manual patching required.
  • EventBus.Post<T> now dispatches along the full inheritance chain.
  • Exception isolation improved: handler errors now include event type context in the log message.

Improvements

  • GameUtil — Added IsWorldLoaded, GetWorld(), SpawnItemAt(id, Transform), Notify().
  • ModRegistry — Added TryFind(name, out ModInfo) and IsRegistered(name). Duplicate registration now logs a warning instead of silently succeeding.

Bug Fixes

  • MenuWindow — Fixed auto-height: Height = 0 now uses true IMGUI content-adaptive sizing instead of a hardcoded 400px fallback.
  • MenuManager — Removed erroneous using UnityEngine.Windows reference.
  • CommandRegistry — Removed dead Init() body; method is now a documented extension point called explicitly from ScavLibPlugin.Awake().

Breaking Changes

  • EventBus.Post<T> now dispatches to base-type subscribers. Only affects code subscribing to BusEvent directly, which was not meaningful in 0.1.0.
  • MenuWindow with Height = 0 now resizes to content instead of 400px. Add public override float Height => 400f to restore the previous behavior.

0.1.0 — Initial Release

  • MenuWindow / MenuBuilder — IMGUI menu framework.
  • ConfigManager — BepInEx config wrapper.
  • EventBus / [Subscribe] / BusEvent — Attribute-based event bus.
  • CommandRegistry / BaseCommand — Console command registration.
  • GameUtil — Basic player state and item spawning helpers.
  • ModInfo / ModRegistry — Mod metadata registration.

Clone this wiki locally