Migrations on mod compatibilities
- DiegoPro77
- Fast Inserter
- Posts: 172
- Joined: Tue Feb 20, 2018 1:40 pm
- Contact:
Migrations on mod compatibilities
Hi guys, I have a question.
I'm currently working on my ore refining mod: as the name says it introduces ore refining chains.
I was trying to add compatibility with Brevven's Lead mod, and I got a problem with migration files.
Let's say that smo is playing both mods, and I release this updated version that adds compatibility. Migrations will unlock the right recipes as long as the player has researched the right technologies, as migration files normally do.
But if smo doesn't run the Lead mod the game crashes since the items (lead intermediates) are not found, since the mod loads everything only if the mod is enabled in the game.
How can I fix this problem?
(Some of the recipe names are "lead-dust0", "lead-clump1", lead-chunk1" if you wanted to know them.)
I'm currently working on my ore refining mod: as the name says it introduces ore refining chains.
I was trying to add compatibility with Brevven's Lead mod, and I got a problem with migration files.
Let's say that smo is playing both mods, and I release this updated version that adds compatibility. Migrations will unlock the right recipes as long as the player has researched the right technologies, as migration files normally do.
But if smo doesn't run the Lead mod the game crashes since the items (lead intermediates) are not found, since the mod loads everything only if the mod is enabled in the game.
How can I fix this problem?
(Some of the recipe names are "lead-dust0", "lead-clump1", lead-chunk1" if you wanted to know them.)
Aka Playmaker. My mods: https://mods.factorio.com/user/77playmaker -|- My Discord Server: https://discord.gg/6NGYQdX
"One day you'll live this word behind, so live a life you will remember."
Expanding your game experience since 2018.
"One day you'll live this word behind, so live a life you will remember."
Expanding your game experience since 2018.
- Deadlock989
- Smart Inserter
- Posts: 2529
- Joined: Fri Nov 06, 2015 7:41 pm
Re: Migrations on mod compatibilities
As far as I know I don't think this is possible with JSON migration files. But you can write Lua migration files as well, and you can conditionally run a code block if and only if a specific mod is present (game.active_mods), or test for the existence of named prototypes, etc.
- DiegoPro77
- Fast Inserter
- Posts: 172
- Joined: Tue Feb 20, 2018 1:40 pm
- Contact:
Re: Migrations on mod compatibilities
Oh interesting thing to know thank you (My knowledge about coding stopped active development in high school unfortunately :.) - and I was programming in Ruby, so pardon my ignorance on Api, events and on functions).Deadlock989 wrote: ↑Fri Dec 29, 2023 11:20 pm As far as I know I don't think this is possible with JSON migration files. But you can write Lua migration files as well, and you can conditionally run a code block if and only if a specific mod is present (game.active_mods), or test for the existence of named prototypes, etc.
Regarding Lua migrations, this is what I wrote on the migration file: (ev-refining_2.1.0.lua)
Code: Select all
if mods ["bzlead"] then
for index, force in pairs(game.forces) do
local technologies = force.technologies
local recipes = force.recipes
if technologies["advanced-material-processing"].researched then
recipes["lead-dust0"].enabled = true
end
end
end
Code: Select all
Error while applying migration: Extended Vanilla: Refining: ev-refining_2.1.0.lua
__ev-refining__/migrations/ev-refining_2.1.0.lua:1: attempt to index global 'mods' (a nil value)
stack traceback:
__ev-refining__/migrations/ev-refining_2.1.0.lua:1: in main chunk
Aka Playmaker. My mods: https://mods.factorio.com/user/77playmaker -|- My Discord Server: https://discord.gg/6NGYQdX
"One day you'll live this word behind, so live a life you will remember."
Expanding your game experience since 2018.
"One day you'll live this word behind, so live a life you will remember."
Expanding your game experience since 2018.
- DiegoPro77
- Fast Inserter
- Posts: 172
- Joined: Tue Feb 20, 2018 1:40 pm
- Contact:
Re: Migrations on mod compatibilities
Wait I found out a piece of code that works and applies the migrations correctly by looking at your first link: (another time, thank you)Deadlock989 wrote: ↑Fri Dec 29, 2023 11:20 pm As far as I know I don't think this is possible with JSON migration files. But you can write Lua migration files as well, and you can conditionally run a code block if and only if a specific mod is present (game.active_mods), or test for the existence of named prototypes, etc.
Code: Select all
for name in pairs(script.active_mods) do
if name == "bzlead" then
for index, force in pairs(game.forces) do
local technologies = force.technologies
local recipes = force.recipes
if technologies["advanced-material-processing"].researched then
recipes["lead-dust0"].enabled = true
end
end
end
end
But these technology unlocks should be checked every time my mod is put together with Lead.
I mean, am I sure that these unlocks will be always applied correctly without having to copy paste the migration file for each new version of the mod?
Aka Playmaker. My mods: https://mods.factorio.com/user/77playmaker -|- My Discord Server: https://discord.gg/6NGYQdX
"One day you'll live this word behind, so live a life you will remember."
Expanding your game experience since 2018.
"One day you'll live this word behind, so live a life you will remember."
Expanding your game experience since 2018.
Re: Migrations on mod compatibilities
You don't have to copy paste the migration file, because which recipes are unlocked is a part of the game state, saved in the savefile. Once unlocked, always unlocked.DiegoPro77 wrote: ↑Sat Dec 30, 2023 10:10 am But the thing that I'm realizing now is: migration files as said here are applied only once and the game knows which files were already applied and which not.
But these technology unlocks should be checked every time my mod is put together with Lead.
I mean, am I sure that these unlocks will be always applied correctly without having to copy paste the migration file for each new version of the mod?
If the mod author of lead recipes adds new recipes in a future mod update, which you also want to unlock with a different technology than their mod specified then you would need an additional migration for that (instead of modifying the already existing migration to include the new prototypes, which would not work for users updating from a version with the old migration).
My mods: Capsule Ammo | HandyHands - Automatic handcrafting | ChunkyChunks - Configurable Gridlines
Some other creations: Combinassembly Language GitHub w instructions and link to run it in your browser | 0~drain Laser
Some other creations: Combinassembly Language GitHub w instructions and link to run it in your browser | 0~drain Laser
- Deadlock989
- Smart Inserter
- Posts: 2529
- Joined: Fri Nov 06, 2015 7:41 pm
Re: Migrations on mod compatibilities
e.g.DiegoPro77 wrote: ↑Sat Dec 30, 2023 9:52 am And what do you mean by "test the existence" of a prototype?
Code: Select all
if game.recipe_prototypes["lead-dust0"] then
-- do something
end
You don't have to loop through every active mod, you can do this:DiegoPro77 wrote: ↑Sat Dec 30, 2023 10:10 am Wait I found out a piece of code that works and applies the migrations correctly by looking at your first link: (another time, thank you)
Code: Select all
if game.active_mods["bzlead"] and game.recipe_prototypes["lead-dust0"] then
for _,force in pairs(game.forces) do
force.recipes["lead-dust0"].enabled = force.technologies["advanced-material-processing"].researched
end
end
This kind of thing is what the on_configuration_changed event is for. This event fires when a saved game is loaded and any mod has changed version (including adding a mod to an existing save that didn't have it before). This would need you to get to grips with control.lua scripting, setting up event handlers and so forth.DiegoPro77 wrote: ↑Sat Dec 30, 2023 10:10 am But the thing that I'm realizing now is: migration files as said here are applied only once and the game knows which files were already applied and which not.
But these technology unlocks should be checked every time my mod is put together with Lead.
I mean, am I sure that these unlocks will be always applied correctly without having to copy paste the migration file for each new version of the mod?
- DiegoPro77
- Fast Inserter
- Posts: 172
- Joined: Tue Feb 20, 2018 1:40 pm
- Contact:
Re: Migrations on mod compatibilities
Yeah it makes sense and, at a certain degree I knew that. The thing was more about what Deadlock said in the last reply, and to work around that thing I should try to study how control.lua files work in a first place.Qon wrote: ↑Sat Dec 30, 2023 10:41 am You don't have to copy paste the migration file, because which recipes are unlocked is a part of the game state, saved in the savefile. Once unlocked, always unlocked.
If the mod author of lead recipes adds new recipes in a future mod update, which you also want to unlock with a different technology than their mod specified then you would need an additional migration for that (instead of modifying the already existing migration to include the new prototypes, which would not work for users updating from a version with the old migration).
It really would be interesting, and useful probably, but is it really worth it for me to go this far for now?Deadlock989 wrote: ↑Sat Dec 30, 2023 12:01 pm This kind of thing is what the on_configuration_changed event is for. This event fires when a saved game is loaded and any mod has changed version (including adding a mod to an existing save that didn't have it before). This would need you to get to grips with control.lua scripting, setting up event handlers and so forth.
Now that you made me think about that, let me explain:
- A player downloads both mods and starts a new run: simplest case;
- A player playing Lead in a world decides to introduce Ev Refining: migrations aren't needed here too because all technologies need to be researched;
- A player playing Ev Refining decides to introduce Lead: migrations should apply thanks to the "if game.active_mods["bzlead"]"; (I'm right on this point am I?)
The only case where we have a problem is the one where a player:
-> Plays both mods -> Updates Ev Refining -> Deletes Lead -> Enables Lead
And well I dunno why someone would do something like that. (It would compromise the entire run.)
Yeah I tend to overdo sometimes while coding, thank you. xDDeadlock989 wrote: ↑Sat Dec 30, 2023 12:01 pm You don't have to loop through every active mod, you can do this:
Aka Playmaker. My mods: https://mods.factorio.com/user/77playmaker -|- My Discord Server: https://discord.gg/6NGYQdX
"One day you'll live this word behind, so live a life you will remember."
Expanding your game experience since 2018.
"One day you'll live this word behind, so live a life you will remember."
Expanding your game experience since 2018.
- Deadlock989
- Smart Inserter
- Posts: 2529
- Joined: Fri Nov 06, 2015 7:41 pm
Re: Migrations on mod compatibilities
If a player can break something, at least one will. Whether it's worth handling or not it is a subjective judgement for you. There are some mods which simply aren't ever going to work out well when introduced or removed mid-game. In that case it may be massively less work for you to simply warn the punters about that.DiegoPro77 wrote: ↑Sat Dec 30, 2023 2:07 pm The only case where we have a problem is the one where a player:
-> Plays both mods -> Updates Ev Refining -> Deletes Lead -> Enables Lead
And well I dunno why someone would do something like that. (It would compromise the entire run.)
For mods which add only brand new recipes to brand new technologies, in general I don't feel any need to worry - the save game state keeps track of it all and if a player removes and then reinstalls the mod, there's not a great deal you can do about that.
But if you add a new recipe to a vanilla technology or arguably a technology provided by a third party mod, players are going to expect to have access to it if they already researched that technology and they add your mod later. For example this mod has a very simple on_configuration_changed script that checks to see if Optics research has already been completed and updates one specific recipe's availability, whenever the mod is added or updated.
There is also the option of using force.reset_technology_effects() - I sometimes use this for when tricksy mod combos change and just wholesale updating every recipe availability at once. For example IR3 does this when Dectorio is added or removed.
Re: Migrations on mod compatibilities
I'm sorry, I focused on the "don't copy migrations each update part" didn't have time before to tell you about on_configuration_changed.DiegoPro77 wrote: ↑Sat Dec 30, 2023 2:07 pm Yeah it makes sense and, at a certain degree I knew that. The thing was more about what Deadlock said in the last reply, and to work around that thing I should try to study how control.lua files work in a first place.
migration scripts are basically just for your own mods internal changes that need to be migrated. Inter-mod configuration and interaction changes is what on_configuration_changed is for. Use that. It's not hard or a lot to learn, you just name the file control.lua (directly in the mod folder, not in a sub folder) and put the code in the event handler (not technically an event like the others, so different syntax).
all you need is your idempotent (it already is so don't worry) migration in the control.lua inside the event handler
Code: Select all
script.on_configuration_changed(function(event)
if game.active_mods["bzlead"] and game.recipe_prototypes["lead-dust0"] then
for _,force in pairs(game.forces) do
force.recipes["lead-dust0"].enabled = force.technologies["advanced-material-processing"].researched
end
end
end)
https://lua-api.factorio.com/latest/classes/LuaBootstrap.html#on_configuration_changed wrote:Register a function to be run when mod configuration changes. This is called when the game version or any mod version changed, when any mod was added or removed, when a startup setting has changed, when any prototypes have been added or removed, or when a migration was applied. It allows the mod to make any changes it deems appropriate to both the data structures in its global table or to the game state through LuaGameScript.
It's not "going far", it's quick, easy and CORRECT. Why do it incorrectly when it's just as easy to do it correctly and avoid all the bugs, no matter what chain of removal and adding of mods you come up with.DiegoPro77 wrote: ↑Sat Dec 30, 2023 2:07 pmIt really would be interesting, and useful probably, but is it really worth it for me to go this far for now?Deadlock989 wrote: ↑Sat Dec 30, 2023 12:01 pm This kind of thing is what the on_configuration_changed event is for. This event fires when a saved game is loaded and any mod has changed version (including adding a mod to an existing save that didn't have it before). This would need you to get to grips with control.lua scripting, setting up event handlers and so forth.
Maybe someone adds the mod, tries removing it to debug which mod is causing some bug, before crafting much of anything from the mods. Then adds the mods back in again. Now suddenly the recipes that worked before are now just gone! But since you have now decided to not write bugs on purpose and put the code in control.lua in the on_configuration_change handler you don't have to worry about thisDiegoPro77 wrote: ↑Sat Dec 30, 2023 2:07 pm And well I dunno why someone would do something like that. (It would compromise the entire run.)
My mods: Capsule Ammo | HandyHands - Automatic handcrafting | ChunkyChunks - Configurable Gridlines
Some other creations: Combinassembly Language GitHub w instructions and link to run it in your browser | 0~drain Laser
Some other creations: Combinassembly Language GitHub w instructions and link to run it in your browser | 0~drain Laser
- DiegoPro77
- Fast Inserter
- Posts: 172
- Joined: Tue Feb 20, 2018 1:40 pm
- Contact:
Re: Migrations on mod compatibilities
Definitively true.Deadlock989 wrote: ↑Sat Dec 30, 2023 2:48 pm If a player can break something, at least one will. Whether it's worth handling or not it is a subjective judgement for you. There are some mods which simply aren't ever going to work out well when introduced or removed mid-game. In that case it may be massively less work for you to simply warn the punters about that.
Yeah, but I must say that Qon is right on this fact:Deadlock989 wrote: ↑Sat Dec 30, 2023 2:48 pm For mods which add only brand new recipes to brand new technologies, in general I don't feel any need to worry - the save game state keeps track of it all and if a player removes and then reinstalls the mod, there's not a great deal you can do about that.
And it can become handy since my mods are not big enough to stand alone: everyone here always asks for compatibilities, and compatibilities, and compatibilities, and so on...Qon wrote: ↑Sat Dec 30, 2023 5:25 pm Maybe someone adds the mod, tries removing it to debug which mod is causing some bug, before crafting much of anything from the mods. Then adds the mods back in again. Now suddenly the recipes that worked before are now just gone! But since you have now decided to not write bugs on purpose and put the code in control.lua in the on_configuration_change handler you don't have to worry about this
I even started to play some of these mods players continue to talk me about just to see how to balance things out. (and have some fun and not just modding xD)
I'll probably add compatibility with IR3 too if it adds new minerals. (There are so many mods wow)
I'll try to learn these control scripts then if this is their job to fix these problems. xDQon wrote: ↑Sat Dec 30, 2023 5:25 pm Inter-mod configuration and interaction changes is what on_configuration_changed is for. Use that. It's not hard or a lot to learn, you just name the file control.lua (directly in the mod folder, not in a sub folder) and put the code in the event handler (not technically an event like the others, so different syntax).
all you need is your idempotent (it already is so don't worry) migration in the control.lua inside the event handlerCode: Select all
script.on_configuration_changed(function(event) if game.active_mods["bzlead"] and game.recipe_prototypes["lead-dust0"] then for _,force in pairs(game.forces) do force.recipes["lead-dust0"].enabled = force.technologies["advanced-material-processing"].researched end end end)
Will keep an eye on that, it seems interesting.Deadlock989 wrote: ↑Sat Dec 30, 2023 2:48 pm But if you add a new recipe to a vanilla technology or arguably a technology provided by a third party mod, players are going to expect to have access to it if they already researched that technology and they add your mod later. For example this mod has a very simple on_configuration_changed script that checks to see if Optics research has already been completed and updates one specific recipe's availability, whenever the mod is added or updated.
Also interesting, if smth is wrong I'll repost here, thank you guys for the helps. <3Deadlock989 wrote: ↑Sat Dec 30, 2023 2:48 pm There is also the option of using force.reset_technology_effects() - I sometimes use this for when tricksy mod combos change and just wholesale updating every recipe availability at once. For example IR3 does this when Dectorio is added or removed.
Aka Playmaker. My mods: https://mods.factorio.com/user/77playmaker -|- My Discord Server: https://discord.gg/6NGYQdX
"One day you'll live this word behind, so live a life you will remember."
Expanding your game experience since 2018.
"One day you'll live this word behind, so live a life you will remember."
Expanding your game experience since 2018.