Trying to put all gun visuals on the client. Have a game where players have pets that fire when the player fires and there are many different kinds of pets and many different kinds of weapons. Current plan: use collection service to
(1) tag pets with ownerID
(2) tag with type of weapon.
When player fires weapon client finds all pets in workspace with player tag and uses the weapon tag to identify the right visual. My concern is that if CollectionService works in the way that loops work in scripts, then this is going to be really costly and slow–and so I should find a different method. I’ve tried loops, they are too costly.
So my question is:
Is using collection service to identify workspace pets with both tags 1 and 2 more efficient than looping through all of the pets in workspace looking for weapon type and ID number (in an IntValue in the pet)?
Or is collection service just another way of doing basically this (and so no better than script loops)?
Clarification. I will have to loop through the table that is returned by CS, of course, but I am hoping to use CS to identify all the relevant pets to loop through in the client code.
It theoretically more efficient as loops would would add lag etc, collectionservice is a service by the game, I’ve used it many times and it’s reliable, for me.
But approximately, how many :GetTagged() functions can I run per second before I run into problems? Can I run (say) 50 gettagged requests in a second? Or will it start to lag? Anyone have any idea?
Interesting. The developer page does talk about “memory leak” being caused by an object just having an unnecessary tag. So maybe there is a running list on the server that can just be accessed directly with little cost? Or perhaps there is concern because the unnecessary tag would trigger tagadded functions in the game involving the tag. Not sure.
I’m pretty sure collection tags are serialized into the instance itself. After all, those tags stay saved between different studio sessions of the same place. That’s probably what they mean by “memory leak from unnecessary tags”.
From my benchmarking turns out GetTagged is slower than organizing your desired Instances in a folder and using :GetChildren(). The difference in per line of code run is micro seconds 6.7827449998003e-05 second which eh is not that significant in my opinion, I’m not going to notice that. Also turns out the speed scales with the amount of parts with the tag with 250 parts (both in folder and workspace) the difference becomes only 1.7577239999082e-05 seconds.
21:35:46.786 Collection service amount: 1000 - Server - Script:18
21:35:46.787 Get children amount: 1000 - Server - Script:21
21:35:48.954 Elapsed time collection service: 1.1235491999832 - Server - Script:31
21:35:48.954 Second per call 0.00011235491999832 - Server - Script:33
21:35:49.400 Elapsed time get children: 0.44527470000321 - Server - Script:40
21:35:49.400 Second per call 4.4527470000321e-05 - Server - Script:42
21:35:49.400 GetChildren is faster than get tagged by: 6.7827449998003e-05 - Server - Script:44
Reproduction code, just copy and paste into a server script:
Summary
local CollectionService = game:GetService("CollectionService")
local folder = Instance.new("Folder")
folder.Parent= workspace
for i=1,1000 do
local part = Instance.new("Part")
part.Anchored = true
part.Parent = folder
end
for i=1,1000 do
local part = Instance.new("Part")
part.Anchored = true
part.Parent = workspace
CollectionService:AddTag(part,"IsAPart")
end
local data = CollectionService:GetTagged("IsAPart")
print("Collection service amount: ", #data)
local data = folder:GetChildren()
print("Get children amount: ", #data)
wait(1)
-- Record the initial time:
local startTime = os.clock()
for i = 1, 10000 do
local data = CollectionService:GetTagged("IsAPart")
end
-- Measure amount of time this took:
local deltaTime = os.clock() - startTime
print("Elapsed time collection service: " .. deltaTime)
local t1 = deltaTime/10000
print("Second per call",deltaTime/10000)
local startTime = os.clock()
for i = 1, 10000 do
local data = folder:GetChildren()
end
-- Measure amount of time this took:
local deltaTime = os.clock() - startTime
print("Elapsed time get children: " .. deltaTime)
local t2 = deltaTime/10000
print("Second per call",deltaTime/10000)
print("GetChildren is faster than get tagged by: ",t1-t2)
Let me know if I did my math wrong or if there are other factors which effects collection services performance which I’m unaware of.
Interesting. For all practical purposes, it seems as though GetTagged and GetChildren are about equal. But GetTagged seems to always run on server? Whereas GetChildren can run on client?
No, you can use both Get Tagged and Get Children on server and client. Just be aware of replication of the tags from server to client and not client to server unless you use remote events.
I can call the collection service from the client, but the actual activity of searching and bringing back the instances with the right tags is run by server, no? Because it is a service. Whereas if I run a GetChildren function in a local over workspace all of the computing is done on the client. Isn’t this right?
No, CollectionService runs on both server and client. Both the client and the server keep copies of all of CollectionService’s information. When you call CollectionService’s methods, these act immediately on the computer that called them, using the information it has stored locally, regardless of whether it is the server or a client. So if you call GetTagged on the client, computing will happen on the client.
The important thing to note is that changes to this information on the server, such as calling AddTag, will also be copied to all of the clients’ own versions of CollectionService. But if you change information on the client, e.g. again by calling AddTag, this will not be copied back to the server and the other clients (because we want to prevent exploiters being able to change the game for everyone). This process of copying data from server to client, or client to server, or client to client, is called replication.
No, you cannot. You will need to either use GetChildren/GetDescendants first and manually filter through the results to find particular tags, or call GetTagged and filter through for instances that are descendants of your folder.