Skip to content

Corpses do not survive save/continue (deferred known issue, ex BUG-018) #153

Description

@aaronstatic

Summary

Killed characters (enemies, recruits, players) do not survive save → quit → Continue. The corpse and its lootable inventory are simply absent after continuing. This was a new capability attempted during the vanilla-persistence migration (EPF never persisted corpses either, so it is not a regression), but after two fix attempts it still fails the real quit-and-continue play-test, so we're deferring it past 1.4.0 and documenting it here for visibility. Contributions welcome.

Repro: kill an armed enemy, do NOT loot the body, save, quit to menu, Continue → body is gone.

What has been tried (internal tracker: BUG-018)

Attempt 1 — scripted persistence config rule (Phase 4 of the persistence migration). A script-defined PersistenceConfigRule (OVT_DeadCharacterPersistenceConfigRule) bound in Configs/Systems/Persistence/Overthrow.conf (Priority 36000, SelfSpawn 1, Character collection, vanilla's six character serializers), plus a death-time re-match via ReloadConfig(victim).

Result: instrumentation proved the engine never calls a script-defined rule's IsMatch — zero calls across world load, initial tracking of every character, and 300 forced ReloadConfig() re-matches. Every rule vanilla binds in a .conf is a native generated class; scripted rules are effectively dead code.

Attempt 2 — dynamic config flip via the API vanilla actually exposes. On the character-killed event, OVT_PersistenceTracking.MarkForSelfSpawn(victim) does GetConfig()m_bSelfSpawn = trueSetConfig(), keeping the matched config's collection/serializers and flipping only that bit. Applied on the death frame. An automated Init-tier test (OVT_TEST_Init_Persistence_DeadCharacterConfigSelfSpawns) kills a spawned recruit and asserts the matched config self-spawns — it was authored red against the live defect and went green with the fix.

Result: the test is still green, but the 2026-08-04 single-player play-test shows corpses still do not survive an actual quit → Continue (tested enemies, recruits and player corpses).

Where the mystery now sits

The config demonstrably has SelfSpawn set after death (asserted in-session), yet nothing comes back through a real restart. So the failure is somewhere downstream that our test harness cannot reach — the true quit-and-continue path restarts the world, which the autotest harness cannot follow (documented limitation). Untested hypotheses from the tracker:

  1. Record lifetime / SelfDelete semantics — if the engine drops a tracked instance's record when the body despawns or cleans up before/at save time, there is nothing to restore.
  2. Restore-side behavior — a self-spawned character record may not rebuild a dead character (life state may not be part of what the six vanilla character serializers capture/apply, or the entity spawns alive and is immediately cleaned up).
  3. Save-time filtering — dead characters may be excluded from the save pass entirely regardless of their config's SelfSpawn flag.

Pointers for anyone picking this up

  • Internal tracker doc: docs/bugs/BUG-018.md (full history, instrumentation numbers)
  • Death-time config flip: OVT_PersistenceTracking.MarkForSelfSpawn (called from OVT_OverthrowGameMode's character-killed subscription)
  • In-session coverage: OVT_TEST_Init_Persistence_DeadCharacterConfigSelfSpawns (Init suite; green — the gap is the restart path, which only manual play-testing exercises)
  • Vanilla persistence API notes: docs/features/core/persistence/vanilla-api-reference.md

Any fix should keep the existing Init test green and add whatever in-session assertions are possible for the newly-discovered failure layer, proven able to fail first (project testing rule: no retries, every case demonstrated red before shipping).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions