[MOD 0.14] Alien Biomes

Topics and discussion about specific mods
Post Reply
User avatar
Earendel
Factorio Staff
Factorio Staff
Posts: 711
Joined: Sun Nov 23, 2014 11:57 am
Contact:

Re: [MOD 0.14] Alien Biomes

Post by Earendel »

gctypo wrote:
DoxxMulder wrote:So I've been using the beta version the mod you've posted in here and I've noticed severe performance issues. I recently upgraded to a 1080ti so I was really blindsided when I can run Doom at 60fps but not factorio. I think it has to do with the sheer number of decoratives placed by this mod. I didn't have the same issues with my old card, but I also used to run sprite resolution at normal instead of high.

I don't really want to turn down the graphics options, does anyone have any tips to increase performance? I've been getting ~37fps/ups fully zoomed out.

EDIT: nevermind, didn't realize I was two versions behind, getting 60/60 now
I have similar issues with 0.3.8. Zooming out causes my FPS to very quickly drop to under 10, going all the way down to 5 at full view. I'm using a much older card though, a GTX 760, but I get a full 60 FPS when the mod is disabled, regardless of zoom.
Do you get any drops if you use the disable decoratives display option?

gctypo
Manual Inserter
Manual Inserter
Posts: 2
Joined: Thu Feb 01, 2018 11:40 am
Contact:

Re: [MOD 0.14] Alien Biomes

Post by gctypo »

Earendel wrote:
gctypo wrote:
DoxxMulder wrote:So I've been using the beta version the mod you've posted in here and I've noticed severe performance issues. I recently upgraded to a 1080ti so I was really blindsided when I can run Doom at 60fps but not factorio. I think it has to do with the sheer number of decoratives placed by this mod. I didn't have the same issues with my old card, but I also used to run sprite resolution at normal instead of high.

I don't really want to turn down the graphics options, does anyone have any tips to increase performance? I've been getting ~37fps/ups fully zoomed out.

EDIT: nevermind, didn't realize I was two versions behind, getting 60/60 now
I have similar issues with 0.3.8. Zooming out causes my FPS to very quickly drop to under 10, going all the way down to 5 at full view. I'm using a much older card though, a GTX 760, but I get a full 60 FPS when the mod is disabled, regardless of zoom.
Do you get any drops if you use the disable decoratives display option?
I tried to test this again today and for some reason couldn't replicate the lag. It just went away. It's fixed I guess.

wvlad
Fast Inserter
Fast Inserter
Posts: 215
Joined: Thu Jul 13, 2017 9:55 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by wvlad »

Hi, after updating I can't load my 0.15 save: "Reached id limit for noise-layer. The game can't contain more than 255 instances of this prototype due to hardcoded limits of the engine."

Though starting a new game works ok.

Without Alien Biomes enabled the save is loaded with no errors.
I have only Angel Infinite ores mod adding tiles enabled, disabling it doesn't affect things.
Checking "remove obsolete tiles" option doesn't help.

Save: https://www.dropbox.com/s/dqbdw3ik38qt471/u2.zip?dl=1

Please help me otherwise I can't migrate to 0.16... :(

User avatar
Earendel
Factorio Staff
Factorio Staff
Posts: 711
Joined: Sun Nov 23, 2014 11:57 am
Contact:

Re: [MOD 0.14] Alien Biomes

Post by Earendel »

wvlad wrote:Hi, after updating I can't load my 0.15 save: "Reached id limit for noise-layer. The game can't contain more than 255 instances of this prototype due to hardcoded limits of the engine."

Though starting a new game works ok.

Without Alien Biomes enabled the save is loaded with no errors.
I have only Angel Infinite ores mod adding tiles enabled, disabling it doesn't affect things.
Checking "remove obsolete tiles" option doesn't help.

Save: https://www.dropbox.com/s/dqbdw3ik38qt471/u2.zip?dl=1

Please help me otherwise I can't migrate to 0.16... :(
Noise layers aren't specific to tiles, anything that is autoplaced can have them.
What happens ij you load the save without alien biomes, save that under a new name, activate alien biomes, then load the new save?

wvlad
Fast Inserter
Fast Inserter
Posts: 215
Joined: Thu Jul 13, 2017 9:55 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by wvlad »

I'll check that.

As I understand there is no way to preserve existing terrain but make it smoothly connect with new areas? So I have to regenerate anyway.

Is there a way to regenerate with more water on existing map? Before update I had much bigger water areas.

wvlad
Fast Inserter
Fast Inserter
Posts: 215
Joined: Thu Jul 13, 2017 9:55 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by wvlad »

So I tweaked regeneration to not break my buildings with water, feel free to use it in the mod if you decide so.

Code: Select all

local function rebuild_nauvis()

  local nauvis_name = "nauvis"
  local nauvis_copy_name = "nauvis-copy"
  local chunksize = 32

  if not game.surfaces[nauvis_copy_name] then
    game.create_surface(nauvis_copy_name)
  end

  local nauvis = game.surfaces[nauvis_name]
  local nauvis_copy = game.surfaces[nauvis_copy_name]

  local function chunk_key(x,y) return x*1000000000 + y end
  local chunks = {}
  for chunk in nauvis.get_chunks() do
    chunks[chunk_key(chunk.x,chunk.y)] = chunk
  end

  local deleted_chunks = { }
  -- make the new chunks
  for _, chunk in pairs(chunks) do
    local count = 0
    count = nauvis.count_entities_filtered{
        area = {{chunk.x * 32 - 12, chunk.y * 32 - 12}, {chunk.x * 32 + 32 + 12, chunk.y * 32 + 32 + 12}},
        force = game.forces["player"],
        limit = 1
      }
    if count > 0 then
      -- there are forces here so copy tiles
      nauvis_copy.request_to_generate_chunks({x = chunk.x * chunksize, y = chunk.y * chunksize}, 0)
    else
      -- no forces, just delete and remake
      nauvis.delete_chunk(chunk)
      chunks[_] = nil
      deleted_chunks[_] = chunk
    end
  end

  nauvis_copy.force_generate_chunk_requests()

  -- copy tiles from generated copy to main
  local water_tiles = {["water-green"] = true,["deepwater-green"] = true,["water"] = true,["deepwater"] = true}
  local tiles = {}
  for _, chunk in pairs(chunks) do
    for y = 0, 31, 1 do
      for x = 0, 31, 1 do
        local position = {
          x = chunk.x * chunksize + x,
          y = chunk.y * chunksize + y
        }
        local tile_name = nauvis_copy.get_tile(position.x, position.y).name
        local copy = true
	if (water_tiles[tile_name]) then -- don't copy water over entities
	    local count = 0
	    count = nauvis.count_entities_filtered{
	        area = {{x - math.random(7,9), y - math.random(7,9)}, {x + math.random(7,9), y + math.random(7,9)}},
	        force = game.forces["player"],
	        limit = 1
	      }
	    if count > 0 then                 
		--tile_name = "mineral-tan-dirt-1"
                tile_name = nil
	     end
	end
        if tile_name then table.insert(tiles, {name = tile_name, position = position}) end
      end
    end
  end
  nauvis.set_tiles(tiles, true)

  -- nauvis.regenerate_decorative() -- does not work properly, everything is at highest density

  game.delete_surface(nauvis_copy)

  -- done, now smooth border tiles


  local step = 0 --doesn't work until next tick?
  local function continue(event)
  if step >= 10 then return end 
  step = step + 1
  if step == 5 then    
       --only chunks with living neighbours participiate    
      for _, chunk in pairs(deleted_chunks) do
          if not chunks[chunk_key(chunk.x-1,chunk.y)]
           and not chunks[chunk_key(chunk.x+1,chunk.y)]
           and not chunks[chunk_key(chunk.x,chunk.y-1)]
           and not chunks[chunk_key(chunk.x,chunk.y+1)]
           and not chunks[chunk_key(chunk.x-1,chunk.y-1)]
           and not chunks[chunk_key(chunk.x+1,chunk.y+1)]
           then
             deleted_chunks[_] = nil
           else -- generate them so can edit
             nauvis.request_to_generate_chunks({x = chunk.x * chunksize+1, y = chunk.y * chunksize+1}, 0)
           end
      end
    
      nauvis.force_generate_chunk_requests()
      return
  end
  if step ~= 10 then return end 

  -- copy border tiles from living neighbours over generated water tiles
  local tiles = {}
  for _, chunk in pairs(deleted_chunks) do
    
    log("Processing deleted chunk " .. chunk.x .. "," .. chunk.y ..", generated:" .. tostring(nauvis.is_chunk_generated({chunk.x,chunk.y})))
    for v = 1, 6, 1 do -- 6 neighbours
    	local cx
    	local cy
    	local min = 0
            local max = 31
            if v == 1 then
                cx = chunk.x
                cy = chunk.y - 1
            elseif v == 2 then
                cx = chunk.x
                cy = chunk.y + 1
            elseif v == 3 then
                cx = chunk.x - 1
                cy = chunk.y
            elseif v == 4 then
                cx = chunk.x + 1
                cy = chunk.y
            elseif v == 5 then
                cx = chunk.x - 1
                cy = chunk.y - 1
                min = 1
                max = 1
            elseif v == 6 then
                cx = chunk.x + 1
                cy = chunk.y + 1
                min = 1
                max = 1
            end
        local chunkFromPos = {x = cx, y = cy}
        -- if there it's a living neightbour
        if (nauvis.is_chunk_generated(chunkFromPos)) and chunks[chunk_key(chunkFromPos.x, chunkFromPos.y)] then
            for m = min, max, 1 do
            local count = math.random(0,3)
            if count~=0 then 
                local position = { x = chunk.x * chunksize, y = chunk.y * chunksize }
                local ox = 0
                local oy = 0
                if v == 1 then
                    position.x = position.x + m
                    position.y = position.y + 0
                    oy = -1
                elseif v == 2 then
                    position.x = position.x + m
                    position.y = position.y + chunksize - 1
                    oy = 1
                elseif v == 3 then
                    position.x = position.x + 0
                    position.y = position.y + m
                    ox = -1
                elseif v == 4 then
                    position.x = position.x + chunksize - 1
                    position.y = position.y + m
                    ox = 1
                elseif v == 5 then
                    position.x = position.x
                    position.y = position.y
                    ox = -1
                    oy = -1
                elseif v == 6 then
                    position.x = position.x + chunksize - 1
                    position.y = position.y + chunksize - 1
                    ox = 1
                    oy = 1
                end
                local position_from = { x = position.x + ox, y = position.y + oy }
                for c = 0,count-1,1 do
                    local dest = { x = position.x - ox * c, y = position.y - oy * c}
                    local current_name = nauvis.get_tile(dest.x, dest.y).name
                    if water_tiles[current_name] then
            	        local new_name = nauvis.get_tile(position_from.x, position_from.y).name
                        if not water_tiles[new_name] then
                               log("Copying tile from " .. serpent.block(position_from) .. " " .. new_name .." to " .. serpent.block(dest) .. " " .. current_name)
                		       table.insert(tiles, {name = new_name, position = dest})
                        end
                    end
                end
            end
          end
        end
    end
  end
  nauvis.set_tiles(tiles, true)
  game.print("Nauvis Regeneration Complete")
  end
  script.on_event(defines.events.on_tick, continue)
end
And also I used this code to increase water:

Code: Select all

local global_bias = 5 -- elevation level
local segmentation_devider = 1.1

local noise = require("noise")
local tne = noise.to_noise_expression 

local function make_basis_noise_function(seed0,seed1,outscale0,inscale0)
  outscale0 = outscale0 or 1
  inscale0 = inscale0 or 1/outscale0
  return function(x,y,inscale,outscale)
    return tne{
      type = "function-application",
      function_name = "factorio-basis-noise",
      arguments = {
        x = tne(x),
        y = tne(y),
        seed0 = tne(seed0),
        seed1 = tne(seed1),
        input_scale = tne((inscale or 1) * inscale0),
        output_scale = tne((outscale or 1) * outscale0)
      }
    }
  end
end


-- Returns a multioctave noise function where each octave's noise is multiplied by some other noise
-- by default 'some other noise' is the basis noise at 17x lower frequency,
-- normalized around 0.5 and clamped between 0 and 1
local function make_multioctave_modulated_noise_function(params)
  local seed0 = params.seed0 or 1
  local seed1 = params.seed1 or 1
  local octave_count = params.octave_count or 1
  local octave0_output_scale = params.octave0_output_scale or 1
  local octave0_input_scale = params.octave0_input_scale or 1
  local octave_output_scale_multiplier = params.octave_output_scale_multiplier or 2
  local octave_input_scale_multiplier = params.octave_input_scale_multiplier or 1/2
  local basis_noise_function = params.basis_noise_function or make_basis_noise_function(seed0, seed1)
  local modulation_noise_function = params.modulation_noise_function or function(x,y)
    return noise.clamp(basis_noise_function(x,y)+0.5, 0, 1)
  end
  -- input scale of modulation relative to each octave's base input scale
  local mris = params.modulation_relative_input_scale or 1/17

  return function(x,y)
    local outscale = octave0_output_scale
    local inscale = octave0_input_scale
    local result = 0

    for i=1,octave_count do
      local noise = basis_noise_function(x*inscale, y*inscale)
      local modulation = modulation_noise_function(x*(inscale*mris), y*(inscale*mris))
      result = result + (outscale * noise * modulation)

      outscale = outscale * octave_output_scale_multiplier
      inscale = inscale * octave_input_scale_multiplier
    end

    return result
  end
end

local function make_multioctave_noise_function(seed0,seed1,octaves,octave_output_scale_multiplier,octave_input_scale_multiplier,output_scale0,input_scale0)
  octave_output_scale_multiplier = octave_output_scale_multiplier or 2
  octave_input_scale_multiplier = octave_input_scale_multiplier or 1 / octave_output_scale_multiplier
  return function(x,y,inscale,outscale)
    return tne{
      type = "function-application",
      function_name = "factorio-multioctave-noise",
      arguments = {
        x = tne(x),
        y = tne(y),
        seed0 = tne(seed0),
        seed1 = tne(seed1),
        input_scale = tne((inscale or 1) * (input_scale0 or 1)),
        output_scale = tne((outscale or 1) * (output_scale0 or 1)),
        octaves = tne(octaves),
        octave_output_scale_multiplier = tne(octave_output_scale_multiplier),
        octave_input_scale_multiplier = tne(octave_input_scale_multiplier),
      }
    }
  end
end


local function make_split_multioctave_noise_function(seed0,seed1,octaveses,octave_output_scale_multiplier,octave_input_scale_multiplier,output_scale0,input_scale0)
  output_scale0 = output_scale0 or 1
  input_scale0 = input_scale0 or 1
  octave_output_scale_multiplier = octave_output_scale_multiplier or 1
  octave_input_scale_multiplier = octave_input_scale_multiplier or 1
  local funx = {}
  for i=1,#octaveses do
    funx[i] = make_multioctave_noise_function(seed0,seed1,octaveses[i],octave_output_scale_multiplier,octave_input_scale_multiplier,output_scale0,input_scale0)
    output_scale0 = output_scale0 * octave_output_scale_multiplier ^ octaveses[i]
    input_scale0  = input_scale0  * octave_input_scale_multiplier  ^ octaveses[i]
  end
  return funx
end


data:extend({
  {
    type = "noise-expression",
    name = "default-elevation",
    expression = noise.define_noise_function( function(x,y,tile,map)
      local plateau_octaves = 3
      local lf_octaves = 6
      local seg = map.segmentation_multiplier / segmentation_devider
      x = x * seg + 10000 -- Move the point where 'fractal similarity' is obvious off into the boonies
      y = y * seg
      local rdi = tile.tier / 8 -- ridge distance-based influcence
      local high_ridge =  16 + rdi + noise.clamp(rdi, 0, 2) * make_multioctave_noise_function(map.seed, 7, 2, 3)(x,y,1/256,1)
      local low_ridge  = -16 - rdi

      local plateau_noise = make_multioctave_noise_function(map.seed, 9, plateau_octaves, 1/3, 3, 4, 1/128)
      local plateaus = noise.max(make_basis_noise_function(map.seed, 10, 8, 1/1024)(x,y) - 8, 3 - tile.tier)

      local high_freq_noise = make_multioctave_modulated_noise_function{
	seed0 = map.seed,
	seed1 = 11,
	octave_count = 6,
	octave0_output_scale = 1/8,
	octave0_input_scale = 1/4,
	octave_output_scale_multiplier = 2,
	octave_input_scale_multiplier = 1/3,
      }
      local low_freq_noise = make_multioctave_modulated_noise_function{
        seed0 = map.seed,
	seed1 = 8,
	octave_count = lf_octaves,
	octave0_output_scale = 1,
	octave0_input_scale = 1/8,
      }
      local very_low_freq_noise = make_basis_noise_function(map.seed, 9, 20, 1/1024)
      local basis = low_freq_noise(x,y) + very_low_freq_noise(x,y)
      local ridged1 = noise.ridge(basis, low_ridge, high_ridge)
      
      local normal = noise.max(ridged1 + high_freq_noise(x,y), plateaus + plateau_noise(x,y)) + global_bias
      
      -- Multily elevation by low-frequency noise to make hilly and non-hilly areas
      local hill_modulation = noise.clamp(make_multioctave_noise_function(map.seed, 12, 4, 2, 1/3)(x,y,1/256,3/4) - 2, 0.1, 1.0)

      -- Elevation below which hill modulation has no effect.
      -- Set to slightly above the water level so that flat plains don't all become a giant beach/sandbar thing.
      -- To do its job it just has to be lower than the first row of cliffs.
      local hill_modulation_identity = map.finite_water_level + 3
      return noise.min(normal, hill_modulation * (normal - hill_modulation_identity) + hill_modulation_identity)
    end)
  }
})

wvlad
Fast Inserter
Fast Inserter
Posts: 215
Joined: Thu Jul 13, 2017 9:55 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by wvlad »

So disabling-enabling alien biomes worked though I had to regenerate the terrain.

I released a separate mod to adjust water generation in 0.16: https://mods.factorio.com/mod/vlads-sol ... r-like-015

Here is the final version to copy also decoratives except cliffs, though it might run pretty long, a few minutes for me:

Code: Select all

local function rebuild_nauvis()

  local nauvis_name = "nauvis"
  local nauvis_copy_name = "nauvis-copy"
  local chunksize = 32

  if not game.surfaces[nauvis_copy_name] then
    game.create_surface(nauvis_copy_name)
  end

  local nauvis = game.surfaces[nauvis_name]
  local nauvis_copy = game.surfaces[nauvis_copy_name]

  local function chunk_key(x,y) return x*1000000000 + y end
  local chunks = {}
  for chunk in nauvis.get_chunks() do
    chunks[chunk_key(chunk.x,chunk.y)] = chunk
  end

  local deleted_chunks = { }
  -- make the new chunks
  for _, chunk in pairs(chunks) do
    local count = 0
    local area = {{chunk.x * chunksize - 10, chunk.y * chunksize - 10}, {chunk.x * chunksize + chunksize + 9, chunk.y * chunksize + chunksize + 9}}
    count = nauvis.count_entities_filtered{
        area = area,
        force = "player",
        limit = 1
      }

    if count == 0  then
        local enemies = nauvis.count_entities_filtered{
            area = area,
            force = "enemy",
            type="unit-spawner",
            limit = 1
          }
        if enemies > 0 and (
            nauvis.get_pollution(area[1]) > 0 or nauvis.get_pollution(area[2])>0 
                or nauvis.count_entities_filtered{
                    area = {{area[1][1]-chunksize*3,area[1][2]-chunksize*3},{area[2][1]+chunksize*3,area[2][2]+chunksize*3}},
                    force = "player",
                    limit = 1  }>0) then
            count = enemies
        end
    end
    if count > 0 then
      -- there are forces here so copy tiles
      nauvis_copy.request_to_generate_chunks({x = chunk.x * chunksize, y = chunk.y * chunksize}, 0)
      nauvis.destroy_decoratives({{chunk.x * chunksize, chunk.y *chunksize}, {chunk.x * chunksize + chunksize - 1, chunk.y * chunksize + chunksize - 1}})
    else
      -- no forces, just delete and remake
      nauvis.delete_chunk(chunk)
      chunks[_] = nil
      deleted_chunks[_] = chunk
    end
  end

  nauvis_copy.force_generate_chunk_requests()

  -- copy tiles from generated copy to main
  local water_tiles = {["water-green"] = true,["deepwater-green"] = true,["water"] = true,["deepwater"] = true}
  local tiles = {}
  for _, chunk in pairs(chunks) do
    for y = 0, 31, 1 do
      for x = 0, 31, 1 do
        local position = {
          x = chunk.x * chunksize + x,
          y = chunk.y * chunksize + y
        }
        local tile_name = nauvis_copy.get_tile(position.x, position.y).name
        local copy = true
	   if (water_tiles[tile_name]) then -- don't copy water over entities
	    local count = 0
	    count = nauvis.count_entities_filtered{
	        area = {{x - math.random(7,9), y - math.random(7,9)}, {x + math.random(7,9), y + math.random(7,9)}},
	        force = game.forces["player"],
	        limit = 1
	      }
	    if count > 0 then                 
		--tile_name = "mineral-tan-dirt-1"
                tile_name = nil
	     end
    	end
        if tile_name then 
            table.insert(tiles, {name = tile_name, position = position})
            if #tiles > 20480 then
                nauvis.set_tiles(tiles, true) 
                tiles = {}
            end
         end
      end
    end
  end
  if #tiles > 0 then nauvis.set_tiles(tiles, true) end
  
  
    local decoratives = nauvis_copy.find_entities()
    log("Found " .. #decoratives .. " decoratives")
    for _, d in pairs(decoratives) do
        local ok  = d.type ~= "resource" and d.type~="cliff"
        local area = d.selection_box or d.bounding_box
        --log("Copying decorative " .. d.name)
        if (ok and (d.minable or d.destructible or d.type=="cliff") and area) then
         --log("Minable, selection box " .. serpent.block(area))
         area.left_top.x = area.left_top.x - 2
         area.left_top.y = area.left_top.y - 2
         area.right_bottom.x = area.right_bottom.x + 2
         area.right_bottom.y = area.right_bottom.y + 2
          if (nauvis.count_entities_filtered{
            area = area,
            limit = 1,
            force = "player"} > 0) 
           or (nauvis.count_entities_filtered{
            area = area,
            limit = 1,
            force = "enemy"} > 0) then 
                ok = false
          end
        end
        if ok then
            local options = {
            name=d.name,
            position=d.position,
            direction=d.direction,
            force=d.force,
            graphics_variation=d.graphics_variation,
            bounding_box=d.bounding_box,
            secondary_bounding_box=d.secondary_bounding_box,
            selection_box=d.selection_box,
            secondary_selection_box=d.secondary_selection_box
            }
            if options.type == "cliff" then 
                cliff_orientation=d.cliff_orientation
            end
           if (not nauvis.create_entity(options)) then log("Can't create entity") end
        end
    end
  --nauvis.regenerate_decorative({"cliff", "small-cliff"})
  -- nauvis.regenerate_decorative() -- does not work properly, everything is at highest density

  game.delete_surface(nauvis_copy)

  -- done, now smooth border tiles


  local step = 0 --doesn't work until next tick?
  local function continue(event)
  if step >= 10 then return end 
  step = step + 1
  if step == 5 then    
       --only chunks with living neighbours participiate    
      for _, chunk in pairs(deleted_chunks) do
          if not chunks[chunk_key(chunk.x-1,chunk.y)]
           and not chunks[chunk_key(chunk.x+1,chunk.y)]
           and not chunks[chunk_key(chunk.x,chunk.y-1)]
           and not chunks[chunk_key(chunk.x,chunk.y+1)]
           and not chunks[chunk_key(chunk.x-1,chunk.y-1)]
           and not chunks[chunk_key(chunk.x+1,chunk.y+1)]
           then
             deleted_chunks[_] = nil
           else -- generate them so can edit
             nauvis.request_to_generate_chunks({x = chunk.x * chunksize+1, y = chunk.y * chunksize+1}, 0)
           end
      end
    
      nauvis.force_generate_chunk_requests()
      return
  end
  if step ~= 10 then return end 

  -- copy border tiles from living neighbours over generated water tiles
  local tiles = {}
  for _, chunk in pairs(deleted_chunks) do
    
    log("Processing deleted chunk " .. chunk.x .. "," .. chunk.y ..", generated:" .. tostring(nauvis.is_chunk_generated({chunk.x,chunk.y})))
    for v = 1, 6, 1 do -- 6 neighbours
    	local cx
    	local cy
    	local min = 0
            local max = 31
            if v == 1 then
                cx = chunk.x
                cy = chunk.y - 1
            elseif v == 2 then
                cx = chunk.x
                cy = chunk.y + 1
            elseif v == 3 then
                cx = chunk.x - 1
                cy = chunk.y
            elseif v == 4 then
                cx = chunk.x + 1
                cy = chunk.y
            elseif v == 5 then
                cx = chunk.x - 1
                cy = chunk.y - 1
                min = 1
                max = 1
            elseif v == 6 then
                cx = chunk.x + 1
                cy = chunk.y + 1
                min = 1
                max = 1
            end
        local chunkFromPos = {x = cx, y = cy}
        -- if there it's a living neightbour
        if (nauvis.is_chunk_generated(chunkFromPos)) and chunks[chunk_key(chunkFromPos.x, chunkFromPos.y)] then
            for m = min, max, 1 do
            local count = math.random(0,2)
            if count~=0 then 
                local position = { x = chunk.x * chunksize, y = chunk.y * chunksize }
                local ox = 0
                local oy = 0
                if v == 1 then
                    position.x = position.x + m
                    position.y = position.y + 0
                    oy = -1
                elseif v == 2 then
                    position.x = position.x + m
                    position.y = position.y + chunksize - 1
                    oy = 1
                elseif v == 3 then
                    position.x = position.x + 0
                    position.y = position.y + m
                    ox = -1
                elseif v == 4 then
                    position.x = position.x + chunksize - 1
                    position.y = position.y + m
                    ox = 1
                elseif v == 5 then
                    position.x = position.x
                    position.y = position.y
                    ox = -1
                    oy = -1
                elseif v == 6 then
                    position.x = position.x + chunksize - 1
                    position.y = position.y + chunksize - 1
                    ox = 1
                    oy = 1
                end
                local position_from = { x = position.x + ox, y = position.y + oy }
                for c = 0,count-1,1 do
                    local dest = { x = position.x - ox * c, y = position.y - oy * c}
                    local current_name = nauvis.get_tile(dest.x, dest.y).name
                    if water_tiles[current_name] then
            	        local new_name = nauvis.get_tile(position_from.x, position_from.y).name
                        if not water_tiles[new_name] then
                               log("Copying tile from " .. serpent.block(position_from) .. " " .. new_name .." to " .. serpent.block(dest) .. " " .. current_name)
                		       table.insert(tiles, {name = new_name, position = dest})
                        end
                    end
                end
            end
          end
        end
    end
  end
  nauvis.set_tiles(tiles, true)
  game.print("Nauvis Regeneration Complete")
  end
  script.on_event(defines.events.on_tick, continue)
end

SHADOW13
Burner Inserter
Burner Inserter
Posts: 12
Joined: Tue Apr 25, 2017 12:02 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by SHADOW13 »

seems not to be compatible with AsphaltRoads mods any more, getting start error:
Error in assignId, tile with name 'Arci-marking-yellow-dl-straight-vertical' does not exists
Source: Arci-marking-yellow-dl-straight-horizontal (tile)
as soon as I disable either mod, it loads fine

User avatar
DarkyPupu
Fast Inserter
Fast Inserter
Posts: 109
Joined: Sun Jun 04, 2017 4:46 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by DarkyPupu »

I've an annoying problem, i have (among others :D ) Alien Biomes, Extra Floors and Asphalt roads installed, which brings me close to the 255 limit (i have 253).

I would like to remove Extra Floors but when i do, i cannot load the save anymore becaure the tiles id go above 255.
On that save, same if i remove Asphalt road or even if i enable the option in alien biomes to remove obsolete tiles.

How can it be that i go above 255 when i remove tiles ? :?

I didn't try to remove the Alien Biomes mod to not delete all existing chunks parts. I would like to keep AB and remove EF.

Any ideas ?

User avatar
Earendel
Factorio Staff
Factorio Staff
Posts: 711
Joined: Sun Nov 23, 2014 11:57 am
Contact:

Re: [MOD 0.14] Alien Biomes

Post by Earendel »

DarkyPupu wrote:I've an annoying problem, i have (among others :D ) Alien Biomes, Extra Floors and Asphalt roads installed, which brings me close to the 255 limit (i have 253).

I would like to remove Extra Floors but when i do, i cannot load the save anymore becaure the tiles id go above 255.
On that save, same if i remove Asphalt road or even if i enable the option in alien biomes to remove obsolete tiles.

How can it be that i go above 255 when i remove tiles ? :?

I didn't try to remove the Alien Biomes mod to not delete all existing chunks parts. I would like to keep AB and remove EF.

Any ideas ?
Yeah that's weird. I think when it does the tile migration phase Factorio tries to load all new and old tiles somehow? I'd call it a Vanilla bug but I'm not sure bug is the right word for it. I haven't checked to see if the devs already have a bug report for it.

Anyway, what I did is remove alien biomes, load the save, save it under a new game, add alien biomes again, reload the new save, regenerate the terrain and endure all the concrete disappearing.
wvlad wrote:So I tweaked regeneration to not break my buildings with water, feel free to use it in the mod if you decide so.

Code: Select all

local function rebuild_nauvis()

  local nauvis_name = "nauvis"
  local nauvis_copy_name = "nauvis-copy"
  local chunksize = 32

  if not game.surfaces[nauvis_copy_name] then
    game.create_surface(nauvis_copy_name)
  end

  local nauvis = game.surfaces[nauvis_name]
  local nauvis_copy = game.surfaces[nauvis_copy_name]

  local function chunk_key(x,y) return x*1000000000 + y end
  local chunks = {}
  for chunk in nauvis.get_chunks() do
    chunks[chunk_key(chunk.x,chunk.y)] = chunk
  end

  local deleted_chunks = { }
  -- make the new chunks
  for _, chunk in pairs(chunks) do
    local count = 0
    count = nauvis.count_entities_filtered{
        area = {{chunk.x * 32 - 12, chunk.y * 32 - 12}, {chunk.x * 32 + 32 + 12, chunk.y * 32 + 32 + 12}},
        force = game.forces["player"],
        limit = 1
      }
    if count > 0 then
      -- there are forces here so copy tiles
      nauvis_copy.request_to_generate_chunks({x = chunk.x * chunksize, y = chunk.y * chunksize}, 0)
    else
      -- no forces, just delete and remake
      nauvis.delete_chunk(chunk)
      chunks[_] = nil
      deleted_chunks[_] = chunk
    end
  end

  nauvis_copy.force_generate_chunk_requests()

  -- copy tiles from generated copy to main
  local water_tiles = {["water-green"] = true,["deepwater-green"] = true,["water"] = true,["deepwater"] = true}
  local tiles = {}
  for _, chunk in pairs(chunks) do
    for y = 0, 31, 1 do
      for x = 0, 31, 1 do
        local position = {
          x = chunk.x * chunksize + x,
          y = chunk.y * chunksize + y
        }
        local tile_name = nauvis_copy.get_tile(position.x, position.y).name
        local copy = true
	if (water_tiles[tile_name]) then -- don't copy water over entities
	    local count = 0
	    count = nauvis.count_entities_filtered{
	        area = {{x - math.random(7,9), y - math.random(7,9)}, {x + math.random(7,9), y + math.random(7,9)}},
	        force = game.forces["player"],
	        limit = 1
	      }
	    if count > 0 then                 
		--tile_name = "mineral-tan-dirt-1"
                tile_name = nil
	     end
	end
        if tile_name then table.insert(tiles, {name = tile_name, position = position}) end
      end
    end
  end
  nauvis.set_tiles(tiles, true)

  -- nauvis.regenerate_decorative() -- does not work properly, everything is at highest density

  game.delete_surface(nauvis_copy)

  -- done, now smooth border tiles


  local step = 0 --doesn't work until next tick?
  local function continue(event)
  if step >= 10 then return end 
  step = step + 1
  if step == 5 then    
       --only chunks with living neighbours participiate    
      for _, chunk in pairs(deleted_chunks) do
          if not chunks[chunk_key(chunk.x-1,chunk.y)]
           and not chunks[chunk_key(chunk.x+1,chunk.y)]
           and not chunks[chunk_key(chunk.x,chunk.y-1)]
           and not chunks[chunk_key(chunk.x,chunk.y+1)]
           and not chunks[chunk_key(chunk.x-1,chunk.y-1)]
           and not chunks[chunk_key(chunk.x+1,chunk.y+1)]
           then
             deleted_chunks[_] = nil
           else -- generate them so can edit
             nauvis.request_to_generate_chunks({x = chunk.x * chunksize+1, y = chunk.y * chunksize+1}, 0)
           end
      end
    
      nauvis.force_generate_chunk_requests()
      return
  end
  if step ~= 10 then return end 

  -- copy border tiles from living neighbours over generated water tiles
  local tiles = {}
  for _, chunk in pairs(deleted_chunks) do
    
    log("Processing deleted chunk " .. chunk.x .. "," .. chunk.y ..", generated:" .. tostring(nauvis.is_chunk_generated({chunk.x,chunk.y})))
    for v = 1, 6, 1 do -- 6 neighbours
    	local cx
    	local cy
    	local min = 0
            local max = 31
            if v == 1 then
                cx = chunk.x
                cy = chunk.y - 1
            elseif v == 2 then
                cx = chunk.x
                cy = chunk.y + 1
            elseif v == 3 then
                cx = chunk.x - 1
                cy = chunk.y
            elseif v == 4 then
                cx = chunk.x + 1
                cy = chunk.y
            elseif v == 5 then
                cx = chunk.x - 1
                cy = chunk.y - 1
                min = 1
                max = 1
            elseif v == 6 then
                cx = chunk.x + 1
                cy = chunk.y + 1
                min = 1
                max = 1
            end
        local chunkFromPos = {x = cx, y = cy}
        -- if there it's a living neightbour
        if (nauvis.is_chunk_generated(chunkFromPos)) and chunks[chunk_key(chunkFromPos.x, chunkFromPos.y)] then
            for m = min, max, 1 do
            local count = math.random(0,3)
            if count~=0 then 
                local position = { x = chunk.x * chunksize, y = chunk.y * chunksize }
                local ox = 0
                local oy = 0
                if v == 1 then
                    position.x = position.x + m
                    position.y = position.y + 0
                    oy = -1
                elseif v == 2 then
                    position.x = position.x + m
                    position.y = position.y + chunksize - 1
                    oy = 1
                elseif v == 3 then
                    position.x = position.x + 0
                    position.y = position.y + m
                    ox = -1
                elseif v == 4 then
                    position.x = position.x + chunksize - 1
                    position.y = position.y + m
                    ox = 1
                elseif v == 5 then
                    position.x = position.x
                    position.y = position.y
                    ox = -1
                    oy = -1
                elseif v == 6 then
                    position.x = position.x + chunksize - 1
                    position.y = position.y + chunksize - 1
                    ox = 1
                    oy = 1
                end
                local position_from = { x = position.x + ox, y = position.y + oy }
                for c = 0,count-1,1 do
                    local dest = { x = position.x - ox * c, y = position.y - oy * c}
                    local current_name = nauvis.get_tile(dest.x, dest.y).name
                    if water_tiles[current_name] then
            	        local new_name = nauvis.get_tile(position_from.x, position_from.y).name
                        if not water_tiles[new_name] then
                               log("Copying tile from " .. serpent.block(position_from) .. " " .. new_name .." to " .. serpent.block(dest) .. " " .. current_name)
                		       table.insert(tiles, {name = new_name, position = dest})
                        end
                    end
                end
            end
          end
        end
    end
  end
  nauvis.set_tiles(tiles, true)
  game.print("Nauvis Regeneration Complete")
  end
  script.on_event(defines.events.on_tick, continue)
end
Would you like to make that into it's own mod with a remote interface? That way Alien Biomes can call the interface and not need it's own code to do that. Ever since I added the regeneration code it's seemed like it would be best as a separate generic terrain regenerator.

Ideally I could make a remote call to get a list of terrain regeneration options, each would return a title and short description so I could add them to an selection interface. Then if one is chosen i call the remote interface to trigger the terrain regeneration, or config popup or whatever the regeneration mod wants to do.

wvlad
Fast Inserter
Fast Inserter
Posts: 215
Joined: Thu Jul 13, 2017 9:55 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by wvlad »

Though I would like to publish it as a seperate mod and help the Factorio community I'm not ready to dedicate time to support it and fix issues.

User avatar
DarkyPupu
Fast Inserter
Fast Inserter
Posts: 109
Joined: Sun Jun 04, 2017 4:46 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by DarkyPupu »

Earendel wrote:
DarkyPupu wrote:I've an annoying problem, i have (among others :D ) Alien Biomes, Extra Floors and Asphalt roads installed, which brings me close to the 255 limit (i have 253).

I would like to remove Extra Floors but when i do, i cannot load the save anymore becaure the tiles id go above 255.
On that save, same if i remove Asphalt road or even if i enable the option in alien biomes to remove obsolete tiles.

How can it be that i go above 255 when i remove tiles ? :?

I didn't try to remove the Alien Biomes mod to not delete all existing chunks parts. I would like to keep AB and remove EF.

Any ideas ?
Yeah that's weird. I think when it does the tile migration phase Factorio tries to load all new and old tiles somehow? I'd call it a Vanilla bug but I'm not sure bug is the right word for it. I haven't checked to see if the devs already have a bug report for it.

Anyway, what I did is remove alien biomes, load the save, save it under a new game, add alien biomes again, reload the new save, regenerate the terrain and endure all the concrete disappearing.
Tried to remove alien biomes in the end but didn't change anything, cannot load save still. If i remove *all* the mods, it loads but it's too much of a hassle for still a kind of new game. I'll just restart another save, and try to not get close to the limit :lol: (basically it'd be only AB i think)

EDIT :

Found the culprit(s), although not where i expected them. For some reasons if i remove a tile-using mod (AB / Asphalt roads / Extra Floors ...), i need to disable also both of "Angels Smelting" and "Scortched earth". I don't know why, but i guess those two mods do something special regarding tiles management. If i disable both of them, and Extra floors (for example), then it works. :?
Mod list

Anson
Fast Inserter
Fast Inserter
Posts: 249
Joined: Sun May 22, 2016 4:41 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by Anson »

DarkyPupu, Earendel, DarkyPupu wrote:I would like to remove Extra Floors but when i do, i cannot load the save anymore becaure the tiles id go above 255.
How can it be that i go above 255 when i remove tiles ? :?
...
Yeah that's weird. I think when it does the tile migration phase Factorio tries to load all new and old tiles somehow? ...
Anyway, what I did is remove alien biomes, load the save, ...
Although i like the nice Alien Biomes landscapes a lot, i decided to avoid all those problems by (at least temporarily) disabling Alien Biomes. After i did that, i could no longer load my save because i got the message that the ID exceeds the 255 limit. this might have been caused by Alien Biomes no longer "compressing" tiles after removing it, but the migration that removed the Alien Biomes tiles trying to load all the tiles?!
thus: how can i remove alien biomes now ?

since i had already thought about starting over (before going really big on my map, and to have a crazy rail world with ice ore instead of water and no plant life (no forests, no coal, no oil), and with no starting equipment besides a stack of wood and maybe a greenhouse :-) this problem can (for me) be solved easily by starting all over without AB, even when that means that i have a much more boring landscape :-(

User avatar
DarkyPupu
Fast Inserter
Fast Inserter
Posts: 109
Joined: Sun Jun 04, 2017 4:46 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by DarkyPupu »

Do you play with AngelSmelting or ScorchedEarth ? If yes try to temporarily disable both, as it was the problem for me.

Yehn
Fast Inserter
Fast Inserter
Posts: 111
Joined: Tue Jul 12, 2016 3:45 am
Contact:

Re: [MOD 0.14] Alien Biomes

Post by Yehn »

Hi,

Made a topic on the mod discussion page but just to give a quick tl;dr here. My computer can't really seem to handle the current incarnation of Alien Biomes. Would it be possible for a pared down version of this mod to be made focusing on the more distinct biomes? Akin to the older versions.

Thanks.

Djohaal
Inserter
Inserter
Posts: 23
Joined: Thu Jan 23, 2014 8:06 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by Djohaal »

I can positively report that alien biomes causes stuttering. After lots of exhaustive testing I nailed the cause of an annoying half-second stutter that occurred every few seconds when running to being caused by being present on any alien biomes region. Transitioning to an area with vanilla biomes (or a save exclusively with them) removes the issue, so did removing AB.

User avatar
Earendel
Factorio Staff
Factorio Staff
Posts: 711
Joined: Sun Nov 23, 2014 11:57 am
Contact:

Re: [MOD 0.14] Alien Biomes

Post by Earendel »

Djohaal wrote:I can positively report that alien biomes causes stuttering. After lots of exhaustive testing I nailed the cause of an annoying half-second stutter that occurred every few seconds when running to being caused by being present on any alien biomes region. Transitioning to an area with vanilla biomes (or a save exclusively with them) removes the issue, so did removing AB.
Can you clarify a few things?

The half-second stutter sounds like the stutter that happens during new chunk generation. Is the problem worse when you're running off into the wilderness vs running in circles in an explored area while the map has no pollution and no radars? If so, the problem might be because there are more things to place per chunk and chunk generation is taking longer.

When you say transitioning to an area with vanilla biomes makes it better, there actually should be any true vanilla biomes because even the green grass and brown dirt gets replaced with the AB equivalents (even if you don't regenerate the terrain). This might be because deoratives may have been removed in those or because the vanilla decoratives might be there instead. To help narrow that down, did you choose to 'regenerate the terrain' or not. Also if you did, are the improved areas places where you had structures previously or were they empty areas.

Finally, does the problem go away if you use the graphics option to not show decoratives?

Djohaal
Inserter
Inserter
Posts: 23
Joined: Thu Jan 23, 2014 8:06 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by Djohaal »

Earendel wrote:
Djohaal wrote:I can positively report that alien biomes causes stuttering. After lots of exhaustive testing I nailed the cause of an annoying half-second stutter that occurred every few seconds when running to being caused by being present on any alien biomes region. Transitioning to an area with vanilla biomes (or a save exclusively with them) removes the issue, so did removing AB.
Can you clarify a few things?

The half-second stutter sounds like the stutter that happens during new chunk generation. Is the problem worse when you're running off into the wilderness vs running in circles in an explored area while the map has no pollution and no radars? If so, the problem might be because there are more things to place per chunk and chunk generation is taking longer.

When you say transitioning to an area with vanilla biomes makes it better, there actually should be any true vanilla biomes because even the green grass and brown dirt gets replaced with the AB equivalents (even if you don't regenerate the terrain). This might be because deoratives may have been removed in those or because the vanilla decoratives might be there instead. To help narrow that down, did you choose to 'regenerate the terrain' or not. Also if you did, are the improved areas places where you had structures previously or were they empty areas.

Finally, does the problem go away if you use the graphics option to not show decoratives?
The half second stutter occoured even when running in circles or back and forth next to the spawn, no chunks were being generated. It'd start as soon a game started, didn't require building any objects or such.

I found out the vanilla terrain was stutter-free because I downloaded a complex factory save to test if other factors were influencing performance, the large factory on an originally vanilla biome had silky-smooth performance. I didn't regenerate the terrain in said save.

The save being stutter free gave me the hint AB might be the culprit, and indeed removing it fixed the problem in any new maps. I think transitioning into the base biomes also was lag-free but I didn't pay close attention to that component (my original post might have been a little misleading there, I apologize). If you have any map seeds that spawn on grass/brown dirt, I'd be glad to test.

I did not try running AB with the decoratives turned off, if the feedback is relevant I can try running a test tomorrrow and post the results.

User avatar
DarkyPupu
Fast Inserter
Fast Inserter
Posts: 109
Joined: Sun Jun 04, 2017 4:46 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by DarkyPupu »

Had to remove alien biomes from server because sadly it's not possible for a friend to even start the game with it (low RAM / 4 Gb). Works fine without AB.
I would like to have like suggested above, maybe a tuned-down version of AB with only most different biomes (no worries if not possible, i imagine it's a hassle to do...)

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2484
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: [MOD 0.14] Alien Biomes

Post by FuryoftheStars »

Hi, I've been seeing the half second stutter as well, but I have so many mods running I just attributed it to too many things firing off simultaneously. I just did some testing by turning off Alien Biomes and indeed, the stutter disappears.

In testing, turning off decoratives does reduce the stutter frequency, but it's definitely still present. What really eliminates the stutter, though, is turning the Sprite resolution from High to Normal (even with decoratives on). ;) Obviously I'm trying to overwork (and probably fry) my poor little laptop. :lol:

We may just be hitting the limits for the rigs we're running? For comparison, my laptop has an Intel Core i7-4810MQ processor @ 2.8 GHz, 16 GB of RAM, and an nVidia Quadro K3100M (which was not meant for gaming) with 4 GB of VRAM.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles

Post Reply

Return to “Mods”