Enter Half-Life Re-imagined, our current competition!
Check out Skewing textures in Hammer, our newest tutorial!
Say hello to Bear, our newest member!


Site Stuff






Valve Predictions 2017

What's the most likely thing Valve will release this year?



A new game


More overpriced hardware


Source 2 SDK


An army of evil killer cyborgs


The hounds



34 secs


3 mins


6 mins


8 mins


26 mins


34 mins


43 mins



A gaming and technology blog by TWHL admins Penguinboy and Ant. A music blog by TWHL users Ant and Hugh.

Advanced r_speeds Control

By Mohammad 'BadMofo' Alavi

This article is intended for advanced mappers. It is assumed that you possess at least a basic understanding of the Half-Life engine and its compile processes. In addition, this technique only works in single player maps - sorry to disappoint you multiplayer mappers.

There have been many techniques described in the past to combat r_speeds, yet none quite like this. Before I go into its details, though, I need to cover some basics. One of the more widely used methods to reduce r_speeds is to convert sections of architecture to func_walls (or any other brush based entity for that fact) so as not to break up world brushes. For the remainder of this editorial, I will refer to func_illusionaries, func_walls, or whatever other entity you choose to reduce r_speeds as simply a brush based entity.

If you need more clarification on the technique described above, I recommend reading this excellent tutorial on basic techniques to reduce r_speeds. Now what are some of the disadvantages to using the above technique? Well the most obvious one is that entities don't VIS-block. A less apparent disadvantage is that they aren't even figured into the VIS calculations. Even a mapper with little experience soon realizes that the engine draws a lot more than what you can see. These off-screen elements are visible if gl_wireframe 2 is enabled in the console. You'll notice that brush based entities are visible more of the time than their world brush counterparts. The engine drawing these off-screen polygons can be a great detriment to FPS in parallel with r_speeds.

    Note: If you are using Software rendering, use r_draworder 1 instead of the gl_wireframe command. When r_draworder is set to 1, the rendering order is reversed, so the farthest objects are drawn last, thereby making them visible when they would otherwise be hidden.

The method I'm about to introduce has its limitations, but it will certainly help lower the r_speeds associated with these off-screen brush-based entities. What we're going to do is manually tell the engine when and when not to draw these off-screen elements. I'll use a hallway leading into a semi large room example for this. Please refer to the figure below:

If you're going to create brush-based entities in the room for the sole purpose of preventing BSP splits, then go ahead and name those entities. Doing so allows them to be targeted later. Furthermore, if the player does not start in this room, then change the brush based entities' fx_modes to texture and their fx_amounts to 0. Doing so will render them invisible. (Note: If brushes are completely invisible, then they are not drawn and their polygons won't contribute to the r_speeds)

Now place two env_renders as shown in the diagram, both targeting the previously mentioned brush-based entities. Env_renders are used to change the fx_amounts and fx_modes (among other things) of any targeted object. We'll set one env_render to change the brush based entities' fx_mode to texture and its fx_amount to 0. Set the second env_render's fx_mode to normal (or solid, if you're working with semi transparent brushes), and its fx_amount to 0 (or 255 if you're working with semi transparent brushes). Doing so will cause this env_render to render the brush based entities within the room visible.

After naming the env_renders appropriately, create two trigger_multiples in the hallway, as shown in the figure. Don't name these triggers. You want the player to trigger the events when they walk through these brushes; giving them a name would nullify that effect. The trigger_multiple that is closest to the room's entrance will need to activate the env_render that turns the brush based entities within the room visible; so label the trigger's target field with the name of the appropriate env_render. The trigger_multiple farthest from the room's entrance needs to do the inverse. It should target the env_render that makes the brush based entities invisible. Finally, make sure to set the delay before reset value on your trigger_multiples to 0.

If it isn't clear what is going on, let me run through the sequence of events. The player will be walking down the hallway towards the large room. At the moment, most of the details of the room are VIS-blocked out of the engine's renderer. Furthermore, the brush-based entities are invisible and thus not being drawn (where normally they would). This allows the mapper to put more detail into the hallway without fear of capping the r_speed limit. As the player approaches the room he walks through the first trigger_multiple and?nothing happens. Nothing is suppose to happen yet so we're still good. As the player walks even closer to the room the VIS-blocked objects within the room may or may not have been drawn yet. This is not up to us, it's up to the engine so it's not as significant. What is significant is that as the player walks through the second trigger_multiple, all the brush-based entities in the room are rendered (just before the player gets there). At this point, all the details of the hallway are behind the players FOV (field of vision) and are not contributing to the r_speeds. Thus, the extra polygons caused by the brush-based entities don't impact the r_speeds as badly at this location, as they would have further down the hallway (where the renderer would have to draw both the details of this large room and of the entire hallway).

Now as the player walks away from the room, he'll eventually hit the first trigger_multiple that will render the brush-based entities invisible, thus reducing the r_speed hit at this further location. The obvious factor is that the placement of these trigger_multiples is vital. The second one needs to be out of the line of sight of any brush based entities--otherwise, the player would see our effect, and we don't want that. That second trigger, however, still needs to be close enough to the entrance to be effective. The first trigger_multiple also needs to be placed intelligently. If it is too far away from the room, then the r_speeds would get too high before the brush based entities were rendered invisible.

As you can see, this method does have its limitations to hallways and corridors. And more importantly, it takes a lot of time and planning to implement this throughout a map. However, the fact is if you wanted to take advantage of this system, you could push the limits of detail and reality in the Half-Life engine even further than before - and isn't that what all good mappers strive to achieve?