Sorting out navigation flow
Getting the nav flow right can be one of the hardest parts in creating a good, working Left 4 Dead map. If the flow from the start to the end of the map is not valid, survivors may not be able to reach the end safe room or finale, rescue closets might not work and the wandering common infected will not spawn.
Please feel free to add to this if you discover any other useful methods/pieces of information.
Firstly, a standard Left 4 Dead campaigns consist of at least two levels. The first level contains the original player spawn area (referred to in the navigation mesh as PLAYER_START) and proceeds to a safe room (CHECKPOINT). The next map goes from safe room to safe room or from safe room to finale (FINALE) if it is the final map. You can have any number of maps you like in your campaign, but for a five-map campaign the general flow are as follows:
- PLAYER START to CHECKPOINT - eg. l4d_airport01_greenhouse.bsp - "Player Start" map.
- CHECKPOINT to CHECKPOINT - eg. l4d_airport02_offices.bsp - "Checkpoint" map.
- CHECKPOINT to CHECKPOINT - eg. l4d_airport03_garage.bsp - "Checkpoint" map.
- CHECKPOINT to CHECKPOINT - eg. l4d_airport04_terminal.bsp - "Checkpoint" map.
- CHECKPOINT to FINALE - eg. l4d_airport05_runway.bsp - "Finale" map.
Note that if you only have a single map (that doesn't lead onto others), the only technically correct format for this is PLAYER_START to FINALE. It is possible to create a single standalone map that does not utilise a finale, and this just involves creating an ending safe room as usual but putting a dummy value in the trigger_changelevel to tell it what map to switch to. As long as you include the next map value the navigation flow will be valid but when your players finish the level the session will not finish correctly, since there will be an error in the console saying the next map cannot be found.
To start editing the navigation mesh, type
exec nav_mode into the console. This sets up Valve's configuration for nav editing and is very useful in accessing all the commands you will need to use. To quit the nav editing mode, press Page Down; note that this doesn't always seem to remove all editing functions, so you may need to type exec config_default afterwards to reset your controls to the default configuration.
The best way to get to know the commands is to open up the nav_mode.cfg file yourself and make a list of the keys. However, some very useful editing commands are below:
- z_spawn (default 1) - This spawns a normal zombie at your crosshair. If you add a parameter after the command the relevant zombie will be spawned; for example, "z_spawn tank" will spawn a tank.
- noclip (default n) - Allows you to fly around the map and through objects. Very useful in positioning yourself for editing high-up areas or for getting to a specific area of your map quickly.
- nav_save (default TAB) - Saves your navigation mesh. Do this often, as there's no function for undoing changes if you mess things up!
- director_start/stop (default F3) - Toggles the director's enabled/disabled state. If enabled (and your flow is valid), wandering zombies will spawn, tanks and witches will spawn, etc.
- respawn_bot (default Numpad DEL) - This respawns a random bot. Note that this is a custom alias created in the nav_mode.cfg file and so will not function unless you have exec'd the file. The alias "respawn_bots" respawns all four bots but is not bound to a key by default.
- warp_all_survivors_here (default ' [apostrophe]) - Warps all survivors (including you) to the spot under your crosshair.
- nb_delete_all (default 2) - Deletes all NPCs (zombies, specials, survivors) from the world.
- nb_move_to_cursor (default 3) - Tells all NPCs to move towards the point under your crosshair. The target point is marked temporarily with a small green cross.
- nav_simplify_selected (default F7) - Attempts to merge any nav areas you have selected to simplify them. Don't try this with the whole map selected as the game will crash.
- nav_gui (default F6) - Opens up the nav-editing GUI with some advanced options. Note that the nav_gui command will need to be typed again to close the window and re-enable movement.
- nav_trouble_report (default PgUp) - Runs a check for the common problems present in navigation meshes. Any problem areas will be highlighted and the number of errors displayed in the console. Try typing the command in the console and add a space to see the different parameters that can be given.
There are also some other very useful commands that are not included in the config:
- z_show_flow_delta 1/2 - This enables flow arrows on the nav sector that you're looking at (if set to 1) or all nav sectors in the area (if set to 2).
- z_show_flow_distance 1 - This enables the flow distance to be displayed: xxxx/xxxx. These numbers relate to the units increasing towards map goal/units increasing from start. If -9999/-9999, the flow to this nav area is broken.
Recomputing the flow
The most common error you'll encounter while nav-editing is the flow error. For a map to work properly there must be distinguishable start and end points and a completely connected route through the map. The director uses the flow to work out how far the survivors are through the map, which areas are in front of them and which are behind.
If when running a map you get a large "Map is unplayable!" error at the start, it's likely that your flow is broken. To fix this, one magic command can help tremendously in debugging: nav_recompute_flow. The command attempts to hook up your starting area (PLAYER_START or CHECKPOINT) with the ending area (CHECKPOINT or FINALE); if it can't, one of these possible errors will be displayed in the console:
- GetGoalArea: Cannot find SPAWN_RESCUE_CLOSET area in FINALE, thus cannot guarantee reachability of goal area.
If your current map is a finale map, you will need to create at least one rescue closet available to the survivors before they reach the finale area. This ensures that there is an available place for the survivors to respawn in the map if they die, since there's no ending safe room present.
To do: Do we always need a rescue closet? I didn't have one in my recent finale and it didn't complain.
If your map is not a finale map, this means there is a problem with your ending safe room. The game cannot find a second checkpoint area in the map and so assumes that it has a finale event. Of course, it then cannot find any nav areas marked FINALE and so reports the finale as broken. See the third item on the checklist below for a list of the entities required in an ending safe room.
- ComputeFlowDistances: ERROR - [Error here]
Depending on what error is being reported, this may be because of a number of problems:
- Cannot determine start/end area - This means you have not set up your beginning/ending checkpoint or finale correctly. See the checklist below for more information.
- Cannot reach start area from end area - This is the easiest of the nav errors and simply means that you have a break in your nav connections somewhere along the line. You can use nav_trouble_report orphan to check for disconnected nav areas and z_show_flow_distance/delta to check the flow ID for each area. Look out for dark blue (one-way) connections which could be pointing backwards, ie. the survivors will be able to walk from the further area to the nearer area but not the other way around. Left 4 Dead also commonly mucks up the meshes on stairs, so these would be your first culprits to check.
- GetGoalArea: Cannot find end area - no checkpoint or finale located.
This means that none of your nav areas have been marked with either CHECKPOINT or FINALE. If you want a checkpoint, you've probably done something wrong concerning your safe rooms - see the third item on the cheklist below. If you want a finale, you need to apply the mark FINALE attribute liberally to the navigation sectors in your finale area.
Correctly setting up checkpoints
For the flow to be computed correctly, it is highly recommended to add what will be needed eventually:
Survivor spawn point
This is the point at which the survivors originally spawn in the very first map of a campaign. You will need:
- Four info_survivor_position entities, placed at least one unit above the ground. Each one will need to have a unique "Order" value and a unique survivor name out of Zoey, Bill, Francis and Louis.
- A weapon_ammo_spawn. This is very important as, bizzarely, it is also used to help determine the flow through a map. If a weapon_ammo_spawn at minimum is not present in either a beginning or ending checkpoint (an area with nav squares marked as CHECKPOINT), the game may not recognise it as a valid checkpoint area. Crazy, I know. To do: confirm
- An info_player_start, placed at least one unit above the ground. It is recommended to mark the nav sector directly underneath this with the PLAYER_START attribute. To do: confirm. I thought it was used before a nav was generated. After a nav is created.
- Four weapon_first_aid_kit_spawns and low powered weapon spawns (weapon_smg_spawn, weapon_pumpshotgun_spawn) are also recommended. Note that any item spawns that are in checkpoints do not need the "Must Exist" flag ticked; they will always be forced to spawn.
The navigation mesh must have the following:
- One single square of nav marked as PLAYER_START.
- A fair radius around this marked as CHECKPOINT. It doesn't really matter too much how big this area actually is, but bear in mind that zombies will not be allowed to spawn on it (same with infected players in Versus mode). Don't make this too small, either; it needs to have plenty of room to cover the survivor's spawn points and any weapon spawns.
- It is recommended to cover a little of the surrounding non-checkpoint nav with the EMPTY attribute, as this will prevent wandering zombies from spawning too near the survivors at the start of the game while not contributing to the checkpoint area. The EMPTY attribute is also recommended for a little way outside of beginning safe rooms.
End safe room
This is any safe room at the end of a map which leads onto the next map. You will need:
- A prop_door_rotating_checkpoint. This is essential to the mechanics of a safe room and must not be a plain prop_door_rotating. It is also highly recommended to name this door "checkpoint_entrance" (to "enter" the safe room) and to set the keyvalue to start open (in whichever direction is most convenient).
- A info_changelevel or trigger_changelevel. The trigger volume should be at least flush with the floor of your safe room and should touch the majority of it (the game works out which nav sectors should be marked as CHECKPOINTby the presence of this volume). The "New Map Name" value absolutely must have something in it, although it does not specifically matter whether the specified map exists or not (if it does not, the safe room will work but just won't load the next map). The name of the map should not include the ".bsp" extension. The "Landmark Name" value should be the name of...
- An info_landmark. This should be somewhere in your safe room and be named uniquely. It should be in exactly the same relative position in the end safe room of the first map and the beginning safe room of the next map, as entities such as players and weapons will be teleported to their new positions relative to this landmark. ALWAYS align these things to the grid, it goes without saying.
- A trigger_transition. This should fill the entirety of you safe room but ideally no more than this, since any entities inside its volume when the map changes will be teleported to their new positions in the next map relative to an info_landmark. The trigger_transition should be named the same as the info_landmark in your safe room, so that they work together.
- A weapon_ammo_spawn. Once again, this is essential for computing the flow.
- First aid kits and weapons of any kind are recommended.
The navigation mesh needs to be set up as follows:
- The entirety of the nav in the safe room, up to and including the door mesh marked as DOOR, needs to be marked with the CHECKPOINT attribute. Any areas that you miss marking will allow zombies to spawn upon them; not too useful if you stagger into an end safe room feeling fairly pleased with yourself, then get pounced on by a Hunter who won't allow a map change until he's dead or out of the safe room.
Beginning safe room
This is the safe room at the beginning of the second map of a campaign onwards. You will need:
- An info_player_start, placed slightly above the ground. This must be over the section of nav marked as CHECKPOINT (note that PLAYER_START is not required this time).
- A weapon_ammo_spawn over the CHECKPOINT nav. Weapon and first aid kit spawns should be in pretty much the same places as they were in the previous safe room to maintain continuity. Note that if the map is loaded after a previous one is completed, on load the default weapons/ammo/first aid in the safe room will be deleted and the items from the previous safe rooms spawned in their relevant places. This ensures that there aren't duplicate spawns for items when the map loads.
- An info_landmark placed in the same relative position as in the previous safe room.
- A prop_door_rotating_checkpoint, recommended to be named "checkpoint_exit" (it "exits" the safe room).
The navigation mesh should be as follows:
- The entirety of the mesh, up to and including the square marked with the DOOR attribute, should be marked as CHECKPOINT.
- The EMPTY attribute should be used a little way after the exit door to ensure that zombies don't start off spawning too close.
A finale is the event at the end of the final map in a campaign. It should include:
- A trigger_finale somewhere within the FINALE nav. This is needed to compute the flow, especially for a standard finale. Otherwise the furthest flow point will be the middle of the finale area. The trigger_finale doesn't necessarily have to interact with the player directly; it can be activated via inputs an entity such as a func_button.
- Flow can also be manipulated with an info_target with a special target name nav_flow_target. This especially useful for Gauntlet style finales but will result in the survivors gaining 100% score as soon as they reach it. Consider how it will effect Versus mode scoring when using this feature.
- If a rescue vehicle is required, take advantage of the outputs that will be fired at different stages by the trigger_finale. It will help synchronize major events during the finale. This is generally beyond the scope of this article. Please see Finale Events Part 1 for more details.
The navigation mesh should be set up as follows:
- The FINALE attribute should be applied liberally to your finale area. Make sure it covers everything, even places where players can't get to but zombies can. Zombies are spawned upon the FINALE section of the mesh; breaks in it can cause problems. Use nav_trouble_report finale to highlight any bits you may have missed. As a note, when the survivors first "see"/walk over the finale mesh, one of them will call out "We're almost outta here!", or the equivalent.
- If a rescue vehicle is used (theoretically the survivors could just run into a safe room that's unlocked at the end of the finale by the trigger_finale, although this wouldn't be very exciting), a nav_generate_incremental should be used to generate the nav at the point where the survivors stand inside the vehicle. These sectors should be marked with the RESCUE_VEHICLE attribute. Without this marking, the flow may not be computed correctly.
These are small rooms that dead survivors can be "rescued" from to allow them back into the game. As I have found out recently, the placing of rescue closets should follow some logic; there's no point putting one right next to the beginning/ending safe room (oops on both counts) as the survivors will respawn in these anyway. Rescue closets aren't required but do make game playing a little easier and also may aid in stopping nav_recompute_flow from complaining about "No rescue closets in finale".
The setup should be thus:
- The room should be completely sealed off apart from one prop_door_rotating. This does not need to have any special properties apart from starting closed.
- The closet should include three info_survivor_rescue entities, not four, as you won't be rescuing yourself. They should be placed slightly off the floor.
The navigation mesh should be marked appropriately by the nav_analyze phase.
Ladders can be a non-obvious source causing a break in your flow. Although a ladder connected with nav_build_ladder may still work for path finding and climbing for NPCs and players, if the ladder is not tied to the entity func_ladder, the game cannot compute flow through them.
- Make sure all ladders are tied to the entity func_ladder. Use nav_trouble_report to find ladders which are not. It will report the assigned numerical name to them. Use nav_edit 1 and z_debug 1 and point at ladders in-game to see its assigned number.
- If nav_trouble_report is highlighting all your nav sectors as "Missing Checkpoint", this means that either your beginning or end safe rooms aren't set up properly. Check through the list above.
- If all else fails with nav editing, a full nav_generate can sort out any inobvious problems.
A basic elevator can start on the bottom or top of the floors available. It is recommended that flow/escape route is already established from starting point to the goal area before setting elevators. This can be done by adding a temporary path to test with, such as adding a temporary ladder for survivors.
If adding an elevator and removing the temporary ladder breaks the flow that was known to work before, consider the following:
- Make sure an there is two info_elevator_floor entities for your elevator that centered and touching the top and bottom locations of the elevator and that the nav mesh is also touching it. When your elevator is properly connected you will see 4 green tracelines from each corner of the nav mesh with nav_edit 1 and z_debug 1. If you see these green tracelines and Survivor Bots follow you into the elevator and your flow is still broken, it means you have a flow break somewhere else in your map.
- Simplify the nav area that is covering the elevator floor. There should be a single nav area covering the entire floor.
ESCAPE_ROUTEshould reach the elevator floor nav area. If there is a small nav area touching the elevator floor, the
ESCAPE_ROUTEwill stop there on that particular floor and can cause problems with bots on other floors. Delete the small nav areas touching the elevator and reestablish all appropriate connections.
- Make sure the elevator nav areas on each floor are the same size and parallel to each other. In nav mode and with
nav_snap_to_gridturned on: create the nav area of the same size with the elevator floor, raise the unconnected copy above the next floor, move the elevator to the next floor, and finally place the nav area on ground. Delete an extraneous nav areas and establish appropriate connections. To do: confirm claims made by this bullet point. needs pictures!
- info_changelevel should point to a non-empty map name. An actual map name is recommended.
- info_changelevel should point to a non-empty landmark. An actual landmark within the map is recommended.
This results in correct nav flow to the goal area and proper bot behavior on an arbitrary number of floors.
Notes about elevators
The nav mesh must flow seamlessly throughout a level, but what happens when you add elevators? Nav sectors seem to not connect vertically down elevator shafts, at least visually, but they will connect properly, generate the desired flow/
ESCAPE_ROUTE, when the criteria are met. It may start working as the campaign reaches completion, but that is most likely an unacceptable answer!
Whereas conventional elevators are made using entities like func_door or func_movelinear (for two-stop elevators) and func_tracktrain (for elevators with 3+ stops), Left 4 Dead uses a bespoke entity for this purpose called func_elevator. This article does not cover the construction of elevators; please see the Elevators article for details.
Getting an elevator to work with bots and maintaining a proper flow can become frustrating. This has resulted in a some creative workarounds:
- Create a large elevator in order to coax the bots into following you in to at least the front
- Create a "backdoor" where the flow is going through a ladder hidden in the elevator shaft
- Start at the top position only
- Add BATTLESTATION attribute to the nav area covering the elevator floors
- nav_connect, nav_splice, nav_split nav area floors together, near or on the elevator
- Add a giant trigger_push or teleport to force survivor bots into the elevator
- Creating nav areas between floors if elevator moves on a slope
These workarounds may or may not work to various degrees and may depend on the situation. In official maps, the situation is always simple and consistent: two floors, in sealed container, moving either up or down the elevator vertically, and towards a goal. None of the workarounds listed were needed in that situation. In more complicated situations, however, these workarounds may offer a solution.