A player trait that flatlines needs
A starting point for an Ostranauts mod. Adds a condition (IsNeedsReduced) that holds your physical and psychological needs below their discomfort thresholds. The recommended path is to grant it via the addcond debug console command — picker‑selectable at character creation is supported but optional and conflicts with at least one other mod (see §5).
aPer → CONDxxxPer → aCOs chain that wires every existing trait), but the specific combination here has not been verified in‑game. Treat it as a scaffold to copy, drop into Mods/, and then iterate on once you can see what the game actually does with it. The values, especially, are first guesses.
1 · What the mod does
It defines a condition called Needs Reduced (IsNeedsReduced) whose periodic effect shifts the trigger thresholds for hunger (Satiety), thirst (Hydration), sleep, fatigue, and the psychological stats far enough that the discomfort conditions never actually fire during normal play. It also slows the consumption rates for malnutrition (StatFood) and dirtiness (StatHygiene), because those two needs don't have a Thresh* handle to grab.
The recommended way to use it is to grant the condition through the in‑game debug console (addcond IsNeedsReduced) at any point — fresh save or existing character. See §7 for the workflow. The condition + loot files are all you actually need on disk.
Optionally, the mod can also register the condition as a player‑pickable trait at character creation. That path adds one extra file (traitscores), is more intrusive, and conflicts with at least one other mod that touches traitscores. The warning callout in §5 explains the tradeoffs; skip it unless you specifically want the trait to appear in the chargen picker.
It is purely additive: new files, no edits to any base‑game data.
2 · The model in 60 seconds
Every "trait" in Ostranauts is a Condition living in data/conditions/. The trait condition itself doesn't do anything mechanical — it carries a name, description, and a list called aPer. Each entry in aPer names a periodic Loot entry that gets re‑applied on a tick. (Wiki: Conditions — the aPer field is documented as "Array of Loot to apply for every stack of this condition.")
Those periodic effects live in data/loot/ as Loot entries with strType: condition. Their aCOs field is a list of strings shaped like StatName=chanceXmin-max, and that's where the actual numbers happen. (Wiki: Modding/Loot — "Each entry follows the pattern Name = chance x min-max.")
The chain looks like:
conditions.json → IsNeedsReduced ← the trait
↓ aPer
loot.json → CONDNeedsReducedPer (strType: condition)
↓ aCOs
→ ThreshStatSatiety = 1.0 x 0.95
ThreshStatHydration = 1.0 x 0.95
-StatFoodRate = 1.0 x 0.95
... etc
[optional]
traitscores.json → makes IsNeedsReduced selectable at chargen
(skip this and grant via `addcond IsNeedsReduced`)
Two important pattern notes you'll see in the existing data:
- The
=valueXdurationshape. The "X" is a literal lowercase x.1.0x0.95means "chance 1.0, magnitude 0.95." ForThresh*entries, higher magnitude = bigger threshold shift = more tolerance before consequences fire. - The leading minus. A leading
-on a string (e.g."-StatFoodRate=1.0x0.95") means "apply the effect negatively" — i.e. subtract from the rate instead of adding to it. That's how you slow a need's consumption. (Wiki: Modding/Loot — "Prefixing with-produces negative payouts.")
You can verify the chain in vanilla by searching for "IsApathetic": it's a condition whose aPer points at CONDApatheticPer, whose aCOs is ["ThreshStatAchievement=1.0x0.2"]. That's a real, shipping trait built exactly the way this mod will be.
If you want a friendlier conceptual overview of how thresholds and discomfort conditions interact (Mild → Moderate → Severe stages, AI priority calculation, etc.), the wiki's Condition Rules page walks the entire loop. Just be aware it uses StatHunger as an illustrative example name throughout — that exact stat does not exist in the actual data (see §8).
3 · The actual stat names you'll need
The names players see in the needs panel are friendlier than the ones the data uses. Mapping:
| What players call it | Underlying stat | Discomfort condrule |
|---|---|---|
| Hunger (the feeling) | StatSatiety | DcSatiety |
| Malnutrition (the actual harm) | StatFood | DcFood |
| Thirst | StatHydration | DcHydration |
| Sleep deprivation | StatSleep | DcSleep |
| Sleep comfort | StatSleepComfort | DcSleepComfort |
| Fatigue | StatFatigue | DcFatigue |
| Hygiene / dirtiness | StatHygiene | DcHygiene |
| Bathroom need | StatDefecate | DcDefecate |
| Achievement / Esteem / Meaning / Autonomy / etc. | StatAchievement, StatEsteem, StatMeaning, StatAutonomy, StatAltruism, StatContact, StatFamily, StatIntimacy, StatPrivacy, StatSecurity, StatSelfRespect | Matching Dc<StatName> for each |
"Hunger" in‑game is actually two stats: StatFood tracks malnutrition (a slow, harmful curve), and StatSatiety tracks the moment‑to‑moment "I want to eat" feeling. You probably want to suppress both. (Wiki: Health and Safety § Satiety and § Malnutrition — the wiki explicitly says "Not to be confused with satiety, or the feeling of fullness.")
4 · The two suppression mechanisms
The base game offers two ways to muffle a need. You can't always pick — some stats only support one.
Mechanism A — Thresh<StatName> (raise the trigger threshold)
This is the cleanest mechanism. Holding a Thresh<StatName> effect raises the value at which StatName trips its discomfort condition. If you raise it high enough, the discomfort never fires, even though the underlying stat keeps moving. The effect sits on top of the base condrule thresholds — you do not edit the base condrule. (Wiki: Condition Rules § Modifying Preferences: Threshold Conditions.)
Stats that have a working Thresh* handle in the base game (verified by grep over data/loot/loot.json):
ThreshStatSatiety ThreshStatHydration ThreshStatSleep ThreshStatSleepComfort ThreshStatFatigue ThreshStatDefecate ThreshStatAchievement ThreshStatAltruism ThreshStatAutonomy ThreshStatContact ThreshStatEsteem ThreshStatFamily ThreshStatIntimacy ThreshStatMeaning ThreshStatPrivacy ThreshStatSecurity ThreshStatSelfRespect
Notable absences: no ThreshStatFood and no ThreshStatHygiene. For those two, fall back to mechanism B.
Mechanism B — -Stat<Name>Rate (slow the consumption rate)
For each "consumed" need, the game also tracks a rate stat: StatFoodRate, StatHydrationRate, StatHygieneRate, StatAtrophyRate. Subtracting from the rate slows how fast the underlying need decays. The base game's IsMetabSlow trait does exactly this — its periodic effect contains "-StatFoodRate=1.0x0.25" and "-StatHydrationRate=1.0x0.25", slowing both by 25 %.
To flatline a need this way you push the rate close to zero. How close is part of the tuning you'll have to do empirically (see §6).
5 · The mod files, copy‑pasteable
Drop these into a new folder under your Ostranauts Mods/ directory. The folder layout mirrors the base game's data/ tree. Everything below is a brand‑new file — nothing you write here overwrites or mutates an existing base‑game entry. (Wiki: Modding/Data Modding § Creating Your First Mod.)
Where it goes on disk
<Steam>/steamapps/common/Ostranauts/Ostranauts_Data/
└── Mods/
├── loading_order.json ← see below
└── NeedsReducedTrait/ ← this whole folder is the mod
├── mod_info.json
└── data/
├── conditions/
│ └── conditions_needsreduced.json
├── loot/
│ └── loot_needsreduced.json
└── traitscores/
└── traitscores_needsreduced.json
mod_info.json
[
{
"strName": "Needs Reduced Trait",
"strAuthor": "<your name>",
"strModURL": "",
"strGameVersion": "0.14.0.0",
"strModVersion": "0.1",
"strNotes": "Adds a player-selectable trait that suppresses physical and psychological needs."
}
]
Bump strGameVersion if you're on a newer Ostranauts build. (Wiki: Modding/Data Modding § mod_info.json.)
loading_order.json
[
{
"strName": "Mod Loading Order",
"strNotes": "Controls the order mods are loaded. 'core' refers to base game data and should usually be first.",
"aLoadOrder": [
"core",
"NeedsReducedTrait"
],
"aIgnorePatterns": []
}
]
This file lives inside Ostranauts_Data/Mods/, alongside the individual mod folders — not inside any specific mod folder. The folder name in aLoadOrder must match the mod folder name exactly, case‑sensitive. You can also let the game generate this for you by clicking the Mods button in Options → Files. (Wiki: Modding/Data Modding § loading_order.json still documents the older Ostranauts_Data/loading_order.json location; the current game places it inside Mods/.)
The trait condition
[
{
"strName" : "IsNeedsReduced",
"strNameFriendly" : "Needs Reduced",
"strColor" : "Good",
"strDesc" : "[us] [is] unusually self-sufficient — physical and psychological needs barely register.",
"nDisplaySelf" : 2,
"nDisplayOther" : 1,
"fDuration" : 0.0,
"aPer" : [ "CONDNeedsReducedPer" ],
"fClampMax" : 1.0
}
]
This mirrors the shape of IsApathetic in data/conditions/conditions.json: a permanent (fDuration: 0.0) condition with a single periodic effect. The Conditions wiki page documents every field. (Wiki: Conditions.)
The periodic effect (the loot entry)
[
{
"strName" : "CONDNeedsReducedPer",
"strType" : "condition",
"aLoots" : [],
"aCOs" : [
"ThreshStatSatiety=1.0x0.95",
"ThreshStatHydration=1.0x0.95",
"ThreshStatSleep=1.0x0.95",
"ThreshStatSleepComfort=1.0x0.95",
"ThreshStatFatigue=1.0x0.95",
"ThreshStatDefecate=1.0x0.95",
"ThreshStatAchievement=1.0x0.95",
"ThreshStatAltruism=1.0x0.95",
"ThreshStatAutonomy=1.0x0.95",
"ThreshStatContact=1.0x0.95",
"ThreshStatEsteem=1.0x0.95",
"ThreshStatFamily=1.0x0.95",
"ThreshStatIntimacy=1.0x0.95",
"ThreshStatMeaning=1.0x0.95",
"ThreshStatPrivacy=1.0x0.95",
"ThreshStatSecurity=1.0x0.95",
"ThreshStatSelfRespect=1.0x0.95",
"-StatFoodRate=1.0x0.95",
"-StatHydrationRate=1.0x0.95",
"-StatHygieneRate=1.0x0.95",
"-StatAtrophyRate=1.0x0.95"
]
}
]
First block: every stat that has a real Thresh* handle. Second block: the rate‑slowing fallback for the four "consumption rate" stats. Hygiene and food (malnutrition) are handled only by the second block, since they don't have a Thresh*.
Register the trait at character creation (optional — read warning first)
- Recommended path: ship only the condition + loot files above. To get the trait onto a character — at any point, including on a fresh save — open the in‑game console and run
addcond IsNeedsReduced(see §7). You don't need a traitscores file at all. - Mod conflicts. The traitscores file below writes into a global "Trait Scores,1" bucket that every mod's traitscores file shares. This method does not work cleanly alongside at least one other mod — for example, the FreeTraits mod replaces the entire base trait list with score‑zeroed entries, and load‑order interactions between two mods that both touch this bucket can produce surprising results. If you ship a traitscores file, expect to test against your specific mod stack.
- Chargen UI gotcha. A trait whose visibility flag (the second number in
TraitName,ageCost,visibilityFlag) is0is silently dropped from the chargen picker, even though the entry exists in the data and can still be granted viaaddcond.0,1shows as a "0 year" free trait;0,0shows up nowhere.
[
{
"strName" : "Trait Scores,1",
"aValues" : [
"IsNeedsReduced,0,1"
]
}
]
The format is TraitName,ageCost,visibilityFlag. The first number is the age cost displayed in chargen (signed; positive = costs years of starting age, negative = a "bad" trait that gives years back). The second number is a visibility flag that must be non‑zero or the chargen UI silently drops the trait. 0,1 shows as a free "0 year" pick (FreeTraits convention); 3,1 matches the base game's strong positive trait shape (IsCharismatic,3,1); 0,0 is invisible to chargen even though the entry exists. Verified in GUIChargenTraits.cs:81 (sums Value[0] as the year cost) and :146 (filters on Value[1] != 0).
loading_order.json in Ostranauts_Data/Mods/ alongside the mod folders), no edits to base‑game data. The trait should appear in the character‑creation trait list under "Needs Reduced" and apply IsNeedsReduced to the player on game start.
6 · Tuning the values
The numbers above are first guesses. Some calibration notes:
The "X" magnitude term
In a string like ThreshStatSatiety=1.0x0.95, the parser reads it as chance=1.0, magnitude=0.95. Looking at vanilla examples for context:
CONDApatheticPerusesThreshStatAchievement=1.0x0.2— small, persistent positive shift.CONDAntiGravStimPerusesThreshStatGrav=1.0x0.5— moderate effect.CONDCaffeine2PerusesThreshStatSleep=1.0x0.5— moderate sleep suppression.- Larger magnitude values tend to mean a stronger effect per tick. Some entries use values up to ~3 for very strong effects.
If your needs aren't suppressed enough at 1.0x0.95, try raising the magnitude further (e.g. 1.0x2.0 or 1.0x3.0).
The rate suppressors
For the rate stats (-StatFoodRate, -StatHydrationRate, -StatHygieneRate), the magnitude behaves like a multiplier on the subtraction. -StatFoodRate=1.0x0.25 in IsMetabSlow slows food consumption by ~25 %; 1.0x0.95 should leave you with very nearly zero rate. If hunger or hygiene are still moving noticeably, push closer to 1.0x1.0.
Don't go too high
If you over‑shift a stat (especially a psychological one), you may push it past the upper end of the condrule — at which point the highest‑tier discomfort can fire instead of the lowest. Land softly: start at 1.0x0.5, raise gradually until comfort holds.
7 · Applying the trait — the recommended way
The cleanest way to use this mod, on a fresh save or an existing one, is to grant the condition directly via the in‑game debug console. You don't need the traitscores file for this — the condition + loot files alone are enough. No character‑creation conflicts to worry about, no chargen UI gotchas.
Open the console and run:
addcond IsNeedsReduced
That attaches the condition to the targeted character (usually the player). Because IsNeedsReduced's fDuration is 0.0 it will persist forever, and the periodic effect will start firing on the next tick.
If you ever want to remove it: removecond IsNeedsReduced. (See Debug on the wiki for the console basics, including how to enable it if it isn't already.)
This works the same on a save that started before the mod was installed — the mod itself is safe to enable mid‑save because it only adds new entries.
data/condrules/condrules.json to raise the discomfort thresholds directly. That mutates an entry the base game (and existing saves) already reference, and risks corrupting in‑progress condition state. The whole reason this mod uses the Thresh* mechanism is to avoid that — you're stacking a shift on top of the existing rule, not editing it.
8 · Pitfalls and confusable names
This is the corner most new modders trip on. Skim before you start, re‑read after the first thing breaks.
StatHunger doesn't exist. The wiki's Condition Rules page uses StatHunger / ThreshStatHunger / DcHungry01 as illustrative names throughout its tutorial. They are pedagogical placeholders. The actual stats are StatSatiety (the feeling) and StatFood (the malnutrition curve), with discomfort condrules DcSatiety and DcFood. If you copy ThreshStatHunger straight out of the wiki, the parser will accept it as a string but nothing in the game will react to it — you'll see no effect.
StatSatiety is the moment‑to‑moment "I want to eat" feeling that ticks up about once per hour and resets when you eat. StatFood is cumulative malnutrition that climbs slowly and only kills you over days of starvation. Suppressing only Satiety leaves your character thin and weak; suppressing only Food leaves them constantly grumpy about being hungry. The mod above does both.
StatSleep vs. StatSleepComfort. StatSleep is the need to sleep (rises with wakefulness). StatSleepComfort is how easy it is to fall asleep right now — high values mean uncomfortable, can't drop off. They have separate condrules and separate Thresh* handles. The mod suppresses both because they're orthogonal.
StatFatigue is not the same as StatSleep. Fatigue is short‑term physical exertion (climbs while working, recovers while resting). Sleep is long‑term wakefulness. A character can be fully rested and still fatigued, or vice versa. Both have Thresh* handles.
StatFood is the level (current malnutrition); StatFoodRate is the rate at which Food rises. Subtracting from the level (-StatFood=...) one‑shot heals malnutrition. Subtracting from the rate (-StatFoodRate=...) makes future malnutrition climb more slowly. Same pattern for StatHydration/StatHydrationRate, StatHygiene/StatHygieneRate, StatAtrophy/StatAtrophyRate. For an ongoing trait you almost always want the rate version.
IsApathetic, IsGlutton, IsInsomniac, …) is a Condition in data/conditions/, not a CondOwner in data/condowners/. CondOwners are objects‑that‑can‑hold‑conditions (humans, items, ships). A trait is a single condition that gets attached to the player CondOwner. Earlier guidance in older write‑ups suggested making a condowner with aStartingConds; that path technically works for items but is the wrong model for a player trait.
"Trait Scores,1" includes the comma. In the traitscores file, the outer strName is literally "Trait Scores,1" — comma and digit included. That's not an entry index in your file, it's the bucket name the game uses to merge your additions into the base trait pool. If you change it to "Trait Scores" or "NeedsReducedTrait", your entry will end up in a different (or new, ignored) bucket and the trait won't appear in character creation.
strType: condition is not a Condition. The CONDxxxPer entries live in data/loot/, not in data/conditions/, even though their names start with COND and they exist to apply conditions. The naming is a convention, not a folder hint. When wiring aPer, the string you put there resolves against loot table names, not condition names.
nDisplaySelf / nDisplayOther control whether the trait shows up in the character UI. Set both to 0 on the trait condition and the player will never see "Needs Reduced" on their status panel — making it impossible to tell whether the mod loaded successfully. Use 2 (always show) on at least nDisplaySelf while you're testing. (Wiki: Conditions field reference.)
[ ] are required. A trailing comma after the last item in aCOs will silently fail to load — LitJson (the parser the game uses) is unforgiving about it. (Wiki: Modding/Data Modding § JSON Basics.)
Ostranauts_Data/Mods/ with a capital M. The folder name you put in loading_order.json's aLoadOrder must match your mod folder name exactly — case‑sensitive on every platform.
9 · If it doesn't work — quick debugging
- Trait doesn't appear in character creation. First: do you actually need the chargen path? The recommended workflow is
addcond IsNeedsReducedin §7 — skip the traitscores file entirely. If you do need it picker‑selectable: check that the outerstrNameis exactly"Trait Scores,1"(the comma‑1 is part of the name); check that the third number inTraitName,ageCost,visibilityFlag(the visibility flag) is not0— the chargen UI silently drops any entry with that flag set to zero, even though the entry exists in the data.0,1shows as a free "0 year" pick. Finally, checkloading_order.jsonincludes your folder name and the spelling matches. - Trait appears but the player doesn't get the condition. Open the console and run
addcond IsNeedsReducedon the player to confirm the condition itself is well‑formed. If that works but starting a new game with the trait selected doesn't, the wiring between traitscores and condition application is the suspect. - Player has the condition but needs still trigger. Open the player's status panel and look for the trait listed (which is why
nDisplaySelf: 2matters during testing). If the underlying need still drops into discomfort, raise the magnitude on the relevantThresh*entry. - Hunger or hygiene still trip. Those two are only handled by the rate‑slowing block. If they still trip, increase the magnitude of the relevant
-Stat*Rateentry toward1.0. - Crash on game load. Almost always a JSON syntax error in one of the four files — missing comma, unterminated string, trailing comma in
aCOs. Run the file through any JSON linter; LitJson is unforgiving. - Mod doesn't load at all. Verify
mod_info.jsonexists at the mod folder root and is valid JSON. Verifyloading_order.jsonsits inOstranauts_Data/Mods/(alongside the mod folders, not inside any one of them) and includes your folder name inaLoadOrder. If you have an older copy atOstranauts_Data/loading_order.jsonfrom following pre‑update wiki instructions, the current game build won't read it — move it. (Wiki: Modding/Data Modding troubleshooting section.)
10 · Sources
Pages from the official wiki that informed this guide. Worth bookmarking for the surrounding context — they cover much more than what's distilled above.
- Modding/Data Modding — mod folder structure,
mod_info.json,loading_order.json, JSON conventions. - Modding/Loot — loot string format (
Name = chance x min-max),strTypevalues, the-prefix semantics. - Conditions — field reference for condition entries, including
aPer("Array of Loot to apply for every stack of this condition"). - Condition Rules — the threshold / discomfort / AI‑priority loop. Uses placeholder names (
StatHunger) that don't exist in the data; use the wiki for the concept, the data for the actual stat list. - Health and Safety — player‑facing names for every physical need, with the Satiety‑vs‑Malnutrition split and the threshold values for each discomfort tier.
- Traits — player‑facing list of vanilla traits, useful as a sanity check that "Needs Reduced" doesn't collide with an existing trait name.
- Debug — in‑game console for
addcond/removecond.