Skip to content

[BUG - Release] Crash in process_simple_actions from overlapping ExecuteInGameThread callbacks #1180

@SSyl

Description

@SSyl

Branch or Release
v3.0.1-932-ge31aaaa6

Game and Engine Version
Abiotic Factor v1.2.x (UE 5.4)

Describe the bug
When multiple deferred actions overlap via ExecuteInGameThread, whether through ExecuteWithDelay chains, direct scheduling from within callbacks, or just multiple mods independently queuing work, the game crashes with get_function_ref "Ref was not function" followed by abort().

I first noticed this during normal gameplay (~20 minutes in, hosting a multiplayer session) with my standard mod loadout and another crash about 30 minutes in. After investigating the crash dumps, I created a minimal reproduction mod that simulates two mods scheduling independent deferred work.

The crash appears to come from process_simple_actions using std::erase_if to iterate m_engine_tick_actions, while callbacks can push new items to that same vector during iteration:
https://github.com/UE4SS-RE/RE-UE4SS/blob/main/UE4SS/src/Mod/LuaMod.cpp#L3650-L3671

Mods directory
Using only default mods and my minimal reproduction mod attached: EngineTickReentryBug.zip

Also available at https://github.com/SSyl/UE4SS-EngineTickReentryBug

The repro simulates two mods with overlapping deferred work:

-- Chain A: schedules next iteration after 50ms
local function ChainA()
    ExecuteWithDelay(50, function()
        ExecuteInGameThread(ChainA)
    end)
end

-- Chain B: schedules next iteration after 75ms
local function ChainB()
    ExecuteWithDelay(75, function()
        ExecuteInGameThread(ChainB)
    end)
end

Why the 50/75ms delays? I felt like they were lenient enough to prove this isn't just a torture test - a hook that runs per frame would be firing every ~8ms at 120fps. You can drop the delays to 25/50 or lower to crash faster, or just call ExecuteInGameThread several times without any delay and it crashes almost instantly. I used two chains to simulate a more realistic scenario where two separate mods are independently doing game-thread work.

To reproduce

  1. Copy EngineTickReentryBug folder into your Mods directory
  2. Launch the game (single or multiplayer, doesn't matter)
  3. Watch the UE4SS console for iteration count logs
  4. Wait for crash (typically 1-5 minutes, varies due to timing-dependent nature)

Expected behavior
Deferred callbacks should execute without crashing, even when they schedule additional deferred work.

Screenshots, UE4SS Log, and .dmp file
5 crash dumps collected, all showing the same call chain:

engine_tick_hook
  → process_simple_actions
    → std::erase_if
      → get_function_ref
        → abort

Iteration counts at crash varied significantly, which makes me think it may be a race condition/timing dependent bug:

  • ~1,190 iterations
  • ~2,058 iterations
  • ~2,299 iterations
  • ~4,300 iterations
  • ~10,800 iterations

Sample log output before crash:

[Lua] [EngineTickReentryBug] Chain A - Iteration 2295
[Lua] [EngineTickReentryBug] Chain B - Iteration 2296
[Lua] [EngineTickReentryBug] Chain A - Iteration 2297
[Lua] [EngineTickReentryBug] Chain B - Iteration 2298
[Lua] [EngineTickReentryBug] Chain A - Iteration 2299
*crash*

Three minidumps are in the zip file, but I have several full dumps (7-8GB) available upon request.

EnginetickRentry-UEMinidumps.zip

GitHub wouldn't let me zip the pdb/dll with it, but I'm using UE4SS 3.0.1-932.

Desktop (please complete the following information):

  • OS: Windows 11 25H2

Additional context

  • I have hundreds of hours on UE4SS v3.0.1-553 (the version currently shipped on Nexus for Abiotic Factor) and never encountered this crash, so I think it was introduced (or at least exposed) via a commit afterwards
  • The original crash during normal gameplay occurred while hosting multiplayer, but the repro crashes in single player as well
  • The timing variance (1k-11k iterations) makes me think it's a race condition
  • Additional context/speculation in my readme at my repro mod's repo: https://github.com/SSyl/UE4SS-EngineTickReentryBug

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions