Page 1 of 1

[SOLVED] on_load help

Posted: Sun May 07, 2017 9:55 pm
by rookhaven
Hi all,

I've looked over everything I can find about how on_load won't access game data and we're supposed to use on_init etc. But I still don't know exactly how to get my mod to load after saving. It works fine when I create a new game. I see this info from the Data Lifecycle page.
During the script.on_load() event handler access to the game table is not available. This handler is meant for only 3 things:

1. Re-setup meta-tables. Meta-tables are not persisted through save-load.
2. Re-setup conditional event handlers (subscribing to an event only when some condition is true to save processing time).
3. Create local references to data stored in the global table
Attempting to change the contents of the global table during the script.on_load() event handler is not allowed. Doing so can lead to desyncs if the mod is used in multiplayer and will generate an error if the game detects it has been changed in any way.

During the script.on_init() event handler access to the game table is available and any and all changes deemed necessary by the mod are free to be performed without risk of breaking anything.
So here are the details:

1.) First of all, everything I've done has been by reverse engineering it from other people's mods, reading the forums, or checking the API (pretty cool API btw). This mod has not been published - I'm just tooling around trying to get it to work. The old homeworld mod is what this is closest to and what I took my logic from.

2.) I'm working on the most recent version of Factorio, which as of this post is 0.15.9.

3.) I've attached what I think are the pertinent files without zipping and attaching the whole mod (which I can do if I need to). config.lua, control.lua, and two civ/city classes which are called by control.lua. I don't think data and the various prototypes are the problem although I have several new entities/items/recipes etc.

4.) The part I don't get is how to re-initialize the meta-stuff and handlers and whatever else on_load without re-initializing the underlying global data. That's where I get lost. So I need to do exactly what they're saying in the Data Lifecycle Page but I don't know how to. The complicated part of this mod is that I have an array of classes which contain associated entities.

5.) To recreate the problem, I start a new game, which brings up my gui, wait a few cycles to update it (I place a city which is a stored class with associated entity), and save the game.

6.) If I load it 1 second later, it runs till the next on_tick call of my Civ:update method and I get the nil variable message. Or I get one about the global being out of whack.

Please can someone help me get the exact syntax I need to make the load work. Thanks.

Re: on_load help

Posted: Sun May 07, 2017 10:27 pm
by Nexela
Would probably be easiest to post the whole mod as well as the log containing errors

Re: on_load help

Posted: Sun May 07, 2017 10:53 pm
by Adil
Well, it's easy, table and metatable relations are not saved. That is, upon load the table exists as if you had called

Code: Select all

setmetatable( mytable, nil)
on it.
Thus to make them work again, you need to find all the tables that used to have metatable and to set those again. For example:

Code: Select all

function Civ:load()
	self.state = global.civ_state
      for _, city in pairs( self.state.cities) do
             setmetatable(city, CIty)
      end
end
I had been adding `restore` method to each class definition when I was doing mods.
An example used to be in my lib for gui callbacks https://github.com/Adilf/gui-lib, it is probably not incompatible yet.

Re: on_load help

Posted: Mon May 08, 2017 1:31 am
by rookhaven
omg it worked!!!! WOOT!

I had to merge it with some of Nexela's stuff over in the other post: viewtopic.php?f=34&t=46775

Here's what I ended up with in the civ_logic.lua file for my class's load function:

Code: Select all

function Civ:load()
	if global.civ_state ~= nil then
		self.state = global.civ_state
		for _, city in pairs(self.state.cities) do
			setmetatable(city, {__index = City})
		end
		if global.actions then
			script.on_event(defines.events.on_tick, on_tick)
		end
	end 
end
Updates the GUI and everything! :D

LOVE U GUYS! Been banging on this all day....