praydog / REFramework

Scripting platform, modding framework and VR support for all RE Engine games
https://cursey.github.io/reframework-book/
MIT License
2.74k stars 340 forks source link

a game crash #254

Closed KrisCris closed 2 years ago

KrisCris commented 2 years ago

I used a Lua script and sometimes it crashes my game. But my friend told me this never happened to him. I am not sure what was happening.

I know this may not be appropriate to post here but I really appreciate it if you can provide me some clue.

[2022-02-01 00:37:20.215] [REFramework] [error] Exception occurred: c0000005
[2022-02-01 00:37:20.215] [REFramework] [error] RIP: 142b7ef07
[2022-02-01 00:37:20.215] [REFramework] [error] RSP: e10cfb90
[2022-02-01 00:37:20.215] [REFramework] [error] RCX: 29dd17d0
[2022-02-01 00:37:20.215] [REFramework] [error] RDX: 24269b40
[2022-02-01 00:37:20.215] [REFramework] [error] R8: 1495926c0
[2022-02-01 00:37:20.215] [REFramework] [error] R9: c5dafc0
[2022-02-01 00:37:20.215] [REFramework] [error] R10: 1476d3980
[2022-02-01 00:37:20.215] [REFramework] [error] R11: bbf0340
[2022-02-01 00:37:20.215] [REFramework] [error] R12: 236a4120
[2022-02-01 00:37:20.215] [REFramework] [error] R13: 20
[2022-02-01 00:37:20.215] [REFramework] [error] R14: 1
[2022-02-01 00:37:20.215] [REFramework] [error] R15: 1495eeb10
[2022-02-01 00:37:20.215] [REFramework] [error] RAX: 1200000000
[2022-02-01 00:37:20.215] [REFramework] [error] RBX: 29dd17d0
[2022-02-01 00:37:20.215] [REFramework] [error] RBP: 29dd17d0
[2022-02-01 00:37:20.215] [REFramework] [error] RSI: 205ca660
[2022-02-01 00:37:20.215] [REFramework] [error] RDI: 24269b40
[2022-02-01 00:37:20.215] [REFramework] [error] EFLAGS: 10297
[2022-02-01 00:37:20.215] [REFramework] [error] CS: 33
[2022-02-01 00:37:20.215] [REFramework] [error] DS: 2b
[2022-02-01 00:37:20.215] [REFramework] [error] ES: 2b
[2022-02-01 00:37:20.215] [REFramework] [error] FS: 53
[2022-02-01 00:37:20.215] [REFramework] [error] GS: 2b
[2022-02-01 00:37:20.215] [REFramework] [error] SS: 2b
[2022-02-01 00:37:20.215] [REFramework] [error] Module: 140000000 D:\Games\SteamLibrary\steamapps\common\MonsterHunterRise\MonsterHunterRise.exe
[2022-02-01 00:37:20.216] [REFramework] [error] Attempting to write dump to D:\Games\SteamLibrary\steamapps\common\MonsterHunterRise\reframework_crash.dmp

reframework_crash.dmp.zip

praydog commented 2 years ago

What script?

KrisCris commented 2 years ago

https://github.com/KrisCris/MHRise_OneKeyQuestClear/blob/main/OneKeyQuestClear.lua

I was trying to use this code to clear the rampage quest but the game randomly crashes at some point during the quest. Sometimes I can see errors about (illegal or invalid or something, I can't clearly recall) accessing a certain function called by my code but in most of the crashes, I can't find any related error in the log except the one I posted above.

I figured that possibly the crash is related to calling a function on some object that might have already been destroyed or something, cuz I tried to call it too frequently.

So, I tried to workaround this by wrapping my code with if counter % 300 == 0 then ... end on line 64, to slow down the function call, and it seems to be working. (It's my first time writing such script so perhaps I did something wrong)

praydog commented 2 years ago

I'll take a look at it, but be aware that scripts can still crash the game if there is something wrong with the underlying game code you're calling, or the game is not set up properly to handle a certain set of behaviors you're creating.

You could also move your code into another callback like:

re.on_pre_application_entry("UpdateBehavior", function()
    -- your code here
end)

as on_frame may not be the most ideal place to do it, it's running in a completely different thread from most of the game code.

KrisCris commented 2 years ago

You could also move your code into another callback like

Sure I will try that, but I did it in the past, turned out it didn't really help.

KrisCris commented 2 years ago

be aware that scripts can still crash the game if there is something wrong with the underlying game code you're calling, or the game is not set up properly to handle a certain set of behaviors you're creating.

Yeah, I was using the ObjectExplorer to see what could be possibly used in my code, basically just trial and error to see if a certain field or method works, hoping the game won't crash. Is there a better way?

praydog commented 2 years ago

Try this instead, it uses a hook on the enemy's update function to call the dieSelf method. This ensures that the enemy has to be active within game memory:

local wants_kill_everything = false
local kill_everything_timer = 0.0

local app_type = sdk.find_type_definition("via.Application")
local get_elapsed_second = app_type:get_method("get_UpTimeSecond")

local function get_time()
    return get_elapsed_second:call(nil)
end

re.on_draw_ui(function()
    local changed = false

    changed = imgui.button("Kill Everything")
    if changed then
        wants_kill_everything = true
        kill_everything_timer = get_time()
    end
end)

re.on_frame(function()
    if wants_kill_everything then
        local now = get_time()
        local delta = now - kill_everything_timer

        if delta > 1.0 then
            wants_kill_everything = false
            kill_everything_timer = 0.0
        end
    end
end)

local function pre_enemy_update(args)
    if wants_kill_everything then
        local enemy = sdk.to_managed_object(args[2])
        enemy:call("dieSelf")
    end
end

local function post_enemy_update(retval)
    return retval
end

sdk.hook(
    sdk.find_type_definition("snow.enemy.EnemyCharacterBase"):get_method("update"),
    pre_enemy_update,
    post_enemy_update
)
praydog commented 2 years ago

And as a side note here, you'll need to filter out the NPCs you don't want to kill with this. It captures all of the enemy NPCs within the update method.

KrisCris commented 2 years ago

Thanks a lot, I will try this after I wake up tomorrow :)

Btw, what does kill_everything_timer do, is it trying to automatically disable the function?

praydog commented 2 years ago

It just keeps track of when you pressed the "kill everything" button. It stops trying to call dieSelf on everything after 1 second passes.

KrisCris commented 2 years ago

Thanks! The new one works very well.