Question about lua control flow

Place to get help with not working mods / modding interface.
Post Reply
Simn
Burner Inserter
Burner Inserter
Posts: 11
Joined: Tue Dec 02, 2014 8:27 pm
Contact:

Question about lua control flow

Post by Simn »

Hi,

I'm new to lua and got confused by the behavior of this small piece of code while toying with surfaces:

Code: Select all

  _G.script.on_event(defines.events.on_chunk_generated,function(e)
    game.print(e.surface.name);
    if (e.surface == surface) then
      for _,entity in pairs(surface.find_entities()) do
        game.print("Destroying " .. entity.name);
        entity.destroy();
      end
      game.print("Destruction done");
      for _,player1 in pairs(force.players) do
        game.print("Teleporting " .. player1.name);
        player1.teleport({x=0,y=0},surface);
      end
    end;
  end);
What I'm seeing ingame is this:

Code: Select all

nauvis
nauvis
my_test
Destroying tree-05
Destroying green-hairy-grass
...
Destruction done
Teleporting simn
Destroying player
my_test is the name of my custom surface, simn is my player name. What I don't understand is how control flow can go from "Teleporting simn" to "Destroying player" without crossing "my_test" again. Any hints as to what's going on there?

MrDoomah
Fast Inserter
Fast Inserter
Posts: 196
Joined: Mon Jun 01, 2015 1:11 pm
Contact:

Re: Question about lua control flow

Post by MrDoomah »

Instead of game.print, try log and see what is printed in the log file.

Factorio automatically skips printing stuff if it has been printed in the last x (1?) seconds. For example if you do

Code: Select all

/c for i = 1,100 do game.print("text") end 
you won't print 100x text, but only 1 time text.

Simn
Burner Inserter
Burner Inserter
Posts: 11
Joined: Tue Dec 02, 2014 8:27 pm
Contact:

Re: Question about lua control flow

Post by Simn »

MrDoomah wrote:Instead of game.print, try log and see what is printed in the log file.

Factorio automatically skips printing stuff if it has been printed in the last x (1?) seconds. For example if you do

Code: Select all

/c for i = 1,100 do game.print("text") end 
you won't print 100x text, but only 1 time text.
Thanks for the reply! However, I don't think this is about the printing itself. For one, my player character actually disappears which suggests that the code really is executed in that order. Also, even if the printing output is buffered, that shouldn't lead to a different order, right?

User avatar
aubergine18
Smart Inserter
Smart Inserter
Posts: 1264
Joined: Fri Jul 22, 2016 8:51 pm
Contact:

Re: Question about lua control flow

Post by aubergine18 »

Chunk generation runs in background.

I found this out by using beta of Creative Mode (beta version found in "WIP BETA TEST FOR 0.2.0" spoiler at bottom of OP) which has Modding > Events feature - tick the chunk generated event (and also change surface event, etc) and you'll get a running commentary of when the events are fired.

So, even if you're on different surface, game will still be doing some chunk generation for all surfaces.
Better forum search for modders: Enclose your search term in quotes, eg. "font_color" or "custom-input" - it prevents the forum search from splitting on hypens and underscores, resulting in much more accurate results.

Simn
Burner Inserter
Burner Inserter
Posts: 11
Joined: Tue Dec 02, 2014 8:27 pm
Contact:

Re: Question about lua control flow

Post by Simn »

aubergine18 wrote:Chunk generation runs in background.

I found this out by using beta of Creative Mode (beta version found in "WIP BETA TEST FOR 0.2.0" spoiler at bottom of OP) which has Modding > Events feature - tick the chunk generated event (and also change surface event, etc) and you'll get a running commentary of when the events are fired.

So, even if you're on different surface, game will still be doing some chunk generation for all surfaces.
That might be the case, but my surface only has a single chunk anyway and the code in question is wrapped in

Code: Select all

if (e.surface == surface)
where "surface" is my custom surface. There should be no interference here, I think.

MrDoomah
Fast Inserter
Fast Inserter
Posts: 196
Joined: Mon Jun 01, 2015 1:11 pm
Contact:

Re: Question about lua control flow

Post by MrDoomah »

Simn wrote:
MrDoomah wrote:Instead of game.print, try log and see what is printed in the log file.

Factorio automatically skips printing stuff if it has been printed in the last x (1?) seconds. For example if you do

Code: Select all

/c for i = 1,100 do game.print("text") end 
you won't print 100x text, but only 1 time text.
Thanks for the reply! However, I don't think this is about the printing itself. For one, my player character actually disappears which suggests that the code really is executed in that order. Also, even if the printing output is buffered, that shouldn't lead to a different order, right?
What happens is (I think) a chunk get generated, the surface gets cleared of all entities, then the player get teleported. And now you think it is done right?
Now the next chunk gets generated, however the text "my_test" has been printed in the last few seconds, so it doesn't get printed again. Then it checks the entire surface again for entities to destroy but the only entity it can find now is your player character, and it gets deleted. Then it doesn't print "Destruction done" because that also has been printed in the last few seconds.

Replace game.print() with log() and check your factorio-current.log.

User avatar
aubergine18
Smart Inserter
Smart Inserter
Posts: 1264
Joined: Fri Jul 22, 2016 8:51 pm
Contact:

Re: Question about lua control flow

Post by aubergine18 »

Alternatively suffix your game.print with a number, for example:

Code: Select all

local num = 0
function _G.print( text )
  num = num + 1
  game.print( text .. ' ' .. num )
end

print( "foo" ) -- 'foo 1'
print( "foo" ) -- 'foo 2'
Better forum search for modders: Enclose your search term in quotes, eg. "font_color" or "custom-input" - it prevents the forum search from splitting on hypens and underscores, resulting in much more accurate results.

Simn
Burner Inserter
Burner Inserter
Posts: 11
Joined: Tue Dec 02, 2014 8:27 pm
Contact:

Re: Question about lua control flow

Post by Simn »

Thanks guys, now I understand what you meant with regards to printing. Adding a counter I indeed see the output as I expect it. This printing behavior can be very confusing, but I suppose there's a reason for it.

Thanks for pointing me to the log function, I didn't find that on http://lua-api.factorio.com/latest/.

MrDoomah
Fast Inserter
Fast Inserter
Posts: 196
Joined: Mon Jun 01, 2015 1:11 pm
Contact:

Re: Question about lua control flow

Post by MrDoomah »

Simn wrote:This printing behavior can be very confusing, but I suppose there's a reason for it.
There was a time when a robot wanted to put an item in your inventory and your inventory was full, it would sprint non stop that your inventory is full. (Probably 60 times a second). They fixed it then by not printing something if it is the same message as the last one printed. Then came the issue if 2 robots wanted to put 2 different items in your inventory and you get spammed again. So now factorio checks the printed messages of the last second or so and doesn't print if it has been printed again.

It has it reasons, but I do sometimes wish there was a forceprint() function that forces the message to be printed, even if it has been printed in the last second.
And with forceprint() i don't mean force.print()

matjojo
Filter Inserter
Filter Inserter
Posts: 336
Joined: Wed Jun 17, 2015 6:08 pm
Contact:

Re: Question about lua control flow

Post by matjojo »

MrDoomah wrote:
Simn wrote:This printing behavior can be very confusing, but I suppose there's a reason for it.
There was a time when a robot wanted to put an item in your inventory and your inventory was full, it would sprint non stop that your inventory is full. (Probably 60 times a second). They fixed it then by not printing something if it is the same message as the last one printed. Then came the issue if 2 robots wanted to put 2 different items in your inventory and you get spammed again. So now factorio checks the printed messages of the last second or so and doesn't print if it has been printed again.

It has it reasons, but I do sometimes wish there was a forceprint() function that forces the message to be printed, even if it has been printed in the last second.
And with forceprint() i don't mean force.print()
to simulate this you could write to a file, or use the log() functions

Post Reply

Return to “Modding help”