goto:    mapping Links    Tutorials


Mapping help Tutorials for Half-Life & Mods


R_speeds and lag reduction: causes, solutions & tools.


Some causes of lag and bad r_speeds:

  • Seeing too many models. Models are recommended instead of brushes, because epolys cause less lag than wpolys. However, there IS a limit, and enough epolys with enough wpolys can cause lag. Here is an example of some CS calculations based on the chart at right:

    With a cart model of 1200 epolys & 2 hostages models of 600 epolys = 2400 epolys total.
    So that area could handle around 800 wpolys. of course, that would be ignoring other player models and weapons and gunfight sprites....
    Lets see, 4 players - about 1500 epoly each??? = 6000 epolys. add the 2400 above for cart & possible hostys = 8400 epolys.
    A wpoly count of 200-300 makes sense there in the area of the cart.

Epoly limits, violations of combinations can cause lag

by Chris 'Tal-N' Blane from the 69thVlatitude forum


100 wpoly + [x100] 10,000 epolys
200 wpoly + [ x45 ] 9000 epolys
300 wpolys + [ x25 ] 7500 epolys
400 wpolys + [ x15 ] 6000 epolys
500 wpolys + [ x10 ] 5000 epolys
600 wpolys + [ x8 ] 4800 epolys
700 wpolys + [ x6 ] 4200 epolys
800 wpolys + [ x4 ] 3200 epolys
900 wpolys + [ x2 ] 1800 epolys

Some solutions to lag and bad r_speeds

Much of this is from an old tutorial by David Hyde, Mad Dog and Richard Neff, at r_speeds & poly reduction. It may be complex, but you do not have to use all of it at once, you can pick and choose. Understand each part somewhat before you use it.

  1. PLAN, pre-plan your line-of-sight everywhere, so there are few brushes with easily stretched texures for long views, and short views get more of the detail brushes. Generally plan to avoid long views, like long streets and long corridors - break it up into an S or L shape if you can. Try not to have wide open areas, like a plaza or open field, with a lot of small details. Try to avoid good lookout points overlooking large areas of detail from above. Often a great view = lousy lag. Keep windows and doors to a minimum facing large open areas, or facing long views. Put walls inside behind windows and doors, so players cannot see through or far into the house.

  2. BSP initially divides your map into 1024x1024x8192 sections. This procedure can produce unwanted brush cuts unless you arrange your map to minimize these effects. Any brush which intersects a line at x or y equal to a multiple of 1024 will be divided in this way. (Since the sections used are 8192 units tall, and the maximum extents of a map are +/-4096 units in any direction, you don't have to worry about these cuts on the z axis.) Of course if your room is larger than 1024 units in either the x or y direction, at least one of these cuts will still be made. However, you can minimize the effects of these cuts by careful arrangement of your brushes. For example, if you have a crate with one face at x=1022, move it over 2 units so that this face is at x=1024. This method can very easily decrease your polygon count by 50 or more in a room with many details.
    You can also during compile change the BSP division with BSP -maxnodesize 4096. This will make larger nodes than 1024 possible, avioding the cut at 1024; but will have the bad side effect VIS leafs also larger, so that the r_speeds may go bad because the engine thinks you can "see more". You may make less wpolys, but end up seeing more of them - so you end up with worse lag/r_speeds. So test any use of this feature carefully!

  3. Do not carve, hollow, or vertex adjust if you can help it. These tend to make problem brushes which cause compile failures and add to the number of wpolys, adding to r_speed problems. Carving especially tends to "shatter" brushes involved, which creates more wpolys. If you must carve, then use the smallest brush possible (to minimize the area involved) and seperate it from a larger brush, as in this example.

  4. Reducing shattering by brushes that touch other brushes:
    1. Func_wall - a func wall does not cause shattering of brushes it touches. So if a small brush (or cylinder, stairs, or other odd shape) intersects or touches a larger brush, turn the smaller/odd one into a func wall. But remember, a func wall is see thru for VIS, so it blocks no line-of-sight into other VIS leafs. Therefore try to keep large brushes regular world brushes, so that they can block VIS.
      Also, since func_wall is see thru for VIS, sides that would normally be invisible - on the floor, for example - will now be visible and could add in a minor way to wpoly counts. Everything has its downside, it seems.
    2. Gapping - if you are running low on entitys, you can try gapping. You leave a 1 or 2 unit space between the problem brush and any brush it might touch. It will not help VIS blocking, because VIS will see thru the gap, but it will reduce shattering caused by odd shapes touching other brushes.

  5. Wedges. If you have four-sided brushes in a spot where the player cannot get to the far side, use a 3-sided wedge brush instead. Depending on the architecture of your map, this simple change can result in a significant decrease in your polygon count. For example, two barred windows are placed in the two test rooms. In the first room, the bars are regular square brushes; in the second room, triangular wedge brushes are used with the point of the triangle facing away from the player. Even up close it is hard to tell that these brushes aren't 4-sided, but the peak polygon count drops by more than 50 with this simple change. This method will likely produce similar results with jail cells and any type of grate, and is also good for stair steps, chair and table legs, ect. (Make sure you func_wall all the wedges, so that shattering does not occur to the brushes they touch! You can often combine all the smaller triangles into one func_wall.)
    SPECIAL NOTE - 3 sided object do NOT break well - do not use for breakables!

  6. The donut hall is good for blocking VIS. Notice how the line-of-sight straight through from top to bottom is blocked.

  7. The underground connection is also good for blocking VIS. One can use either a tunnel to connect two areas, and VIS will be blocked by the ground. Overhead connections like walkways do not work as well, because the player's side veiw is often not blocked so he sees a lot of surrounding areas, with high r_speeds. Of course, the room to room view would still be blocked, but the connector would be come the new problem.

  8. Use still sprites and models to substitute for brushes, especially complex or detailed ones. They will cause some lag, but if used carefully in a limited way, they will save more on wpolys lag. For example, for a tree do not try to make one out of brushes, but use a still sprite or a model instead. The same for a complex spoked wheel cart, a detailed tank or a cow.

  9. SKY. This may be the most obvious one of all. Environment (or sky) textures do not contribute towards the polygon count. You can replace brushes that do little to contribute to the look of a room with sky brushes to lower your polygon count. However, SKY brushes do need to be rendered, which can secretly lag fps, even while wpolys are not counted. So it is best to use SKY brushes instead of invisible { textured brushes poutside where SKY will be rendered anyway, and use the invisible { textured brushes indoors where SKY might add lag.

  10. Stretch textures on brushes when you can. 2x, 3x, or 4x (up to 9x, more makes problems) in both x and y axis helps. Wpolys are larger, but fewer - and so run faster and r_speeds are lower. It takes an equal amount of work for the engine to render a small brush with small wpolys as a large wpoly on a textures stretched brush.
    If you stretch a 256x256 texture 9x then the 224 (for tiling) subdivide will also be stretched 9x = a wpoly of 2016x2016. That is about the maximum wpoly you can have - regardless of what texture size you use. 9x 224x224 = 2016x2016, 9x128x128 = 2016x2016, 9x16x16 = 2016x2016 subdivide. The only difference is how many times the smaller textures will tile within that 2016. For more info on this, see my texture dimensions tutorial.

    NOTE: There have been discussions about the 240(not tiling)/224(for tiling) subdivide on faces to create wpolys, and how using a 224x224 or 240x240 texture can keep wpolys low with minimal stretching.

    This is true, but texture quality still suffers - the engine resamples the 224 or 240 at 128x128, aliases and resizes to use. This results in a loss of texture quality, and maybe crosshatching. So resizing the texture to 224x224 or 240x240 does not make much of a difference in Wpolys, and causes severe losses of texture quality. You would be better off to use a 128x128 texture and stretch it if you are going cover a 256x256 brush with a stretched texture to aviod the 240 (not tiling) subdivide. That way you have the same low wpoly from stretching the texture without giving the engine extra work to resample.

    Furthermore, a 16x16 texture will not make wpolys 16x16 if it is not stretched. Instead it will make the wpoly at the brush size or 224 (for tiling), whichever is smaller. It is texture stretching which stretches (or shrinks) the subdivide - not the texture size!

    sample of stretching using the texture tool.
    note that the texture is a 128x128, and is stretched 1.5x.

  11. Make details part of textures. This is primarily intended for all of you engineers and architects and wannabe's out there - you know who we're talking about. It may be very tempting to try to mimic a real environment with brushes as much as possible, down to the smallest details. However, this practice will very often produce a completely beautiful, but unplayable map. If architectural details aren't critical to gameplay, consider simplifying your level by simulating details with textures.

  12. NULL texture. This is a new texture that work's with Merle's extensions to Zoner's compile tools. NULL textured faces are simply deleted from the map at compile = less wpolys. However NULL is tricky to work with since it can lead to hall-of-mirrors type errors or other problems.

  13. Fixing water - there are several ways to hide the water for the "water everywhere seen" problem in multiplayer maps and still have transparent water:
    1. chopping - it is claimed to help to chop your water into sections of 512x512 (or smaller) and tie each section to a different func_water. However I myself could not get this to work! My water was still visible everywhere!
    2. texture I - Make, and use an animated water texture without the '!' at the beginning of the name, along with func_water entity. Only textures with a ! on the beginning of the name will be used as water textures by the engine. Possible problem: the water_surface may only be seen by one side.
    3. texture II - Use a func_illusionary instead of func_water, then un-select smart edit. In the key of skin, add the value "-3". Now it should sound like water, and if you jump it will not hurt, just like water. Possible problem: the water_surface may only be seen by one side top.

Mitering or Mitre - recent research has shown it is not needed, if the textures on all faces is aligned to world, and match. With all textures matching, compile turns the touching brushes into one face anyway. So i do not incude that.

HINT/SKIP brushes - complex subject i did not include. There is a good tutorial on HINT/SKIP at counter-map anyway. See the links


Tools to use to find problem areas in a map:

These are all console commands, to use get in the map, then into the console - for most people the ~ key.

For gl commands you will want to start in single player test mode which is done with a batch file or WC command like this test.bat :


by tommy14

website copyright (c) January 2003 Tommy of Escondido