Regenerate map under existing factory, any ideas?
Regenerate map under existing factory, any ideas?
I have reasonably sized base (360 hours playtime, 1k SPM, 1 rocket/min, ~8000 rockets launched) started on 0.15 map. Biters present on a map, normal settings.
Since change to 0.16 new chunks are generated by different algorithm so map looks inconsistent. But I used to it, to some degree. In 0.17 map generating will likely change again.
I don't want to spend another ~300 hours of gameplay to build a new base of similar size on a new 0.17 map. And I still like to expand existing base.
I wonder is it possible to destroy whole map, while keeping structures, and communications intact, and have it regenerated whole?
I understand that water areas and all mineral deposits will move, and at some areas cliffs might appear, but fixing my base after such "disaster" looks much more interesting for me, comparing to fresh start from scratch.
Empty explored chunks of map can be easily destroyed by mod, and then regenerated by game as new. But is it possible to destroy terrain in a chunk without affecting other structures? Or to mark all chunks "needed to be map generated"? For sample, when I manually shoot from an artillery cannon to a maximum distance, map is likely generated "on a fly" under flying cannon shell. Is it possible to use same mechanic, by marking whole map for regeneration?
Since change to 0.16 new chunks are generated by different algorithm so map looks inconsistent. But I used to it, to some degree. In 0.17 map generating will likely change again.
I don't want to spend another ~300 hours of gameplay to build a new base of similar size on a new 0.17 map. And I still like to expand existing base.
I wonder is it possible to destroy whole map, while keeping structures, and communications intact, and have it regenerated whole?
I understand that water areas and all mineral deposits will move, and at some areas cliffs might appear, but fixing my base after such "disaster" looks much more interesting for me, comparing to fresh start from scratch.
Empty explored chunks of map can be easily destroyed by mod, and then regenerated by game as new. But is it possible to destroy terrain in a chunk without affecting other structures? Or to mark all chunks "needed to be map generated"? For sample, when I manually shoot from an artillery cannon to a maximum distance, map is likely generated "on a fly" under flying cannon shell. Is it possible to use same mechanic, by marking whole map for regeneration?
Re: Regenerate map under existing factory, any ideas?
At least you can delete generated chunks which are still empty (without buildings of you)
https://mods.factorio.com/mod/DeleteEmptyChunks
https://mods.factorio.com/mod/DeleteEmptyChunks
Re: Regenerate map under existing factory, any ideas?
Yes I know about that and another similar but older mods.
But question is about replacing whole map.
I suppose it might be done in LUA, by telling to engine that map need to be regenerated chunk by chunk.
Mentioned above mod also iterate all chunks, checking some conditions, and in the end deleting some chunks. After that deleted pieces getting regenerated by game engine.
In my case deleting chunks probably will not work, since player structures are also store there, are they? Or not?
But question is about replacing whole map.
I suppose it might be done in LUA, by telling to engine that map need to be regenerated chunk by chunk.
Mentioned above mod also iterate all chunks, checking some conditions, and in the end deleting some chunks. After that deleted pieces getting regenerated by game engine.
In my case deleting chunks probably will not work, since player structures are also store there, are they? Or not?
Re: Regenerate map under existing factory, any ideas?
I believe they are. Does anyone know if it would be possible to store the contents of a chunk, delete it, regenerate it, and restore the contents (possibly landfilling/removing trees/cliffs) via mod? It seems like something that should be possible but I wouldn't know.Dixi wrote: ↑Sun Dec 30, 2018 2:04 pm Yes I know about that and another similar but older mods.
But question is about replacing whole map.
I suppose it might be done in LUA, by telling to engine that map need to be regenerated chunk by chunk.
Mentioned above mod also iterate all chunks, checking some conditions, and in the end deleting some chunks. After that deleted pieces getting regenerated by game engine.
In my case deleting chunks probably will not work, since player structures are also store there, are they? Or not?
There are 10 types of people: those who get this joke and those who don't.
Re: Regenerate map under existing factory, any ideas?
That is an interesting option but not the thing I'm looking for.
I want to keep existing base, not to get in a new world, while keeping research and full pockets.
Are you sure that engine creates map only on empty chunks?
In API calls there are methods
request_to_generate_chunks(position, radius)
force_generate_chunk_requests()
set_chunk_generated_status(position, status)
I wonder what will happen if one calls
request_to_generate_chunks({0,0}, 1000)
Will it wipe the map and generate new or only terrain will regenerate, as I want?
I can't find chunk structure description. I afraid, that that it's actually C++ game data, that can be referenced from LUA calls, and only limited methods are available to us.
Update.
So far results were .... umm ... unexpected.
/c game.player.surface.request_to_generate_chunks({0,0}, 1000)
Freezes the game and crushed: game, steam, web browser. Probably, because it tried to allocate too much RAM.
Smaller request
/c game.player.surface.request_to_generate_chunks({0,0}, 100)
drops FPS/UPS to 3 for a minute. When operation was complete, nothing changes.
It seems that map on chunks with player owned structures are not generated by above call.
Re: Regenerate map under existing factory, any ideas?
It's a bit of a guess but I think you might need to set status of all chunks first.
Calling just generate will check they are there already and skip them.
Setting them all to defines.chunk_generated_status.nothing might cause some reaction - I did not try so it might do nothing as well
Calling just generate will check they are there already and skip them.
Setting them all to defines.chunk_generated_status.nothing might cause some reaction - I did not try so it might do nothing as well
Re: Regenerate map under existing factory, any ideas?
Ohh, then you can try https://mods.factorio.com/mod/nicefill, it makes new generated hidden map surface and when you place landfill, it takes tiles from hidden surface and places correctly and smooth.
So if your surface is "nauvis" then hidden surface will be "NiceFill_nauvis" and you can make reading from one surface and rewrite chunks on your surface.
Re: Regenerate map under existing factory, any ideas?
I've checked NiceFill mod LUA code. I understand how he creates a new surface and calls map generator to create terrain chunks there, but I don't understand how to copy chunks (or tiles) from there to primary surface. In NiceFill that method might be a little complicated since he wants to copy only "landiffled" tiles, and sometimes 1-2 tiles around them for terrain blending or to make land-water borders looks correctly.
Re: Regenerate map under existing factory, any ideas?
I was thinking at some point about adding a "cleanup" function to NiceFill, that would traverse chunks and fix inconsistent ground texture, and i might actually do it now that somebody actually has use for it.darkfrei wrote: ↑Mon Dec 31, 2018 10:24 am Ohh, then you can try https://mods.factorio.com/mod/nicefill, it makes new generated hidden map surface and when you place landfill, it takes tiles from hidden surface and places correctly and smooth.
So if your surface is "nauvis" then hidden surface will be "NiceFill_nauvis" and you can make reading from one surface and rewrite chunks on your surface.
There is however a problem of foliage, aka decorations that NiceFill currently ignores. I need to think about it.
Re: Regenerate map under existing factory, any ideas?
Do you mean that copying just tiles or whole chunks from new generated surface to original "nauvis" is not enough, and it won't make map "like a new"? "foliage, aka decorations" - are they additional objects on a map? Are they like player structures, attached to some tiles?staviq wrote: ↑Mon Dec 31, 2018 11:10 am I was thinking at some point about adding a "cleanup" function to NiceFill, that would traverse chunks and fix inconsistent ground texture, and i might actually do it now that somebody actually has use for it.
There is however a problem of foliage, aka decorations that NiceFill currently ignores. I need to think about it.
Re: Regenerate map under existing factory, any ideas?
Useful links:
https://lua-api.factorio.com/latest/LuaGameScript.html
https://lua-api.factorio.com/latest/Lua ... rator.html
https://lua-api.factorio.com/latest/LuaSurface.html
Here is the code that you looking for:
Before: After:
https://lua-api.factorio.com/latest/LuaGameScript.html
https://lua-api.factorio.com/latest/Lua ... rator.html
https://lua-api.factorio.com/latest/LuaSurface.html
Here is the code that you looking for:
code
It makes new hidden map surface, copy settings from old surface, than replaces your map with new generated tiles.Before: After:
Last edited by darkfrei on Mon Dec 31, 2018 3:53 pm, edited 2 times in total.
Re: Regenerate map under existing factory, any ideas?
Optimized code, needs much more time, but works with megabases.
Example:
I have one 500 hours long save game from 0.15, save file is about 92 MB, it has 96469 chunks and need up to about 14.7 GB of memory. It was ready in 1837 seconds or about 30 minutes.
Before: After:
Code: Select all
/c
log ('start')
local surface = game.player.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 ('hidden map is created')
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 = {}
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}})
end
end
end
surface.set_tiles(tiles)
nf_surface.delete_chunk({x=chunk.x*32, y=chunk.y*32})
end
log ('complete')
I have one 500 hours long save game from 0.15, save file is about 92 MB, it has 96469 chunks and need up to about 14.7 GB of memory. It was ready in 1837 seconds or about 30 minutes.
Before: After:
Last edited by darkfrei on Mon Dec 31, 2018 3:50 pm, edited 1 time in total.
Re: Regenerate map under existing factory, any ideas?
Yes this code works. But it does not moves whole player made structures to a new map. It only replacing old terrain types with new, without any changes to geography and ore deposits. As staviq correctly mentioned, new copied terrain will looks really flat and lifeless, since we do not copy foliage and other decorations.
It seems to me that task of coping existing base to a new map is more complicated then it was on first glance.
If I will not find another solution to move existing base to a new map, in the end, idea of NewGamePlus mod might be useful. Fill whole inventory with nuclear plant, some miners/smelters, factories, bots, and start on a new map with existing research tree. I only doubt that my pockets will carry enough stuff. Need to check NewGamePlus forum part, to see if anyone already made "shopping list" to fill my inventory most optimal way.
It seems to me that task of coping existing base to a new map is more complicated then it was on first glance.
If I will not find another solution to move existing base to a new map, in the end, idea of NewGamePlus mod might be useful. Fill whole inventory with nuclear plant, some miners/smelters, factories, bots, and start on a new map with existing research tree. I only doubt that my pockets will carry enough stuff. Need to check NewGamePlus forum part, to see if anyone already made "shopping list" to fill my inventory most optimal way.
Last edited by Dixi on Mon Dec 31, 2018 6:17 pm, edited 1 time in total.
Re: Regenerate map under existing factory, any ideas?
Well, I've been meaning to learn lua anyway...
There are 10 types of people: those who get this joke and those who don't.
Re: Regenerate map under existing factory, any ideas?
That's a nice way to update old saves to new map generator.darkfrei wrote: ↑Mon Dec 31, 2018 2:16 pm Optimized code, needs much more time, but works with megabases.
Code: Select all
/c log ('start') local surface = game.player.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 ('hidden map is created') 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 = {} 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}}) end end end surface.set_tiles(tiles) nf_surface.delete_chunk({x=chunk.x*32, y=chunk.y*32}) end log ('complete')
Would be even nicer though if you added a check so it doesn't remove all concrete.
My Mods: mods.factorio.com
Re: Regenerate map under existing factory, any ideas?
I think concrete is located in same layer as decorative foliage. And listed above code does not work with it - it only replace old tiles with new, according to changed map generator. So it's mostly cosmetic change.
Re: Regenerate map under existing factory, any ideas?
We have also hidden tiles under concrete, that must be replaced, but not the concrete, refined concrete, hazard concrete left and right, refined hazard concrete left and right. And stone path.
Re: Regenerate map under existing factory, any ideas?
Yes, and those hidden tiles must not be replaced with water, otherwise you get destroyed buildings or instant deaths when mining or replacing the concrete.
You can get that effect by using the creative modes magic wand to paint concrete over water.
PS:
You might also want to call game.player.force.clear_chart() afterwards so the map is forced to update.
You can get that effect by using the creative modes magic wand to paint concrete over water.
PS:
You might also want to call game.player.force.clear_chart() afterwards so the map is forced to update.
My Mods: mods.factorio.com
Re: Regenerate map under existing factory, any ideas?
Thanks! Hidden surface has no water, water by 'nauvis' will be not overwritten.Optera wrote: ↑Tue Jan 01, 2019 6:29 am Yes, and those hidden tiles must not be replaced with water, otherwise you get destroyed buildings or instant deaths when mining or replacing the concrete.
You can get that effect by using the creative modes magic wand to paint concrete over water.
PS:
You might also want to call game.player.force.clear_chart() afterwards so the map is forced to update.
The clear_chart must help with memory leak. Maybe unchart_chunk(position, surface) https://lua-api.factorio.com/latest/Lua ... hart_chunk