Page 2 of 2

Re: Regenerate map under existing factory, any ideas?

Posted: Wed Jan 02, 2019 7:05 am
by Optera
I haven't noticed memory leaks.

Running game.player.force.clear_chart() afterwards forces the game to forget all map data so the map view looks nice after the surface update.

Another improvement would be to call game.delete_surface(nf_surface_name) once the script is done to reduce save game bloat from additional surfaces.
Deleting the whole surface at the end you might save some performance by omitting delete_chunk in the loop. Depends on how delete_surface and delete_chunk operate though. From my limited testing it seems faster to leave generated chunks and delete the complete surface as last step.

Here's the script preserving concrete while updating the surface beneath.

Code: Select all

local surface = game.surfaces["nauvis"]
if surface then 
  log ("creating temporary surface")
  local nf_surface_name = "nf_"..surface.name
  if not game.surfaces[("nf_"..surface.name)] then
    local settings = surface.map_gen_settings
    settings.autoplace_controls["enemy-base"] = {frequency="none",size="none",richness="none"}
    settings.autoplace_controls["trees"] = {frequency="none",size="none",richness="none"}
    settings.autoplace_settings =
        { entity = {treat_missing_as_default = false, settings = {frequency = "none", size = "none", richness = "none"}},
          decorative = {treat_missing_as_default = false, settings = {frequency = "none", size = "none", richness="none"}}}
    settings.water = "none"
    settings.starting_area = "none"
    settings.peaceful_mode = true
    settings.cliff_settings = {cliff_elevation_0 = 0, cliff_elevation_interval = 0, name = "cliff"}
    game.create_surface(nf_surface_name, settings)
  end
  log ("updating tiles on surface "..surface.name)
  local nf_surface = game.surfaces[nf_surface_name]
  for chunk in surface.get_chunks() do
    if not nf_surface.is_chunk_generated({x=chunk.x, y=chunk.y}) then
      nf_surface.request_to_generate_chunks({x=chunk.x*32, y=chunk.y*32}, 0)
    end
    nf_surface.force_generate_chunk_requests()
    local tiles = {}
    local floor_tiles = {}
    for x = (chunk.x*32), (chunk.x*32+31) do
      for y = (chunk.y*32), (chunk.y*32+31) do
        local tile = surface.get_tile(x, y)        
        if tile.collides_with("ground-tile") then
          local nf_tile = nf_surface.get_tile(x, y)
          table.insert (tiles, {name=nf_tile.name, position = {x=x,y=y}})
          local tile_prototype = tile.prototype
          if tile_prototype and tile_prototype.layer >= 60 then -- player placed floors are layer 60 upwards            
            table.insert (floor_tiles, {name=tile.name, position = {x=x,y=y}})
          end
        end
      end
    end
    -- setting nf_surface tiles before covering the floor ensures mining concrete reveals the correct surface
    surface.set_tiles(tiles)
    surface.set_tiles(floor_tiles)  
    -- nf_surface.delete_chunk({x=chunk.x*32, y=chunk.y*32})
  end
  log ("cleaning up")
  game.delete_surface(nf_surface_name)

  for _,force in pairs(game.forces) do
    force.clear_chart()
  end
  log ("complete")
end
I turned it into a tiny mod automatically running the update as migration script for testing.
WorldGen_Update_0.0.1.zip
(1.72 KiB) Downloaded 120 times

Re: Regenerate map under existing factory, any ideas?

Posted: Wed Jan 02, 2019 9:20 am
by darkfrei
Optera wrote: Wed Jan 02, 2019 7:05 am Another improvement would be to call game.delete_surface(nf_surface_name) once the script is done to reduce save game bloat from additional surfaces.
Deleting the whole surface at the end you might save some performance by omitting delete_chunk in the loop. Depends on how delete_surface and delete_chunk operate though. From my limited testing it seems faster to leave generated chunks and delete the complete surface as last step.
Deleting of whole empty surface needs another 15 minutes (on my save file), it's huge lag and it looks faster without it.

Re: Regenerate map under existing factory, any ideas?

Posted: Wed Jan 02, 2019 10:16 am
by Optera
It was the exact opposite for me regenerating this map:
2019-01-01-21-19-30-1592799.png
2019-01-01-21-19-30-1592799.png (494.68 KiB) Viewed 1514 times
Perhaps your PC started swapping to disk. With my changes the script took over 9GB RAM during conversion.
Afterwards it even reduced Memory usage for this save from 6.4GB to 6.2GB. Probably since it removed a lot of foliage.