some biter entity.set_command seems to be super slow?

Place to get help with not working mods / modding interface.
Post Reply
yagaodirac
Fast Inserter
Fast Inserter
Posts: 152
Joined: Sun Jun 16, 2019 4:04 pm
Contact:

some biter entity.set_command seems to be super slow?

Post by yagaodirac »

For some reason, I have to call this function every 100 ticks or even more frequently. Every time I have to call this on 10k biters. The tick I call this, the game lag for a third second. Any suggestions?

orzelek
Smart Inserter
Smart Inserter
Posts: 3911
Joined: Fri Apr 03, 2015 10:20 am
Contact:

Re: some biter entity.set_command seems to be super slow?

Post by orzelek »

Only suggestion I could give is to stagger the commands over ticks.
You are also risking pathfinder trouble when commanding so many biters since that will be a lot of pathfinding to run in short time.

User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5150
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: some biter entity.set_command seems to be super slow?

Post by Klonan »

yagaodirac wrote:
Sat Mar 13, 2021 2:02 pm
Every time I have to call this on 10k biters. The tick I call this, the game lag for a third second.
Well no wonder, doing 10k API calls no matter what is going to be pretty heavy
yagaodirac wrote:
Sat Mar 13, 2021 2:02 pm
Any suggestions?
As Orzelek said, spread it out over several ticks, for instance you can say it will only do 100 units per tick

yagaodirac
Fast Inserter
Fast Inserter
Posts: 152
Joined: Sun Jun 16, 2019 4:04 pm
Contact:

Re: some biter entity.set_command seems to be super slow?

Post by yagaodirac »

orzelek wrote:
Sat Mar 13, 2021 2:52 pm
Yes, it must be very reliable.

yagaodirac
Fast Inserter
Fast Inserter
Posts: 152
Joined: Sun Jun 16, 2019 4:04 pm
Contact:

Re: some biter entity.set_command seems to be super slow?

Post by yagaodirac »

Klonan wrote:
Sat Mar 13, 2021 3:08 pm
I made a scenario with only control.lua file.
I tried to set command both via a lua table(directly set to every biter) or a unit group.
The direct way doesn't work in crowded situation. And if the distraction set to by_enemy, the biters disappear after 10ish seconds.
The indirect way( via a unit group) moves the biters no matter how crowded the group is. But it's way slower than the direct way.

But no matter which method, I have to write a container. Why don't you provide a container, like std::vector in cpp.


The file is like

Code: Select all

-------------- CALL BACK ----------------
script.on_event(defines.events.on_chunk_generated, function(event)
      --log(serpent.block(event))

   if math.abs(event.position.x)>100 or math.abs(event.position.y)>100
   then
      --game.print("TOOOOOOOOOOOOOOOOOO FAAAAAAAAAAAAAAAAAAAAAAAAARRRRRRR")
      local void_tiles = {}
      local index = 1
      for x = event.area.left_top.x, event.area.right_bottom.x - 1 
      do
         for y = event.area.left_top.y, event.area.right_bottom.y - 1 
         do
            void_tiles[index] = {name = "out-of-map", position = {x,y}}
            index = index + 1
         end
      end
      game.surfaces[1].set_tiles(void_tiles)
      return 
   end



   local auto_gen_resource = event.surface.find_entities_filtered{area = event.area, type = "resource"}
   for k,v in pairs(auto_gen_resource)
   do v.destroy()
   end
   local auto_gen_enemy = event.surface.find_entities_filtered{area = event.area, force = "enemy"}
   for k,v in pairs(auto_gen_enemy)
   do
      if v.name == "biter-spawner" or 
         v.name == "spitter-spawner" or 
         v.name == "small-worm-turret" or
         v.name == "medium-worm-turret" or
         v.name == "big-worm-turret" or 
         v.name == "behemoth-worm-turret" 
      then v.destroy()
      end
   end
   local auto_gen_tree = event.surface.find_entities_filtered{area = event.area, type = "tree"}
   for k,v in pairs(auto_gen_tree)
   do 
      v.destroy()
   end
   local auto_gen_simple_entity = event.surface.find_entities_filtered{area = event.area, type = "simple-entity"}
   for k,v in pairs(auto_gen_simple_entity)
   do 
      v.destroy()
   end


end)







script.on_event(defines.events.on_tick, function(event)
   if game.tick == 0
   then 
      game.players[1].character.destroy()
   end

   if game.tick == 0
   then 
      biters = {}
      unit_group = game.surfaces[1].create_unit_group({position = {0,0}})
      for i = 1,5000
      do
         biters[i] = game.surfaces[1].create_entity({name = "small-biter", position = {math.random()*100, math.random()*100}})
         unit_group.add_member(biters[i])
      end

      --log(serpent.block(biters))

      belts = {}
      for x = -100,100,10 do
         for y = -100,100,10 do
            belts[#belts+1] = game.surfaces[1].create_entity({name = "transport-belt", position = {x,y}, force = "player"})
         end
      end
   end


   if game.tick%60 == 11111111111111111111111
   then
  

      for k,v in ipairs(biters)
      do
         if v.valid
         then  
            v.set_command({type = defines.command.go_to_location, 
               destination = {math.random()*4-200, math.random()*4-200},
               distraction = defines.distraction.none,
               --pathfind_flags = {
               --   allow_destroy_friendly_entities  = false,
               --   allow_paths_through_own_entities =false,
               --   cache = false,
               --   prefer_straight_paths = true,
               --   low_priority =false,
               --   no_break  = true
               --},
               radius = 10
               })
         end
      end
   end


   if game.tick%60 == 1
   then
      unit_group.set_command({type = defines.command.go_to_location, 
         destination = {math.random()*4-200, math.random()*4-200},
         distraction = defines.distraction.none,
         --pathfind_flags = {
         --   allow_destroy_friendly_entities  = false,
         --   allow_paths_through_own_entities =false,
         --   cache = false,
         --   prefer_straight_paths = true,
         --   low_priority =false,
         --   no_break  = true
         --},
         radius = 10
         })
   end

   for k,v in ipairs(belts)
   do 
      if v.valid
      then
         v.health = 11111
      end
   end

end)

Post Reply

Return to “Modding help”