Page 1 of 1

Parts of lua execution skipped in for loop?

Posted: Tue Sep 27, 2022 5:14 pm
by derpumu
Hi, I am relatively new to Lua and modding, not to programming though, and I came across a piece of behavior that I absolutely find no explanation for.

here's my striped-down control.lua. Down in the for loop I have marked a part in the for loop that only gets executed once even though there are multiple iterations through the loop:

Code: Select all

local enable_debug_print = true
local taggable_types={"tree"}

function debug_print(msg)
    if enable_debug_print then game.print(msg) end
end

function is_taggeable_entity(entity)
    debug_print("  is_taggeable_entity trace IN")
    -- interesting entities have more to mine for than just wood
    if not entity.minable then
        debug_print("  entity not minable")
        return false
    end
    
    local mining = entity.prototype.mineable_properties
    if mining.results or mining.result then
        debug_print("    mining results")
        return true
    else
        debug_print("    no mining result")
        return false
    end
    debug_print("    how did we even get here???")
    return false
end    

function chunk_charted(event)
    debug_print('=================================================')
    local surface = game.get_surface(event.surface_index)
    local area = event.area

    local taggeable_entities = {}
    local chunk_entities = surface.find_entities_filtered{area=area, type=taggable_types}
    debug_print(tostring(#chunk_entities)..' entities in chunk')

    for _, entity in pairs(chunk_entities) do
        debug_print(tostring(_)..': test entity '..entity.name)
        
        -- why is this only executed once??
        local taggeable = is_taggeable_entity(entity)
        if taggeable then
            debug_print('  found taggeable entity.name: '..entity.name)
            table.insert(taggeable_entities, entity)
        else
            debug_print("  not taggeable")
        end
        -- until here?
        
        debug_print(  'entity tested '..entity.name)
    end
    -- 
end


script.on_event(defines.events.on_chunk_charted,                    chunk_charted)
An example output with 2 entities in the charted chunk looks like the attached image:
Untitled.png
Untitled.png (220.45 KiB) Viewed 960 times
It looks similar with other chunks with more trees that are tested. Why does the Lua interpreter execute the is_taggeable_entity function and the whole if/else block that depends on its return value only once? When I replace the condition with something static like "1 ~= 2" the if/else gets executed every time. I've Googled for an explanation but apparently did not have the right search words, I came up empty. Running something similar in a UA Repl online executed everything every time.

Re: Parts of lua execution skipped in for loop?

Posted: Tue Sep 27, 2022 5:37 pm
by Silari
Print is setup to ignore multiple calls with the same parameters. If you call print("hello") five times in a row, it'll print once and ignore the rest. It doesn't want the console spammed with the same message. If you really need to see them all, switch to the log command which logs everything.

Re: Parts of lua execution skipped in for loop?

Posted: Tue Sep 27, 2022 6:24 pm
by Pi-C
derpumu wrote:
Tue Sep 27, 2022 5:14 pm

Code: Select all

function chunk_charted(event)

        -- why is this only executed once??
        local taggeable = is_taggeable_entity(entity)
        if taggeable then
            debug_print('  found taggeable entity.name: '..entity.name)
            table.insert(taggeable_entities, entity)
        else
            debug_print("  not taggeable")
        end
        -- until here?
end
Your call to is_taggeable_entity will always return false! Compare minable properties in data stage and in control stage: In the data stage, result/results are optional properties, but in the control stage, there is only entity.prototype.mineable_properties.products.

Re: Parts of lua execution skipped in for loop?

Posted: Tue Sep 27, 2022 6:41 pm
by derpumu
Silari wrote:
Tue Sep 27, 2022 5:37 pm
Print is setup to ignore multiple calls with the same parameters. If you call print("hello") five times in a row, it'll print once and ignore the rest. It doesn't want the console spammed with the same message. If you really need to see them all, switch to the log command which logs everything.
Thank you! I thought I'd had tried to pass the array index to the prints, that should've make the prints different right? Will try that and log out tomorrow.

@Pi-c thank you, I'll have a look into those