Regenerate map under existing factory, any ideas?

Anything that prevents you from playing the game properly. Do you have issues playing for the game, downloading it or successfully running it on your computer? Let us know here.
User avatar
Optera
Smart Inserter
Smart Inserter
Posts: 2920
Joined: Sat Jun 11, 2016 6:41 am
Contact:

Re: Regenerate map under existing factory, any ideas?

Post 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 89 times
User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2905
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: Regenerate map under existing factory, any ideas?

Post 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.
User avatar
Optera
Smart Inserter
Smart Inserter
Posts: 2920
Joined: Sat Jun 11, 2016 6:41 am
Contact:

Re: Regenerate map under existing factory, any ideas?

Post 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 1222 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.
Post Reply

Return to “Technical Help”