Skip to content

fix: vr dropped weapon crashes and loot sync - #12

Open
cmpayc wants to merge 1 commit into
vr-supportfrom
fix/dropped_weapons
Open

cmpayc wants to merge 1 commit into
vr-supportfrom
fix/dropped_weapons

Conversation

@cmpayc

@cmpayc cmpayc commented Sep 30, 2026

Copy link
Copy Markdown
Owner

Summary

Dropped weapons were killing VR sessions. A weapon dropped by a dying actor sometimes never gets its 3D, leaving an invisible reference with a live rigid body, and touching one crashed the game two ways: picking it up through the crosshair, or destroying it inside Havok. The root cause of the crashes was where we destroyed it. Delete ran on whichever Papyrus VM worker serviced that tick, alongside the renderer and Havok. It now runs on the main loop, disabled first and deleted only once the game confirms the disable landed.

Loot sync works again on every weapon that has its 3D, and several separate faults found along the way are fixed with it.

Highlights

  • Removals moved to the main loop. Thread ids from both clients: the main loop uses one thread all session, GameVM::Update uses seven. Disable then Delete, split across passes, because Papyrus Disable queues onto a task pool.
  • Orphaned references are left alone, not destroyed. Invisible either way, and it is the difference between a stuck weapon and a dead session.
  • Adoption fixes. No longer takes a reference another drop owns, or one with no 3D. Both cost a later drop its own weapon.
  • The ragdoll guard no longer crashes in its own log line. It refused a bad add correctly, then died naming the actor.
  • A bleedout is no longer read as a resurrection, which had been respawning a corpse and wiping the inventory just synced into it.
  • TESObjectREFR::Load3D added and verified (AE 19727), documented as not a repair for an orphaned drop. The 3D comes back; the stale rigid body does not go away.

Known wart

The diagnostic cell walk in HookRemoveInventoryItem is load-bearing: it delays the game's own drop sequence enough for the 3D load to win. With it, 106 drops across five sessions and no orphans. Without it, 9 drops and 2. It stays, with the measurement code around it, until the race has a real fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant