I’ve noticed that when hosting a listen server, the host’s fps will drop by around 10-15 for each client that joins the game (even if the clients are not controlling a pawn and just spectating).
Does anyone know what’s causing this slowdown, or how I might investigate what is happening?
Thanks @Nathaniel3W I still haven’t used the GameplayProfiler, so I will certainly look into using it.
One extra bit of information; if i’m running both the client and host instances on the same machine, the client instant runs fine, while the host instance still sees the slowdown. Meaning it can’t be to do with using excessive system resources.
This leads me to think there are some blocking network functions that impact the fps render time for the host.
Just thought i’d add this in case anyone has any thoughts.
I’ve been trying to analyse performance using the gameplay profiler to determine why the listen host is dropping in performance so much for each client that joins.
This is “frame function summary” for the listen host. (PLEASE RIGHT CLICK AND OPEN IN NEW TAB TO VIEW). On the left is a profile of just the listen host in-game with no clients joined and the right is with two clients joined and in game:
This is the “aggregate function summary”:
I’m really not sure how to make much use of this data.
Even if clients join as spectators, the same drop in host’s performance occurs. Is doesn’t appear to be system resources related, as the host can host a dedicated server, then run the game on the same computer and join the server with no slowdown at all. Any ideas of what might be causing the slowdown would be much appreciated.
it’s hard to see a reason with this alone, but from a quick glance it seems you are doing a ton of traces which ends up adding a ton of time to the world tick time
go to the frame actor/class call graph and see where the traces are coming from. or maybe upload the profiling file somewhere to have a deeper look at it, since just this screenshot doesn’t give enough details into where the traces come from
I had a look at the profiles. there really seems to be a lot of time taken by traces but they don´t seem to come from your script code as they are not shown (they simply get grouped into World Tick Time) which probably means it’s something from native code
perhaps you have some particle with a collision module enabled? it’s the kind of thing that would be making native traces that don’t go through your code. either that or something of that nature
it’s a long shot but you could try different stats to try to isolate the source of the issue - UDK | StatsDescriptions
you can try all of them until you find which has a big delta between the player-less server and when the players join. I would start with collision, physics, or octree
actually the terminology described in the stats octree section of the documentation seems to match the terminology of the traces that were shown in your gameplay profiler sessions. maybe something with actor encroaching but that’s just a wild guess
Hmmmm, so this is interesting. Looking at the octree stats for host only and then host + 1 joined player shows a huge increase in “ZE MNF Checks”:
I need to test on the vanila UT example game to see if this is exclusively happening on my game. I wish there was a way to inspect the origin of these calls in UDK. @Chosker if you have any other ideas while I’m testing, i’m all ears. Thanks again for the ideas you’ve suggested so far.
Edit: Interestingly, I just tried on the stock map DM-Deck and this didn’t have the issue. The line checks increase was very mior and proportional with the extra player. So something about my map is causing a radical increase in line checks once the second player joins.
I’m afraid I cannot be of much more help at this time
from the docs this seems to be the more relevant increases on your case:
ZE MNF CHecks - Total zero extent multi-node filter checks performed.
ZE Line CHecks - Total Actor zero extent line checks performed.
sadly I don’t know how the octree works, all I know by now is that it seems related to the navmesh. however I never used the navmesh in my game so I don’t know much of its entrails.
there seems to be some console commands related to the octree though - UDK | ConsoleCommands just search for “octree” within that page. maybe one of those commands gives you enough verbose to understand what causes it
still, I have no clue why one joined player would cause such big difference though. another wild guess: out of world traces for an actor related to the joining client
I believe I’ve figured it out. For every client on the server, the server is doing a line-check to every single actor that is bAlwaysRelevant=false, which in my case was around 2000 loot actors spawned around the world.
This was occuring every NetUpdateFrequency per second (set per actor). Now I know what is causing it, i should be able to implement fixes to address the issue.
Side note: I wish there was a way to prevent replication checks for clients that are x distance away from said actor. The constraints you can set in the actor replicating applies to all clients on the server (apart from bNetOwner). Which is pretty limiting for an open-world game, where one client could be on the other side of the map from another.
yeah it’s sad you can’t prevent replication checks by distance on any actor.
in UE4 the Actor class has NetCullDistanceSquared which does exactly that. In UDK only the Projectile class seems to have NetCullDistanceSquared implemented natively, so apparently the only way to use it is to extend from the Projectile class :rolleyes:
otherwise yeah you’ll have to come up with something
Update: I added dynamic scaling of NetUpdateFrequency for all actors causing the issue, based on their distance from the nearest viewing player. The results are pretty awesome. Check the stats: coop_host_performance_benchmench.jpg - Google Drive
>200% performance increase for hosts. I’m very happy with the results. Thanks for your help @Chosker.