Decane / SRP

Sky Reclamation Project for S.T.A.L.K.E.R.: Clear Sky
http://www.moddb.com/mods/srp
119 stars 20 forks source link

LUA error: sim_board.script:558: attempt to index local 'se_npc' (a nil value) #120

Closed AdamOSDev closed 3 years ago

AdamOSDev commented 3 years ago

The game crashes straight to desktop with this error while engaging the enemy on the mission "Find the commandant". Occurs at random sometimes during the fight and every time after the mission is complete and all or most of the Freedom soldiers survive.

Attached is a zip containing everything in my _appdata_folder. The save s34 is right before the fighting is triggered. The quicksave is during fighting and will crash after a few seconds upon loading and engaging the enemy. A word of caution: A bad guy will pop out from the right, in front of you, a second or two after loading. It always crashes a few seconds after killing him.

Game version: 1.5.10 (Steam)

The mods below were installed on top of a clean install of Clear Sky.

SRP 1.3.1 optional features installed:

Attachment: appdata.zip

Decane commented 3 years ago

Thanks for reporting. I've reproduced the crash. Some more details about what's causing it:

! [LUA][ERROR] Abort(): Server entity is nil for NPC with ID 20480 of mutant squad 39

stack traceback:
    _g.script:53: in function 'abort'
    sim_board.script:558: in function 'assign_squad_to_smart'
    sim_squad_generic.script:1467: in function 'is_finished'
    sim_squad_generic.script:480: in function 'update'
    se_monster.script:235: in function <se_monster.script:230>
stack trace:

Basically, the crash has nothing to do with the scenario in the Dark Valley. Instead, it happens when the offline mutant squad 39 at Yantar wipes out the stalkers at the "Factory backyard" and is then assigned to it.

The crash happens because NPC 20480 in that mutant squad doesn't exist, yet there is a record of an NPC with that ID in the squad's NPC table, so the game attempts to access the NPC userdata object when there is none. I need to investigate further to understand how the game is getting into such a state.

Fortunately for you, the crash doesn't happen every time, because sometimes the stalkers manage to "kill" NPC 20480 before they are overrun. When that happens, the mutant squad's NPC table entry for 20480 is removed before the game has a chance to attempt to access a server entity with that ID in sim_board:assign_squad_to_smart, which is where the crash happens. This happened to me a few times after loading save "s34". So maybe give that save a few more tries. Check your map to see if the mutant squad fighting stalkers at the Yantar factory turns to a darker shade of red without the game crashing. If it does, you're home-free.

AdamOSDev commented 3 years ago

Thanks for getting back to me so soon. I tried starting from s34 and it only crashed twice. I was able to progress a lot further until I hit another "attempt to index local 'se_npc' (a nil value)" related crash. I accepted two side missions: 8x scope and one from Yar to return a PDA from his friend who got killed by bloodsuckers. I decided to tackle the latter first. I made it on top of the three silos right outside Freedom's base where Yar's buddy's body was. After retrieving the PDA, the bloodsuckers spawned in a nearby building and the game crashed. I'll include the _appdata_folder at the bottom again. The game crashes a few seconds after the quicksave is finished loading. I have a feeling this is going to continue happening. I don't want to lose progress and have to redo sections so I think I'll wait until you figure it out ;).

Out of curiosity, what do you use to debug the game? I'm interested in poking around.

Attachment: appdata.zip

Decane commented 3 years ago

I figured out what is seemingly randomly deleting offline mutant with ID 20480 from your game:

! [LUA][ERROR] Mutant with ID 20480 exists. ! [LUA][ERROR] Released corpse with ID 20480 and removed it from release table. ! [LUA][ERROR] Mutant with ID 20480 doesn't exist.

It's the human corpse deletion script (release_body_manager.script). The script thinks there exists a dead human NPC with ID 20480, when in fact that ID actually corresponds to a live mutant, which is hence getting (wrongly) deleted instead. I don't yet understand how this situation has come about - need to keep investigating.

Out of curiosity, what do you use to debug the game?

I pepper the scripts with print statements. Tedious, but effective.

Decane commented 3 years ago

Since release_body_manager.script itself always deletes game entities 'cleanly' (in the sense that the deleted game entity's ID is also deleted from the corpse table used by the script to keep track of dead human NPCs to eventually delete), I think we can confidently say that the scenario above can only have happened as follows:

So what was the "other mechanism" that deleted the human NPC corpse and thereby orphaned its ID in release_body_manager.script's corpse table? One possibility is an anomaly - certain anomalies can shred dead NPCs to bits, which results in the server entity being deleted without its ID being removed from the corpse table. Another possibility is the sr_bloodsucker scheme - that looks to delete the marsh creature's victim NPC in an unsafe way after the victim has been killed.

I can patch the latter, but anomalies tearing NPCs apart happens in-engine, so I can only mitigate it in the SRP, possibly by adding a check to release_body_manager.script that verifies that a game entity is human and dead before permitting its deletion.

Decane commented 3 years ago

Fixed in https://github.com/Decane/SRP/commit/28c2900e05ba7354f37505f76316dbd03a09dd3e.

AdamOSDev commented 3 years ago

I applied the changes in the above fix to my copy of release_body_manager.script and loaded from an earlier save and did a bunch of stuff and tried Yar's mission again. The game still crashes with the same error. The game crashes precisely 1 minute and 20 seconds after loading my most recent save, which I took inside the base. I tried moving out of the base and staying exactly in the same spot. The time to crash is the same. As a sanity check, I verified my script matched your updated one. Am I missing something?

Decane commented 3 years ago

Is that save one you've already uploaded? If not, could you share it here, please?

Decane commented 3 years ago

The fix I submitted is preemptive only; it doesn't retroactively restore any already mistakenly deleted game entities. Maybe that's why your game is still crashing. But I need to inspect your save to be able to say for sure.

AdamOSDev commented 3 years ago

It happened on the one already uploaded and the new saves I made tonight. In the attachment I included all the saves after s34.

Attachment: appdata.zip

AdamOSDev commented 3 years ago

Could adding the sleeping bag after starting a new game cause this?

Decane commented 3 years ago

Could adding the sleeping bag after starting a new game cause this?

No. Your game is crashing because:

! [LUA][ERROR] Abort(): Server entity is nil for NPC with ID 20493 of mutant squad 47

Squad 47 is the mutant squad just north of the stalker base at Agroprom. It's missing a member that the game thinks it should have, very likely due to the bug discovered earlier in release_body_manager.script.

One way we could try to salvage your game is to temporarily add the following code into the if not first_update_done then ... end branch of function actor_binder:update in bind_stalker.script:

local board = sim_board.get_sim_board()

for squad_id, squad in pairs (board.squads) do
    for npc_id in pairs (squad.squad_npc) do
        if sim:object(npc_id) == nil then
            squad.squad_npc[npc_id] = nil
            squad.npc_count = squad.npc_count - 1
            if squad.online_object[npc_id] ~= nil then
                squad.online_object[npc_id] = nil
                squad.online_counter = squad.online_counter - 1
            end
            if squad.commander_id == npc_id then
                for k in pairs (squad.squad_npc) do
                    squad.commander_id = k
                    break
                end
            end
            squad.sound_manager:unregister_npc(npc_id)
            dbglog("Removed nil NPC with ID "..npc_id.." from squad with ID "..squad_id)
        end
    end
end

After you've loaded up your save with that code in place, open the console. You should see the following message:

! [LUA][ERROR] Removed nil NPC with ID 20493 from squad with ID 47

Hopefully that will be the only one of its kind. Once you've done this, you can rest easy knowing that you've cleansed every squad in the Zone of invalid NPC records brought about by the previous release_body_manager.script bug.

AdamOSDev commented 3 years ago

This appears to have worked. The game didn't crash after loading the quicksave and your message appeared in the console. I saved my game and removed the temp code. I'll continue playing and let you know if I encounter this again. Thanks again!