Commonly referred to as the BSP, this tag contains level geometry, weather data, material assignments, AI pathfinding information, lightmaps, and other data structures. The name "BSP" is commonly used to refer to non-object level geometry in general. Aside from sounds and bitmaps, the BSP tends to be one of the largest tags in a map.
BSP stands for Binary Space Partitioning, a technique where space within a sealed static mesh is recursively subdivided by planes into convexleaf nodes. The resulting BSP tree can be used to efficiently answer geometric queries, such as which surfaces should be collision-tested for physics objects.
While a scenario can reference multiple BSPs, Halo can only have a single BSP loaded at a time. Transitions between BSPs can be scripted (switch_bsp), e.g. using trigger volumes. Objects in unloaded BSPs are not simulated.
Although multiple BSPs are intended for singleplayer maps and do not synchronize, some custom multiplayer maps have used nearly identical BSPs which only differ in lighting to add a day/night switch scripted by a button in the escape menu.
The most commonly used shader type for BSPs is shader_environment, suitable for most opaque surfaces and alpha-tested grates or billboard trees (as in Timberland). This shader type supports the blending between multiple detail maps, often used for ground maps with dirt and grass areas.
Transparent shaders can also be used, for example:
Clusters are sealed volumes of a BSP separated by portal planes. They are used both as a rendering optimization and artistically; map authors can assign weather_particle_system, wind, sound_environment, and sound_looping tags to define local atmospheric and ambience qualities for each section of the map. Different clusters can also reference different skies.
Note that it may still be desirable to reference weather for indoor clusters if there are outdoor areas visible from them, otherwise snow and rain particles will abruptly disappear. To mask weather in such clusters, use weather polyhedra.
Areas of a map which need a fog layer can be marked using fog planes. These are 2D surfaces which reference fog tags, not to be confused with atmospheric fog which is part of the sky tag.
Weather polyhedra are simple convex volumes where weather particles will not render. They can be used to mask rain or snow from under overhangs, doorways, and indoor spaces when the cluster has weather.
When a JMS is compiled to BSP by tool, connected convex faces with the material name +weatherpoly will generate weather polyhedra. Within the tag, the polyhedra are represented as a center point, bounding radius, and up to 16 planes which enclose a volume.
The game can only support a maximum of 8 visible weather polyhedra. Beyond this point, some polyhedra will be ignored and Sapien will print warnings.
The BSP contains data on traversable surfaces which aid AI in pathfinding (walking to a destination). This data is generated automatically during BSP compilation and is retained even in when the BSP is compiled into multiplayer maps.
When a shader_environment references a lens_flare, lens flare markers are automatically created and stored in the BSP tag during initial structure compilation or updated with structure-lens-flares. These are used to give lights a "glowy" appearance. If the shader has a lens flare spacing of 0, a single lens flare is placed on the surface(how?). Otherwise, the lens flares are evenly spaced within the surface according to the spacing value (world units).
A BSP can contain up to 65535 lens flare markers, and up to 256 types of lens flares. However, there is a much lower limit to how many the game will draw at a given time, exactly how many is unknown.
Phantom BSP is a collision artifact sometimes produced when compiling BSPs. It manifests itself as invisible surfaces which projectiles and vehicles collide with (but not players), and mostly appears around sharp corners near cases of "nearly coplanar faces" warnings in your WRL file.
Bungie was aware of this bug, and even implemented a Sapien feature to help spot it (collision_debug_phantom_bsp 1). If you find phantom BSP in your map, there are a few steps you can take to resolve it:
Preemptively, keep your geometry simple and robust without an abundance of dense, complex, or spiky shapes. Flat surfaces like floors and walls should be kept as flat as possible by using alignment tools when modeling rather than "eyeballing it".
Fix any "nearly coplanar" warnings in your source model by scaling affected faces to 0 along their normal axis or using alignment. Since Tool slightly rounds vertex coordinates when compiling BSPs, sometimes this warning cannot be resolved for surfaces which are not axis-aligned.
Using phantom_tool to compile your BSP will prevent phantom BSP at the cost of slightly increasing the tag size.
There is an element of chance to phantom BSP appearing which depends on how your geometry is recursively subdivided form a BSP tree. Modifying unrelated parts of your level like adding portals or moving vertices can sometimes affect how the level is subdivided and make phantom BSP disappear.
If you do not have access to source JMS, and are trying to fix a BSP tag, the tool Ghostbuster may fix it.
On a technical level, cases of phantom BSP are dividing planes where a child index is -1, but the space on that side of the plane is not actually completely outside the level. The artifact is bounded by all parent dividing planes.
BSP holes or leaks are another type of collision artifact where items or players can fall through the map. It is not known what causes this, but it can be resolved by altering triangulation around the affected area (rotating edges). Compiling the BSP with phantom_tool also prevents this.
A reference to the bitmap storing the level's baked lightmaps. The level will not be visible without this.
f32 (world units)
The lowest Z-axis height (absolute, not frame relative) that vehicles can reach while occupied. Does not affect other object types. An unoccupied vehicle will still drop below this soft barrier, but when it becomes occupied again it will quickly shoot back up into the play area. An example of a map using a vehicle floor is Gephyrophobia to prevent players from flying too far below the bridge.
f32 (world units)
The maximum Z-axis height (absolute, not frame relative) that vehicles can reach while occupied. Does not affect other objects types. Above this point, occupied vehicles will elastically move back below the ceiling. This can be used to limit the height that players in flying vehicles like Banshees can reach for gameplay reasons. An example of this can be seen in Blood Gulch.
An block of nodes used to efficiently find collideable surfaces. Each node divides space with an infinite plane and references two child nodes by index into this block. The first element in the block is the root node. A test point can be recursively tested against planes to find a leaf of potentially colliding surfaces.
An index into the planes block. The plane divides 3D space in two. Generally, tool chooses surfaces to make dividing planes using an unknown heuristic. The first few levels of BSP seem to use special axis-aligned planes which are stored at the tail of the planes block, likely to avoid poor early heuristic choices which would negatively affect collision testing performance.
Index of the bsp3d node representing space to the back of the dividing plane. If the index is -1, then the space behind the plane is considered outside the sealed BSP (Sapien labels this as "solid" space when using debug_structure). Otherwise, if the highest order bit is set (0x80000000), the remaining 31 bits (mask 0x7FFFFFFF) represent an index into the leaves block.
Planes are infinite 2D surfaces in 3D space. They are used both to subdivide the BSP in each bsp3d node and to define collideable surfaces. The first 8 planes in the block seem to serve a special purpose -- the first 4 define the XY bounding box, with the next 4 axis aligned planes unkown. Furthermore, the last 8 planes in the block are used for the first few levels of bsp3d nodes. A single plane may be referenced from multiple bsp3d nodes since the surfaces that planes derive from can also be found in multiple leaves.
A plane which divides 3D space in two, stored as a 3-float normal and d (distance from origin) parameter.
Leaves mark the transition between the 3D BSP and a collection of convex collideable surfaces in the same localized area. Each set of co-planar surfaces within this leaf is stored within a child 2D BSP.
Note that surfaces may be found under multiple leaves, since any surface which is not completely on either side of a 3D plane will need to belong to both child 3D BSP nodes.
Flags used to optimize collision checks at runtime.
contains double sided surfaces
Indicates if any surface in any of this leaf's 2D BSPs is double-sided (e.g. glass).
bsp2d reference count
Determines how many contiguous 2D BSP references belong to this leaf.
first bsp2d reference
Index of the first 2D BSP reference associated with this leaf. It will be followed by a number of other 2D BSP references according to the above count.
Represents either a 2D BSP of surfaces, or a singular surface if the node index is flagged. In either case, test points or 3D line traces should be projected onto the basis plane in order to continue
Index for the plane used to decide what basis plane is best to project on (X,Y), (Y,Z) or (X,Z). The basis plane is chosen by the referenced plane's most significant normal component. The meaning of a flagged plane index is unknown.
The starting node for the 2D BSP on this plane. If flagged, then the index (masked to 0x7FFFFFFF) refers to a surface instead.
Surfaces are planar collideable polygons. They are not necessarily triangular (4 is also common, and Blood Gulch has one with 7 edges), and can be visualized in sapien using debug_structure 1. These surfaces are not used for the rendered geometry.
Index into the planes block for this surface's plane. Note that multiple co-planar surfaces may reference the same plane since this plane index is a copy of the parent bsp2d reference's plane index, even when flagged.
Indicates if the surface is a climbable ladder.
Indicates if the surface is breakable. The surface must also have a breakable surface index below.
Index into this tag's breakable surfaces block. It is unknown if this is a signed or flagged field, but since it is 8-bit there cannot be more than 256 unique breakable surfaces in a BSP.
Edges, surfaces, and vertices form a data structure called a doubly connected edge list (DCEL), also known as a half-edge data structure. The edges and their vertices define the boundaries of the collideable surfaces within a leaf.
Sets which sky is visible when within this cluster. Indexes the skies block of the scenario tag, so a value of 0 would mean the first sky, 1 the second, etc. A value of -1 marks this cluster as indoor/interior for the purposes of certain sky tag fields.
It is unknown how exactly Tool determines which clusters are indoor when compiling a BSP, but it does validate that all sky faces in a cluster are of the same sky. For example, a cluster cannot contain both +sky0 and +sky1 materials.
When a player moves between clusters with different skies, there is no transition. The sky will abruptly change.
Named points with orientation within the BSP. They are similar to gbxmodel markers but are not to be confused with scenario cutscene flags. These markers become visible in Sapien when enabling snap to markers in the tool window.