Check whether an entity has power?

Place to get help with not working mods / modding interface.
Post Reply
KoRaLLL
Burner Inserter
Burner Inserter
Posts: 15
Joined: Sun Sep 11, 2022 7:22 pm
Contact:

Check whether an entity has power?

Post by KoRaLLL »

Hey all!

Just a quick question, I have the below function for checking whether or not an entity that resides in a specific type has power or not.

The function of this is that, if this entity doesn't have power, it explodes.

Code: Select all

function check_power(event)

	-- Check every second --
	if event.tick % 60 == 0 then

		-- Loop the surfaces to find all of these entity types --
		for _,surface in pairs(game.surfaces) do
			
			-- These entities --
			local all_entities = game.surfaces[surface.index].find_entities_filtered{type = search_types}

			-- Now we loop each entity, checking whether or not they are powered --
			if(next(all_entities)) then
				for _,entity in pairs(all_entities) do

					-- Does this entity have power usage and is a part of a network? --
					if(entity.is_connected_to_electric_network() == false or entity.power_usage == 0) then
						entity.destroy()
					end

				end
			end

		end

	end

end
The code functions as I'd expect and it works, but I worry about the impact on late-game UPS with using the on_tick event.

Is there a better way to check whether or not an entity is currently powered? The issue comes from the fact that this needs to be "up to date".

As always, I appreciate any and all help/assistance here. Thank you!

User avatar
Stringweasel
Filter Inserter
Filter Inserter
Posts: 318
Joined: Thu Apr 27, 2017 8:22 pm
Contact:

Re: Check whether an entity has power?

Post by Stringweasel »

There two main ways you can optimise this loop:

- Most important, don't find_entities every time. Rather listen to build/destroy events and with that keep a list in global of all the entities you want to check. Then loop through that list. This is typically called caching.
- You can limit the amount of entities the loop can process at once, like 50 for example. And then stagger the checks, e.g: using a function like flib's https://factoriolib.github.io/flib/modu ... l#for_n_of
Alt-F4 Author | Factorio Modder
Mods: Hall of Fame | Better Victory Screen | Fluidic Power | Biter Power | Space Spidertron | Spidertron Dock | Weasel's Demolition Derby

KoRaLLL
Burner Inserter
Burner Inserter
Posts: 15
Joined: Sun Sep 11, 2022 7:22 pm
Contact:

Re: Check whether an entity has power?

Post by KoRaLLL »

Stringweasel wrote:
Wed Jan 18, 2023 3:11 pm
There two main ways you can optimise this loop:

- Most important, don't find_entities every time. Rather listen to build/destroy events and with that keep a list in global of all the entities you want to check. Then loop through that list. This is typically called caching.
- You can limit the amount of entities the loop can process at once, like 50 for example. And then stagger the checks, e.g: using a function like flib's https://factoriolib.github.io/flib/modu ... l#for_n_of
I appreciate this response. I am caching the entities already for another function, but it didn't seem relevant here.

You say to listen to the build/destroy events..but what about in cases where a boiler runs out of fuel? Nothing has been built/destroyed, but power has been lost, and in this event I'd like to trigger my function, but as far as I'm aware there's no events related to the loss of power.

And for the # of entties to loop through, in this instance the player will be able to build as many of these entities as they like.

I understand that it's not too optimised but I can't see any way to track power loss.

User avatar
Stringweasel
Filter Inserter
Filter Inserter
Posts: 318
Joined: Thu Apr 27, 2017 8:22 pm
Contact:

Re: Check whether an entity has power?

Post by Stringweasel »

KoRaLLL wrote:
Thu Jan 19, 2023 7:37 am
You say to listen to the build/destroy events..but what about in cases where a boiler runs out of fuel? Nothing has been built/destroyed, but power has been lost, and in this event I'd like to trigger my function, but as far as I'm aware there's no events related to the loss of power.
That's not what I meant, maybe I didn't explain it correctly :)

I'm saying to use the build/destroy events to keep track of all the entities in the game that you want to check the power of. And then every tick (or 60) you loop through that cached list. Currently your loop will every tick (or 60) search every surface for every entity, which is really bad for performance. You'll start seeing it when you have multiple surfaces and thousands of entities.

I did the same thing for Biter Power where I need to roll a dice every now and then for every applicable entity and see if the biters inside might escape. The on_build is here. And you can see during the on_tick calculations there is no `find_entities_filtered` or similar.
Alt-F4 Author | Factorio Modder
Mods: Hall of Fame | Better Victory Screen | Fluidic Power | Biter Power | Space Spidertron | Spidertron Dock | Weasel's Demolition Derby

KoRaLLL
Burner Inserter
Burner Inserter
Posts: 15
Joined: Sun Sep 11, 2022 7:22 pm
Contact:

Re: Check whether an entity has power?

Post by KoRaLLL »

Stringweasel wrote:
Thu Jan 19, 2023 8:18 am
KoRaLLL wrote:
Thu Jan 19, 2023 7:37 am
You say to listen to the build/destroy events..but what about in cases where a boiler runs out of fuel? Nothing has been built/destroyed, but power has been lost, and in this event I'd like to trigger my function, but as far as I'm aware there's no events related to the loss of power.
That's not what I meant, maybe I didn't explain it correctly :)

I'm saying to use the build/destroy events to keep track of all the entities in the game that you want to check the power of. And then every tick (or 60) you loop through that cached list. Currently your loop will every tick (or 60) search every surface for every entity, which is really bad for performance. You'll start seeing it when you have multiple surfaces and thousands of entities.

I did the same thing for Biter Power where I need to roll a dice every now and then for every applicable entity and see if the biters inside might escape. The on_build is here. And you can see during the on_tick calculations there is no `find_entities_filtered` or similar.
Haha when I was on my drive this morning I had an epiphany of what you actually meant!

Thanks again for this and the explanation, this makes wayyyyyyyy more sense than looping all entities of that type.

Post Reply

Return to “Modding help”