Page 1 of 1

Order of mod loading problem

Posted: Mon Aug 15, 2016 5:39 pm
by canidae
I have a mod (let's call it "A") that does some initializing stuff in event "on_player_created". Another mod (let's call it "B") also does some initializing in event "on_player_created".
The problem is that mod A wants to call a remote method mod B expose when mod A receives the "on_player_created" event, but at this time mod B hasn't received the "on_player_created" yet, and is missing some initialization (i.e. setting some global["foo"]), causing the exposed method to fail as it relies on a completed initialization.
If I were to rename mod A to a name that starts with a letter later in the alphabet I'm betting it would work because then mod B would be done with event "on_player_created" by the time mod A handles the same event.
Currently I "solve" this with a hack in mod A:

Code: Select all

        script.on_event(defines.events.on_tick, function(event)
            remote.call("ModB", "doSomething", params)
            script.on_event(defines.events.on_tick, nil) -- remove this event listener
        end)
But this really just is postponing the issue, if other mod makers starts doing the same you're just as far (you could of course make it wait until the 2nd, 3rd, etc. tick, but it's still a hack).

Is there a better way, am I missing something?
If not, should we design mods to emit a "mod_loaded" event that other mods can listen to and act accordingly?

Re: Order of mod loading problem

Posted: Mon Aug 15, 2016 5:59 pm
by steinio
If you add

Code: Select all

"dependencies": ["modB >= 0.0.1"]
to info.json of mod A then the mod B will be loaded before A.

Maybe this resolves your problem but looks like a race condition because both events fire at the same time.

Greetings steinio

Re: Order of mod loading problem

Posted: Mon Aug 15, 2016 6:10 pm
by Adil
Well, it's better to expose self-contained functions, that don't have side effects such as depending on separately declared instances of data, or have a guarantee that the data is initialized already.
Other than that, you could move the initialization of mod B from event to an exposed method and call that during the initialization of A. Something like this:

Code: Select all

script.on_event(defines.events.on_player_created, function()--init A
    remote.call('modB','init')
    --continue initialization of A
or you can perform whether the data needed is initialized in the initB (called through interface or event no matter)

Code: Select all

function initB()
global.needed_data=global.needed_data or init_needed_data()
--go on
end
Unlike other events, player_created doesn't have any information that is not accessible without the event:
most commonly your data looks like

Code: Select all

global.data={
    [player_index1]=player_1_data, 
    [player_index2]=player_2_data,
    --....
    } 
so, a trivial loop over game.players will reveal the players, that are not initialized yet:

Code: Select all

for _,p in pairs(game.players) do
    if not global.data[p.index] then
        init_player_data(p);
    end
end 
Or add dependency indeed, completely forgot about that one.

Re: Order of mod loading problem

Posted: Mon Aug 15, 2016 6:57 pm
by canidae
Cheers for the replies.
Simply making mod B a dependency for mod A will solve it (adding myself to the "completely forgot about that"-wagon), although it feels kinda "wrong" since it really isn't a dependency (and I'm not too happy about it showing the missing dependency in red text, as if the user really needs to install it). It's more of a "in case the player also got this mod then this should be done".

Intriguingly enough I actually also have the exact opposite problem: I have a mod that must be executed on event "on_research_finished" before a certain other mod executes its code for the exact same event. Luckily in my case this isn't a problem as the event handler in my mod is loaded before the other mod (even though the other mod doesn't depend on my mod). Granted, I think I could've fixed this case too if my mod were to be executed last, but that may not always be the case.

Re: Order of mod loading problem

Posted: Mon Aug 15, 2016 7:04 pm
by steinio
You can put a questionmark before to make it optional.

Code: Select all

"dependencies": ["? modB"]
(Seems the version number could be spared.

Re: Order of mod loading problem

Posted: Mon Aug 15, 2016 7:39 pm
by canidae
Thanks again, although I'm afraid that doesn't remove the red text from the dependency list.

It's not pretty, but I think I'll just wing it with my little on_tick hack. It works (for now, at least).

Re: Order of mod loading problem

Posted: Mon Aug 15, 2016 10:10 pm
by orzelek
Using the ? leaves red text in there - it's been proposed few times to make it different. Mod is still optional and all runs properly.