BSP flags (Source)
public/bspflags.h
defines bitfields used to tell the game engine and compiler how a brush face should be drawn in-game (surface flags), and what should be inside the brush (contents flags). They are descended from the method used by Quake II.
These are normally defined via Material map compile flags, but they can also be applied directly into a VMF's brush face, using "contents" "####"
for contents flags and "flags" "####"
for surface flags (wherein ####
is the bitfield represented in base 10 form). Some values are also defined via other means, such as func_detail for CONTENTS_DETAIL.
Some of the contents flags are also used for MDL models, and are set using the $contents
QC command.
List of flags
Surface flags
Surface flags on different faces of a brush generally do not need to match. If two or more conflicting flags are assigned, then the flag with the lowest bit value will take priority.
Unlike Quake II, surface flags are stored as a 16-bit value instead of a 32-bit value. This is because most information about how to draw the surface can be determined instead at runtime via the VMT.
Bit | Flag name | Dev comment | Description |
---|---|---|---|
0x0001 | SURF_LIGHT | value will hold the light strength | Normally set on any surface that matches a RAD file entry; not actually written to the BSP, unlike Quake II.
Confirm:Can the value field be set in a VMF, or does it require regressing to MAP instead?
|
0x0002 (removed since ) | SURF_SLICK | effects game physics[sic] | Deprecated:Legacy Quake II flag; deprecated in favor of surface properties.
|
0x0002 (in all games since ) | SURF_SKY2D | don't draw, indicates we should skylight + draw 2d sky but not draw the 3D skybox | Shows only the 2D skybox. Set via $Compile2DSky
Confirm:
%Compile2DSky assigns both SURF_SKY2D and SURF_SKY; what happens if a face only has SURF_SKY2D? |
0x0004 | SURF_SKY | don't draw, but add to skybox | Shows both the 2D and 3D skybox. Set via $CompileSky |
0x0008 | SURF_WARP | turbulent water warp | Tells VVIS and the engine renderer that the surface is water. Set via %CompileWater , but not %CompileSlime . Confirm:Why does VVIS read this?
|
0x0010 | SURF_TRANS | (None) | Surface is translucent, either via $translucent or $alpha .
Confirm:Might also apply to
$alphatest . |
0x0020 (removed since ) | SURF_WET | the surface is wet | Deprecated:Legacy Quake II flag; deprecated in favor of surface properties.
|
0x0020 (in all games since ) | SURF_NOPORTAL | the surface can not have a portal placed on it | Set via %NoPortal |
0x0040 (removed since ) | SURF_FLOWING | scroll towards angle | Deprecated:Legacy Quake II flag; deprecated in favor of material proxies.
|
0x0040 (in all games since ) | SURF_TRIGGER | FIXME: This is an xbox hack to work around elimination of trigger surfaces, which breaks occluders | Set via %CompileTrigger. Doesn't do anything in the PC versions. |
0x0080 | SURF_NODRAW | don't bother referencing the texture | Set via %CompileNoDraw |
0x0100 | SURF_HINT | make a primary bsp splitter | Set via %CompileHint |
0x0200 | SURF_SKIP | completely ignore, allowing non-closed brushes | Set via %CompileSkip. Should never be used on anything except a hint brush. |
0x0400 | SURF_NOLIGHT | Don't calculate light | Face is unlit. Set via %CompileNoLight if using or newer or .
Set automatically on UnlitGeneric materials. |
0x0800 | SURF_BUMPLIGHT | calculate three lightmaps for the surface for bumpmapping | Implied by $bumpmap and/or $normalmap. Actually calculates four lightmap, with the fourth being used when bumpmapping is disabled. |
0x1000 | SURF_NOSHADOWS | Don't receive shadows | Using or VBSP, set via %CompileNoShadows .
Confirm:How is it used in vanilla compilers? It seems to be unrelated to info_no_dynamic_shadow.
|
0x2000 | SURF_NODECALS | Don't receive decals | Set via $nodecal. Can also set via %nopaint in Portal 2. |
0x4000 | SURF_NOCHOP | Don't subdivide patches on this surface | Set via %CompileNoChop. Has the side effect of affecting triangulation, as well. |
0x8000 | SURF_HITBOX | surface is part of a hitbox | [Why?] |
0x0020
can reliably be used as a custom surface flag on mods not using portals.Contents flags
Contents flags on different faces of a brush almost always need to match. Mismatched contents will result in compiler errors, and leaves it up to the compiler to decide what contents a brush should have. If two or more conflicting flags are assigned, then the flag with the lowest bit value will take priority.
In addition to brushes, some of these flags can also be set on MDLs using $contents parameter.
Bit | Flag name | Official description | Notes |
---|---|---|---|
0x00000000 | CONTENTS_EMPTY | No contents | Technically not a flag, but rather the lack of any flags. This cannot be manually assigned to a surface, as brush faces with the contents field set to zero in the VMF (or MAP) file will be treated as solid[citation needed]. Instead, use %CompileNonSolid, a func_illusionary, or a non-solid func_brush. |
0x00000001 | CONTENTS_SOLID | an eye is never valid in a solid | Default contents |
0x00000002 | CONTENTS_WINDOW | translucent, but not watery (glass) | Affects VIS testing. |
0x00000004 | CONTENTS_AUX | (none) | Unused. |
0x00000008 | CONTENTS_GRATE | alpha-tested "grate" textures. Bullets/sight pass through, but solids don't | Equivalent to a combination of two brushes: one %CompileNonSolid, and the other %CompileClip. Set via %CompilePassBullets or $contents "grate" .
|
0x00000010 | CONTENTS_SLIME | (none) | Set via %CompileSlime. Unlike Quake II, slime does not do damage; a separate trigger_hurt should be used for this. |
0x00000020 | CONTENTS_WATER | (none) | Set via %CompileWater. |
0x00000040 (removed since ) | CONTENTS_MIST | (none) | Unknown purpose; only set by %CompilePlayerControlClip. |
0x00000040 (in all games since ) | CONTENTS_BLOCKLOS | block AI line of sight | Only visible to NPCs and bots. Transparent to players. |
0x00000080 | CONTENTS_OPAQUE | things that cannot be seen through (may be non-solid though) | Any player-visible brush that isn't translucent or transparent is opaque. |
0x00000100 | CONTENTS_TESTFOGVOLUME | (none) | |
0x00000200 | CONTENTS_UNUSED | (none) | |
0x00000400 (removed since ) | CONTENTS_UNUSED6 | Unused NOTE: If it's visible, grab from the top + update LAST_VISIBLE_CONTENTS if not visible, then grab from the bottom. |
|
0x00000400 (in all games since ) | CONTENTS_BLOCKLIGHT | Not actually unused; comment is vestigial.
Confirm:Is this in Left 4 Dead engine branch as well?
Confirm:Can this block dynamic lights, unlike toolsblocklight?
| |
0x00000800 | CONTENTS_TEAM1 | per team contents used to differentiate collisions between players and objects on different teams |
Typically to set barriers that prevent one team from entering another team's spawn zone.
Used in multiple games, including , but only able to be set via %CompileTeam in and newer. |
0x00001000 | CONTENTS_TEAM2 | ||
0x00002000 | CONTENTS_IGNORE_NODRAW_OPAQUE | ignore CONTENTS_OPAQUE on surfaces that have SURF_NODRAW | |
0x00004000 | CONTENTS_MOVEABLE | hits entities which are MOVETYPE_PUSH (doors, plats, etc.) | |
----------------- | ----------------- | remaining contents are non-visible, and don't eat brushes | ----------------- |
0x00008000 | CONTENTS_AREAPORTAL | (none) | Is an areaportal. |
0x00010000 | CONTENTS_PLAYERCLIP | (none) | Solid to players, including bots. |
0x00020000 | CONTENTS_MONSTERCLIP | (none) | Solid to monsters, better known in Source as NPCs. Also solid to bots in CSGO, even though they are players. |
0x00040000 (removed since ) | CONTENTS_CURRENT_0 | currents can be added to any other contents, and may be mixed | Effectively identical to a trigger_push traveling the same direction. Mix these to go in diagonals. |
0x00080000 (removed since ) | CONTENTS_CURRENT_90 | ||
0x00100000 (removed since ) | CONTENTS_CURRENT_180 | ||
0x00200000 (removed since ) | CONTENTS_CURRENT_270 | ||
0x00400000 (removed since ) | CONTENTS_CURRENT_UP | ||
0x00800000 (removed since ) | CONTENTS_CURRENT_DOWN | ||
0x00040000 (in all games since ) | CONTENTS_BRUSH_PAINT | N/A (source code not public) | |
0x00080000 (in all games since ) | CONTENTS_GRENADECLIP | N/A (source code not public) | |
0x00100000 (in all games since ) | CONTENTS_DRONECLIP | N/A (source code not public) | |
0x01000000 | CONTENTS_ORIGIN | removed before bsping an entity | Coordinates of enter of the brush is written to the origin KV, to dictate the pivot point of certain entities.[ Deprecated]
|
0x02000000 | CONTENTS_MONSTER | should never be on a brush, only in game | Is a monster, better known in Source as an NPC. |
0x04000000 | CONTENTS_DEBRIS | (none) | Solid to point traces (ex hitscan weapons) and non-debris physics objects[confirm]. Non-solid to QPhysics entities, such as players. |
0x08000000 | CONTENTS_DETAIL | brushes to be added after vis leafs | World brushes with these contents don't affect VIS. Brushes with these contents can be toggled with r_drawfuncdetail . Automatically given to any brushes in a func_detail. This flag is stripped from brushes which are part of a brush entity.
|
0x10000000 | CONTENTS_TRANSLUCENT | auto set if any surface has trans | Used for alpha sorting on (non-detail) worldspawn brushes. |
0x20000000 | CONTENTS_LADDER | (none) | Is a ladder. |
0x40000000 | CONTENTS_HITBOX | use accurate hitboxes on trace | |
0x80000000 | N/A | N/A (not defined) | Unused |
0x00000200
and 0x80000000
can reliably be used for custom contents flags in mods shipping custom DLLs (and preferably custom VBSP).