Map Optimization Thread!


Fig. 1. Yeah, I’ve got my work cut out for me.

I figured I’d start a purpose built thread for this because I have a TON of questions about optimizing in Source. My in-progress mod has been long delayed because of Source’s difficulty rendering any kind of open spaces, and as a result I had to totally redesign the entire world map to better cater to Source’s strengths (indoor areas, and outdoor scenes broken up by cliffs and other natural formations to keep entity budget down).

I’m currently attempting to design a dockyard for the mod, and I am running into some difficulty regarding alignment of buildings and the use of Source’s optimization toolset.

For those of you unfamiliar with Source Engine optimization (and yes, you would be reading this thread to learn something), I’ll briefly explain what each thing does.

BASIC SOURCE OPTIMIZATION PRIMER (Based on what I know. Feel free to correct me if anything is wrong and I’ll update this.)


NoDraw textures are effectively telling the game that “nothing texture-wise needs to be drawn here.” This is useful for areas that are “out of bounds” or otherwise inaccessible for players through normal movement. Using these on the other side of walls or floors where the player cannot go is the primary use for NoDraw. No performance cost,

Hint textures are effectively a manual method of telling VVIS (the map visibility calculator at compile time) where something can and cannot be drawn. VVIS does a lot of the heavy lifting, but not necessarily the most efficiently. Using Hint effectively can effect your map’s visibility calculation time quite positively with a minimum of in-game performance cost. For instance, in a corridor that bends in a C shape


I -------------
I I
I I
I I
I -------------

Can be optimized with hint textures. Better example here. Heck, watch that whole video, it explains all of this a TON better.

Occluders are effectively free-standing walls that can be built anywhere. At run-time, the game engine must run calculations while the Occluder wall is active to figure out what is and is not being hidden by the func_occluder. This is primarily for areas where there are a lot of props in a specific area that you want to hide when the player can’t see them and an Areaportal is out of the question. Use these with caution, since this is not calculated in compile, it is run dynamically in-game and can therefore actively sabotage performance if overused.

The Far Z Clip function of env_fog is another choice for long range visibility culling. This uses a fog effect defined by the mapper to cover the dropping of long distance props and geometry. Silent Hill’s distinctive fog effect evolved from a similar method of optimization due to the first game using the limited memory of the original PlayStation up too fast and the fog had to be used to keep the game from lagging uncontrollably.

Areaportals are the pickiest form of optimization but potentially the most powerful. These seal off areas of your map completely between areas. Put one in a door of a building that doesn’t connect back to the outside, and while the door is closed the entire building and everything in it does not draw. This helps the renderer be capable of detailed interiors and exteriors without requiring both to be drawn simultaneously, and is generally a very good tool. However, you have to be VERY careful employing them, because if there is any part of the building that links back to the outside that doesn’t have another portal sealing it off, the map will leak and you’ll have to go back and fix it. Fun fun fun!

Two principal variants of areaportals exist: the standard version, designed to be toggled on and off with inputs or linked to a prop state such as a door, and the “window” version, which uses a brush to fade with. When you get close to a dark interior in HL2 and the scene gradually fades into view? That’s a window areaportal at work.

Also, TextFAM reminded me that even if an areaportal is an always-open portal, it has the effect of culling geometry and props that are drawn through it. So instead of drawing the entire room beyond, it only renders what the player client can see through it. Again, use with caution, because this is dynamically calculated by the engine, and if you have a bunch of portals in the same area it can also cause problems in your compile.



Fig. 2. First part of my large Dockyard whiteboard mockup. Already trying some ideas with optmization on paper, but it’s harder to visualize top-down because I don’t have the advantage of seeing where I can put the skybox walls to optimize without impeding player freedom.

The Dock map is going to be divided into three main areas- the initial area with a drydock and prisoner induction building, the second area consisting of a warehouse and lots of shipping containers, and the third area, with a full dock crane, secondary warehouse, and crane. The third area should be able to let a sniper take pot shots at the player across any area in view. I could employ the far-Z clip of an env_fog, but I’d like to preserve long range viewpoints if possible because combat is always more interesting when you force the player to consider both range and verticality. One of the better combat sequences in HL2 was the inside of the old factory where the player was being constantly attacked from above, their level, and then subsequently below (right before Forget About Freeman starts, if you’re wondering which map).


Fig. 3. - Part 2 of the dockyard. Try to connect both areas in your head and imagine how much of a pain in the ass that will be to both detail properly and optimize to keep a 60fps framerate at Episode Two system requirements. My mod will probably require higher requirements than Ep2, at least in terms of having system overhead to keep these sorts of environments running smoothly.

The primary problem with employing areaportals in my dockyards map is that I intend to design the map in such a way that players can travel freely across the roofs of buildings, shipping containers, and other such building elements. This plays hell with Source’s areaportals because they have to completely seal areas with materials or skybox textures, and areaportals will also stop drawing anything behind them if turned off. Obviously I can use them for building doors and openings, but the amount of windows I intend to have will result in there being easily 20+ areaportals in the warehouse structure at the center of the map. This will be even more hellish if I build blast holes into the layout for natural light (like I plan on doing).

I plan to use occluders to control visibility in the shipping container maze outside the warehouse, but this only handles props, not brushwork. Areaportals would be impossible here because it’s too open and it wouldn’t seal without massive modifications to skybox walls and level design.

Hint and Skip is rather difficult to use without a clear idea of how VVIS uses the walls. The tutorial on VDC is somewhat in-depth but I’m not sure which side does what, and how many I can safely use.

I’ve learned a ton over the years from this site and many others, and I’d really like a chance to strut my stuff and release something playable. But playable = decent framerate and good looking, and that’s going to be difficult with such open levels. Anyone have any tips I could use, or ideas to modify the layout to make it easier to optimize the area?

For large, open outdoor areas - or spaces where visibility blocking isn’t always feasible or cost effective, using prop fade distances is nearly always the best way to get precious frames. Each prop needs to be individually tuned so it’s extremely time consuming, but in large outdoor spaces it’s pretty much the only way to stop framerates from tanking in detailed areas.

Also, your description of hint/skip is pretty misleading, but maybe that’s just a problem with explanation rather than understanding. Skip doesn’t do anything - the skip texture simply tells the compiler to altogether skip that face when compiling. Faces textured with skip simply don’t make it into the .bsp in any way, shape or form. The hint texture tells VBSP to divide visleafs across that face. This is nigh on impossible to explain adequately without a good understanding of visleaves. Visleafing is ineffective in very open areas, but a good combination of visleafs, areaportals, occluders, and fade distances can really bring framerates up in open areas.

It’s also worth mentioning that areaportals can really help performance even if they aren’t “closed”. “Closed” referring to when an areaportal is not rendering anything behind it. “Open,” areaportals which you can see through, cull visibility, by only rendering what you can see through the open areaportal, instead of using visleaves. This can really boost performance if used well. For instance, let’s say you’re inside, and you have a huge window leading to a large outdoor area. By default, the entire outdoor area may render while inside, due to the way the visleaves are sectioned. With an open areaportal in that window gap, the engine will only render what you can see based upon your viewcone when looking through that open areaportal. This can bring significant performance gains.

Hope this has helped. Apologies if I’m just repeating stuff you already understand.

I am HORRIBLE with Hint/Skip so thank you for clarifying. I did know that Areaportals cull visibility but I neglected to mention that in the OP. Thanks! Updated the OP.

func_viscluster for big open areas with unbroken visibility works good too.

It tells that visleaves in the volume can see each other.

I did end up using func_viscluster in one of my maps, cut down on compile times a TON. It doesn’t actually combine everything into one visleaf, it just says “all visleafs touching this volume are automatically assumed to all see each other.”

func_viscluster is always powerful but doesn’t mean apply it everywhere.

Use portal file to see where leafs can see each others.

Usually used on big open areas with no broken visibility.

More optimization stuff. If you guys can read any of this, any suggestions on how to portal this area and still enable walking on the roof?

(Below is a continuous image from left to right)

I can see from the diagram that you are already portaling the doors. At the very least, do the same with the windows (with the always-open portals that Text mentioned earlier). And if not that, you can also consider making the windows opaque (like how BM did with ST) so that, since you aren’t seeing anything outside, you can effectively seal off the warehouse and have a lot less stuff drawn.

I wish I could be more help here, but I’ve only really worked with Hint/Skip, which you already know about.

One thing I could mention, even though I know it is definitely not the type of optimization you’re looking for right now, is that when you put physics props in, use map_edit after compiling and wc_update_entity to set objects correctly, then set them to start asleep. You an read a little bit more about it here.

^ Very useful tip. I will definitely try this.

Founded in 2004, Leakfree.org became one of the first online communities dedicated to Valve’s Source engine development. It is more famously known for the formation of Black Mesa: Source under the 'Leakfree Modification Team' handle in September 2004.