RvS Mapping Tutorials
Odds & Ends

Zones, Portals, and Anti-Portals
-by Beckett, last updated May 1, 2003

This tutorial will teach you how to improve the performance of your map by placing effective portals and anti-portals.

This tutorial assumes that you understand the basics of UnrealED and know how to manipulate brushes, build map geometry, generate terrain, and load custom maps into Raven Shield. If this is not the case, I recommend you start with my first tutorial,
Building Your First Raven Shield Map, and work through most of my other tutorials before coming back to this one.


The most important step in optimizing the performance of your map is to divide it into multiple zones. This frees the engine from having to render all geometry at all times, and enables it to focus on just the areas that the player is viewing at the time. To be a distinct zone, a room or area must contain a single ZoneInfo actor, and it must be sealed off completely--with a combination of geometry brushes and zone portal sheets—from the rest of the map.

Let’s walk through a simple example. Pick any texture and carve out two unconnected rooms of any size, with around 64 units of space between them. Rebuild the map. Select the 3d perspective view and switch to “Zone/Portal” view ([Alt+2]). Notice that each room displays as a different color, indicating that there are two distinct zones. Now carve out a simple hallway between the two rooms. Open the Actor Classes browser, expand “Info” and select “ZoneInfo”. Right click and place a ZoneInfo in the center of each room. Rebuild the map. Notice that—uh oh—both rooms are the same color now. Even though we have placed two ZoneInfos, the rooms are no longer sealed off from each other. We need to add a zone portal to seal the connecting passage.

Switch to “Texture” view ([Alt+6]) and make sure you have “Realtime Preview” turned off in the 3d viewport or you won’t be able to see the portal sheet that we place. (Press [P] or click the Joystick icon to toggle “Realtime Preview” on and off.) Right click the “Sheet” primitive button (below Linear Staircase on the left toolbar). Select “AX_YAxis” and build a sheet to the same height and width as your hallway. Position the sheet as if it were a door, so that it perfectly seals the middle of the hallway (you may need to rotate the brush). Open the texture browser and open the “R6_Common.utx” package. Select the “Portal” texture. (this is not important to the functioning of the zone portal, but will clearly identify it in the editor). Click the “Add Special Brush” button (below Intersect on the left toolbar). Select “Zone Portal” from the dropdown list. Select the “Two Sided” checkbox and click the “OK” button. Click the “Close” button. Now switch back to “Zone/Portal” view and rebuild the map again. If you placed the portal sheet properly each room will display as a different color again. If both rooms are still the same color, check the size and positioning of the sheet to make sure there aren’t “leaks” on any side; the passageway must be completely sealed.

Now when the player is looking from one room into the next, the engine will render both rooms. However, when the player is looking in the other direction, the 2nd room won’t render at all. If you place your zones intelligently, the engine will never need to render more than a few zones at the same time, and will result in better performance on your map. The most common placement of zone portals will be in doorways and window frames since these are the most common openings into an otherwise sealed room. Note that dividing your map into zones offers a few benefits in addition to performance: you can assign different ambient sounds, EAX effects, weather effects, and ambient light levels to each zone. (I’ll cover each of these in future tutorials.)


In the case of large rooms and outdoor areas, it doesn’t make sense to try to break the area into multiple zones. In these situations you should attempt to place some large physical objects (hills, huge rocks, stage curtains, etc.) to cut down the line-of-sight distance, and then place anti-portals inside these objects.

Let’s walk through an example. Start a new map, subtract a large area (at least 4096x4096), and build mostly-flat terrain with two sizable hills, each near an opposite corner of the map. Leave some room to hide in the corner behind each hill. (If you’ve never worked with terrain before, this is no small task. You’ll want to read my
Terrain Tutorial and come back to this part at a later date.) Scatter a few static meshes around the middle of the map (above the terrain of course). Place few BSP cubes and spheres as well. Place the necessary insertion zone, lighting, and path node actors; then rebuild and save the map.

Load the map in-game from the Custom Missions menu. Press [~] to open the console. Type “ghost” and press [Enter]. Type “rmode 1” and press [Enter]. Press [~] to close the console. Now, fly around the map a bit in wireframe view. Note that even when you are completely behind one of the hills, you can still see the wireframe models of the entire map, indicating that all of the objects are being rendered at all times. Let’s go back to the editor and try to change that.

There are two types of anti-portals you can use. The editor is a bit inconsistent with the naming, but I’ll refer to them as anti-portal brushes and anti-portal volumes. There isn’t a whole lot of difference between them, and I tend to prefer using anti-portal volumes. I’ll show you how to place both types.

First, we’ll place an anti-portal brush inside the first hill. Make sure you have “Realtime Preview” turned off and “Show Volumes” turned on in each viewport, or you won’t be able to see the anti-portals that we place. (Press [P] and [O] to toggle these on and off.) Select the cube primitive and size and position your red builder brush so that it ‘fills’ the hill as well as possible without any corners sticking up out of the terrain. The best way to check for proper positioning, is to show terrain (Press [T]) in 2d viewports. If we wanted to, we could break out the 2d editor and brush clipping tools and try to sculpt the brush to resemble the shape of the terrain hill, but it’s really not worth the effort. (Plus, it could cause major problems if it resulted in an anti-portal with any concave surfaces). A cube primitive will work fine, just keep it thin so that it can sit pretty high under the terrain without sticking out the sides.

Open the texture browser, open the “R6_Common.utx” package, and select the “AP” texture (the texture is not important in any way to the functioning of the anti-portal, but it will help differentiate the anti-portal brush from other brushes on the map). Click the “Add Special Brush” button on the left toolbar. Choose “Anti-Portal” from the dropdown list, and click the “OK” button. Click the “Close” button and move the builder brush out of the way. At this point, with the camera positioned above the terrain in the 3d view, you should not be able to see any part of the purple ‘Anti Portal’ texture sticking out of the terrain. If you do see any corners sticking out, you should reposition the anti-portal brush to bury it completely. Do not, however, resize the anti-portal or it will no longer function correctly.

Note that you can also use a sheet for anti-portal brushes. This can be useful for situations where you want to occlude the individual sides of a building. You would place the anti-portal brush the same way we did above, just starting with a sheet rather than a cube primitive (and when using a sheet, I recommend creating the special brush as “two-sided”).

Now, let’s place an anti-portal volume inside the second hill. Move the red builder brush to the other side of the map and size and position it so that it ‘fills’ the second hill as well as possible. We don’t need to bother with a texture this time, since volumes don’t have any surfaces. Once the builder brush is positioned, click the “Add Antiportal” button on the left toolbar. (In case you’re curious, the “Add Antiportal” option in the “Brush” menu does the exact same thing. And once the anti-portal volume is created, the editor actually refers to it as an ‘AntiPortalActor’. Try not to get confused by the inconsistent terms. It really is a volume, I swear.)

Move the builder brush out of the way and make sure no corners of the volume are sticking out of the terrain. If you accidentally leave part of an anti-portal outside of an object, it could cause objects to disappear from view even when a player is looking right at them. Worse still, if you ever allow a player to walk into your anti-portal, they will see a hall-of-mirrors effect.

Now that our anti-portals are in place, rebuild and save the map. Load the map in-game and enter ghost and wireframe mode, just as we did earlier. Fly around the map, staying mostly low to the ground, and positioning yourself at different angles behind each hill. Make sure that you keep yourself inside the subtracted area and outside of the terrain, or you’ll get a false impression of how the anti-portals are functioning.

Notice now, that objects and terrain disappear when hidden behind either of the anti-portals. As you move around the edge of the anti-portals, you may notice that different types of actors are occluded (hidden) a bit differently. BSP geometry is occluded one BSP node at a time, terrain is occluded in 16x16 blocks, and a static mesh is only occluded if every polygon on that mesh is behind the anti-portal. With just one anti-portal in each hill, you’ll find that there are a lot of angles where no occlusion occurs. You could improve this by adding additional connected anti-portals sitting at different angles, all placed under your hill or mountain range. However, use your anti-portals intelligently and sparingly. If you place too many, the engine will have to work so hard to calculate the occlusions, that it will negate the performance benefit of having the areas occluded at all.

The methods for placing an anti-portal inside a static mesh are exactly the same as those we used for the terrain hills. If the object blocking the player’s vision is a BSP brush, the method is almost the same, however in that situation the anti-portal should not be placed completely ‘inside’ the BSP brush, it should be roughly the same size. It is essential that the anti-portal touches the subtracted area outside the brush, or it will not function properly. (This isn’t an issue with terrain or static meshes, since even when you are under terrain or inside a static mesh, you are technically in subtracted space).


The ‘rmode 1’ wireframe view works great for testing zones as well as anti-portals. Always run through your entire map in this mode and make sure objects are not being rendered when they should be occluded. Note that objects in adjacent zones will be rendered as long as the player can see through a window or doorway into any part of that zone. Note also that an anti-portal will only hide objects in the same zone, so if you place an anti-portal/dividing wall, then a crate, then a window/zone portal, then a bookcase--all in a single line of sight--the anti-portal will hide the crate but not the bookcase in the next zone. We used ghost mode in this tutorial so that you could get a feel for exactly how anti-portal occlusion works. However, when testing portals and anti-portals in your own maps, it’s probably better to stay out of ghost mode so you see the exact same angles that the player will see.

Important note: It is possible to switch the 3d viewport to wireframe mode right in the editor. Other tutorials indicate that if you turn on “Realtime Preview” and “Show Volumes”, you can test if your anti-portals are working right from the editor. This worked occasionally for me, but it appears to be very inconsistent. I spent a lot of wasted time trying to figure out why my anti-portals weren’t occluding properly, when in fact they were working fine in-game. So, I recommend that you always test your zones and anti-portals in-game, using the “rmode 1” view as described above.

I hope you found this tutorial helpful. If there's anything I've gotten wrong, please let me know and I'll correct the information. Email me if you have any questions or mapping issues you'd like to discuss.

Display a printable version of this article

© 2005, RvSMaps.com, all rights reserved
Send questions, critiques, etc. to http://www.juncmodule.net/rvs/rvsmaps/content/contact.htm