Although the Unreal Engine automatically applies occlusion culling, a lot of the traps and mini-games we make have code, animations, and particle effects that run in the background, even if they aren’t in the camera’s view. Most of it is quite trivial, but given that the traps are the most frequently used asset in the game, we thought this was an excellent area to perform a stress test on several gaming computers and see how it would impact performance in terms of frame rate, frame latency, and online networking.
For this build, we procedurally generated the entire dungeon from the beginning (as opposed to generating and deleting on the go) and spawned roughly 300 traps. All the in-game meshes were placeholder and do not have any materials. We’re fully aware that materials and textures are an entire field of its own that needs to be efficient, but that’s a topic we’ll handle later on when we have official assets.
While we were at it, we wondered if it’d be fun at all to have a dungeon crawler that went to the extremes and had nothing but traps at every step of the way. Would it be so painfully punishing and yet rewarding that players would call it the “Dark Souls” of multiplayer party games?
To get a fresh perspective on our game, we invited a friend of ours, Alex, an avid gamer, to playtest with us. Here’s some gameplay footage.
So, it was definitely not Dark Souls-like at all. In fact, it was such a pain to get through the pathways, especially with the poor visual cues and the inability to move an inch without falling off the platform.
Back to the main goal at hand…
Frame rate and frame latency were great and stayed steady throughout the playthrough, even when the camera view zoomed out and a significant number of traps were being rendered.
Online networking, unfortunately, suffered and issues with server-client desyncing made it unplayable at times. The players on the client side would report walking through the trap meshes, teleporting across the screen, and getting damaged by a trap before it even activated. By the end of the playthrough, the server saw all the pendulums moving, but none of the clients saw the pendulums moving.
Basically, a lot of the remote procedure calls (RPC)—multicasts and rep notifies—were getting lost in the lag. As we got further and further into the map, it became more apparent that the later traps and mini-game rooms were missing some RPCs that should’ve been called (e.g. the pendulums moving only on the server side). This is likely due to how our procedural generation works at the moment, where the entire world is generated at once, making the number of remote procedure calls to send from server to client quite large in such a small amount of time.
This week we’ve made some great progress and resolved a majority of those issues by running periodic checks, using a blueprint interface to communicate values calculated from the server’s end, reducing the number of remote procedure calls, and reworking the procedural generation to create and delete the world as the players move forward, rather than all at once.