Skip to content

PlayerUtil

Kanisuko edited this page May 25, 2026 · 7 revisions

PlayerUtil

Namespace: ScavLib.util

Safe, null-protected wrappers around the player's Body component. All methods return safe default values (0, false, null) when no world is loaded — they will never throw a NullReferenceException.

Two write paths are provided throughout this API:

  • Recommended writes — respect the game's internal logic where possible (e.g. Feed, HealAll). Use these by default.
  • Raw writes (suffix Raw) — direct field assignment with Mathf.Clamp protection. Bypass game logic intentionally. Use only when you know what you are doing.

Inventory Shortcuts

Method Returns Description
GiveItem(string id) GameObject Spawn item at player feet and auto-pickup. Returns the spawned GameObject, or null on failure.
TakeItem(string id) bool Drop the first inventory item matching the given ID. Returns true if found and dropped.
HasItem(string id) bool Check if the player has at least one item with the given ID in their surface inventory (slots + wearables).
GetAllItems() List<Item> Get all items currently in the player's slot inventory (not wearables). Returns an empty list if not in game.
FindItemById(string id, out Item item) bool Search full inventory including containers and wearables by ID.
FindItemByTag(string tag, out Item item) bool Search full inventory including containers and wearables by tag.
PlayerUtil.GiveItem("bandage");

if (PlayerUtil.HasItem("rifle"))
    GameUtil.Log("Player has a rifle.");

if (PlayerUtil.FindItemById("medkit", out var kit))
    ItemUtil.Repair(kit);

Vital Sign Reads

Method Returns Normal range / Notes
GetHunger() float Normal: 100. Below 0 = starving.
GetThirst() float Normal: 100. Above 175 = over-hydration.
GetStamina() float 0 ~ 100.
GetEnergy() float 0 ~ 100. Below 7 = exhausted.
GetConsciousness() float 0 ~ 100. Below 30 = incapacitated.
GetBrainHealth() float 0 ~ 100. At 0 = dead.
GetBloodOxygen() float 0 ~ 100. Normal: ~98.
GetBloodVolume() float Normal: 100. Max: 200. Can go negative.
GetBloodPressure() float Normal: ~120.
GetHeartRate() float Normal: ~70 BPM. Below 20 = cardiac arrest.
GetRespiratoryRate() float 0 ~ 100. Normal: ~100.
GetTemperature() float Celsius. Normal: 36.6 ~ 37.
GetHappiness() float -100 ~ 100. Composite totalHappiness after all modifiers.
GameUtil.Log($"HR: {PlayerUtil.GetHeartRate():F0} BPM  " +
             $"BP: {PlayerUtil.GetBloodPressure():F0}  " +
             $"SpO2: {PlayerUtil.GetBloodOxygen():F0}%");

Extended Vital Reads

These cover the full Body field set added in 0.3.0.

Circulation

Method Returns Notes
GetBloodViscosity() float -100 ~ 100. 0 = normal. Positive = thicker blood (raises pressure).
GetBloodVesselSize() float 0.85 ~ 1.15. 1.0 = normal. Affects blood pressure calculation.
GetFibrillationProgress() float 0 ~ 100. Above 100 triggers cardiac arrest.
GetHeartRatePressureOffset() float -30 ~ 80. Offsets the heart rate target.
GetFibrillationForced() bool If true, fibrillation is active regardless of normal triggers.
GetHasPulmonaryEmbolism() bool Immediately triggers isDying.
GetStrokeAmount() float 0 ~ 100. Above 50 triggers isDying.

Adrenaline

Method Returns Notes
GetAdrenaline() float 0 ~ 100. Reserve pool; curAdrenaline moves toward this value.
GetCurAdrenaline() float 0 ~ 100. Active value that actually affects heart rate and pain.

Infection / Toxicology / Sepsis

Method Returns Notes
GetSepticShock() float 0 ~ 100. Above 75 triggers isDying.
GetSicknessAmount() float 0 ~ 100. Above 85 infects the pelvis limb.
GetVenomTotal() float 0 ~ 100. Injected venom pool; venomCurrent moves toward this.
GetVenomCurrent() float 0 ~ 100. Active venom affecting blood oxygen and viscosity.

Bleeding

Method Returns Notes
GetInternalBleeding() float 0 ~ 100. Slowly self-heals; above 5 generates hemothorax.
GetHemothorax() float 0 ~ 100. Above 40 = present; above 70 = heavy.
GetAveragePain() float Read-only. Highest limb pain after Resilience reduction.
GetTotalBleedSpeed() float Read-only. Sum of all limb bleed rates minus regen speed.

Neurology / Psychology

Method Returns Notes
GetShock() float 0 ~ 100. Above 10 triggers ragdoll.
GetPainShock() float 0 ~ 1. Above 0.66 drops consciousness to zero.
GetTraumaAmount() float 0 ~ 100. Accumulated from sustained suffering; affects happiness.
GetRadiationSickness() float 0 ~ 100. Above 60 triggers isDying.
GetHorrifiedLevel() float 0 ~ 200. Each point reduces totalHappiness by 0.5%.
GetFocusedLevel() float 0 ~ 200. Symmetric to horrifiedLevel; used by drug/buff effects.
GetBrainGrowSickness() float 0+. Decays over time; used by special story item effects.

Happiness / Weight

Method Returns Notes
GetHappinessBase() float -100 ~ 100. Base value before modifiers. GetHappiness() returns the final composite.
GetWeightOffset() float -80 ~ 100. 0 = normal weight. Affects movement speed and blood pressure.

External Conditions

Method Returns Notes
GetWetness() float 0 ~ 100. Continuously lowers body temperature.
GetDirtyness() float 0 ~ 100. Above 75 eating may increase sickness.
GetSnowAmount() float 0 ~ 100. Affects temperature insulation calculation.
GetHearingLoss() float 0 ~ 100. Recovers over time; reduces happiness by 0.2 per point.

Claws

Method Returns Notes
GetClawHealth() float 0 ~ 100. Below 20 unarmed attacks may self-injure.
GetClawRegrowTime() float Seconds remaining on regrowth acceleration (×3 speed while > 0).

Immunity

Method Returns Notes
GetImmunity() float 0 ~ 200. Normal: ~100. Affects limb infection speed.
GetAntibioticImmunityTime() float Seconds remaining on antibiotic bonus (+70 immunity while > 0).

Stimulants / Sleep / Appearance

Method Returns Notes
GetCaffeinated() float Seconds remaining on caffeine effect.
GetBadSleepAmount() float Seconds of poor-sleep penalty (caps consciousness at 70 while > 0).
GetDisfigured() bool Eating causes additional head pain when true.
GetEyeGone() bool One eye lost.
GetBothEyesGone() bool Both eyes lost.

State Queries

Method Returns Condition
IsAlive() bool brainHealth > 0
IsConscious() bool Alive AND consciousness > 30
IsDying() bool Any critical vital threshold breached
IsCriticallyDying() bool Stricter version of IsDying — imminent death
IsInCardiacArrest() bool heartRate < 20
IsSleeping() bool Player is currently asleep
IsExercising() bool Player is currently performing a workout
IsBreathing() bool Read-only. alive AND respiratoryRate > 10
IsInWater() bool Read-only.
HasScubaGear() bool Read-only.
IsStanding() bool Read-only. Not in ragdoll.
IsCrouching() bool Read-only.
IsOnHardStimulants() bool Read-only.
UsedNeuralBooster() bool Read-only. One-time per save.

Recommended Writes

These methods respect the game's clamping and logic where meaningful.

Method Description
Feed(float amount) Add to hunger. Clamped to -100 ~ 100. Negative values allowed.
Hydrate(float amount) Add to thirst. Clamped to 0 ~ 200.
RestoreStamina(float amount) Add to stamina. Clamped to 0 ~ 100.
RestoreEnergy(float amount) Add to energy. Clamped to 0 ~ 100.
HealAll() Reset all vitals to safe values and heal every non-dismembered limb. Does not regrow dismembered limbs.
// Fully restore the player
PlayerUtil.HealAll();

// Partial restore
PlayerUtil.Feed(50f);
PlayerUtil.Hydrate(50f);
PlayerUtil.RestoreStamina(100f);

Raw Writes

Direct field assignments with Mathf.Clamp protection. These bypass game logic — use only when intentional.

Core vitals

Method Range
SetHungerRaw(float) -100 ~ 100
SetThirstRaw(float) 0 ~ 200
SetStaminaRaw(float) 0 ~ 100
SetEnergyRaw(float) 0 ~ 100
SetConsciousnessRaw(float) 0 ~ 100
SetBrainHealthRaw(float) 0 ~ 100 — setting to 0 kills the player
SetTemperatureRaw(float) 20 ~ 45 (°C)

Circulation

Method Range
SetBloodVolumeRaw(float) -100 ~ 200
SetBloodOxygenRaw(float) 0 ~ 100
SetBloodPressureRaw(float) 0 ~ 250
SetHeartRateRaw(float) 0 ~ 300
SetRespiratoryRateRaw(float) 0 ~ 100
SetBloodViscosityRaw(float) -100 ~ 100
SetBloodVesselSizeRaw(float) 0.85 ~ 1.15
SetFibrillationProgressRaw(float) 0 ~ 100
SetHeartRatePressureOffsetRaw(float) -30 ~ 80
SetFibrillationForcedRaw(bool)
SetHasPulmonaryEmbolismRaw(bool)
SetStrokeAmountRaw(float) 0 ~ 100

Adrenaline

Method Range
SetAdrenalineRaw(float) 0 ~ 100
SetCurAdrenalineRaw(float) 0 ~ 100

Infection / Toxicology / Sepsis

Method Range
SetSepticShockRaw(float) 0 ~ 100
SetSicknessAmountRaw(float) 0 ~ 100
SetVenomTotalRaw(float) 0 ~ 100
SetVenomCurrentRaw(float) 0 ~ 100

Bleeding

Method Range
SetInternalBleedingRaw(float) 0 ~ 100
SetHemothoraxRaw(float) 0 ~ 100

Neurology / Psychology

Method Range
SetShockRaw(float) 0 ~ 100
SetPainShockRaw(float) 0 ~ 1
SetTraumaAmountRaw(float) 0 ~ 100
SetRadiationSicknessRaw(float) 0 ~ 100
SetHorrifiedLevelRaw(float) 0 ~ 200
SetFocusedLevelRaw(float) 0 ~ 200
SetBrainGrowSicknessRaw(float) 0+

Happiness / Weight

Method Range
SetHappinessBaseRaw(float) -100 ~ 100
SetWeightOffsetRaw(float) -80 ~ 100

External Conditions

Method Range
SetWetnessRaw(float) 0 ~ 100
SetDirtynessRaw(float) 0 ~ 100
SetSnowAmountRaw(float) 0 ~ 100
SetHearingLossRaw(float) 0 ~ 100

Claws / Immunity / Stimulants / Sleep / Appearance

Method Range
SetClawHealthRaw(float) 0 ~ 100
SetClawRegrowTimeRaw(float) 0+ (seconds)
SetImmunityRaw(float) 0 ~ 200
SetAntibioticImmunityTimeRaw(float) 0+ (seconds)
SetCaffeinatedRaw(float) 0+ (seconds)
SetBadSleepAmountRaw(float) any
SetSleepingRaw(bool) — Note: does not trigger sleep animation.
SetDisfiguredRaw(bool)
SetEyeGoneRaw(bool)
SetBothEyesGoneRaw(bool)

PlayerUtil.Thresholds

Named constants for every threshold used by the game's moodle system. Use these instead of hard-coding magic numbers to keep your mod consistent with the game's own UI.

if (PlayerUtil.GetBloodOxygen() < PlayerUtil.Thresholds.BLOOD_OXYGEN_SEVERE)
    GameUtil.Alert("Low blood oxygen!", important: true);

Blood Pressure

Constant Value
BLOOD_PRESSURE_CRITICAL_LOW 60
BLOOD_PRESSURE_LOW_3 83
BLOOD_PRESSURE_LOW_2 96
BLOOD_PRESSURE_LOW_1 110
BLOOD_PRESSURE_HIGH_1 130
BLOOD_PRESSURE_HIGH_2 145
BLOOD_PRESSURE_HIGH_3 162
BLOOD_PRESSURE_CRITICAL_HIGH 180

Blood Oxygen

Constant Value
BLOOD_OXYGEN_CRITICAL 45
BLOOD_OXYGEN_SEVERE 60
BLOOD_OXYGEN_LOW 75
BLOOD_OXYGEN_MILD 90

Heart Rate (BPM)

Constant Value
HEART_RATE_CARDIAC_ARREST 20
HEART_RATE_BRADYCARDIA_SEVERE 40
HEART_RATE_BRADYCARDIA_MILD 60
HEART_RATE_TACHYCARDIA_MILD 110
HEART_RATE_TACHYCARDIA_SEVERE 160
HEART_RATE_TACHYCARDIA_CRITICAL 200

Temperature (°C)

Constant Value
TEMPERATURE_HYPOTHERMIA_CRITICAL 28.0
TEMPERATURE_HYPOTHERMIA_SEVERE 32.5
TEMPERATURE_HYPOTHERMIA_MILD 34.0
TEMPERATURE_COLD 35.5
TEMPERATURE_NORMAL 37.0
TEMPERATURE_WARM 38.0
TEMPERATURE_HYPERTHERMIA_MILD 39.0
TEMPERATURE_HYPERTHERMIA_SEVERE 40.25
TEMPERATURE_HYPERTHERMIA_CRITICAL 41.5

Hunger / Thirst / Stamina / Energy

Constant Value
HUNGER_STARVING 15
HUNGER_VERY_HUNGRY 35
HUNGER_HUNGRY 50
HUNGER_PECKISH 75
THIRST_CRITICAL 20
THIRST_VERY_THIRSTY 35
THIRST_THIRSTY 55
THIRST_MILDLY_THIRSTY 75
THIRST_OVERHYDRATED_3 175
STAMINA_EXHAUSTED 15
STAMINA_VERY_TIRED 35
ENERGY_EXHAUSTED 7
ENERGY_VERY_TIRED 15

Consciousness / Pain / Brain

Constant Value
CONSCIOUSNESS_UNCONSCIOUS 20
CONSCIOUSNESS_INCAPACITATED 30
PAIN_AGONY 80
PAIN_SEVERE 55
PAIN_MODERATE 30
BRAIN_DAMAGE_SEVERE 30
BRAIN_DAMAGE_MODERATE 60

Systemic Conditions

Constant Value
BLEED_SPEED_CRITICAL 0.30
BLEED_SPEED_HEAVY 0.15
BLEED_SPEED_MEDIUM 0.06
INTERNAL_BLEEDING_CRITICAL 50
HEMOTHORAX_HEAVY 70
HEMOTHORAX_PRESENT 40
STROKE_CRITICAL 70
SEPSIS_CRITICAL 80
SEPSIS_MODERATE 50
RADIATION_CRITICAL 80
RADIATION_SEVERE 50

Happiness / Weight

Constant Value
HAPPINESS_MISERABLE -75
HAPPINESS_DEPRESSED -50
HAPPINESS_HAPPY_4 75
WEIGHT_UNDERWEIGHT_4 -50
WEIGHT_OVERWEIGHT_4 50

For the full list of all 60+ constants, see the source file util/PlayerUtil.Thresholds.cs.


Usage Example

using ScavLib.util;
using ScavLib.event_bus;
using ScavLib.event_bus.events;

[BepInDependency("com.kanisuko.scavlib", "0.4.0")]
[BepInPlugin("com.yourname.yourmod", "YourMod", "1.0.0")]
public class YourPlugin : BaseUnityPlugin
{
    private void Awake()
    {
        EventBus.Register(this);
    }

    [Subscribe]
    private void OnWorldLoaded(WorldLoadedEvent e)
    {
        if (!PlayerUtil.IsAlive()) return;

        // Vital sign check using Thresholds constants
        if (PlayerUtil.GetBloodOxygen() < PlayerUtil.Thresholds.BLOOD_OXYGEN_LOW)
            GameUtil.Alert("Blood oxygen is low!", important: true);

        if (PlayerUtil.IsDying())
            PlayerUtil.HealAll();

        // Give the player a starting item
        PlayerUtil.GiveItem("bandage");
    }
}

Clone this wiki locally