...Well you're right!CS bots (the AI players) are stupid as hell. Why? Because they follow a very simple set of AI movement commands, which are triggered via a mesh. This mesh (called the navigation mesh - let's call it the nav mesh) covers the ground and floors of a map, and gives hints to the bots on how they should move around.
This means that bots rely entirely on the quality of a map's nav mesh. Thus, it is up to you as level-designer to craft your nav mesh to a sufficient quality. The bots will appear smarter, and human players will be guaranteed a good time when playing alongside them.
If you have zero experience with Valve Hammer Editor, this tutorial will not be helpful for you (atleast to a large extent). Thus, if you are wanting to edit a nav mesh without using Valve Hammer Editor, I would recommend looking at this basic tutorial instead (see link below).
If you have zero experience editing nav meshes, I would recommend looking at the basic tutorial first, and then continuing on (same link below).
Link: How to Modify NAV Files
Otherwise, let us begin!
Tutorial: Advanced Bot Navigation
Contents1. Introduction to the nav mesh
2. Manipulating the auto-generation of the nav mesh
2a. Non-solid objects
2b. Gaps in-between objects
3. Auto-generating the manipulated nav mesh
4. Applying the manipulated nav mesh to your original map
5. Hand-editing the nav mesh
1. Introduction to the nav meshNav meshes are automatically generated. Have you ever downloaded a custom CS map (maybe from Game Banana), and found that when you play it for the first time with bots, you have to wait for something to load? That is the map's nav mesh being auto-generated.
The auto-generated nav mesh is decent. Even perfect when the map is super simple. But more often than not there are some "flaws" in the mesh, which cause bots to behave strangely (and sometimes frustratingly stupidly).
You might have already noticed these stupid behaviours in your favourite CS maps. A classic example is in de_cpl_fire, where bots on the terrorist side get stuck behind the wire fence at t-spawn. This is exactly what we are aiming to fix.
In this tutorial, we will learn how to achieve two main things:
(A) Using Valve Hammer Editor to manipulate the auto-generation of a map's nav mesh, and
(B) Hand-editing the nav mesh using the CS commands function.
In regards to the latter, we will only cover minor edits to the nav mesh. Creating, deleting, or naming mesh pieces will not be covered. However, I have another tutorial which does cover these aspects (see link below).
Link: How to Modify NAV Files
2. Manipulating the auto-generation of the nav meshThe idea of Part A is not to edit the nav mesh at all. Instead, we will use Valve Hammer Editor (VHE) to add "temporary" brushes* to our original map. *A brush is any shape that is created in VHE. By doing this, the "temporary" brushes will manipulate the final shape of the auto-generated nav mesh. Therefore, we have complete control over the mesh's shape.
To begin, open your original, final map in VHE, and save a copy of it under a new name. For example, the copy of a map named de_dust2 would be named de_dust2_nav.
So... what problems can be fixed with this technique?
2a. Non-solid objectsThis is the classic de_cpl_fire glitch. The wire fences at t-spawn are non-solid objects. This means that players can shoot through them, as if nothing was there. But this also means that the nav mesh auto-generates through them, indicating to any bots that there is nothing there.
You: "But if they're non-solid, why can't players move through the wire fences?!"
Well, additionally, a special type of VHE brush is placed on top of the wire fence brush. It is the same size and shape as the wire fence, but has a different texture painted onto it, called "clip". This special brush is non-solid for bullets and the nav mesh, but is solid for players. Thus, players cannot walk through them.
So due to this logical error, any bots will think that the wire fence is non-solid and will try to walk though it... but then they can't walk through it because of the special clip brush. Hence they get stuck. Does it make sense?
Below is a screenshot of a small map that I made with VHE to re-create the glitch in de_cpl_fire. The yellow and red rectangles are pieces of the nav mesh. As you can see the mesh goes right through the wire fence.
Of course it doesn't have to be a wire fence. The idea is, any case in your map where you have used the technique of a non-solid brush, layered with the special brush that is painted with the texture called "clip". Other examples may be barbed wire, clothes lines, or other thin objects.
If your map doesn't include any brushes like this, then you may skip to the next section of this tutorial. Otherwise, this is what we will do to fix the problem.
Remember to make sure that you are editing the COPY of your original map in VHE.
1. Duplicate either the non-solid brush, or the clip brush. Paint this new brush with any texture that you like (I am using a bright red texture, so I may be certain that the brush is not part of my original map).
2. Make sure that your duplicated brush is a world brush (select the brush > right-click the brush in any 2D view: a pop-up will appear > click "Move to World").
3. Place the duplicated brush in the same x,y,z position as the wire fence brush. Also, make sure it is the same shape and size.
The final layers of brushes should look like this in VHE (with the different textures flickering back-and-forth as you move the 3D camera).
Now the nav mesh will not be auto-generated through the non-solid object. Chapter 3 of this tutorial shows the final result of this technique.
2b. Gaps in-between objectsSometimes, the opposite of chapter 2a happens: Instead of the mesh going through an impassable area, the mesh doesn't go through a passable one. A primary example of this is in wooden bridges that have gaps between each wooden slat.
Create a combination of new brushes to fill out the gaps in-between the original brushes.
As we did for the previous example, make sure that the new brushes have the same x,y,z position, and shape and size, as the original brushes (or atleast fit the new brushes as well as you can).
As you can see in the screenshot, I made the new brushes narrower than the original bridge. This is to keep the bots away from the edge (making it less likely for them to fall off). These little things add up to make the bots in your map smarter.
2c. StairsIf your map doesn't feature any stairs, then you may skip this chapter (unless you're curious... I won't stop you!).
Anyway, observe the below images.
Notice how the pieces of nav mesh are all broken up? This messiness isn't a big problem for bots to navigate, but it does make it hard when you want to hand-edit individual pieces of mesh (which is necessary for stairs, as we will see later in this tutorial).
1. Create a new brush, with the same position and dimensions as your staircase.
2. Clip the top face of the brush, from the tip of the bottom-most stair, to the tip of the top-most stair, like so.
2d. LaddersFor ladders, you will most likely not need to add any "temporary" brushes in VHE. Instead, you want to make sure that the func_ladder brush is thick enough for the nav mesh to respond to it.
Take this screenshot as an example, where the func_ladder brush is 14px thick.
This is thick enough in most cases. Otherwise, try making it thicker. Last resort, you may add some "temporary" brushes (similar to what we did in the above chapters) to further manipulate the auto-generated nav mesh.
3. Auto-generating the manipulated nav meshThis is the part where we see the results of all our hard work!
Compile your modified map, and load it into Counter-Strike with atleast 1 bot (AI player).
As soon as the bot has joined the game, a loading bar will appear. That is the map's nav mesh being auto-generated. Remember, this only works if you have a bot player. After the loading bar has completed, the map will re-load, and you may enter again as CT or T.
This is where we begin using CS commands. Do the following:
1. Hit the keyboard button ~ (it is above Tab). A window will appear. This is the command console.
2. At the bottom of the window is a text input box. Type into it "bot_kick", and the hit Enter.
3. Now type "bot_nav_edit 1", and then hit Enter.
4. Hit ~ again to close the command console.
Any bots have now been removed from the map (we don't need them). But primarily, you will notice many red (or yellow) rectangles covering the floors, similar to some of the screenshots in the previous chapters of this tutorial. These are the pieces of your map's nav mesh!
Find all of the temporary brushes that you have added. You will see that the nav mesh isn't going through them, nor is it splitting up unnecessarily across them (bridge and stairs).
Here's what each of my examples looks like:
1. Wire fence
4. Ladder. In the case of the ladder, you want to make sure that the blue lines (which you can see the below screenshot) link with the nearest mesh pieces. If there is only a single blue line running up the ladder, and it doesn't split, or corner at the top, then there is no connection.
If you are happy with how your nav mesh looks, then let us continue!
4. Applying the manipulated nav mesh to your original mapThis is the sweet part about nav meshes: they are a separate entity from CS maps. They are a separate file from your map file. Thus, they can be renamed and used in any map that you desire (however you would not normally apply them to different maps, for obvious reasons). The file-type of nav meshes has the extension .nav. Moreover, "Nav" files have the same name as the map that they were auto-generated on.
Now minimise Counter-Strike. Open your Window's Explorer and follow these steps:
1. Find your Counter-Strike folder. Then, follow this path: "cstrike" > "maps".
2. Scroll through the "maps" folder until you find your map's name. Let's say the map name is "de_dust2_nav": There should be a few different file-types of that same name. Focus on "de_dust2_nav.nav", which is your map's Nav file. Note: your actual MAP file would be called "de_dust2_nav.bsp".
3. Duplicate this Nav file.
4. Rename the duplicated file to your ORIGINAL map's name. For example, "de_dust2", should be "de_dust2.nav" (NOT "de_dust2_nav.nav"). If there is already a Nav file with the same name, replace it with this one.
Your original map's nav mesh is now the same as the updated one (the one with the extra brushes).
Open Counter-Strike again and load your original map. Make sure that "bot_nav_edit" is set to 1, and take a look at the modified nav mesh. It should fit and flow nicely!
Here's what each of my examples looks like:
1. Wire fence
4. Ladder. No need screenshot, it's the same!
5. Hand-editing the nav meshThis stage is where we do the little, necessary tweaks, and are as important as the techniques we learned about in the previous chapters. There are three things in your map that you will want to tweak: A. Your staircases... B. Any mesh pieces that ask the Bots to do the wrong thing... C. Using "bot_nav_precise" when necessary.
ALet's start with your staircases. Make sure that "bot_nav_edit" is set to "1".
Now follow these steps:
1. Go to one of your staircases and highlight a mesh piece that spans across it. You can do this by aiming at it until it turns yellow.
2. Open the console and type "bot_nav_no_jump". A diamond will appear in the center of the mesh piece.
3. Repeat this process for all the pieces that span across your staircases. Look at the below image to see what it should look like:
Doing this will ensure that Bots do not jump while trying to travel along the staircase. This is a good thing, because in some instances, jumping will cause them to fall and take damage (which just makes them look dumb).
You can do this for any ramps, wooden bridges, staircases, single stairs, or any other elevation to ensure that bots don't jump unnecessarily.
You may also see why making the stair mesh a single, or only a few pieces makes this process much easier.
BNow for the second thing we need to fix: Mesh pieces that ask the Bots to do the wrong thing.
Some mesh pieces will be set to "JUMP" or "CROUCH", even though Bots are not actually supposed to jump or crouch when they walk through them... How do we fix this?
Simply, follow these steps:
1. Skim around the map and search for any mesh pieces which are set to "JUMP" or "CROUCH" when they shoudn't be. You can observe whether a mesh piece is set to those by looking at the text on the lower-left hand corner of the HUD.
2. Select a bad mesh piece (aim at them 'til they're yellow), and open the console. Type "bot_nav_jump" if you want to remove the "JUMP", or "bot_nav_crouch" if you want to remove the "CROUCH". Typing those two commands again will enable jumping or crouching again.
3. Repeat this process for all mesh pieces that have this problem. When skimming for bad mesh pieces, look out for tables, and other "skeletal" forms, which may encourage the mesh to set nearby pieces to CROUCH or JUMP when unnecessary.
Note: I would recommend playing several rounds with Bots, to make sure that you catch any weird, annoying, or buggy mesh pieces.
CWhat is "bot_nav_precise"? Simply put: When you set a mesh piece to this mode, Bots travelling through it will make sure to stay inside its boundaries.
There is an interesting AI behaviour in C-S which tells Bots that they can move away from their current mesh piece early, if there is another nearby mesh piece to move to which is not next to the current. This saves time, but causes a fault where Bots moving along platforms and catwalks, sometimes fall off.
It probably allows them to navigate large areas too, with lots of mesh pieces, very efficiently, but when it comes to delicate areas, like stairwells and catwalks, you need to make sure that Bots do not "jump / skip" mesh pieces. Instead, they must stay inside the boundaries of each mesh piece, and precisely move from one piece to the next.
This is where "bot_nav_precise" comes in. Select a mesh piece (aim at it), open the console, and type in "bot_nav_precise". The mesh piece should now have a cross in the middle:
Now bots will not leave the boundaries of this mesh piece, and only move to other mesh pieces that are directly linked to it.
8. ConclusionYou can see that editing the navigation meshes of your maps can be quite an art. Watching Bots travel along a smooth mesh can quite satisfying, as they no longer seem stupid! You'll notice that we hardly edited the mesh at all. We didn't add or remove any mesh pieces, which guarantees that the map will not crash. Its also much easier to build a few brushes in Hammer than to fiddle around with tens of nav-mesh pieces, no?
Here are some points that you should remember:
A. I said it before and I'll say it again: You want to generate a satisfactory navigation mesh with the navigation BSP, rather than edit a buggy mesh from your standard BSP.
B. If there's anywhere that you don't want your Bots to go, block it off with a brush in your navigation BSP!
C. Toggle the states of "NO JUMP", "JUMP", or "CROUCH" for the navigation pieces, if your Bots are jumping or crouching when unnecessary.
D. If there is ever a part in your map that causes Bots to jump when they're not meant to, just change the mesh pieces to "bot_nav_no_jump".
This is the end of the tutorial! Thanks for reading :)
Apparently you can fix bugged navigation meshes (primarily caused by deleting green or purple line'd mesh pieces), by following these steps:
1. kick all bots using bot_kick all command
2. edit the navfile as you want
3. save the nav file with bot_nav_save
4. restart the map with 1 bot
5. before joinning the game, type in console bot_nav_analyse
6. join the game: the new navmesh will be analysed, errors will be removed, and the game doesn't crash anymore!
Let me know in the comments if you would like to see a video of some Bots moving through obstacle courses, by using maps with the above techniques. I'm just wondering whether or not I should do this, or if its interesting to you guys...