Page 1 of 1

Slow down with Tile entity

Posted: Sun Oct 08, 2017 2:01 am
by TheSAguy
Hi,

In my mod Bio Industries, I've added a new tile, called the Musk Floor. It's a tile that creates electricity like a solar panel.
The way it works is that I create a hidden solar panel when you place the floor.

I've has a few posts about this entity causing slow-down when placed in bulk, especially in Multiplayer
I'm not sure why that is, but suspect it has something to do with my check when removing or replacing tile.

Here is that code:
Code
Again, this is just a guess. I was hoping someone could possibly review my code and see if there is something I'm doing that would cause this slow-down.
Someone also reported this crash when replacing some tiles. I've never had it crash though.
I've attached the mod and just the control file.
Thanks.

Re: Slow down with Tile entity

Posted: Sun Oct 08, 2017 3:43 am
by quyxkh
Cheap checks first, and cache expensive-check results, and don't do checks you don't use the results of.

I factored out common code and applied some whitespace discipline.

Code: Select all

local function solar_mat_removed_at(surface, position)
	local radius = 0.5
	local area = {{position.x - radius, position.y - radius}, {position.x + radius, position.y + radius}}
	local n = 0
	for _,o in next,surface.find_entities_filtered{name='bi_solar_pole',area=area} or {}
		do o.destroy() n = n+1 end
	writedebug(string.format('%g bi_solar_poles removed',n))
	for _,o in next,surface.find_entities_filtered{name='bi_solar-panel_for_Solar-Mat',area=area} or {}
		do o.destroy() n = n+1 end
	writedebug(string.format('bi_solar-panel_for_Solar-Mat',n))
	end

local function Player_Tile_Remove(event)
	local player = game.players[event.player_index]
	if event.item_stack.name == 'bi-solar-mat' and player.mining_state.mining then
		writedebug(string.format('%g solar mats removed',event.item_stack.count))
		return solar_mat_removed_at(player.surface, player.mining_state.position)
		end
	end


local function Robot_Tile_Remove(event)
	local robot = event.robot 
	if event.item_stack.name == 'bi-solar-mat' then
		writedebug(string.format('%g solar mats removed',event.item_stack.count))
		return solar_mat_removed_at(robot.surface,robot.position)
		end
	end
--------------------------------------------------------------------
but I think this is going to have other problems too. Here's a trace I get from placing a 5×5 batch of hazard concrete:

Code: Select all

on_player_mined_item    {item_stack = {count = 8, name = "concrete"}, name = 8, player_index = 1, tick = 50764}
on_player_mined_item    {item_stack = {count = 1, name = "hazard-concrete"}, name = 8, player_index = 1, tick = 50764}
on_player_built_tile    {name = 45, player_index = 1, positions = {{x = 0, y = 0}, {x = 0, y = 1}, {x = 0, y = 2}, {x = 0, y = 3}, {x = 1, y = -1}, {x = 1, y = 0}, {x = 1, y = 1}, {x = 1, y = 2}, {x = 1, y = 3}, {x = 2, y = -1}, {x = 2, y= 0}, {x = 2, y = 1}, {x = 2, y = 2}, {x = 2, y = 3}, {x = 3, y = -1}, {x = 3, y = 0}, {x = 3, y = 1}, {x = 3, y = 2}, {x = 3, y = 3}, {x = 4, y = -1}, {x = 4, y = 0}, {x = 4, y = 1}, {x = 4, y = 2}, {x = 4, y = 3}}, surface_index = 0, tick = 50764}
You're going to need to check all the built-tile locations, not just the one the player clicked near.