Chunk iterator not working properly?

Place to get help with not working mods / modding interface.
Post Reply
Romner_set
Inserter
Inserter
Posts: 30
Joined: Thu Mar 07, 2019 4:25 pm
Contact:

Chunk iterator not working properly?

Post by Romner_set »

I am making a mod that will degrade terrain as the pollution goes up.

The chunk iterator "iterates" through only 1 chunk (solved, it was a stupid typo - x instead of y. I use a qwertz keyboard so y is right on the left of x).

Code: Select all

pollution_multiplier_table = {
["grass-1"]=1, --changes tile name to pollution multiplier
["grass-2"]=1,
["grass-3"]=2,
["grass-4"]=3,
["dirt-4"]=4,
["dirt-6"]=5,
["dirt-7"]=6,
["dirt-5"]=7,
["dirt-3"]=8,
["dirt-1"]=9,
["dirt-2"]=10,
["red-desert-3"]=11,
["dry-dirt"]=9,
["sand-3"]=12,
["sand-2"]=13
}

terrain = {
["grass-1"]="grass-3", --changes tile name to tile name to set
["grass-2"]="grass-3",
["grass-3"]="grass-4",
["grass-4"]="dirt-4",
["dirt-4"]="dirt-6",
["dirt-6"]="dirt-7",
["dirt-7"]="dirt-5",
["dirt-5"]="dirt-3",
["dirt-3"]="dirt-1",
["dirt-1"]="dirt-2",
["dirt-2"]="red-desert-3",
["red-desert-3"]="sand-3",
["dry-dirt"]="dirt-2",
["sand-3"]="sand-2",
["sand-2"]="sand-1"
}

local tiles_to_set = {} --A table that will contain all tiles that will be set to another tile

script.on_event(defines.events.on_tick, function(event)
    if event.tick % 300 == 0 then --every 5 seconds
        for chunk in game.surfaces[1].get_chunks() do --!iterate through chunks (not working?)
            local tile = game.surfaces[1].get_tile(chunk.x/32, chunk.y/32)
            if pollution_multiplier_table[tile.name] ~= nil then
                add_tiles_to_table(pollution_multiplier_table[tile.name], chunk, tile)
            end
            if #tiles_to_set > 0 then --set tiles if there are some to set
                game.surfaces[1].set_tiles(tiles_to_set)
                tiles_to_set = {} --remove everything from tiles_to_set
            end
        end
    end
end)

function add_tiles_to_table(pollution_multiplier, chunk, tile)
    local chunk_pollution = game.surfaces[1].get_pollution({chunk.x, chunk.y})
    if chunk_pollution >= pollution_multiplier*72 then --*final value is 1008
        local tile_name = terrain[tile.name]
        for x = -16,16  do  --Loop through chunk tile positions
            for y = -16,16 do
                local current_tile = game.surfaces[1].get_tile(tile.position.x+x, tile.position.y+y)
                if terrain[current_tile.name] ~= nil then --if tile name is in the terrain table
                    table.insert(tiles_to_set, {name = tile_name, position = current_tile.position})
                    if not string.find(terrain[current_tile.name], "grass") then --if tile name to set isn't some kind of grass
                        game.surfaces[1].destroy_decoratives{area={current_tile.position, current_tile.position}} --remove decoratives (bushes, tall grass, etc.)
                    end
                end
            end
        end
    end
end
Attachments
This is what happens.
This is what happens.
P7W4UVE - Imgur.png (3.83 MiB) Viewed 3940 times
Last edited by Romner_set on Wed Nov 20, 2019 8:37 pm, edited 3 times in total.

Bilka
Factorio Staff
Factorio Staff
Posts: 3138
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: Chunk iterator not working?

Post by Bilka »

Code: Select all

local tile = game.surfaces[1].get_tile(chunk.x/32, chunk.y/32)
The chunk coordinates are small, they are "chunk positions", so by dividing those by 32, you always end up with roughly the same tile position. You most likely meant to multiply by *32 to get from chunk position to tile position. For that see viewtopic.php?p=447586#p447586 or the area parameter of the chunk iterator.
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.

Romner_set
Inserter
Inserter
Posts: 30
Joined: Thu Mar 07, 2019 4:25 pm
Contact:

Re: Chunk iterator not working?

Post by Romner_set »

Bilka wrote:
Sun Oct 13, 2019 1:19 pm
You most likely meant to multiply by *32 to get from chunk position to tile position.
Yes. I saw "You can translate a Position to a chunk position by multiplying the x/y values by 32.", but I read "You can translate a chunk position to a Position by dividing the x/y values by 32." Thank you.

Romner_set
Inserter
Inserter
Posts: 30
Joined: Thu Mar 07, 2019 4:25 pm
Contact:

Re: Chunk iterator not working?

Post by Romner_set »

Bilka wrote:
Sun Oct 13, 2019 1:19 pm
The chunk coordinates are small, they are "chunk positions", so by dividing those by 32, you always end up with roughly the same tile position. You most likely meant to multiply by *32 to get from chunk position to tile position. For that see viewtopic.php?p=447586#p447586 or the area parameter of the chunk iterator.
I didn't have time because of school, but today I continued my work on the mod and this happens no matter what I do : Image
.zip of the mod : https://www.dropbox.com/s/yyi5144cam4dt ... 0.zip?dl=0
Last edited by Romner_set on Wed Oct 23, 2019 4:13 pm, edited 3 times in total.

Romner_set
Inserter
Inserter
Posts: 30
Joined: Thu Mar 07, 2019 4:25 pm
Contact:

Re: Chunk iterator not working?

Post by Romner_set »

if you don't want to download it :

Code: Select all

--!I'm using VS Code with Better Comments plugin so if you see anything like --? --! --* or --TODO: then it's because of that.

pollution_threshold = {
["grass-1"] = 76, --changes tile name to pollution threshold
["grass-2"] = 76,
["grass-3"] = 76,
["grass-4"] = 153,
["dirt-4"] = 229,
["dirt-6"] = 307,
["dirt-7"] = 384,
["dirt-5"] = 461,
["dirt-3"] = 538,
["dirt-1"] = 615,
["dirt-2"] = 638,
["red-desert-3"] = 769,
["dry-dirt"] = 638,
["sand-3"] = 846,
["sand-2"] = 923,
["sand-1"] = 1000
}

terrain = {
["grass-1"] = "grass-3", --changes tile name to tile name to set
["grass-2"] = "grass-3",
["grass-3"] = "grass-4",
["grass-4"] = "dirt-4",
["dirt-4"] = "dirt-6",
["dirt-6"] = "dirt-7",
["dirt-7"] = "dirt-5",
["dirt-5"] = "dirt-3",
["dirt-3"] = "dirt-1",
["dirt-1"] = "dirt-2",
["dirt-2"] = "red-desert-3",
["red-desert-3"] = "sand-3",
["dry-dirt"] = "dirt-2",
["sand-3"] = "sand-2",
["sand-2"] = "sand-1"
}

local tiles_to_set = {} --A table that will contain all tiles that will be set to another tile

script.on_event(defines.events.on_tick, function(event)
    local surface = game.surfaces[1]
    if event.tick % 300 == 0 then             
        for chunk in (surface.get_chunks()) do
--*     For some reason, if surface.get_chunks() is enclosed in (), the script executes
--*     much quicker using much less resources, so i'm gonna leave it like that .-.
            local chunk_pollution = surface.get_pollution({chunk.x*32, chunk.y*32}) 
            while pollution_multiplier == nil do --if pollution_multiplier is nil, find another tile in the chunk to decide on if the chunk should be degraded
                for x = -16, 16 do --iterate through tile positions in chunk
                    for y = -16, 16 do
                        local tile = surface.get_tile(chunk.x*32+x, chunk.y*32+y)
                        if tile.valid then
                            pollution_multiplier = pollution_threshold[tile.name]
                        end
                        if x == 16 and y == 16 then
                            if pollution_multiplier == nil then
                                pollution_multiplier = 0
                            end
                            break
                        end
                    end
                end
            end
            if chunk_pollution > pollution_multiplier then
                for x = -16,16  do  --iterate through tile positions in chunk
                    for y = -16,16 do
                        local current_tile = surface.get_tile(chunk.x*32+x, chunk.x*32+y)
                        if current_tile.valid then
                            local tile_to_set = terrain[current_tile.name]
                            if tile_to_set ~= nil then --if tile name is in the terrain table
                                table.insert(tiles_to_set, {name = tile_to_set, position = current_tile.position})
                                if not string.find(tile_to_set, "grass") then --if tile to set isn't some kind of grass
                                    surface.destroy_decoratives{area={current_tile.position, current_tile.position}} --remove decoratives (bushes, tall grass, etc.)
                                end
                            end
                        end
                    end
                end
            end
        end
        if #tiles_to_set > 0 then --set tiles if there are some to set
            surface.set_tiles(tiles_to_set)
            tiles_to_set = {} --remove everything from tiles_to_set
        end
    end
end)

mrvn
Smart Inserter
Smart Inserter
Posts: 5709
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Chunk iterator not working?

Post by mrvn »

Instead of doing all chunks every 5s (which will freeze the game) you should do a constant number of chunks (e.g. 1) per tick.

Which means store a list of all chunks globally and work through that list a bit every tick. When you reach the end get a new list.

Romner_set
Inserter
Inserter
Posts: 30
Joined: Thu Mar 07, 2019 4:25 pm
Contact:

Re: Chunk iterator not working?

Post by Romner_set »

mrvn wrote:
Thu Oct 24, 2019 1:41 pm
Instead of doing all chunks every 5s (which will freeze the game) you should do a constant number of chunks (e.g. 1) per tick.

Which means store a list of all chunks globally and work through that list a bit every tick. When you reach the end get a new list.
Same thing happens. Solves lag spikes though, so thanks anyway.

Code: Select all

pollution_threshold = {
["grass-1"] = 76, --changes tile name to pollution threshold
["grass-2"] = 76,
["grass-3"] = 76,
["grass-4"] = 153,
["dirt-4"] = 229,
["dirt-6"] = 307,
["dirt-7"] = 384,
["dirt-5"] = 461,
["dirt-3"] = 538,
["dirt-1"] = 615,
["dirt-2"] = 638,
["red-desert-3"] = 769,
["dry-dirt"] = 638,
["sand-3"] = 846,
["sand-2"] = 923,
["sand-1"] = 1000
}

terrain = {
["grass-1"] = "grass-3", --changes tile name to tile name to set
["grass-2"] = "grass-3",
["grass-3"] = "grass-4",
["grass-4"] = "dirt-4",
["dirt-4"] = "dirt-6",
["dirt-6"] = "dirt-7",
["dirt-7"] = "dirt-5",
["dirt-5"] = "dirt-3",
["dirt-3"] = "dirt-1",
["dirt-1"] = "dirt-2",
["dirt-2"] = "red-desert-3",
["red-desert-3"] = "sand-3",
["dry-dirt"] = "dirt-2",
["sand-3"] = "sand-2",
["sand-2"] = "sand-1"
}

local tiles_to_set = {} --A table that will contain all tiles that will be set to another tile
local i = 1 --counter

script.on_event(defines.events.on_tick, function(event)
    if chunks == nil then
        chunks = {} --create chunks table
        for chunk in game.surfaces[1].get_chunks() do --insert all current chunks into that
            table.insert(chunks, chunk)
        end
    else
        local chunk_pollution = game.surfaces[1].get_pollution({chunks[i].x*32, chunks[i].y*32})
        while pollution_multiplier == nil do --if pollution_multiplier is nil, find another tile in the chunk to decide on if the chunk should be degraded
            for x = -16, 16 do --iterate through tile positions in chunk
                for y = -16, 16 do
                    local tile = game.surfaces[1].get_tile(chunks[i].x*32+x, chunks[i].y*32+y)
                    if tile.valid then
                        pollution_multiplier = pollution_threshold[tile.name]
                    end
                    if x == 16 and y == 16 then
                        if pollution_multiplier == nil then
                            pollution_multiplier = 0
                        end
                        break
                    end
                end
            end
        end
        if chunk_pollution > pollution_multiplier then
            for x = -16,16  do  --iterate through tile positions in chunk
                for y = -16,16 do
                    local current_tile = game.surfaces[1].get_tile(chunks[i].x*32+x, chunks[i].x*32+y)
                    if current_tile.valid then
                        local tile_to_set = terrain[current_tile.name]
                        if tile_to_set ~= nil then --if tile name is in the terrain table
                            table.insert(tiles_to_set, {name = tile_to_set, position = current_tile.position})
                            if not string.find(tile_to_set, "grass") then --if tile to set isn't some kind of grass
                                game.surfaces[1].destroy_decoratives{area={current_tile.position, current_tile.position}} --remove decoratives (bushes, tall grass, etc.)
                            end
                        end
                    end
                end
            end
        end
    end
    if #tiles_to_set > 0 then --set tiles if there are some to set
        game.surfaces[1].set_tiles(tiles_to_set)
        tiles_to_set = {} --remove everything from tiles_to_set
    end
    if i == #chunks then --if end of chunks table reached
        chunks = nil
        i = 1 --restart counter
    else
        i = i+1 --progress the counter
    end
end)

mrvn
Smart Inserter
Smart Inserter
Posts: 5709
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Chunk iterator not working?

Post by mrvn »

No idea why you don't get all chunks. Looks OK but I can't test right now.

But get_chunks() might be an inefficient approach anyway. Over time the list of chunks can get larger so creating a table for it can be costly.
Maybe you should catch the on_chunk_generated event and add the chunk coordinates to your chunks table. Then the chunk_table always contains all chunks and you don't get the spike when you reach the end and create a new table of all chunks.

Since that method doesn't use the game.surfaces[1].get_chunks() it might fix your problem.

PS: will you support other surfaces too?

Romner_set
Inserter
Inserter
Posts: 30
Joined: Thu Mar 07, 2019 4:25 pm
Contact:

Re: Chunk iterator not working?

Post by Romner_set »

mrvn wrote:
Thu Oct 24, 2019 3:31 pm
No idea why you don't get all chunks. Looks OK but I can't test right now.

But get_chunks() might be an inefficient approach anyway. Over time the list of chunks can get larger so creating a table for it can be costly.
Maybe you should catch the on_chunk_generated event and add the chunk coordinates to your chunks table. Then the chunk_table always contains all chunks and you don't get the spike when you reach the end and create a new table of all chunks.

Since that method doesn't use the game.surfaces[1].get_chunks() it might fix your problem.

PS: will you support other surfaces too?
Definitely less UPS drops, but it still doesn't iterate through all chunks. (only in the \ pattern)

Code: Select all

---- TABLES ----
pollution_threshold = { --changes tile name to pollution threshold
["grass-1"] = 76,
["grass-2"] = 76,
["grass-3"] = 76,
["grass-4"] = 153,
["dirt-4"] = 229,
["dirt-6"] = 307,
["dirt-7"] = 384,
["dirt-5"] = 461,
["dirt-3"] = 538,
["dirt-1"] = 615,
["dirt-2"] = 638,
["red-desert-3"] = 769,
["dry-dirt"] = 638,
["sand-3"] = 846,
["sand-2"] = 923,
["sand-1"] = 1000
}
terrain = { --changes tile name to tile name to set
["grass-1"] = "grass-3",
["grass-2"] = "grass-3",
["grass-3"] = "grass-4",
["grass-4"] = "dirt-4",
["dirt-4"] = "dirt-6",
["dirt-6"] = "dirt-7",
["dirt-7"] = "dirt-5",
["dirt-5"] = "dirt-3",
["dirt-3"] = "dirt-1",
["dirt-1"] = "dirt-2",
["dirt-2"] = "red-desert-3",
["red-desert-3"] = "sand-3",
["dry-dirt"] = "dirt-2",
["sand-3"] = "sand-2",
["sand-2"] = "sand-1"
}
tiles_to_set = {} --A table that will contain all tiles that will be set to another tile

---- ON INIT ----
script.on_init(function()
    chunk_i = 0 --count starts at 0, because on_chunk_generated fires after the first on_tick
    chunks = {}
end)

---- ON TICK ----
script.on_event(defines.events.on_tick, function(event)
    if chunk_i ~= 0 then
        local chunk_pollution = game.surfaces[1].get_pollution({chunks[chunk_i].x*32, chunks[chunk_i].y*32})
        while pollution_multiplier == nil do --if pollution_multiplier is nil, find another tile in the chunk to decide on if the chunk should be degraded
            for x = -16, 16 do --iterate through tile positions in chunk
                for y = -16, 16 do
                    local tile = game.surfaces[1].get_tile(chunks[chunk_i].x*32+x, chunks[chunk_i].y*32+y)
                    if tile.valid then
                        pollution_multiplier = pollution_threshold[tile.name]
                    end
                    if x == 16 and y == 16 then
                        if pollution_multiplier == nil then
                            pollution_multiplier = 0
                        end
                        break
                    end
                end
            end
        end
        if chunk_pollution > pollution_multiplier then
            for x = -16,16  do  --iterate through tile positions in chunk
                for y = -16,16 do
                    local current_tile = game.surfaces[1].get_tile(chunks[chunk_i].x*32+x, chunks[chunk_i].x*32+y)
                    if current_tile.valid then
                        local tile_to_set = terrain[current_tile.name]
                        if tile_to_set ~= nil then --if tile name is in the terrain table
                            table.insert(tiles_to_set, {name = tile_to_set, position = current_tile.position})
                            if not string.find(tile_to_set, "grass") then --if tile to set isn't some kind of grass
                                game.surfaces[1].destroy_decoratives{area={current_tile.position, current_tile.position}} --remove decoratives (bushes, tall grass, etc.)
                            end
                        end
                    end
                end
            end
        end
        if #tiles_to_set > 0 then --set tiles if there are some to set
            game.surfaces[1].set_tiles(tiles_to_set)
            tiles_to_set = {} --remove everything from tiles_to_set
        end
    end
    if chunk_i == #chunks then --if end of chunks table reached
        chunk_i = 1 --restart counter
    else
        chunk_i = chunk_i+1 --progress the counter
    end
end)

---- ON EVENT ----
script.on_event(defines.events.on_chunk_generated, function(chunk)
    table.insert(chunks, {x = chunk.position.x, y = chunk.position.y})
end)
script.on_event(defines.events.on_chunk_deleted, function(chunk)
    table.remove(chunks, find_table_index(chunks, {x = chunk.position.x, y = chunk.position.y}))
end)

---- FUNCTIONS ----
function find_table_index(table, val)
    for i, value in pairs(table) do
        if value == val then
            return i
        end
    end
end
PS: Yes, I will definitely support more surfaces. For now I need to get the mod working.

mrvn
Smart Inserter
Smart Inserter
Posts: 5709
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Chunk iterator not working properly?

Post by mrvn »

Well, ... Output your list of chunks and index when you process chunks and see what's going on.

Does the list of chunks contain the right chunks? Does the index go through all of them and then repeat?

Romner_set
Inserter
Inserter
Posts: 30
Joined: Thu Mar 07, 2019 4:25 pm
Contact:

Re: Chunk iterator not working properly?

Post by Romner_set »

mrvn wrote:
Fri Oct 25, 2019 8:10 pm
Well, ... Output your list of chunks and index when you process chunks and see what's going on.

Does the list of chunks contain the right chunks? Does the index go through all of them and then repeat?
There are over 200 chunks even though there are about 25 charted (at most). Iterates through them all, then resets. Also if just 1 chunk has reached the threshold to degrade, all chunks in the \ pattern get changed. Maybe on_chunk_charted could be better? I will have to test that.(currently it takes a long time to iterate through all the chunks)

I fixed 1 thing : the chunk.position*32 isn't the central tile, it is the up-left tile. Results are better than before, but UPS drops are far more significant when setting the tiles.
Image

Code: Select all

---- TABLES ----
pollution_threshold_table = { --changes tile name to pollution threshold
["grass-1"] = 76,
["grass-2"] = 76,
["grass-3"] = 76,
["grass-4"] = 153,
["dirt-4"] = 229,
["dirt-6"] = 307,
["dirt-7"] = 384,
["dirt-5"] = 461,
["dirt-3"] = 538,
["dirt-1"] = 615,
["dirt-2"] = 638,
["red-desert-3"] = 769,
["dry-dirt"] = 638,
["sand-3"] = 846,
["sand-2"] = 923,
["sand-1"] = 1000
}
terrain = { --changes tile name to tile name to set
["grass-1"] = "grass-3",
["grass-2"] = "grass-3",
["grass-3"] = "grass-4",
["grass-4"] = "dirt-4",
["dirt-4"] = "dirt-6",
["dirt-6"] = "dirt-7",
["dirt-7"] = "dirt-5",
["dirt-5"] = "dirt-3",
["dirt-3"] = "dirt-1",
["dirt-1"] = "dirt-2",
["dirt-2"] = "red-desert-3",
["red-desert-3"] = "sand-3",
["dry-dirt"] = "dirt-2",
["sand-3"] = "sand-2",
["sand-2"] = "sand-1"
}
tiles_to_set = {} --A table that will contain all tiles that will be set to another tile

---- ON INIT ----
script.on_init(function()
    chunk_i = 1
    chunks = {}
    chunks_generated = false
end)

---- ON TICK ----
script.on_event(defines.events.on_tick, function(event)
    if chunks_generated then
        log(chunk_i)
        local chunk_pollution = game.surfaces[1].get_pollution({chunks[chunk_i].x*32, chunks[chunk_i].y*32})
        while pollution_threshold == nil do --if pollution_threshold is nil, find a tile in the chunk to decide on if the chunk should be degraded
            for x = 0, 32 do --iterate through tile positions in chunk
                for y = 0, 32 do
                    local tile = game.surfaces[1].get_tile(chunks[chunk_i].x*32+x, chunks[chunk_i].y*32+y)
                    if tile.valid then
                        pollution_threshold = pollution_threshold_table[tile.name]
                    end
                    if x == 32 and y == 32 then
                        if pollution_threshold == nil then
                            pollution_threshold = 0
                        end
                        break
                    end
                end
            end
        end
        if chunk_pollution > pollution_threshold then
            for x = -32,32  do  --iterate through tile positions in chunk
                for y = -32,32 do
                    local current_tile = game.surfaces[1].get_tile(chunks[chunk_i].x*32+x, chunks[chunk_i].x*32+y)
                    if current_tile.valid then
                        local tile_to_set = terrain[current_tile.name]
                        if tile_to_set ~= nil then --if tile name is in the terrain table
                            table.insert(tiles_to_set, {name = tile_to_set, position = current_tile.position})
                            if not string.find(tile_to_set, "grass") then --if tile to set isn't some kind of grass
                                game.surfaces[1].destroy_decoratives{area={current_tile.position, current_tile.position}} --remove decoratives (bushes, tall grass, etc.)
                            end
                        end
                    end
                end
            end
        end
        if chunk_i == #chunks then --if end of chunks table reached
            chunk_i = 1 --restart counter
            if #tiles_to_set > 0 then --set tiles if there are some to set
                game.surfaces[1].set_tiles(tiles_to_set)
                tiles_to_set = {} --remove everything from tiles_to_set
            end
        else
            chunk_i = chunk_i+1 --progress the counter
        end
        pollution_threshold = nil
    end
end)

---- ON EVENT ----
script.on_event(defines.events.on_chunk_generated, function(chunk)
    if not chunks_generated then
        chunks_generated = true
    end
    log("chunks1 :")
    log(#chunks)
    table.insert(chunks, {x = chunk.position.x, y = chunk.position.y})
    log("chunks2 :")
    log(#chunks)
end)
script.on_event(defines.events.on_chunk_deleted, function(chunk)
    table.remove(chunks, find_table_index(chunks, {x = chunk.position.x, y = chunk.position.y}))
end)

---- FUNCTIONS ----
function find_table_index(table, val)
    for i, value in pairs(table) do
        if value == val then
            return i
        end
    end
end

Romner_set
Inserter
Inserter
Posts: 30
Joined: Thu Mar 07, 2019 4:25 pm
Contact:

Re: Chunk iterator not working properly?

Post by Romner_set »

Nope, if anything, on_chunk_charted makes it worse.

mrvn
Smart Inserter
Smart Inserter
Posts: 5709
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Chunk iterator not working properly?

Post by mrvn »

Note that the game generates a lot of chunks around what is visible on the map. That allows for aliens to exist outside your visible map and expand into the visible part. Without this you could kill all aliens on the map and no news ones would appear anymore.

25 chunks is rather on the low side. Test your code for >1000 chunks or >10000 chunks. You can chart chunks using lua commands for testing. Or download one of the mega factories and use that as performance test. How much time will your mod cost compared to the mega factory? Is it still playable?

Romner_set
Inserter
Inserter
Posts: 30
Joined: Thu Mar 07, 2019 4:25 pm
Contact:

Re: Chunk iterator not working properly?

Post by Romner_set »

mrvn wrote:
Mon Oct 28, 2019 10:51 am
Note that the game generates a lot of chunks around what is visible on the map. That allows for aliens to exist outside your visible map and expand into the visible part. Without this you could kill all aliens on the map and no news ones would appear anymore.

25 chunks is rather on the low side. Test your code for >1000 chunks or >10000 chunks. You can chart chunks using lua commands for testing. Or download one of the mega factories and use that as performance test. How much time will your mod cost compared to the mega factory? Is it still playable?
The mod iterates through all chunks (over 10k) but does nothing (I let it run for about an hour and terrain didn't change even though there was a lot of polution).

Romner_set
Inserter
Inserter
Posts: 30
Joined: Thu Mar 07, 2019 4:25 pm
Contact:

Re: Chunk iterator not working properly?

Post by Romner_set »

Still need help with this. Why doesn't it iterate through all chunks? ._.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Chunk iterator not working properly?

Post by eradicator »

Romner_set wrote:
Sat Nov 02, 2019 12:08 pm
Still need help with this. Why doesn't it iterate through all chunks? ._.
When dealing with something you don't understand it always helps to visualize it:

Code: Select all

/c
rendering.clear()
local i = 0
for chunk in game.surfaces.nauvis.get_chunks() do i=i+1
  rendering.draw_text{
    color = {r=1},
    target = {chunk.x*32+16,chunk.y*32+16},
    surface = game.surfaces.nauvis.index,
    text = i,
    scale = 10,
    }
  if i%5 == 0 then rendering.draw_rectangle{
    color = {g=1},
    left_top = chunk.area.left_top,
    right_bottom = chunk.area.right_bottom,
    surface = game.surfaces.nauvis.index,
    } end
  end
In /editor mode you can zoom out very far to see the result:
chunkiterorder.png
chunkiterorder.png (438.22 KiB) Viewed 3641 times
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

Romner_set
Inserter
Inserter
Posts: 30
Joined: Thu Mar 07, 2019 4:25 pm
Contact:

Re: Chunk iterator not working properly?

Post by Romner_set »

DONE.
FINALLY.
I am so stupid that I put chunks[chunk_i].x instead of chunks[chunk_i].y so the position was basically x, x instead of x, y.
Such a stupid mistake that lead to a month of debugging.
Incase someone wants the mod, PM me and I'll send you the link when I release it. I will also be making trees get destroyed with enough pollution (after becoming 'dead').

Thank you all for the help, improved UPS at the very least :)

Honktown
Smart Inserter
Smart Inserter
Posts: 1026
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Re: Chunk iterator not working properly?

Post by Honktown »

Romner_set wrote:
Mon Nov 18, 2019 7:27 pm
DONE.
FINALLY.
I am so stupid that I put chunks[chunk_i].x instead of chunks[chunk_i].y so the position was basically x, x instead of x, y.
Such a stupid mistake that lead to a month of debugging.
Incase someone wants the mod, PM me and I'll send you the link when I release it. I will also be making trees get destroyed with enough pollution (after becoming 'dead').

Thank you all for the help, improved UPS at the very least :)
Happens to the best of us. Congrats on persisting and were able to fix it.
I have mods! I guess!
Link

User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2903
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: Chunk iterator not working properly?

Post by darkfrei »

The mistake like position = {x = x, x = x} or {x = x, y = x} comes too often, it needs be right correct after this common copy-paste.

Post Reply

Return to “Modding help”