From Valve Developer Community
Revision as of 20:29, 16 September 2007 by Andreasen (talk | contribs) (Moving incomplete information to discussion page as requested.)
Jump to: navigation, search

Areaportals are used for in-game control of visibility from one area to another. They are similar to Occluders (which only blocks entities).

A portal has two states: Open or closed. While in its open state, the portal allows visibility between its bordering areas. When the portal is closed, it blocks this visibility instead. (The result is black and opaque.) You can think of it like an invisible door, which still blocks visibility.

Areaportals are typically linked to doors, matching their open/closed state, making the engine ignore drawing what is behind a door while it is closed (despite the door not being able to block visibility on its own). They may also be triggered to open or close through the I/O system (like for example trigger_multiples).

For an easy-to-understand tutorial on areaportals, see the areaportal tutorial.

Open portals

Additionally, open areaportals will also limit what is rendered beyond it, to that is directly visible through it, increasing performance.

Because of this behavior, always-open areaportals are sometimes used at the doorways to large outdoor areas. Simply placing an always-open areaportal at the end of the hallway that opens into a wide expanse, can produce a substantial performance gain. While the player is inside, looking out of the doorway, only that which is in the leaves directly visible through the doorway will be drawn.

Creating an areaportal

  1. Create the portal volume with a brush solid, completely sealing the gate between the areas that you wish to control.
  2. Make it just as thick as its door (or frame, in case there is no door). (Area volumes are designed to be very thin. One of its two main surfaces sets the border between the areas, while the opposite surface blocks the visibility between them. There also seems to be no way to specify exactly which of these two surfaces that will be used for which purpose. The compiler decides this, probably according to the leaf compile order. This order can be hard to keep track of, so to be on the safe side, and considering that both surfaces cut visleaves, a portal should stretch between two acceptable border positions, usually with the same thickness as its door or frame.)
  3. Texture all the faces of the brush with the tools\toolsareaportal material.
  4. Tie the brush to a func_areaportal entity.
  5. Make sure that the Initial State keyvalue is correctly set (so that it doesn't end up blocking visibility when it shouldn't). If you wish to link it to a named door, set the Initial State of the portal to the same initial state as the door, and put the name of the door in the Name of Linked Door keyvalue of the portal.


Sealing an area / Portal leaks

It is vital that the areas that a portal is supposed to seal off doesn't leak into each other. Just as with regular leaks, an area of the map is only considered sealed from another if it is completely surrounded by world brushes (with the exception of areaportal brushes), without gaps. Detail brushes or displacement brushes can not seal an area. Additional portals must be used to seal every entrance to the area. If the compiler can still find a way between the two main surfaces of any one portal, it will report a portal leak.

Picture: In the left picture we see an obvious portal leak (shown by the red line). On the right, another portal is added to seal the area(s).

Compiling Portals

Areaportals are handled by the BSP program (vbsp.exe).

When they compile correctly, the BSP program will report the following:

Processing areas...done

However, if a leak occurs, vbsp will instead report the following:

Brush <brush number>: areaportal brush doesn't touch two areas

These error messages are not as easy to spot as normal leak error messages, but when it comes to locating the leak in the map, the BSP program will generate a pointfile to help you, just as for regular geometry leaks.

Glview will display areaportals as gray obstructions.

Portal specific console variables

You can debug and test portals in-game, using a couple of portal specific console variables:

r_DrawPortals [0/1]

r_DrawPortals 0
This setting is default. Portals are not drawn.
r_DrawPortals 1
Outlines any portal border surface (between two areas) in green. (Sometimes more than one portal is condensed into one.) If the portal belonging to it is open, a second green box is also drawn, showing what the visibility on the other side is clipped to.

r_portalscloseall [0/1]

r_portalscloseall 0
This setting is default. Portals are displayed according to their state.
r_portalscloseall 1
Forces all portals closed (so that they cannot be opened). Overrides r_portalsopenall 1. (Try this if portals don't seem to be doing anything. It can tell you whether the problem is just that the portals aren't closing properly.)

r_portalsopenall [0/1]

r_portalsopenall 0
This setting is default. Portals are displayed according to their state.
r_portalsopenall 1
Forces all portals open (so that they cannot be closed).

r_PortalTestEnts [0/1/?]

r_PortalTestEnts 0
Entities inside visible leaves are drawn, even these entities are not visible themselves.
r_PortalTestEnts 1
This setting is default. Clip entities against portal frustrums. (Don't draw entities that aren't directly visible through the portal.)

Window portals

Areaportals can be used for windows too, with the use of the func_areaportalwindow entity. This type of portal instead controls the transparency of a window depending on how close the player is to it, effectively shutting out any scenery beyond it if the player isn't interested in it.

Performance cost and overuse

While areaportals are designed to save resources (by limiting what is being rendered) giving substantial performance benefits when used correctly, each areaportal require some run-time calculations whenever open and visible in the current view. This presents somewhat of a trade off between the benefit and the cost of the portal, as too many open areaportals simultaneously visible in the current view, while not hiding enough things, could even cost more performance than they save.

Areaportals and water

One other tricky aspect of using areaportals is that they are not allowed to cross water boundaries, like the water surface. To accomplish this, you will need to divide the portal into two - one portal above the water surface, and another portal below it - so that they both meet at the water plane.

Portals in multiplayer games

Areaportals are overall somewhat less useful in multiplayer (and especially deathmatch) games than in singleplayer. The multiple player presence will not only prevent portals from closing as often (to free resources) but players in both of its areas even renders them unable to hide anything from them, making them completely useless, and only costing resources instead of saving them. Only seal off rarely frequented areas of such a map, possibly with doors that automatically close.

Further reading

For more details, see the entity documentation for the func_areaportal and func_areaportalwindow entities.

Example maps

Unfortunately, there is no SDK sample map for areaportals.

Note.png Note: See the discussion page for info on a demo map.