Escaping the OKLG Public Enemy doom loop
Save-file recipe for crew that have spiraled into permanent hostility with a station faction.
The scenario
You arrive at OKLG. Something happens — maybe an AyoSec officer reads one of your crew as committing trespass, maybe a brawl spills out of a bar — and one of your crew picks up OKLG Public Enemy status. From that moment on, every OKLG NPC that sees them is licensed to attack. Your crew defends themselves. Each defensive swing is itself an assault under OKLG law, which re-applies the Public Enemy condition and grinds their faction standing further into the ground. After half an hour of in-game time, their My Standings reads -7346.30 and they get jumped on sight.
This page is the surgical save-edit recipe to get a single crew member out of the spiral, plus the data-mod options for permanently breaking the loop.
Two systems, not one. "OKLG Public Enemy" is a binary condition (you have it or you don't). The -7346.30 standing number is a separate runtime accumulator stored per-relationship in the save. Fixing the spiral takes editing both: strip the condition, then zero the accumulated hostility on the relationships that drove the number down.
How the doom loop is wired
Confirmed in the base game data:
data/conditions/conditions.jsondefinesCrimeOKLGThreat("OKLG Public Enemy") withfDuration: 0.0(permanent, no decay) andbRemoveAll: true(a single counter-grant clears all stacks).data/crime/crime.jsonhas theOKLGAssaultrow:strLaw: OKLG+strCrime: assault→strLootCondsPerp: CrimeOKLGThreat. Every OKLG-jurisdiction assault stamps the condition.data/condtrigs/condtrigs.jsondefinesTIsAIReportCrimeValidVictimwithaReqs: [CrimeOKLGArrest, CrimeOKLGThreat, …]andbAND: false. Any of those flags makes the holder a "valid victim" — which is what licenses OKLG NPCs to swing at them without it counting as fresh assault on the AI's part.- The accumulator value lives separately, in each crew member's
social.aRelationships2[]array — specifically in thefAnimosityfloat on each per-target relationship record.
So the loop: crime committed → CrimeOKLGThreat stamped → AI permitted to attack → defensive swing in OKLG zone is itself an OKLGAssault → re-stamp → fAnimosity ticks up on every swing of every OKLG NPC the crew member is fighting → standing display drops. There's no automatic decay path; only deliberate save edits or amnesty plot interactions clear it.
Save layout — what you're editing
Verified by walking an actual saves/<character>_<id>/ folder against the JsonCondOwnerSave / JsonSocial / JsonRelationship shapes from the decompiled C#.
Folder shape
%AppData%\..\LocalLow\Blue Bottle Games\Ostranauts\saves\
└── <Character Name>_<id>\
├── <Character Name>_<id>.zip ← the save itself
├── portrait.png ← sidecar metadata
├── saveInfo.json ← sidecar metadata
└── screenshot.png ← sidecar metadata
Inside the zip
<Character Name>.json ← player save: plots, objectives, market, etc. (no humanoid NPCs)
saveInfo.json ← duplicate of the sidecar
portrait.png ← duplicate
screenshot.png ← duplicate
ships/
<ship-reg>.json ← one per ship/station instance the player has visited
OKLG.json ← OKLG main station instance
OKLG_BIZ.json ← OKLG bureaus (where most resident NPCs live)
OKLG_RES.json ← OKLG residential
OKLG_SEC.json ← OKLG security
OKLG_FLOT.json ← OKLG flotilla annex
BCER.json, BCRS.json ← other station instances
<ship-reg>/*.png ← per-ship room previews (skip)
Crew migrate between ship files based on physical location. The crew member who needs editing is serialized in whichever ship/station file represents the place they're currently standing. If they were brawling in OKLG_BIZ when you saved, their CondOwner is in ships/OKLG_BIZ.json — not in the player file, not in the ship they came in on.
What a humanoid CondOwner looks like inside a ship file
Each ship file is a single-element array wrapping a dict. The dict's aCOs array holds CondOwner-shaped objects. Most are inert props (no social). The humanoids — your crew, station residents, anyone with a name — have social populated. The fields that matter for this fix:
- strID verified
- For humanoid NPCs, this equals the character's full name (e.g.
"Autumn Jocelyn Sellers"). Inert props use GUIDs like"82827c35-fb7d-4be3-aaf3-e56db75929d0". Search the file by name to find your crew. - strFriendlyName verified
- Same as
strIDfor humanoids. Either field works for the search. - aConds verified
- Array of cond-strings, format
"Name=value x duration". The Public Enemy flag lives here as"CrimeOKLGThreat=1.0x1". - aFactions verified
- Array of faction strings. A Galilean Confederacy crew member shows
["GalileanConfederacy", "<their name>"]— the second entry is the character's own name, used as a self-faction marker. - social.aRelationships2 verified
- Array of per-target
JsonRelationshipobjects. One entry per other person this crew has interacted with. - social.aRelationships2[].fAnimosity verified
- Per-target hostility accumulator (float). In a peaceful save, observed range was 0–94. In your spiraled save, expect three-digit values on every OKLG NPC the crew has been in combat with — these are what aggregate to
-7346.30. - social.aRelationships2[].fKindness, fFamiliarity verified
- Companion accumulators — positive interactions and total interaction count. Don't touch these. They're history you want to keep.
- social.aRelationships2[].strPSpec verified
- Identifies who the relationship is with (the other person's name).
The surgical fix
Step 0 — back the save up
Copy the entire <Character Name>_<id>\ folder somewhere safe. There is no in-game undo for a botched save edit.
Step 1 — open the zip in 7-Zip without extracting
7-Zip lets you edit a file inside an archive in place. Right-click the .zip → 7-Zip → Open archive. Don't fully extract and rezip — easy to break the archive structure or get the path separators wrong.
Step 2 — find the right ship file
Your crew is in whichever ship/station instance file matches where they were standing when you saved. If you don't know which one, search each candidate ships/OKLG*.json for the crew member's full name. The one that contains a hit (in a "strID" or "strFriendlyName" field, not just a casual mention in a log) is the right file.
Edit that file in the archive (7-Zip lets you open it in your editor of choice; on save, it asks whether to update the archive — say yes).
Step 3 — strip the wanted conditions
Find your crew's aConds array. Delete every entry whose name matches one of:
| Condition | What it does |
|---|---|
CrimeOKLGThreat | The Public Enemy flag — OKLG AI is licensed to attack. The critical one. |
CrimeOKLGArrest | Active OKLG warrant. AyoSec will try to subdue rather than kill, but it's still hostile. |
CrimeOKLGNoUndock | Prevents ship undock while the warrant is active. |
CrimeOKLGStolenShip | Marks the ship as flagged stolen by OKLG. |
The full set is what TIsWantedOKLG in data/condtrigs/condtrigs.json tests against. Removing all four flips the crew member back to the friendly-default TIsNotWantedOKLG branch.
If the crew is also wanted under another faction (CrimeCCREThreat, CrimeVenusThreat, CrimeGalConThreat), strip those too — same naming pattern, same rationale.
Step 4 — zero out the accumulated hostility
Inside the same crew member's social.aRelationships2 array, find every relationship whose strPSpec resolves to an OKLG-faction NPC. The personspec name will look like "AF_OKLGCiv", "AF_OKLGLEO", "AF_OKLGCorp", etc. — these are the auto-faction selectors from data/personspecs/personspecs_autofactions.json. Or it'll be a specific NPC's full name (in which case you can look that NPC up in the same ship file to confirm their aFactions).
For each such relationship, set "fAnimosity": 0.0. Leave fKindness and fFamiliarity alone — you don't want to wipe the crew's interaction history, just the hostility tally.
Example before / after on one relationship:
{
"strPSpec": "AF_OKLGLEO",
"fAnimosity": 187.0, ← change to 0.0
"fFamiliarity": 245.5,
"fKindness": 12.0,
"aRelationships": [...],
"aEvents": [...],
"dictConds": { ... },
"dictCondsRELOnly": { ... }
}
Lazy shortcut. If editing every OKLG-faction relationship is too much surgery, you can delete the entire aRelationships2 array on this crew member. The Social component re-initializes on load with an empty relationship history. Your crew member loses all relationship memory across all NPCs (every stranger again), but that's a clean slate and the fAnimosity problem is gone with it.
Step 5 — save inside 7-Zip and reload
7-Zip will prompt to update the archive. Confirm. Don't restart Steam between save and reload — the file timestamp is what the launcher checks.
Recurrence — and why you should plan for it
The save edit is a snapshot fix, not a permanent one. Reload at OKLG with the same crew, throw a single defensive punch, and the loop restarts. The base game data still maps OKLGAssault → CrimeOKLGThreat, and self-defense in an OKLG zone is itself an OKLGAssault.
Pick one of the three options below depending on how much disruption you want:
Option A — physical relocation (zero code changes)
The cheapest fix: undock from OKLG immediately on reload, fly somewhere else, and don't bring this crew member back to OKLG zones. Combat outside OKLG-law jurisdiction doesn't trigger the OKLG crime emitter. Your crew stays clean. If you want to revisit OKLG, leave the at-risk crew on your ship (or on a friendlier station) and go in solo.
Option B — small JSON mod, demotes assault to warrant
Edit data/crime/crime.json in your mod folder. Change the OKLGAssault row's strLootCondsPerp from "CrimeOKLGThreat" to "CrimeOKLGArrest". After the edit:
{
"strName": "OKLGAssault",
"strLaw": "OKLG",
"strCrime": "assault",
"strLootCondsPerp": "CrimeOKLGArrest", ← was "CrimeOKLGThreat"
"strPledge": "AIReportCrimeOKLGThreat"
}
OKLG NPCs now respond to assault with arrest behavior (subdue, drag to jail) instead of shoot-on-sight. The CrimeOKLGArrest flag is still in TIsAIReportCrimeValidVictim's OR list, so this softens the response without making OKLG a free-for-all crime zone. Globally affects the game, not just your crew.
Option C — small JSON mod, exempts crew from "valid victim"
Edit data/condtrigs/condtrigs.json. Find TIsAIReportCrimeValidVictim and add "IsCrew" (or whatever crew-flag your CondOwner template uses) to its aForbids list:
{ "strName": "TIsAIReportCrimeValidVictim",
"aReqs": ["CrimeOKLGArrest", "CrimeOKLGThreat",
"CrimeVenusArrest", "CrimeVenusThreat",
"CareerPirate", "IsMeatWall"],
"aForbids": ["IsCrew"], ← add this
"bAND": false }
OKLG (and Venus) AI no longer treat player crew as fair game even when flagged. The crime conditions still apply, the rep loss still happens, but the actual ambushing stops. Cleanest behavioral fix; doesn't change crime accounting or affect non-crew NPC behavior at all.
Confidence — what was verified vs. inferred
| Claim | Status |
|---|---|
| Save folder layout (folder + zip + sidecars) | verified against an actual save |
| Player JSON has no humanoid NPCs; crew live in ship files | verified (40,168 CondOwners in player file, 0 with social) |
Humanoid strID equals full name | verified |
JsonRelationship field set incl. fAnimosity / fKindness / fFamiliarity | verified on a real save's social array |
fAnimosity carries non-trivial values that scale with hostile interactions | verified (range 0–94 in a peaceful save) |
CrimeOKLGThreat definition + crime → cond mapping in data/crime/crime.json | verified against base game data |
TIsAIReportCrimeValidVictim as the doom-loop pivot CT | verified against base game data |
"My Standings: -7346.30" UI value is the sum of fAnimosity contributions across faction members | inferred — exact aggregation formula not traced; standing-display code wasn't read end-to-end. Zeroing fAnimosity per OKLG-faction relationship is the right surgical edit regardless. |
Deleting aRelationships2 wholesale is safe | inferred from the Social.cs init code being null/empty-tolerant; not tested on a live save. |
Adding IsCrew to TIsAIReportCrimeValidVictim.aForbids works as described | inferred — confirm the actual flag your crew CondOwners carry by inspecting one of them; it may be IsPlayerCrew or similar. |
Quick-reference card
Path: %AppData%\..\LocalLow\Blue Bottle Games\Ostranauts\saves\<char>_<id>\<char>_<id>.zip → ships/OKLG*.json
Find: search the file for the crew member's full name (matches strID and strFriendlyName).
Strip from aConds[]: any CrimeOKLGThreat=…, CrimeOKLGArrest=…, CrimeOKLGNoUndock=…, CrimeOKLGStolenShip=….
Zero in social.aRelationships2[]: fAnimosity on every entry whose strPSpec is an OKLG-faction NPC.
Move ship away from OKLG before any further play, or apply Option B / C as a permanent fix.