Jump to content

Retiring entities and TheSim:FindEntities


Tykvesh
  • Closed

Entities that are removed from Ents table but not retired yet, may break the return table from TheSim:FindEntities with a nil value. I assume FindEntities translates GUIDs intro entities via the Ents table, so that's why it ends up with a nil.

Since ipairs is often used with FindEntities, this will cause the loop to stop at the nil value, skipping the rest of the table.

function EntityScript:Remove()
	if self.parent then
		self.parent:RemoveChild(self)
	end
	
	if self.platformfollowers then
		for k,v in pairs(self.platformfollowers) do
			k.platform = nil
		end
	end
	
	OnRemoveEntity(self.GUID)
	
	--Anything below that uses FindEntities may get a broken table
	
	self:PushEvent("onremove")
	
	--tell our listeners to forget about us
	self:StopAllWatchingWorldStates()
	self:RemoveAllEventCallbacks()
	self:CancelAllPendingTasks()
	
	for k, v in pairs(self.components) do
		if v and type(v) == "table" and v.OnRemoveEntity then
			v:OnRemoveEntity()
		end
	end
	
	for k, v in pairs(rawget(self.replica, "_")) do
		if v and type(v) == "table" and v.OnRemoveEntity then
			v:OnRemoveEntity()
		end
	end
	
	if self.updatecomponents then
		self.updatecomponents = nil
		UpdatingEnts[self.GUID] = nil
		num_updating_ents = num_updating_ents - 1
	end
	NewUpdatingEnts[self.GUID] = nil
	
	if self.wallupdatecomponents then
		self.wallupdatecomponents = nil
		WallUpdatingEnts[self.GUID] = nil
	end
	NewWallUpdatingEnts[self.GUID] = nil
	
	if self.children then
		for k,v in pairs(self.children) do
			k.parent = nil
			k:Remove()
		end
	end
	
	if self.OnRemoveEntity then
		self:OnRemoveEntity()
	end
	self.persists = false
	self.entity:Retire()
end

Steps to Reproduce

This is fixed by hiding the entity from searches by adding the "CLASSIFIED" tag:

function OnRemoveEntity(entityguid)
	PhysicsCollisionCallbacks[entityguid] = nil

	local ent = Ents[entityguid]
	if ent then
		if debug_entity == ent then
			debug_entity = nil
		end

		BrainManager:OnRemoveEntity(ent)
		SGManager:OnRemoveEntity(ent)

		ent:KillTasks()
		NumEnts = NumEnts - 1
		Ents[entityguid] = nil
		
		--the entity is removed from Ents table but not retired yet
		--so we don't want to include it in FindEntities searches anymore
		ent:AddTag("CLASSIFIED")

		if UpdatingEnts[entityguid] then
			UpdatingEnts[entityguid] = nil
			num_updating_ents = num_updating_ents - 1
		end

		if WallUpdatingEnts[entityguid] then
			WallUpdatingEnts[entityguid] = nil
		end
	end
end
  • Like 1



User Feedback


FindEntities doesn't find retired entities, lua's ipairs also is "weird" and will actually continue iterating for ipair even if it encounters a nil value in cases like this.
Changed Status to Closed

  • Thanks 1
  • Potato Cup 1

Share this comment


Link to comment
Share on other sites

@zarklord_klei That's why I specified that this happens before the entity is retired. There's a bunch of callbacks between an entity being removed from Ents table and being retired (see above).

Also, ipairs in DST worked the way you would expect it to for years on my end.

Edit: Here's a quick test:

local test = SpawnPrefab("waffles");
test:SpawnChild("figatoni");
test:ListenForEvent("onremove", function(inst) local ents = TheSim:FindEntities(0, 10000, 0, 0);
print("spawned waffles and figatoni");
print("search results during 'onremove' event for waffles:");
print("ipairs:");
for i, v in ipairs(ents) do print(i, v) end;
print("pairs:");
for k, v in pairs(ents) do print(k, v) end end);
test.Transform:SetPosition(0, 10000, 0);
test:Remove()
Quote

[00:21:41]: spawned waffles and figatoni    
[00:21:41]: search results during 'onremove' event for waffles:    
[00:21:41]: ipairs:    
[00:21:41]: pairs:    
[00:21:41]: 2    103481 - figatoni    

Edited by Tykvesh
  • Like 1

Share this comment


Link to comment
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
  • Create New...