Map Optimization Guide (Killing Floor 2)
Introduction
This page will give a comprehensive guide to increasing the performance in your map and also optimizing the player experience; looking at such things as making smooth movement around the map, avoiding getting caught on props and general exploit fixing. Its recommended that you read through the entire guide and apply all the principles to your map before you release it on the workshop.
The techniques below are listed in order of the stages you should implement them; starting from being able to apply them at anytime and ending with final/last stage tweaks before publishing a map.
Lighting and Dynamic Shadows
PointLights VS SpotLightsSpotLights perform better than PointLights. SpotLights cast in 1 particular direction, While Pointlights have to cast multiple SpotLights in directions around the entire radius of the sphere (PointLights are 2x more costly in performance; however in saying this - you are able to have many combinations of PointLights and SpotLights without too much of a performance hit). Both lights are affected by the size of the Radius that they have - as you would expect, having a larger radius has a larger impact on performance. It is recommended to adjust the radius size to be just enough to get the desired effect and not to be over generous. You may be able to achieve the same lighting intent with a smaller radius and larger brightness. The PointLight PitfallOne trap a lot of new maps fall into is the unintended over-use and mishandling of dynamic shadows with PointLights. This is not entirely the level designers fault as one particular variable: Cast Per Object Dynamic Shadows is enabled by default. This is located under the PointLight Properties > Light Component > Light Component. See Figure 1.1. You always want to make sure that this variable is DISABLED for any PointLights in your map. NEVER use dynamic shadows with PointLights. Dynamic Shadows should only be reserved for SpotLights. This particular option may not seem problematic when playing in the editor, this is because the performance hit only occurs when there are many actors (Zeds/Players) within the light's radius. Each of these actors will be casting dynamics shadows, which are already quite demanding. During gameplay, you may see huge fluctuations with your FPS based on the action/number of zeds present in the screen within the vicinity of these lights. This performance hit can be magnified quite significantly when you end up having a cluster of PointLights also casting dynamic shadows in the same area. You can easily check and disable this variable on all PointLights on your map by:
Doing this trick alone should see a significant increase in performance if they were previously enabled. SpotLights casting Dynamic ShadowsAs mentioned previously, Dynamic Shadows are quite an intensive features to use in a map. Their performance impact is proportional to the complexity of the geometry of the map and the amount of moving actors (Players and Zeds) that they cast shadows from. Poor performance can be magnified if there are a cluster of SpotLights that cast Dynamic Shadows as well. It's recommended to use them sparingly and to avoid clustering them together. Try to use them to accent certain parts of the map, as opposed to making all SpotLights cast them, as they can have larger visual impact; less is more (eg: Casting shadows from car high-beams/floodlights, using them on alarm systems or around a fireplace - usually locations/lights that are bold and already stick out). |
Mesh Density and Material & Particle Effect Complexity
Although there really aren't any guidelines for using meshes and materials, mappers should still take notice things such as the amount of tris in meshes and the complexity of materials applied. It can be very easy to take good looking complex meshes for granted and place them generously around the map, resulting in clusters of high tri densities that may impact performance when looking at them. I would say anything with a tri count in the 3,000 or more range should be used with regards to their complexity; reducing frequency as the tri count increases. The same thing can be said for materials and you should be aware that the following sort of materials may impact performance when there are high densities of them:
Tree and foliage assets fall into both of these categories (especially Zed Landing assets). Tree meshes usually contain a large number of tris to display leaves. These leaves also usually use transparent and displacement materials. When coupled together, small clusters of trees and foliage can immediately hit performance. This can be very easy to do since they can look decent placed anywhere so we can get carried away placing many different combinations of trees and foliage. This isn't so much saying "Never use them", more or less just use them wisely; if you can turn the coverage of some foliage from 5 meshes to 2-3 (or even 4) without any major visual impact, definitely do it. The exact same thing can be said about particle effects, especially those that create fog, smoke or use transparent textures/materials. An overuse and mishandling of them can quickly lead to poor scene performance. Figure 2.1 Shows some examples of assets that when overused may see a performance hit in your scene, these mainly contain high tri counts or/and use complex materials. |
Movement Optimization
What and Why?
BEFORE YOU CONTINUE: Load your map and run along ALL the walls hugging it as tightly as possible. If you clipped or stopped moving at any point, your map needs movement optimization and is not ready for the workshop. All players can relate to the frustration of kiting around a map only to get stuck on a random part of it which leads to their death. Movement optimization is based on a general understanding that although in the real-world we have the opportunity to contort our bodies around objects as we move, in the game-world we do not have that luxury due to engine limitations with collisions. Due to this, we have to dedicate some additional time to workaround the limitations of in-game collisions make sure that players don't clip or get stuck on parts of the level. How?An extremely comprehensive video tutorial made by Seanchaoz perfectly explains how to optimize movement for your maps: KF2 SDK Guide - Basic Movement Optimization Figure 3.1 shows a typical corridor, on the surface it looks fine but there are a couple of problems that will frustrate players:
Ideally we want to make sure that no collisions stick out and players move along a smooth surface/wall. A lot of small props (like the window frame or alarm) only stick out a small fraction, but that is enough to stop the player. Although some issues may not seem obvious, we can check the collisions of the map in one of two ways (See Figure 3.2):
Fixing Issue 1: Small Prop CollisionThis issue is the easiest to fix. Small props that dont really have a large profile or are too small to really be considered for collsion can be fixed by:
Figure 3.3 shows the final properties of these props. Fixing Issue 2: Props that stop player momentumWe can't really use the same technique above for larger props (such as pillars); doing so allows players and rigid bodies (dosh & weapons) to enter into them which gives a bad feeling of polish and can break immersion. The best option here is to encompass these props in a KFPawnBlockingVolume that angles some of the side-faces as to 'ramp' the player off them. Doing this allows the player slide along the wall without stopping forward (or backward) momentum. See Figure 3.4. It's a good idea to make sure that nearly any wall allows the player to slide along them. The nature of KF2 higher difficulties often sees teams kiting around a map, and the last thing they want to encounter is a small object on a corner, wall or in the middle of their path that stops their movement. By default the KFPawnBlockingVolumes have their properties to block rigid bodies. This can also be argued to break immersion or make the volumes feel out of place (especially for objects that act as small islands in the middle of an open room - not being able to throw dosh over them). If you wish to change this go to the volume's Properties > Collision and disable 'Block Rigid Body'. Also displayed in Figure 3.4. This will allow rigid bodies to pass through the volume but also collide with the actual geometry of the meshes. Fixing Issue 3: Props that players can stand on or stick out too muchThe trim here can use either fixes from Issues 1 and 2. However, I would lean towards using the blocking volumes. From experience, disabling collision on these can end up having problems previously discussed where items can clip partially inside them. So a simple rectangle volume could be used to cover the trim. The crates will definitely need a blocking volume, however they also introduce new issues:
Simply putting a volume around the crates is 'Okay' but not the best. In these situations it would be good to reconsider the placement of crates as well, in this case you can:
Ultimately it will be up to you to make the best judgement call here, but you should always consider what the player experience will be, and it should always take priority over prop decoration. In this case, I decided to slightly move the crates and introduce a small crate to fill in the 'empty space' created by the volume. When you bring all these techniques together you can further optimize the volumes themselves. In Figure 3.5 I created a single volume that covered the entire wall of the corridor. I didn't need to change the collision of any of the props apart from the alarm which stuck out from the wall just a little bit too much. |
Looking For Map Exploits
Much like the discussions with movement optimization (especially with situation 3): If it sticks out, a player can stand on it, and they may be able to chain jumping on props to get in positions of exploit where Zeds cannot get to them. You will need to go over your map with a fine-tooth comb to make sure that no props can be used as jumping islands to escape the map or get into positions they shouldn't be in. Here are a couple of tips to find/fix exploitable spots on your map:
|
Fixing Spawns and Pathing
Just like how players can get stuck on props, Zeds encounter the same problems, however it is usually with the floors they run on.
Mesh Merging
What and Why?Mesh merging is a step that all level designers should do to their maps as they approach completion. It aims to further enhance the look of your map by combining multiple static meshes on the same plane/axis so that:
It also has the added benefits of increasing performance by:
This is because you are now calculating collisions and drawcalls for 1 mesh instead of say 4, 8, 20 and even up to 30+ meshes in some cases. ALL MAPS SHOULD MERGE THEIR MESHES WHERE POSSIBLE How?Before you dive directly into Mesh Merging you should do a preliminary pass over your map to see if you can replace smaller modular kit pieces with larger configurations when possible (e.g. Two 1x1 floor pieces next to each other can be replaced with one 1x2 floor piece). See Figure 4.1. Comprehensive Wiki Guide: Setting Up UV's and Mesh Merging (Killing Floor 2) Community Video (by Seanchaoz): KF2 SDK Tutorial - Combined Meshes |
Setting Render Distance
What and Why?
When we aren't looking or cannot see meshes, particle effects, lights or any other actors, it make sense that they should not be rendered on the screen, especially if they are really far away. We can statically set the distances that these actors can render to help improve performance of the map. This saves the Dynamic Occlusion System (discussed below in Precomputed Visibility) from having to determine if the object is still visible or not past a certain distance; ultimately increasing performance. If you cannot implement Precomputed Visibility, you must at very least set proper render distances for ALL actors on your map. This step can be done before or after mesh merging, but I recommend doing it after so you don't have to go through all the other meshes to double check render distances set. How?We can set the render distances on any actors by assigning a value to the Max Draw Distance variable under an actor's Rendering Properties (Lights, StaticMesh, Particle Effects, nearly all render-able actors contain a Rendering category. See Figure 5.1. The value you set for the Max Draw Distance is highly dependent on the mesh's location on the map so you will need to select portions of your map and assign them individually. Here are some general guidelines to help speed up the process:
ExamplesBelow is an example breakdown of a portion of KF-Desolation and how I approached rendering distances and viewing angles.
|
Image | |||
---|---|---|---|
Description | Step 1 - Initial Ruling on Line of Sight through rooms | Step 2 - Setting Render Distances working on Largest Distance to Lower Distances | Step 3 - Tweaking render distances after playtesting |
Splatter Map Resolution Standardization
What and Why?Towards the end of the creation process and after mesh merging you should take some time to address the Splatter Maps around the map. Having consistent Splat Maps around your map gives it an additional layer of polish; as during gameplay the map will be sprayed with blood on all sorts of walls, floors, props and ceilings and we want to make sure the scaling and presentation of the blood is consistent. How?You can check the consistency of Splat Maps on your map by selecting the SplatterMap Density [TW] View (yellow) and you can rebuild them by selecting Build Splatter Maps [TW] (red) shown in Figure 6.1. You can set the Splat Map resolution on any static mesh by opening the properties and enabling 'Override Splatter Map Res' and Setting the value for 'Overridden Splatter Map Res' under Static Mesh Component > Persistent Splats. See Figure 6.2. You should aim to keep all the static mesh object splatter maps consistent. It can be a time consuming process of selecting, tweaking and rebuilding splats but the end result provides a much more professional looking map when it is covered in that delicious KF2 blood. There are a couple of console commands to help you debug when playing in the editor (these require you to enablecheats):
ExamplesFigure 6.3 shows a before and after of Splatter Map Resolution Standardization. A good scale for Splat Maps is also present in the image. You can gauge and check the scale in comparison to Zeds by pressing '\' which will hover a clot around the map. Generally Splat Maps should be able to fit a single clot within them |
Precomputed Visibility
What and Why?
Precomputed Visibility is a final optimization step that you can add to your map to squeeze the last amount of performance out it. Although we set the mesh and lighting render distances in a previous step, this was only one technique used to help actor culling in our map. By default the maps will use UDK's Dynamic Occlusion System, this is a fine approach in a general sense but it can have a performance cost with calculating what should be culled dynamically while playing. Utilizing Precomputed Visibility will allow us to statically save some occlusion culling around the map to increase performance.
How?
Comprehensive Wiki Guide: Setting Up Precomputed Visibility (Killing Floor 2)
Final Words
All the above techniques are used in Official KF2 maps to optimize the player experience. If you wish to make official quality maps that people would like to play and have good performance, you should implement all techniques discussed on this page.
It may seem like a lot to do, and frankly it is, but this is game development and we have a responsibility to deliver the best experience we can for the players. Personally I find a certain charm and rewarding quality when you see the performance of your map increase, even by a little bit.
Best of luck to all those who strive for the best out of their work! -Delta