Page 1 of 1

Filter that returns all bot (de)constructible entities in LuaSurface.find_entities_filtered

Posted: Fri Jan 11, 2019 7:10 am
by _italics_
Instead of using LuaSurface.find_entities and looping through the entire set of results to see if they are deconstructible or a ghost, I'd like to use find_entities_filtered.

Code: Select all

      local entities = player.surface.find_entities(area)
      for index,entity in pairs(entities) do
          if entity.to_be_deconstructed(player.force) or entity.type == "entity-ghost" or entity.type == "tile-ghost" then
              ...
          end
      end
Probably this would be much faster:

Code: Select all

    local entities = player.surface.find_entities_filtered{area = area, bot_constructible=true}

Side question, in https://www.factorio.com/blog/post/fff-256 I noticed:
We did a similar improvement a while back with the personal Roboports, where they independently check for nearby ghosts, outside of the global (per force) construction queue.
Sounds like exactly what I want, but it sounds like making this list/query accessible would be exposing a bit too much of the implementation details.

Re: Filter that returns all bot (de)constructible entities in LuaSurface.find_entities_filtered

Posted: Fri Jan 11, 2019 8:49 pm
by Rseding91
_italics_ wrote:
Fri Jan 11, 2019 7:10 am
Side question, in https://www.factorio.com/blog/post/fff-256 I noticed:
We did a similar improvement a while back with the personal Roboports, where they independently check for nearby ghosts, outside of the global (per force) construction queue.
Sounds like exactly what I want, but it sounds like making this list/query accessible would be exposing a bit too much of the implementation details.
All that does on the C++ side is exactly what you're doing.

Re: Filter that returns all bot (de)constructible entities in LuaSurface.find_entities_filtered

Posted: Sat Jan 12, 2019 2:14 pm
by _italics_
Yep, but it's a quite time-consuming step for me. I expect using a filter will be faster, presumably avoiding creating a lot of LuaEntities that will be discarded garbage anyway.

Here's a profile log from a large search area:

Code: Select all

00001.630: 00:14:08.00: Tick: 50880
00000.159: 00:14:08.00: finding entities
00096.835: 00:14:08.00: done finding 32406 entities
00001.801: 00:14:08.00: filtering entities
00189.109: 00:14:08.00: done filtering entities
00001.693: 00:14:08.00: targets: 17949
00000.353: 00:14:08.00: calculating distances
00053.693: 00:14:08.00: done calculating distances
00001.703: 00:14:08.00: sorting targets
00056.299: 00:14:08.00: done sorting targets

00928.845: 00:14:09.00: Tick: 50940
00001.714: 00:14:09.00: finding entities
00149.865: 00:14:09.00: done finding 32349 entities
00001.803: 00:14:09.00: filtering entities
00161.472: 00:14:09.00: done filtering entities
00001.695: 00:14:09.00: targets: 17892
00000.322: 00:14:09.00: calculating distances
00052.371: 00:14:09.00: done calculating distances
00001.703: 00:14:09.00: sorting targets
00054.479: 00:14:09.00: done sorting targets

00952.209: 00:14:10.00: Tick: 51000
00000.116: 00:14:10.00: finding entities
00195.362: 00:14:10.00: done finding 32323 entities
00001.743: 00:14:10.00: filtering entities
00159.473: 00:14:10.00: done filtering entities
00001.716: 00:14:10.00: targets: 17866
00000.330: 00:14:10.00: calculating distances
00049.141: 00:14:10.00: done calculating distances
00001.782: 00:14:10.00: sorting targets
00054.818: 00:14:10.00: done sorting targets
As you can see, retrieving and then filtering targets is taking most of the time.

edit2: removed irrelevant blabbering from this request

Re: Filter that returns all bot (de)constructible entities in LuaSurface.find_entities_filtered

Posted: Sat Jan 12, 2019 5:22 pm
by _italics_
More careful profiling showed that it was the to_be_deconstructed(player.force) call that took the most amount of time:

Code: Select all

00001.758: 00:14:08.00: Tick: 50880
00000.276: 00:14:08.00: finding entities
00090.411: 00:14:08.00: done finding 32406 entities
00019.670: 00:14:08.00: filtering loops
00027.862: 00:14:08.00: done filtering entity.type
00107.360: 00:14:08.00: done filtering tbd
00184.067: 00:14:08.00: inserted targets into temp table for profiling distance calculation
00001.744: 00:14:08.00: calculating distances to 17949 targets
00033.331: 00:14:08.00: done calculating distances

00903.011: 00:14:09.00: Tick: 50940
00001.734: 00:14:09.00: finding entities
00065.218: 00:14:09.00: done finding 32349 entities
00010.825: 00:14:09.00: filtering loops
00030.413: 00:14:09.00: done filtering entity.type
00164.391: 00:14:09.00: done filtering tbd
00220.140: 00:14:09.00: inserted targets into temp table for profiling distance calculation
00000.307: 00:14:09.00: calculating distances to 17892 targets
00034.890: 00:14:09.00: done calculating distances
Eventually I have figured out that moving player.force to a local variable makes it almost as fast as checking entity.type:

Code: Select all

         LOGGER.log("filtering loops")
         for index,entity in pairs(entities) do
            if entity.type == "entity-ghost" or entity.type == "tile-ghost" then
               n = n + 1
            end
         end
         LOGGER.log("done filtering entity.type")
         local force = player.force
         for index,entity in pairs(entities) do
            if entity.to_be_deconstructed(force) then
               n = n + 1
            end
         end
         LOGGER.log("done filtering tbd")

Code: Select all

00002.083: 00:14:08.00: Tick: 50880
00000.278: 00:14:08.00: finding entities
00084.582: 00:14:08.00: done finding 32406 entities
00018.234: 00:14:08.00: filtering loops
00031.167: 00:14:08.00: done filtering entity.type
00041.645: 00:14:08.00: done filtering tbd
00142.572: 00:14:08.00: inserted targets into temp table for profiling distance calculation
00001.730: 00:14:08.00: calculating distances to 17949 targets
00038.488: 00:14:08.00: done calculating distances
Not sure why accessing player.force is so slow.

Anyway, back to the original request, I still wish I could begin at the "calculating distances" point immediately after calling something like find_entities_filtered{area = area, bot_constructible=true}.

Re: Filter that returns all bot (de)constructible entities in LuaSurface.find_entities_filtered

Posted: Sat Jan 12, 2019 8:53 pm
by Rseding91
Accessing player.force creates a LuaForce every time you do it and is then thrown away.