L4D Level Design/Nav Meshes
Next we'll create a Navigation Mesh, or "Nav Mesh", for our level. The Nav Mesh represents the "walkable areas" of a map. This allows the Survivor Bots and Infected to "know" how to move around in the environment, and tells the AI 'director' where it can spawn infected.
- 1 Create tutorial04.vmf and compile
- 2 Getting Started
- 3 Generating a new Nav Mesh
- 4 Nav Area selection
- 5 Nav Config files
- 6 Splitting Nav Areas
- 7 Adding Attributes
- 8 Analyzing the Nav
- 9 Adding Nav to a Ladder
- 10 Connecting Nav Areas
- 11 Drawing your own Nav areas
Create tutorial04.vmf and compile
In Hammer, open the map file
tutorial03.vmf that you created in the previous tutorial (if it's not already open). This should be located in the tutorial mapsrc folder, by default:
C:\Program Files\Steam\steamapps\common\left 4 dead\sdk_content\mapsrc\
Now we'll make a new version to work with and compile it:
- Go to File menu and choose Save As...
- Change the name to
- Press to open the Run Map dialog and click on the OK button to compile it.
When the level loads:
- As before, we'll get a "Map is unplayable" dialog because we don't yet have a Nav Mesh. Press Continue to dismiss the dialog.
- Bring down your developer console (tilde)
"director_stop"and press the key.
- This will stop the AI Director from spawning Infected.
- Enter the command
"nb_delete_all"and press .
- This will remove any Infected and Survivor bots from the current game.
- Enter the command
"nav_edit 1"and press .
- This will switch the game to Nav Mesh editing mode.
- Hide the console again with .
With the console closed, look at the floor in the middle of the hallway between the two rooms.
Bring down the console and type "
nav_mark_walkable" and press .
Close the console and you should see a pyramid-like shape on the ground where you are pointing.
You have just placed a nav generation marker called a "
Bring down your console again and type "
nav_generate_incremental" and press .
This will generate a set of nav areas around the
nav_mark_walkable marker. Nav mesh areas appear as series of connected square blocks. It should generate throughout your entire two room level.
nav_mark_walkablemarkers throughout your level. Each
nav_mark_walkablehas a radius that it creates areas around. In general, build nav areas for one section at a time to keep the nav mesh clean.
nav_generate_incrementalautomatically saves the Nav Mesh into you map when it is run. If you want to save your progress manually, use can use the "
nav_generate_incremental is run, all of the new nav areas it creates stay selected. This comes in handy if you make a mistake and want to run the generation again. To delete the selected nav, enter the command "
nav_delete" into the console and it will delete all nav areas that are selected. If you try this, you can recreate the nav areas by simply dropping another
nav_mark_walkable marker and running
- To deselect nav, type "
- To select a nav area, look at the area with your cursor and type "
nav_toggle_in_selected_set". This will select the nav area you are pointing at.
As you can tell, editing the Nav Mesh uses a lot of console commands. The most effective way to edit, instead of typing a console command each time, is to bind keys to these commands to use as shortcuts.
A config (.cfg) file has been included that makes it easier to start with.
Bring down your console and type:
bind PGDN "exec nav_mode"
Now pressing thekey will toggle between "Nav Edit" mode and "Game" mode.
Binding your own keys (advanced)
To set your own keys using the
bind command, bring down your console and type:
bind <key> "console command"
For example, if you want to bind the
nav_toggle_in_selected_set", type this in your console:
bind z "nav_toggle_in_selected_set"
You may want to open the
left4dead/cfg/nav_mode.cfg file in a text editor to add or change key bindings.
- For more information on binding commands to keys, see Bind.
nav_mode.cfg. If you're using your own bindings, you'll have to substitute your own key shortcuts for the one given.
You will also notice that the Nav Mesh in your level currently has large areas that cover the entire room. Sometimes it's necessary to split those large areas into smaller ones. For example, if you want to add an attribute like where the survivors start and you want the area to be right in front of the weapons table.
You can split up nav areas by using "
In the included
nav_split is bound to the key.
As you point at the nav areas, you will see a white line that moves either North/South or East/West with your cursor. Position the cursor so that a line draws to the right of the weapon table in the first room you created.
This line shows where the split will happen if you use
Pressto perform the split.
Now, position the cursor so that the new area you just split in front of the weapon table is split in half in the other direction.
Pressto perform the split and see the result.
Nav areas may contain attributes that designate specific purposes. For example, a nav area marked with the attribute "EMPTY" means that a common infected cannot spawn on it. Let's say that you have a kitchen with a counter in it, and you don't want infected to be standing on the counter top when the player gets there because it looks weird. You can mark this area as "EMPTY".
First, enter the "
z_debug 1" command to allow the attributes to be viewed.
In our first nav mesh that we're creating, we need to designate where the Survivors are going to start when they appear in the map. Let's mark the area in front of the weapon table that we just split as "PLAYER_START"
Point your cursor at the area in front of the weapon table and use "
nav_toggle_in_selected_set" by pressing the key.
Now bring down your console and type "
mark PLAYER_START" and press .
This will turn the selected area into a Player Start position for the survivors. It should turn a purple color.
clear_attribute <attribute name>" in the console to remove it. For example:
Left 4 Dead requires certain nav areas in its levels for the Director to work properly. For this simple test level, we will use another attribute called "FINALE".
Walk down to the second room in this level and select the area that occupies by looking at it and pressing thekey.
Bring down the console and type "
mark FINALE" and press .
This will turn this room into a finale area and it will turn blue.
Now, the level has all it needs for the Director to work properly. The Director can create a "flow" from the starting point to the destination point.
To make the level a little more playable, let's mark the areas around the Player Start area as "EMPTY" so that the player won't get mobbed right after jumping into the map.
Select all the areas around the Player Start with thekey.
Bring down the console and type "
mark EMPTY" and press .
This will prevent "wandering" common infected from appearing in these areas when the map starts.
Save the nav mesh by using "
Available attributes for marking areas in Navigation Mesh editing mode.
|BATTLEFIELD||Designates a region where a planned crescendo event will play out. Infected spawning, except in Versus modes, will halt so long Survivors reside in it. Once the event starts, Mobs will spawn and swarm dynamically only inside this area; Infected spawning comes to a halt if Survivors manage to escape the region.
This should be applied to a large region of the map; capable of containing a
|BATTLESTATION||Indicates a strong defensive area for a panic event, usually next to supplies/weapons. Intended to be used only in areas containing BATTLEFIELD or FINALE attribute.
In , Survivor bots may roam and reside in these areas before an event starts so long they think they aren't too far from human players. However, they may give up their station when an event starts, or they take damage, running back near a human player.
|BREAKABLEWALL||No effect, not used by func_breakable either. To do: Is this meant for only?|
|CHECKPOINT||Designates the start/safe-room areas of the map. The round starts when a survivor leaves this area, and ends when the door is closed at the ending checkpoint with only the survivors inside. Infected are prohibited from spawning inside this area at all times.|
|CLIFF||Doesn't do anything. Used only by the nav generation system to keep a note on nav square edges.|
|CROUCH||Cut down the navigation time needed for this mesh, as bots need to crouch here. Automatically added by a|
|DONT_HIDE||Marks areas that are not suitable hiding spots.|
|DOOR||Marks areas in which a door is located, perhaps just for flow calculations.aA Automatically added by the game during a nav_analyze.|
|EMPTY||Prevents wandering infected from being populated in this location. Useful for places outside the survivors playable area, or any other place you do not want wandering/sleeping infected to spawn (e.g. rooftops & surfaces infected fall off of).|
Note: Does not affect mobs/special-infected.
|ESCAPE_ROUTE||Basic guideline path of map from start to finish by linking spawns/checkpoints to the ending checkpoint/finale. This path helps the game/AI to make proper decisions based on routes and level progression. Marking areas with this should be left strictly for the|
|FINALE||Indicates a finale area. Has mostly similar characteristics to|
|LYINGDOWN||Causes zombies to lie down when not aroused by player. Found in|
|MOB_ONLY||Only Infected mobs are capable of accessing this area.|
|NOT_CLEARABLE||Prevents an area from being "cleared" by Survivors, and allows infected to spawn here indefinitely; Cleared areas are not used by the Director to spawn infected, and NOT_CLEARABLE modifies such a rule.
Used in the outer-most areas survivors are able to attack or have line-of-sight to, but can't really see (e.g. through fog). A navigation mesh is 'cleared' once survivors view the area, and remove them of all spawned infected.
|NO_MERGE||Disallows this navigation mesh being merged with other meshes. Only used during navigation mesh generation; trying to apply this otherwise has no effect.|
|NO_MOBS||Prevents infected mobs from spawning in this location. Commonly used to help mobs spawn further away from survivors and in more secluded areas of the map.
Also used to keep sources of mobs from appearing unnatural or odd, such as spawning on rooftops of certain buildings. A clever example of NO_MOBS is in the "drainage" level of the Death Toll campaign. It is used in the long pipes so that infected must spawn in the upper areas and run at you down the lengths of the pipe, rather than just around the corners.
|NOTHREAT||Navigation meshes with this attribute will not allow|
|OBSCURED||Affects the amount and manner of which infected can spawn. This is a very important navigation attribute, use both wisely and with caution.
There are two primary uses: Indicates that the area is not viewable by survivors, and allows the director to spawn flowing, or large waves of mobs. It is often used in blocked alleyways and other areas that survivors cannot view. The director can still create effective mobs without the use of OBSCURED, but they will usually be further outside the survivor PVS.Allows infected to spawn even when there is line-of-sight to a survivor. Useful in unreachable areas with heavy fog, or areas with props that don't block line-of-sight in the engine, but still obscure the survivors view on all sides (e.g. bushes & leafy trees). Bot line-of-sight is also blocked to prevent omniscient behavior.
Tip: Props that have collisions disabled are always unable to block line-of-sight and will need the help of OBSCURED
|OBSTACLE_TOP||No effect, not related to func_nav_avoidance_obstacle.
Can be found in
|PLAYERCLIP||Marked automatically if a brush with the Player clip texture is on it. Automatically considered blocked by Survivors, but infected will still use it - great for creating zombie spawn closets or infected-only ladders.|
|PLAYER_START||This attribute is to be applied in the exact nav mesh area(s) that the players spawn in, so flow computing will work as intended. Only necessary for the first level of each campaign.|
|PRECISE||Defines an area that requires precision to navigate properly. Bots will avoid having random variations to their pathfinding while on areas marked with this.|
|RESCUE_CLOSET||Marks off the location of rescue closets inside the level. Automatically assigned during a|
|RESCUE_VEHICLE||Marks where survivors should go to during rescue. Used only in a Finale sequence and remains locked until "FinaleEscapeVehicleReadyForSurvivors" is fired. Area covered in RESCUE_VEHICLE should be the location of the rescue vehicle once it is in position. In some cases, a lead-in must be made to make the path onto the vehicle navigable (see 'No Mercy' finale).|
|STOP_SCAN||Function unknown. To do: Properly document|
|STAIRS||Bots treat areas up to 180(?) H/Us high as flat ground; Useful in disallowing Commons from climbing or making Survivor Bots not jump. |
Warning: Chargers and Hunters bots will not their abilities on these areas, presumably they're looking for targets straight ahead of them.
|TANK_ONLY||All bots, but Tanks will only navigate through this. Thus the flow won't compute through navigation meshes using this attribute.|
|THREAT||Acts as spawn area suggestions for Boss Infected (Tank & wWtch). Only nav areas along the|
|UNDERWATER||Added automatically when a navigation mesh is created / generated underwater. Unknown if this does anything..|
The Population decides what Common and Uncommon infected roam your map. Useful for making your map feel more realistic, like a country side using rural infected, or placing Roadcrew uncommons on your map when a construction site is nearby.
See Left 4 Dead Infected Populations for detailed instruction on how to use existing populations, or making your very own.
If you make a mistake or if you find that the auto generation of the nav mesh has mistakes, you can delete nav areas with the command "
nav_delete". For example, the weapons table doesn't actually need a nav area on top of it. It may cause survivors to jump up onto it, which might not be desirable.
In the config file provided, this command is already bound to thekey.
To delete a nav area, point at it, select it with thekey. Make sure you only have the areas you want to delete selected, then press .
Now that we have a basic nav mesh, we need the game to analyze it so that the director knows where it can spawn infected.
Bring down the console and type "
nav_analyze" and press .
This might take a few seconds and then the level will reload.
To test spawning infected, use "
director_start" in the console and reload the level with "
Your scene should look something like this now.
If you open up tutorial03 in the game, and switch to
nav_edit 1, you'll see how a ladder looks with nav placed on it.
To create nav on a
func_ladder, position your cursor over it in nav_edit mode and use "
While a lot of the nav areas will be connected properly when you use
nav_generate_incremental, there are some that you might want to tweak or change. For example, the catwalk we created in tutorial03 might not have connected properly to the areas below it.
To connect 2 nav areas, select them and use "
nav_connect" in the console. The key is currently bound to this in the nav_mode.cfg file.
This will connect the areas in both directions and form a light blue line as seen in this image.
Common infected and the Witch can climb up to 180 units using this connection method. For higher distances use Infected-only Ladders.
Special infected and the Tank can not climb any distance up, they require Infected-only Ladders to climb up.
This is probably caused by the Special infected and Tank being playable characters which require ladders. All Infected and the player bots can jump down. Survivor bots may not jump down if the drop would cause in death.
To connect 2 areas one-way only, you will need to select the one you want to be able to connect to the other and then point to the second with the cursor but don't select it. Then, press
Make sure in both cases that the two areas you want to connect are not layered on top of one another. This will cause infected to bump their heads when they try to climb up.
nav_generate_incremental leaves out areas that you want to have nav on. In these cases, you will need to draw your own nav area.
Drawing nav areas is done with 2 keys. One key is bound to "
nav_begin_area" and other bound to "
nav.cfg file has
nav_begin_area bound to the left mouse button and "
nav_end_area" bound to the right mouse button.
Point to the area you want to create an area and click the left mouse button. As you move the mouse around, you can see where the nav area will draw until you press the right mouse button to end drawing and create the area.
Click the right mouse to activate
nav_end_area and see the result.
You might notice that the cursor doesn't snap to a grid when you're in this mode. You can set the snapping properties using "
nav_snap_to_grid" in the console.
nav.cfg, the key is bound to "
incrementvar nav_snap_to_grid 0 2 1". This will change the grid size when you press the bound key and continue to toggle through the sizes each time you press the key.
It is also possible to draw a ladder using
nav_end area. Simply point at a corner of the ladder and move the cursor vertically to go to the opposite corner.