The "outside" skin/face plane/facets boundary of a model or map. Half-Life maps have 4 hulls, one for visual rendering and three for collision detection. Hull is mentioned when you have a LEAK error when compiling a map.
Note: in the following table, boundaries and size are expressed as 3D vectors in the X, Y and Z coordinates respectively. Note that none of these are tied to a floor, ceiling, or wall especially.
Index |
Minimum boundary |
Maximum boundary |
Size |
Description* |
|
(0, 0, 0) |
(0, 0, 0) |
(0, 0, 0) |
This is the physical hull, basically the planes and brush faces. |
1 |
(-16, -16, -36) |
(16, 16, 36) |
(32, 32, 72) |
This is the hull that limits where a standing player can go. Basically this one keeps players from getting "buried in the floor or the wall". The model has little to do with the hulls. |
2 |
(-32, -32, -32) |
(32, 32, 32) |
(64, 64, 64) |
This hull limits where large monsters can go such as the Gargantua, Gonarch and Bullsquid. |
3 |
(-16, -16, -18) |
(16, 16, 18) |
(32, 32, 36) |
This one is for the crouching player. |
4 |
n/a |
n/a |
n/a |
This is a bogus hull error and does not really exists. |
* Sourced from VERC
Mechanism
John Carmack introduced with Quake the BSP format, and with it clip hulls in order to speed up collision detection.
A naive algorithm to calculate player collision would usually involve calculating the distance between a plane and a point (center of the player entity) then subtracting the thickness of the player entity from its center. This calculation is done for both sides of all three axial directions, totaling 6 each.
Carmack's solution is to pre-calculate the "thickness" part during compilation by expanding the collide-able planes outward the same distance to the center point of the player entity, so that inside the game loop the collision detection code only has to check if the distance is greater than zero. Hull 1 accounts for normal standing players, and hull 3 accounts for the crouched size of players. Hence for the purpose of world collision, the players are reduced to singular points in space.
Hulls and clipnodes are very intertwined concepts, in fact clip hulls are composed of clipnodes.
Controlling hull generation
Modern GoldSrc compilers like VHLT provide several ways to control aspects of hull generation.
The coarsest control knob is turning whole hulls off. This can be achieved by passing the following arguments to HLBSP:
-noclip
– skips clip generation entirely. the map will have no collision whatsoever
-nohull#
(#=1…3) – skips generation of specified hull number from world geometry
A typical use case is to use
-nohull2
on multiplayer maps where there are no monsters (thus none using Hull 2) and no
func_pushable
using the same, slashing roughly 1/3rd of the tight clipnode budget. More careful consideration is required before removing hull 2 in singleplayer maps.
After that there are finer per-brush, per-area, or per-entity control on hull generation:
- Using the
NOCLIP
texture on a brush
- Using the
zhlt_noclip
keyvalue on func_detail
or brush entities
This skips clip generation on
all hulls, however.
Third, comes the
CLIP and co. family of
tool textures which instructs the generation of clipnodes on some or all hulls. If using any of the earlier methods to skip building clipnodes off of world geometry, these clip brushes can be used to manually add back collision. The textures are:
CLIP
– all hulls
CLIPHULL#
(#=1…3) – hull #
Last but not least, a very powerful entity called
info_hullshape
can customize the sizes of the hulls for specific entities or for the whole map, and the hard and fast values in the table above is no more.
While the above can be safely used to customize clipnode generation using default hull sizes as the base, modifying hull sizes itself would have implications. For example, a lot of NPCs use the naive collision detection method since they don't express the same agility as players, so reducing hull sizes may not make NPCs magically fit narrower gaps than their original hull shape intended.