"Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Bugs that are actually features.
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1449
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

"Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by TheSAguy »

Hi,

Someone is getting the below error on loading a new game:. It's on code that's been around a long time, so not sure if a new Factorio release changed anything:

Code: Select all

205.288 Error ServerMultiplayerManager.cpp:95: MultiplayerManager failed: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research_finished (ID 18)
__Natural_Evolution_Buildings__/control.lua:556: attempt to perform arithmetic on field 'deduction_constant' (a nil value)
stack traceback:
        ...mapps/common/Factorio/temp/currently-playing/control.lua:787: in function 'set_research'
        ...mapps/common/Factorio/temp/currently-playing/control.lua:122: in function 'init_forces'
        ...mapps/common/Factorio/temp/currently-playing/control.lua:22: in function <...mapps/common/Factorio/temp/currently-playing/control.lua:19>"
I asked on the forums and the following was suggested:
eradicator wrote:That error is from the wave defense scenario. Looking at that one can see that it uses research_all_technologies which raises on_research_finished during it's own on_init. You can also see that in the error message. Meaning that your on_research_finished handler gets called before your own on_init. Or at least that would be my guess. A workaround would be to initialize your constant during the research event. But it feels a bit buggy that the scenario gets to init before the mods....(bug report-ish?)
This is out of my scope of knowledge, but thought I'd post it here.

The code I'm using is:

On Init:

Code: Select all

	if global.deduction_constant == nil or global.deduction_constant == 0 then
		global.deduction_constant = 0.00025 -------- DEDUCTION CONSTANT
	end
And when finishing research:

Code: Select all


---------------------------------------------
script.on_event(defines.events.on_research_finished, function(event)

 
    if research == "TerraformingStation-2" then
        global.deduction_constant = global.deduction_constant + (global.deduction_constant / 4)
    end      

    if research == "TerraformingStation-3" then
        global.deduction_constant = global.deduction_constant + (global.deduction_constant / 4)
    end    	
  
end)

Related Post

Thanks.
User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5267
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by Klonan »

Well, the mod is doing things incorrectly, you should always check some variable is valid before trying to use it, and apart from that, not really a Factorio bug.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by eradicator »

@Klonan:
Can you confirm this is indeed happening because the mods own on_init is beeing called after the scenario on_init?
Because if that is the case that would mean mods in general can't rely on using on_init becaues they can't rely on it actually being executed early enough. Which in turn would mean that all initialization of global objects etc would have to be spread all over the place and i'm not sure anymore what the use of on_init in that case would be anymore. I.e. a scenario can raise any arbitrary event during it's on_init, so all mod event handlers would need to be agnostic to on_init.
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.
Rseding91
Factorio Staff
Factorio Staff
Posts: 14273
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by Rseding91 »

eradicator wrote:@Klonan:
Can you confirm this is indeed happening because the mods own on_init is beeing called after the scenario on_init?
Because if that is the case that would mean mods in general can't rely on using on_init becaues they can't rely on it actually being executed early enough. Which in turn would mean that all initialization of global objects etc would have to be spread all over the place and i'm not sure anymore what the use of on_init in that case would be anymore. I.e. a scenario can raise any arbitrary event during it's on_init, so all mod event handlers would need to be agnostic to on_init.
That's what happens now and there's no way I can think of that would work around that issue except for mods to not do things like that in on_init.

If changing things in on_init didn't fire events then mod(s) would break if they expected events to be fired. If on_init does fire events then mod(s) would break if they didn't expect the events to happen before on_init.

I guess for now I'll change it so the game won't fire any events until on_init has been called on each mod. That just means that mod(s) need to handle the full setup in on_init instead of relying on events before it's called.
If you want to get ahold of me I'm almost always on Discord.
User avatar
steinio
Smart Inserter
Smart Inserter
Posts: 2638
Joined: Sat Mar 12, 2016 4:19 pm
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by steinio »

on_init inception
Image

Transport Belt Repair Man

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

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by eradicator »

Rseding91 wrote:
eradicator wrote:@Klonan:
Can you confirm this is indeed happening because the mods own on_init is beeing called after the scenario on_init?
Because if that is the case that would mean mods in general can't rely on using on_init becaues they can't rely on it actually being executed early enough. Which in turn would mean that all initialization of global objects etc would have to be spread all over the place and i'm not sure anymore what the use of on_init in that case would be anymore. I.e. a scenario can raise any arbitrary event during it's on_init, so all mod event handlers would need to be agnostic to on_init.
That's what happens now and there's no way I can think of that would work around that issue except for mods to not do things like that in on_init.

If changing things in on_init didn't fire events then mod(s) would break if they expected events to be fired. If on_init does fire events then mod(s) would break if they didn't expect the events to happen before on_init.

I guess for now I'll change it so the game won't fire any events until on_init has been called on each mod. That just means that mod(s) need to handle the full setup in on_init instead of relying on events before it's called.
Er, wait what. Maybe i wasn't clear enough...but wouldn't the whole situation be resolved if the order of calling was changed:

First call on_init on all mods.
Then call on_init of the scenario script.

?
Last edited by eradicator on Mon Jan 29, 2018 7:48 pm, edited 2 times 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.
Rseding91
Factorio Staff
Factorio Staff
Posts: 14273
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by Rseding91 »

eradicator wrote:Er, wait what. Maybe i wasn't clear enough...but wouldn't the whole situation be resolved if the order of calling was changed:

First call on_init on all mods.
Then call on_init of the scenario script.

?

Any mod can also call research_all_technologies which will fire the research_finished event for mods that haven't had on_init called.
If you want to get ahold of me I'm almost always on Discord.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by eradicator »

Rseding91 wrote: Any mod can also call research_all_technologies which will fire the research_finished event for mods that haven't had on_init called.
Right. I knew i was forgetting something. But your for now solution makes things worse from a mod dev perspective.

As with that mods have to compensate for every possible change a scenario made. Have to assume all events have already happend any amount of times. And what's worst: scenarios can't use many things that are added by mods anymore. I.e. if a mod adds an entity that relies on on_built for special setup then either:
a) no scenario can ever use that entity in on_init or
b) the mod has to scan the whole existing map in on_init for potential instantces of that entity. Which makes writing entities like that hell.

So. Please..just leave it as is unless someone finds a magical proper solution.
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.
Rseding91
Factorio Staff
Factorio Staff
Posts: 14273
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by Rseding91 »

eradicator wrote:
Rseding91 wrote: Any mod can also call research_all_technologies which will fire the research_finished event for mods that haven't had on_init called.
Right. I knew i was forgetting something. But your for now solution makes things worse from a mod dev perspective.

As with that mods have to compensate for every possible change a scenario made. Have to assume all events have already happend any amount of times. And what's worst: scenarios can't use many things that are added by mods anymore. I.e. if a mod adds an entity that relies on on_built for special setup then either:
a) no scenario can ever use that entity in on_init or
b) the mod has to scan the whole existing map in on_init for potential instantces of that entity. Which makes writing entities like that hell.

So. Please..just leave it as is unless someone finds a magical proper solution.
This problem already exists as you can add/remove mods on the fly which will then get on_init called in the middle of a save file.

Mods *already* have to do all of what you describe in on_init if they want to be correct.
If you want to get ahold of me I'm almost always on Discord.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by eradicator »

Rseding91 wrote: This problem already exists as you can add/remove mods on the fly which will then get on_init called in the middle of a save file.

Mods *already* have to do all of what you describe in on_init if they want to be correct.
Untrue. If a mod is added in the middle of a save then entities of that mod can not already exist on the map.
What i mean is:

scenario on_init calls surface.create_entity(new-mod-building)

Currently it would work if the mod does not need special handling for new-mod-building or it does it's special handling without relying on its own on_init, and otherwise (hopefully) error.
With your change the mod now has to wait for on_init and then scan the whole map for new-mod-building to do it's special handling, and if it doesn't the entity exists on the map but is missing it's special handling (i.e. entity is broken, no error was issued).

I think it's ultimately a question of whom you want to shift the burden to, scenario authors or mod authors.
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.
Rseding91
Factorio Staff
Factorio Staff
Posts: 14273
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by Rseding91 »

eradicator wrote:
Rseding91 wrote: This problem already exists as you can add/remove mods on the fly which will then get on_init called in the middle of a save file.

Mods *already* have to do all of what you describe in on_init if they want to be correct.
Untrue. If a mod is added in the middle of a save then entities of that mod can not already exist on the map.
What i mean is:

scenario on_init calls surface.create_entity(new-mod-building)

Currently it would work if the mod does not need special handling for new-mod-building or it does it's special handling without relying on its own on_init, and otherwise (hopefully) error.
With your change the mod now has to wait for on_init and then scan the whole map for new-mod-building to do it's special handling, and if it doesn't the entity exists on the map but is missing it's special handling (i.e. entity is broken, no error was issued).

I think it's ultimately a question of whom you want to shift the burden to, scenario authors or mod authors.
But, create_entity doesn't fire any events so it doesn't matter anyway?
If you want to get ahold of me I'm almost always on Discord.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by eradicator »

Rseding91 wrote:
eradicator wrote:
Rseding91 wrote: This problem already exists as you can add/remove mods on the fly which will then get on_init called in the middle of a save file.

Mods *already* have to do all of what you describe in on_init if they want to be correct.
Untrue. If a mod is added in the middle of a save then entities of that mod can not already exist on the map.
What i mean is:

scenario on_init calls surface.create_entity(new-mod-building)

Currently it would work if the mod does not need special handling for new-mod-building or it does it's special handling without relying on its own on_init, and otherwise (hopefully) error.
With your change the mod now has to wait for on_init and then scan the whole map for new-mod-building to do it's special handling, and if it doesn't the entity exists on the map but is missing it's special handling (i.e. entity is broken, no error was issued).

I think it's ultimately a question of whom you want to shift the burden to, scenario authors or mod authors.
But, create_entity doesn't fire any events so it doesn't matter anyway?
Well, if done correctly by the scenario author it should raise on_built or script_raised_built after that?

Coming up with a good example on short notice is difficult. But making mods "miss" events just sounds completly wrong to me.
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.
chrisgbk
Long Handed Inserter
Long Handed Inserter
Posts: 93
Joined: Mon Jan 02, 2017 4:31 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by chrisgbk »

Rseding91 wrote: That's what happens now and there's no way I can think of that would work around that issue except for mods to not do things like that in on_init.

If changing things in on_init didn't fire events then mod(s) would break if they expected events to be fired. If on_init does fire events then mod(s) would break if they didn't expect the events to happen before on_init.

I guess for now I'll change it so the game won't fire any events until on_init has been called on each mod. That just means that mod(s) need to handle the full setup in on_init instead of relying on events before it's called.
Does this mean that the events just don't happen at all until on_init has been called for all mods(ie: are ignored and dropped), or do they get deferred until on_init has been called for all mods(ie: save a queue of events that would have been called, then call them in order), or is it just until that particular mod finishes on_init and will then start receiving events?

My preferred interpretation would be the second one; it lets all the events exist and happen as they would have, but guarantees a specific order and prevents events during initialization, and then the documentation can specify the behaviour that events are queued until all on_init handlers finish. It puts the burden of correctness on the mod/scenario authors to not rely on events being raised during on_init to change state before it finishes running, while letting them raise events that might be required for things such as inter-mod dependencies where you don't have access to the other mods internal state, but can use events to request it to act.

In a similar way, this could happen for on_configuration_changed as well, for the case of a mod being added in the middle of a game, and possibly on_load as well.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by eradicator »

@Rseding:

So regarding your change to throw away all events for a mod that has not been on_init'ed yet: I tried to come up with a really good example but couldn't find one, so here's another mediocre example (skip to paragraph 2 if you don't care):
My mods do (as the OPs mod) have handlers for on_research_finished(), which are of course essential to recieve for the inner workings of my mod. They do not (as opposed to OP) rely on any global variables, but with the changed behavior they will still not be called before my on_init is called, over which i have no control. So this means that while they worked perfectly fine with the old behavior i now have to include an additional function into on_init that scans the technology tree for any techs that i care about. And i have to include such an additional function for every event that might possibly have been raised before my on_init.
Yes, i'm aware that as a mod author i have to cope with unexpected changes to the API, i don't mind that. But this change looks to me like it would affect far too many unrelated mods, just to prevent an error message from showing, and in favor of hidden (and far more annoying to debug) errors due to missed event calls.

-----

I thought about this a while and the only semi working solution i could come up with was the theoretical situation where a mechanism exists for mods to populate the global table with default values before on_init. From what i've seen of mine and other mods the usual practice is to include something like

global.myvar = global.myvar or default_value

in the on_init/on_config_changed handlers. So my thought was...if it was possible to somehow supply these fixed default_values before on_init that at least the situation in this thread would be migitated.
So in a theoretical situation where such a mechanism existed a mod can rely on its global table being in a correct state for all events, except if...the mod explicitly modified the global table in on_init based on the actual game state (sounds unlikely?). Remote.call cross-mod situations should not be affected by this because the call order in that case should be explicitly defined by mod dependencies.
Would you mind telling me your opinion on this? I bet i missed considering something again. (Unrelated to the fact that this would be heaps of additional work for you and thus is unlikely to happen i mean.)

------

Also finally unrelated to the problem discussed here i still do think that the scenario script should call on_init last (after all mods), simply because i think that logically it should have "the last say" as to what the game state is: base -> mod -> scenario. Meaning that the scenario should be considered an addition to the modded base game and not the mods an addition to the scenario'ed base game. I.e. If a mod wants to add some default items to a players inventory, but a scenario decides to override all default items then the scenario should be able to do that. And i believe in the current situation where the scenario event handlers are called first the mods event handlers would "win" when adding/replacing the players inventory.
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.
Rseding91
Factorio Staff
Factorio Staff
Posts: 14273
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by Rseding91 »

eradicator wrote:My mods do (as the OPs mod) have handlers for on_research_finished(), which are of course essential to recieve for the inner workings of my mod. They do not (as opposed to OP) rely on any global variables, but with the changed behavior they will still not be called before my on_init is called, over which i have no control. So this means that while they worked perfectly fine with the old behavior i now have to include an additional function into on_init that scans the technology tree for any techs that i care about. And i have to include such an additional function for every event that might possibly have been raised before my on_init.
You already have to do that. Your mod can be loaded into a save file that already has technology researched and you're not going to get the events for those already-researched technologies.
If you want to get ahold of me I'm almost always on Discord.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by eradicator »

Rseding91 wrote:
eradicator wrote:My mods do (as the OPs mod) have handlers for on_research_finished(), which are of course essential to recieve for the inner workings of my mod. They do not (as opposed to OP) rely on any global variables, but with the changed behavior they will still not be called before my on_init is called, over which i have no control. So this means that while they worked perfectly fine with the old behavior i now have to include an additional function into on_init that scans the technology tree for any techs that i care about. And i have to include such an additional function for every event that might possibly have been raised before my on_init.
You already have to do that. Your mod can be loaded into a save file that already has technology researched and you're not going to get the events for those already-researched technologies.
Not for the ones that my mod adds though. Maybe i'm getting this wrong?
  1. Scenario calls force.research_all_technologies()
  2. (old) My mods on_research_finished handler fires when it sees my technologies.
  3. (new) My mod is not initialized yet so i miss all on_research_finished events.
  4. (new) On_init i have to test if my technologies were researched.
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.
Rseding91
Factorio Staff
Factorio Staff
Posts: 14273
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by Rseding91 »

eradicator wrote:
Rseding91 wrote:
eradicator wrote:My mods do (as the OPs mod) have handlers for on_research_finished(), which are of course essential to recieve for the inner workings of my mod. They do not (as opposed to OP) rely on any global variables, but with the changed behavior they will still not be called before my on_init is called, over which i have no control. So this means that while they worked perfectly fine with the old behavior i now have to include an additional function into on_init that scans the technology tree for any techs that i care about. And i have to include such an additional function for every event that might possibly have been raised before my on_init.
You already have to do that. Your mod can be loaded into a save file that already has technology researched and you're not going to get the events for those already-researched technologies.
Not for the ones that my mod adds though. Maybe i'm getting this wrong?
  1. Scenario calls force.research_all_technologies()
  2. (old) My mods on_research_finished handler fires when it sees my technologies.
  3. (new) My mod is not initialized yet so i miss all on_research_finished events.
  4. (new) On_init i have to test if my technologies were researched.
They could be if that technology already existed due to being added by another mod - name collisions and such.
If you want to get ahold of me I'm almost always on Discord.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: "Error while running on_init: Error while running event Natural_Evolution_Buildings::on_research

Post by eradicator »

Rseding91 wrote: They could be if that technology already existed due to being added by another mod - name collisions and such.
I consider unintended name collisions a bug already. And that's unlikely to happen with my naming scheme anyway.
As i don't have a really good counter example i'll just give up until i have one ;). I do have one last question though:

Code: Select all

[0.16.21] Changed events so they won't fire until every mod has had on_init ran.
This sounds different from what you said here. I assumed this would be on a per-mod basis. I.e. after modA has run its on_init it can recieve events from modB on_init. But the changelog sounds like during on_init all events are completely dropped until every existing on_init has been called? ("until each mod has run on_init" vs "until every mod has run on_init")
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 “Not a bug”