Jump to content

[Question] modmain.lua scope and functions with crashing


Recommended Posts

There are two mods currently in place on the Steam Workshop.

Exhibit A: http://steamcommunity.com/sharedfiles/filedetails/?id=367593872

Exhibit B: http://steamcommunity.com/sharedfiles/filedetails/?id=356833566

 

Running A and B at the same time causes a crash when choosing the 'Webber' character from B.

Stack trace: http://pastebin.com/KjuhmFCN

 

Relevant code from A: http://pastebin.com/FQAAqtJP

Relevant code from B: http://pastebin.com/rdXq2752

 

 

 

From what I am seeing B is the source of the crash from the usage of the keyword 'local' for the function 'DontTriggerCreep'.

Removing 'local' and making this function more(entirely?) global removes the crash from happening.

 

I have tried various tweaks on fixing A to not produce a crash, but the only solution I found was merely copy-pasting the existing function code from the game's source files into A itself which is not a good way of doing things as far as I know.

 

 

 

So the questions are:

1) When modmain.lua is ran, should mods that declare functions keep them isolated with the 'local' keyword, or should they instead have all of their defined functions in the global scope?

 

2) In the case with A and B, should B change its instance of the function to be more(entirely?) global, or something changed with how it is hooking the function?

Link to comment
Share on other sites

This seems to be just a mistake on the part of the mod developer of webber, the function is declared after its used?

 

*edit* If the lag mod is yours and you just want to fix it, I'd just throw in a hack for webber

function DisableMovementPrediction(wrld, player)    if player == GLOBAL.ThePlayer then        if player.prefab == "webber" then            player.components.locomotor.triggerscreep = false            player.components.locomotor:SetSlowMultiplier(1)            player:OldEnableMovementPrediction(false)        else            player:EnableMovementPrediction(false)        end    endend
Edited by Sarcen
Link to comment
Share on other sites

 

This seems to be just a mistake on the part of the mod developer of webber, the function is declared after its used?

 

*edit* If the lag mod is yours and you just want to fix it, I'd just throw in a hack for webber

 

Hmm, yeah, I moved the 'DontTriggerCreep' function before the postinit hook and no crashes occur.

 

So this is a bit confusing to me.

When B is ran by itself it creates the postinit hook, then declares the function the postinit uses, and then calls the postinit at the very end.

This would be fine by itself since it doesn't call the undeclared function.

 

However, when A is ran with B, then B gets ran first because of the hook already in place, and then A runs.

At this point B gets re-ran and doesn't find the declared function?

Link to comment
Share on other sites

@CarlZalph, Idk what you are talking about, but by the look of the code EnableMovementPrediction just never works on Webber. It just never gets called normally so there are no issues.

 

 

*edit* It looks like this is a Klei bug, and Webber modder assuming its actually using inst:EnableMovementPrediction

 

But it never does.

 

Line 373 of player_common.lua calls

EnableMovementPrediction(inst, true)

not

inst:EnableMovementPrediction(true)

 

small difference, but it calls the local version inside player_common.lua, not the one defined in the inst. (Even tho it assigns the local function to inst.EnableMovementPrediction (line 1035))

 

Edited by Sarcen
Link to comment
Share on other sites

*edit* It looks like this is a Klei bug, and Webber modder assuming its actually using inst:EnableMovementPrediction

 

But it never does.

 

Line 373 of player_common.lua calls

EnableMovementPrediction(inst, true)

not

inst:EnableMovementPrediction(true)

 

small difference, but it calls the local version inside player_common.lua, not the one defined in the inst. (Even tho it assigns the local function to inst.EnableMovementPrediction (line 1035))

Actually, I included that override of EnableMovementPrediction to protect against people breaking Webber's movement by calling it on themselves. The existing call to EnableMovementPrediction occurs before Webber gets his movement fixed, anyway.

 

But it looks like I made a mistake there anyway. The problem isn't that DontTriggerCreep is local, I think, but that it's actually being declared after the common_postinit. But I'll do a more thorough look into it when I get back to a place where I can do some proper host-client debugging, there are a few more issues I want to look at...

 

 

1) When modmain.lua is ran, should mods that declare functions keep them isolated with the 'local' keyword, or should they instead have all of their defined functions in the global scope?
You should always make something local unless you have a reason to make it global. This is coming from the principle of information hiding, which basically is about preventing clashes from using the same names in the same space. So if I made DontTriggerCreep global, and someone else wrote a DontTriggerCreep that was actually doing something else without knowing about mine, that creates a compatibility issue. (granted, I made a more subtle mistake here that also created a compatibility issue, but there are some things that are easier to see before they happen than others :p
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...