6.5 KiB
Medical-kit teardown ownership audit
No production cleanup is proposed yet: the two identified medical-kit instances have not been established as successor-owned scene stock. Deleting tracked stock to remove these errors would therefore be an unproven change with a risk of removing carried inventory.
Established evidence
docs/evidence/native-2026-09-19-050515/console.log.txt:620-621identifies{AE578EEA4244D41F}Prefabs/Items/Equipment/Kits/MedicalKit_01/MedicalKit_01_US.etand{21EF98BFC1EB3793}Prefabs/Items/Equipment/Kits/MedicalKit_01/MedicalKit_01_USSR.et. Both have unnamed owners, valid cached/global catalog references, and no current GameMode at that teardown point. This session did not reproduce a missing-manager error.- Current
addons/core/Configs/ERR/EveronSites.confstocks field dressings, saline and morphine; neither diagnostic medical-kit resource appears in any successor addon source/resource. The prisoner loadout also does not explicitly add these kits. - Both kit prefabs remain in the installed vanilla US/USSR inventory catalogs (
InventoryItems_EntityCatalog_US.conf:1290, USSR:1002). Preserving complete medical/inventory support is intentional. Catalog membership is not proof that the deleting entity is a world instance owned by the successor. - Installed
SCR_EntityCatalogEntry.ClassSpecificInitandSCR_EntityCatalogInventoryItem.ClassSpecificInitcallResource.Loadand inspect entity/component sources. These inspected methods do not callSpawnEntityPrefabor register entities with successor ownership. Resource/template cleanup or another native subsystem is a possibility, not a proven cause. - Installed
SCR_BaseItemSupportStationComponent.DelayedInitcaches the global catalog manager and calls super. ItsInitValidSetupprints the stale-named resupply error if that reference is absent. - Installed
SCR_BaseSupportStationComponent.OnDeleteinvokes virtualInitValidSetupbefore unsubscribing damage/support dependencies. ItsEOnInitqueuesDelayedInitandOnDeletedoes not explicitly remove that callback. Both dependency teardown order and initialization/delete ordering remain relevant hypotheses.
Why blanket successor cleanup is unsafe
ERR_SiteService.m_Entities contains sites, containers, stock, transport and extraction aircraft. Successful preparation also registers all those objects in GameMode ownership. The collection records creation ownership, not current inventory custody. A stock item remains listed after a player picks it up. ERR_Actors.DeleteSpawned(item) only refuses a directly controlled player entity; it does not protect an item merely because it is now in that player's inventory. Rollback() deletes this entire list in reverse order and would also remove the extraction aircraft. It must not be repurposed as normal endscreen cleanup.
The current Stop() intentionally stops updates without removing those physical objects. Ordinary victory preserves passengers, aircraft and result while the native endscreen exists. This is appropriate and should remain unchanged.
Exact possible pre-restart boundary
Installed SCR_BaseGameMode invokes RestartSession after GetAutoReloadDelay (lines 715-717), after its game-mode-end notification. protected void RestartSession() (line 781) checks authority, invokes TryShutdownServer, then calls GameStateTransitions.RequestScenarioRestart() (line 789). A successor-only override could perform bounded owned-item disposal immediately before calling unchanged super, while the old world's manager still exists. This would happen after the endscreen delay, not on victory.
That hook is only justified as the error fix if the deleting station is proven to be one of the owned objects, and every relevant restart route uses this method. Direct scenario-restart requests or shutdown/Workbench play termination are separate lifecycle paths. A generic component destructor is already too late to guarantee catalog manager lifetime.
If ownership is established, the narrow implementation should track spawned stock items separately from sites/vehicles, establish current custody before deletion, and remove only items still in their owned site storage or unclaimed world stock. Never traverse/delete a player body, reconnection-reserved body, aircraft/passenger hierarchy or other subsystem's catalog prototype. Only release bookkeeping for taken or already-deleted stock. Call item deletion while the required manager exists; retain vanilla OnDelete and its errors. Verify idempotence and delete ordering with actual named instances. Do not claim kit errors fixed until the exact observed owners are handled and raw two-round logs demonstrate it.
Isolated diagnostic extension
The only code change in this handoff is addons/core/Scripts/Game/ERR/ERR_NativeStationTeardownDiagnostic.c, extending the existing WORKBENCH-only opt-in diagnostic. Use existing --station-teardown-diagnostics / -errStationTeardownDiag 1 activation. It still invokes unchanged super in DelayedInit, OnDelete and InitValidSetup, and leaves all native errors visible.
At native DelayedInit it captures scalar/string evidence: whether initialization was observed, successor mode present, owner world equals the current game world, whether the site service knows that exact owner, inventory-slot presence, and parent prefab. It prints at most 64 initialization records. Teardown's existing maximum 64 records gain those initial facts plus current world/site/inventory/parent observations. It stores no new entity/manager references and schedules no work. initSiteOwned=false alone does not prove permanent nonownership; an item could be adopted later. Likewise absence of GameMode at delete makes current ownership unavailable, so the initialization and world evidence must be interpreted together.
Suggested run: ordinary two-round Core scenario with retained vanilla inventory catalogs and the existing diagnostic flag. Correlate kit resource names and init/delete records, then repeat with physical medical treatment and representative looting. Determine whether the kit owner is in the main world and ever successor-owned before proposing its removal. Also retain the raw catalog-manager error count. No completed-smoke marker is added and no runner qualification is changed.
No engine run, original workspace edit, installed resource change or production deletion was performed for this audit. The diagnostic extension is source-reviewed and awaiting native compilation. Existing source-hash evidence for the base lifecycle remains in docs/evidence/native-error-audit-2026-09-19/source-hashes.json.