Managing the Void: Understanding BSP and PVS in Source Engine Geometry
Learn how the Source Engine uses BSP and PVS to manage visibility and collision, and why 'leaks' in your brush geometry can break your map compilation.
10 Jul 2025, 18:12 UTC

The Problem: The 'Leak' and the Compile Loop
For anyone building in the Source Engine, there is a specific kind of frustration that occurs when a map fails to compile: the dreaded 'Leak' error. A leak happens when a gap in your brush-based geometry allows the engine to 'see' the void—the infinite empty space surrounding your level. This isn't just a visual glitch; it breaks the engine's ability to calculate visibility, leading to massive performance drops or a complete failure to generate a playable map.
The takeaway is that Source does not treat your map as a collection of independent objects, but as a partitioned volume of space. To fix leaks and optimize performance, you must understand how Binary Space Partitioning (BSP) and the Potentially Visible Set (PVS) work together to define what the player can actually see.
Brushes and the BSP Tree
In Source, architectural geometry is created using brushes—convex hulls defined by planes. Unlike a standard 3D model (which is a shell of polygons), a brush is a solid volume. When you compile your map, the engine uses a BSP compiler to slice the entire 3D world into a tree structure.
This partitioning serves two primary purposes:
- Collision Efficiency: Instead of checking if a player is colliding with every single polygon in the map, the engine traverses the BSP tree to quickly narrow down which specific volume the player is currently inside.
- Visibility Determination: The tree divides the map into 'leaves' (the smallest possible empty spaces). These leaves are the foundation for the PVS.
PVS: Pre-calculating the View
The Potentially Visible Set (PVS) is a pre-calculated table that tells the engine: "If the player is in Leaf A, they can possibly see Leaf B, but they can never see Leaf C."
By calculating this during the compile process rather than in real-time, the engine can instantly discard entire sections of the map from the rendering pipeline. If you have a leak, the PVS calculation fails because the 'void' is technically a leaf that connects to everything, making the visibility table infinite and impossible to compute.
Practical Example: Sealing a Room
To ensure a map compiles correctly, you must create a "sealed shell." Here is the logic for verifying a sealed environment in the Hammer Editor:
- Create the Shell: Build a room using six brushes (four walls, floor, and ceiling). Ensure every edge is snapped to the grid to prevent microscopic gaps.
- The Void Test: Run a full compile. If the log reports
"Leak found!", the compiler has found a path from the inside of your room to the outside void. - Diagnostic Check: Use the
leakscommand in the developer console or look for the leak line in the compile log. The engine will draw a red line from the leak point to the void. - Verification: Once the leak is sealed, enable
r_visleafs 1in the game console. You should see the map divided into colored boxes (leaves). If the entire map is one single color, your visibility is not partitioned, and performance will suffer.
Trade-offs: Brushes vs. Props
While brushes are essential for the BSP tree and PVS, they are inefficient for complex shapes. Every additional brush increases the complexity of the BSP tree, which can lead to exponential increases in compile times.
| Feature | Brush Geometry | Static Props (Models) |
|---|---|---|
| Purpose | World structure, walls, floors | Detail, furniture, organic shapes |
| Visibility | Defines PVS leaves | Hidden/Shown by PVS leaves |
| Cost | Increases compile time | Increases GPU draw calls |
Limitations and Constraints
The biggest limitation of this system is that BSP geometry is static. Because the PVS is pre-calculated during compilation, you cannot move a brush-based wall during gameplay to change visibility. If you need a door that affects visibility, you must use a func_brush, but the underlying PVS leaf structure remains fixed. To change the world geometry fundamentally, the map must be re-compiled and re-loaded.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.