Take a screen shot of all of the client memory.
Does your game use MeshParts? if so, try setting the collision fidelity for some of the more complex meshes to either Hull or Box and see if you can still reproduce the problem. This is what was happening in my game pre-release. I was going mad trying to figure out the cause of the lag spikes, scanning every line of code in the game. Then I changed all the meshes to Hull and it resolved itself.
It varies from Studio to actual Player, but I have never witnessed it go above 600 MB.
It does use quite a bit of MeshParts yes. I’d say 90% of the time I make sure to use Box fidelity but I will triple check.
I’ll keep you posted, thanks.
If you use quite a bit of MeshParts and already have many of them set to either Box or Hull, I think your problems might be less physics related and more rendering related. Try turning on Network Streaming (if that’s an option) and see how much that affects performance. I was having problems with rendering causing frame drops on mobile devices and ended up setting up my own custom chunk-loading system for my game to fix the problem. Also having RenderFidelity set to Automatic helps a ton too.
With the MicroProfiler, it always seems to be a game of pure chance. If you read the quote, it prefaces with to my understanding. There’s simply not enough raw information on the MicroProfiler to adequately use it to pinpoint performance issues, at all. You just have to assume based on what a label reads and take a shot in the dark while attempting to address areas of performance.
That being said, going off of the largest bars in your game, it seems that you will need to look into optimising the following (completely best guesses, I have no clue what I’m talking about):
- Scene, Shadows: Relates to the lighting engine. Are you using ShadowMap?
- runJob: Loops in the scheduler. This can be from while, for or RunService-bound loops.
- Physics: Anything simulated by the physics engine. That’s all non-anchored parts, if I recall correctly. There may be other criteria to meet, though I doubt it.
- gameStepped: Seems that Stepped needs to complete a lot of operations.
- Stepped: Ditto. ^
- Humanoid: Humanoids by nature are very expensive. Try reducing the cost of humanoids through various actions like disabling state types you do not need for humanoids.
Really though? Optimise, optimise, optimise. But do not micro-optimise and waste your time. Pass some small operations to the client and use the server as a medium to transfer data to other clients for rendering or whatever (provided input is checked).
By the way: if you’re doing tweens, absolutely stay away from the server if you aren’t doing so already. It’s easier on you to write it but more taxing on performance to carry it out. If a tween needs to be done, get the server to pass data to all clients and have the clients run the tweens.
Thank you for the detailed reply!
I am using ShadowMap lighting, it looks very nice though noticing the Scene bar I figure that it’s costly. Is this true? I would hope not as I can’t see myself switching back to Voxel or Compatibility as ShadowMap truly completes the game aesthetically.
As for Humanoids & Tweening, I have a lot of humanoids but 75% of them perform animations only and act as nothing else.
I did not know Tweening was so costly to the server. I did a stress test when I was testing Tweening vs Humanoid:MoveTo() for pathing and tweening the characters cut the lag in half.
I feel the method for tweening you mention sounds like it could be more bad than good at least for my game.
Just one of the things that move are enemies, and they walk down a long path marked with nodes to reach the end. Sometimes they can be ‘Stunned’ which halts their pathing for a time, or sometimes other things will stop them very, very frequently. Sometimes there are up to 100 or more of these enemies. Would this not be more costly to be firing to all clients?
If you’re already using Tweening to move them around, maybe it wouldn’t be so hard to convert your NPCs to non-Humanoid NPCs? Just a thought. For some reason, Humanoids cause huge amounts of physics lag. I also had this problem before.
See here: NPCs Causing FPS Drops
But how would I use animations if I removed the humanoids?
I know there’s lerping and such but I would have to revamp almost everything and CFraming animations is ridiculously tedious.
Again, most of my post is based off of assumptions. I have absolutely no clue what I’m talking about, but hopefully something I said has some relevance and could potentially see improvements if picked away at. I just read the labels and made as best a guess I could.
I would assume that it is costly, considering that ShadowMap has significantly more to render especially with shadows and the control you’re given over them. I’m talking about the properties of Lighting and the ability to cast shadows from BaseParts.
That being said, ShadowMap itself probably isn’t expensive since I’ve seen games running fine with it - the expensive is probably correlated to what it needs to calculate before rendering shadows. Note how I said shadows can be rendered by BaseParts earlier - that means factoring in unions and MeshParts.
ShadowMap is in fairly early release, so I wouldn’t expect it to be the most performant lighting option available. It could be optimised down the road, but for now, developers need to help themselves to this optimisation by also ensuring that the lighting engine isn’t rendering too much at once. Don’t underestimate the engine though; it’s very quick but sometimes an intensive game can hamper performance.
Humanoids are still expensive on the backend. Just having a humanoid itself already brings the backend expenses of a humanoid to the table. One commonly known method of bringing down the expense of humanoids is by disabling their state types.
Yeah. Tweening on the server is generally a bad idea, as is any kind of aesthetic handling on the server’s end. Tweens have to set a property’s value over time and work in tandem with any events related to changing properties. I myself tween on the server, but if you compare tweening on the server and the client in a full game environment, you’ll notice the server’s tween is choppy.
Remotes can take up to 60 KB/second and clients can handle a lot of operations. The bottleneck is only the time it takes to make a trip from the server to the client, their own device specifications and their network. Clients are capable of handling a lot - typically inconsequential things while the server handles crucial tasks that can affect game play.
Firing to all clients would hardly have much of a cost, surprisingly. The only cost you’re going to get is sending data from the server to clients. The data you send is probably only worth a few bytes - remote limits sit at a full 60 KB. Assuming you only send a single byte of data, that’s around 1.7x10-4 % of your sending limit, which is very small.
I don’t know how to do such a thing first-hand, but can’t you fetch the animation data and then CFrame the parts accordingly? I’m not entirely sure, but this sounds like something someone must’ve made a script for by now.
I just know that Humanoids are super physics heavy and 100+ (like you were saying you have) will cause immense lag problems if all within close proximity of each other. I was having problems with only 15-20 being close to each other & had to scrap an entire game not too long ago.
Unfortunately, you can’t break down an uploaded animation into its keyframes and poses, which means that getting CFrame data and applying it to limbs is not possible. The best way to reuse animations with humanoids is to use an AnimationController, though they’ve supposedly given some developers grief when it comes to replication. Don’t think that’d be much of an issue in this case though.
Ah, yes. I forgot about AnimationControllers tbh since I’ve never had a real use for them in any of my games. I feel AnimationControllers would be a much better solution than keeping every drawback that Humanoids have in them just for the sole purpose of animations.
Which humanoid state costs the least?
And which method would ensure it remains that way.
hum:SetStateEnabled(Enum.HumanoidStateType.RunningNoPhysics,true)
hum:SetStateEnabled(Enum.HumanoidStateType.FallingDown,false)
hum:SetStateEnabled(Enum.HumanoidStateType.Running,false)
hum:SetStateEnabled(Enum.HumanoidStateType.Climbing,false)
hum:SetStateEnabled(Enum.HumanoidStateType.Ragdoll,false)
hum:SetStateEnabled(Enum.HumanoidStateType.GettingUp,false)
hum:SetStateEnabled(Enum.HumanoidStateType.Jumping,false)
hum:SetStateEnabled(Enum.HumanoidStateType.Landed,false)
hum:SetStateEnabled(Enum.HumanoidStateType.Flying,false)
hum:SetStateEnabled(Enum.HumanoidStateType.Freefall,false)
hum:SetStateEnabled(Enum.HumanoidStateType.Seated,false)
hum:SetStateEnabled(Enum.HumanoidStateType.PlatformStanding,false)
hum:SetStateEnabled(Enum.HumanoidStateType.Dead,false)
hum:SetStateEnabled(Enum.HumanoidStateType.Swimming,false)
hum:SetStateEnabled(Enum.HumanoidStateType.Physics,false)
or
enemy.Humanoid.StateChanged:connect(function(s)
if s ~= Enum.HumanoidStateType.RunningNoPhysics then -- or whichever statetype is the most efficient
enemy.Humanoid:SetStateEnabled(s,false)
end
end)
What’s the interval in ms between each line in ur screenshot
There is none it’s not a loop it’s just a block of code that assigns some things. Humanoid:SetStateEnabled() makes it so they cannot change to that state, though I’m not sure if it always works.
I had a case where it switched back to a state that I kept disabling. This was a long time ago though so I might’ve done something wrong.
No like in your first screen shot zoom out to like 12ms in the micro profiler and take the screen shot again
Disabling or enabling a state is one time. Once a state is disabled, the humanoid cannot ever enter that state. If it’s enabled the humanoid can enter that state. The first one is what you want - obviously though, in a different manner, such as a table.
Here’s some further screenshots from different frames after a few tweaks. Physics is getting better though it has a few big stalls like this once and a while though not as often as before.
Render is now starting to pop up a lot more and a lot stronger.
So is “Replicator ProcessPackets”.
Sometimes this lag happens when there appears to be nothing much going on and sometimes it will happen when there is a lot going on.
Pinpointing this has proven to be very difficult. And yet somehow all my scripts are running optimally as before, nothing is overworking (or seems to be in the console).
Another question I have…
If I were to put the culprits of the Physics stalling into a state of ‘total non-collide-ability’ by setting their collision group to not collide with anything else, would that not fix or at least help ease the problem?