Call function based on installed mods outside of events.

Place to get help with not working mods / modding interface.
Post Reply
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Call function based on installed mods outside of events.

Post by eradicator »

What?
I'd like to call a function f() only if a specific mod M is installed. f() affects the state of my mod (event registry, etc), so it needs to be called each time the mod starts. (Edit: In "control.lua" stage)

What's the problem?
Sounds trivial sure, just:

Code: Select all

if game.active_mods['M'] then script.on_load(f) end
Except "game" is not accessible before or even inside on_load. So i'm at a loss at how to do this. Both mods are my own, so i can do some degree of black magic if someone could tell me the right incantation.
Last edited by eradicator on Wed Sep 11, 2019 6:53 pm, edited 1 time in total.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

mrvn
Smart Inserter
Smart Inserter
Posts: 5709
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Call function based on installed mods outside of events.

Post by mrvn »

One simple way would be to have public function "enable_M_support" in your first mod. Then in M.on_load() you call that.

Another, ugly way would be to register for on_tick and then in the first tick check game.active_mods['M'] and remove the on_tick.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Call function based on installed mods outside of events.

Post by eradicator »

mrvn wrote:
Wed Sep 11, 2019 6:45 pm
One simple way would be to have public function "enable_M_support" in your first mod. Then in M.on_load() you call that.
Control stage is not a shared lua state. Remote.call() has the same problem of not being allowed outside events.

mrvn wrote:
Wed Sep 11, 2019 6:45 pm
Another, ugly way would be to register for on_tick and then in the first tick check game.active_mods['M'] and remove the on_tick.
Not desync safe.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Call function based on installed mods outside of events.

Post by eradicator »

I think i can (ab-)use require, which isn't so bad because i need to require some stuff anyway. But i don't like being forced to use pcall.

Code: Select all

if pcall(require,'__M__/dummy') then f() end
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

Choumiko
Smart Inserter
Smart Inserter
Posts: 1352
Joined: Fri Mar 21, 2014 10:51 pm
Contact:

Re: Call function based on installed mods outside of events.

Post by Choumiko »

remote should be available in on_load right? So add a (dummy) remote to mod M, if it's there call f() ?

I remember some quirks with remote and on_init (or on_load) but just checking if it's there should be fine

mrvn
Smart Inserter
Smart Inserter
Posts: 5709
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Call function based on installed mods outside of events.

Post by mrvn »

eradicator wrote:
Wed Sep 11, 2019 6:52 pm
mrvn wrote:
Wed Sep 11, 2019 6:45 pm
One simple way would be to have public function "enable_M_support" in your first mod. Then in M.on_load() you call that.
Control stage is not a shared lua state. Remote.call() has the same problem of not being allowed outside events.

mrvn wrote:
Wed Sep 11, 2019 6:45 pm
Another, ugly way would be to register for on_tick and then in the first tick check game.active_mods['M'] and remove the on_tick.
Not desync safe.
Damn, this is harder than it sounds.

Bilka
Factorio Staff
Factorio Staff
Posts: 3139
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: Call function based on installed mods outside of events.

Post by Bilka »

Use remote interfaces to provide the functions. Then you can check for the existence of the remote interface during on load. You cannot do mod-dependent functions during control lua parsing (without hacks) - aka outside on_load.
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Call function based on installed mods outside of events.

Post by eradicator »

Bilka wrote:
Wed Sep 11, 2019 7:35 pm
Use remote interfaces to provide the functions. Then you can check for the existence of the remote interface during on load. You cannot do mod-dependent functions during control lua parsing (without hacks) - aka outside on_load.
Mmmh. Checking for the *existance* of a remote interface does infact work even during control parsing (before on_load). Though unlike my pcall(require,'') solution it's dependant on load oder. As the main thing i need actually *is* to require a file from M - for which load order doesn't matter - both solutions seem to work for me. Getting rid of the pcall might be nicer though. Any substantial reasons pro/contra each of the solutions?

Code: Select all

if remote.interfaces['M-interface'] then require('__M__/main') end
Btw do you have any clue why active_mods is not available at "script" level but only at "game" level?
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

Post Reply

Return to “Modding help”