For such a simply designed game, the Mind the Traps build for the Epic MegaJam was running around 47 FPS on our high performance computer, which was not a good sign. We had some culprits in mind but given the one week time crunch, we unanimously decided to forgo efficiency for a more complete game. Plus, the judges would be using hardcore computers to test the games, so any FPS drops wouldn’t be noticeable.
The week afterwards we played the same build on gaming laptops and the frame rate was unbearably horrid. That’s when we realized that the first thing we needed to take care of to make this game even worth selling was the frame rate. Who’s going to play a game where the characters are teleporting all over the place?
So, what exactly was causing the drop in performance?
The best way to test the performance of your game is to make a build and run that build on various computers. How your game performs in the editor window in Unreal Engine 4 is not the same!
The performance metrics we tracked were frame rate (FPS) and frame latency (ms). The better the performance, the higher the frame rate, the lower the frame latency.
Vsync was disabled to ensure the readings were more accurate; otherwise, it would have capped the readings at 30 fps (~33.3 ms) or 60 fps (16.6 ms).
Each build was made at the highest possible settings.
- Turn off Vsync by pressing the “~” key to open the console and typing in “r.vsync 0”. Type “r.vsync 1” in the console to turn it back on.
- Show the frame rate and frame latency by opening the console and typing in “stat fps”.
Culprit #1: High Poly Walls
These are the dungeon walls. Don’t laugh, but yes that’s 4,018 vertices for a single wall panel, double-sided. Take that, multiply it by 20 for each minigame room, and include all the shadows that are being calculated and your computer will cry “Uncle!”
At the time of the Epic MegaJam none of us were familiar with how to do normal mapping in Unreal Engine, so we cheated and just straight up made high poly walls.
Normal mapping is the method of creating high poly details on a low poly model by “faking” the shadows of the bumps when light is shone on it.
We measured the FPS (and ms) before the knight walked into the room and after the knight walked into the room (camera renders all four sides of the room), and as expected the FPS dropped quite a notable amount. Look at the numbers at the top right of the GIF below.
- Before knight walks into room: 58 FPS (17 ms)
- Knight is inside room: 49 FPS (20 ms)
Culprit #2: Torchlight
The torchlight is made up of a low poly handle, translucent fire particles, and a dynamic point light—it’s dynamic because it moves around with the knight.
According to the performance guidelines in the UE4 documentation, there are a few items that we got marked off on:
- Static lights are the fastest, Stationary lights are less optimal, and Dynamic lights are the most costly.
- Dynamic/Stationary point lights are the most expensive, directional lights are a little cheaper, and spot lights are best.
- Opaque materials are fastest due to having the best z buffer culling, masked are a bit slower, and translucent materials are slowest because of overdraw.
As you can see in the following GIF, the performance increased quitely noticeably (FPS went up, ms went down) when the knight and its torchlight left the camera view. This was a result of the camera not needing to render both the point light and the translucent material of the torch.
- Before knight walks on spring: 49 FPS (20 ms)
- Knight flies outside of the camera view: 53 FPS (18.5 ms)
Culprit #3: Fog
Fog was an issue on a previous project that we worked on in the Unity engine. We weren’t sure how it impacted performance in the Unreal Engine, so we tested it anyway.
When turning the fog visibility on and off, we noticed there was almost no change in performance. Apparently, Unreal Engine handles fog really well.
- Fog on: 100 FPS (10 ms)
- Fog off: 100 FPS (10 ms)
The experiment was done in a casual and crude manner but the results were clear. In the next couple weeks we’ll be making the following fixes:
- We’ll learn how to use normal mapping. All the walls will be replaced by low poly models (essentially cubes) with normal mapped textures.
- All the torches on the dungeon walls will be set to static.
- Point lights will be replaced with spotlights wherever possible.
- The translucent material for the flame particles will be altered to opaque since the translucency is not noticeable anyway.