Migrations

Migrations are a way to fix up a save file which was used in an older version of the game or mod. Migrations are any .lua file or any .json file stored in the mod's "migrations" folder.

Migrations are sorted by mod order first and then by the migration file name using lexicographical comparison. Each save file remembers which migrations from which mods have been applied and will not apply the same migration twice. When adding a mod to an existing save all migration scripts for that mod will be run. Migrations are typically used to but are not limited to changing prototype types or correct research/recipe states after changes.

JSON prototype migrations allow changing one prototype to another prototype. Typically this is done when re-naming something. Note that ghost entities are not always able to be migrated, in which case they are removed instead. Reasons for this include a change in the type of the entity, or the entity becoming unbuildable.

Example
stone-wall was previously named "wall" and was re-named:
{
  "entity":
  [
    ["wall", "stone-wall"]
  ],
  "item":
  [
    ["wall", "stone-wall"]
  ]
}

The following prototype types are available for migration:

JSON migrations are applied as a map is loaded. Multiple such migrations can be applied at once. All JSON migrations are applied before any Lua migration is applied.

Lua migrations allow altering the loaded game state. Typically this is done when recipes or technologies have changed. The game resets recipes/ technologies any time mods, prototypes, or startup settings change, so this does not need to be done in migration scripts.

Example
When the rail-chain-signal and additional tank ammo were added to the game, previous existing technology was changed so it would unlock the recipes. The game however could have already researched those technologies leaving the recipes disabled.
for index, force in pairs(game.forces) do
  local technologies = force.technologies
  local recipes = force.recipes

  recipes["rail-chain-signal"].enabled = technologies["rail-signals"].researched

  if technologies["tank"].researched then
    recipes["explosive-cannon-shell"].enabled = true
  end
end