First of all; your Humanoid list is being fetched by iterating over the entire Workspace. Depending on how many immediate descendants (children) of the Workspace you have, the list that the script needs to work with grows absurdly. That’s added the fact that it performs this operation in a cycle that lasts less than a full second.
You have a few ways of changing the line list = game.Workspace:children()
to stop it from polling a massive amount of instances at a time. As well, there are some issues with this code itself, albeit minor.
Issues:
-
game.Workspace
is a “legacy” method of indexing the Workspace. You should either use the workspace
variable that references it, or game:GetService("Workspace")
as the canonical way to fetch a service.
-
Instance:children()
was deprecated in favour of Instance:GetChildren()
for better naming convention. Try to avoid using deprecated methods, as it is good practice.
Potential Solutions:
- Place any relevant NPCs in a Folder and change the list to iterate through the children of that folder instead
- Create a ModuleScript that handles the gathering of any Humanoid figures in the game and polls an update of the list every few seconds (I usually go with 3); replace this line to fetch the Humanoid [1]
- Use the CollectionService to tag any Humanoids currently in or added to the game, then iterate through any tagged Humanoids via
CollectionService:GetTagged("YOUR_TAG_NAME")
[1]:
local Module = {}
local HumanoidList = {}
local function UpdateList()
while true do
HumanoidList = {}
for _, Member in pairs(SOME_LOCATION) do
if Member:FindFirstChild("Humanoid") then
table.insert(HumanoidList, Member.Humanoid)
end
end
wait(3)
end
end
spawn(UpdateList)
function Module.GetList()
return HumanoidList
end
function Module.GetCharacterModelFromHumanoid(Humanoid)
return Humanoid:FindFirstAncestorOfClass("Model")
end
return Module
Caveats with the above code:
- There are no practical application examples; it’s up to you to determine how to use or modify the above code to suit your needs, if you go with a ModuleScript approach
- I do not do any type checking or argument validation; I simply assume that every use of the ModuleScript is properly done
- The update function itself still poses the same problem of determining where it’s appropriate to fetch your list from. See my potential solutions above
- As this is just an example and not something I put effort into, it’s not necessarily the best piece of work. I encourage you to refactor it yourself or apply another system that’s still capable of retrieving characters and/or their humanoids
After all that’s said and done, that’s the main point of concern that is really to be taken up. There’s just a couple more things that I would like to point out.
This is going to evaluate to 0, so your while loop is going to inherit the minimum from wait(N)
. You can fix this in three ways that I know of:
- Use whole numbers and divide.
math.random(5, 5)/10
- Use the Random API.
Random.new():NextNumber(0.5, 0.5)
- Just use
wait(0.5)
and get rid of the random statement altogether.
The fact that your code runs this fast while being expensive is one of the largest sources of lag for your game. If you can fix the function to not iterate through the workspace for NPCs and change this interval, you should be good.
This wouldn’t cause lag. The main issue is the code you’re using itself. So long as you aren’t running any expensive functions frequently or using code that prompts red flags for lag, you’ll be fine. A singular control script is usually nice for certain things but if you can’t do it, don’t worry about it yet. To me, this kind of thing just serves as a way to streamline behaviour and update one thing if I have to update multiple; it still requires extra work to accommodate for specialised settings per NPC or whatever.
I’m not sure what they meant by “custom scripts”, since there’s literally only LuaSourceContainers available to you. This advice is… well, fairly useless, especially if they can’t give a reasoning or explanation behind what they’ve said, much less if they even know what they’re talking about.
It depends. There is nothing inherently bad with setting a low interval for a while loop. What causes a problem is if you’re running expensive functions within those intervals, which is the main produce of lag. In the case that you have lag for small loops, you either have to think about the efficiency of the functions you’re running or a longer interval (which is typically just a band-aid solution, since the expensive function would still exist).
In the instance that a zero value is passed to wait(N)
, it’ll use the minimum. The interval isn’t the only concern, though having a decent interval is surely appreciated when it comes to looping code (depending on the use case, it changes). The main problem is a combination of both an extremely low interval between each loop and the function being called in it.
Humanoids themselves are expensive but that’s in terms of the coding department and a majority of that expense is handled in the backend. There’s another underlying issue and that stems from the script being used itself, which is from a legacy era of NPCs.