This article's documentation is for anything that uses the Source engine. Click here for more information.

BSP flags (Source)

From Valve Developer Community
(Redirected from Surface flags)
Jump to navigation Jump to search
English (en)Translate (Translate)

edit

🖿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.

Icon-Important.pngImportant:Hammer Hammer 4.x (including Hammer++ Hammer++) strips these values! Put applicable geometry in an instance to avoid issues.

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 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.

Only some of these flags will have any effect when used on displacements.

Bit Flag name Dev comment Description
0x0001 SURF_LIGHT value will hold the light strength Only used internally by VRAD, to prevent treating texlights with SURF_NOLIGHT as having SURF_NOCHOP; not written to BSP. Comment is vestigial from Quake II Quake II.
0x0002 (removed since Source 2007) SURF_SLICK effects game physics[sic]
Obsolete-notext.pngDeprecated:Legacy Quake II Quake II flag; deprecated in favor of surface properties.
0x0002 (in all games since Source 2007) 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
Note.pngNote:%Compile2DSky assigns both SURF_SKY2D and SURF_SKY; if a face only has SURF_SKY2D assigned, it will not be drawn as a skybox, and light will not be cast from it.
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. Required for planar reflections to work on world brushes.
0x0010 SURF_TRANS (none) Surface is translucent, either via $translucent or $alpha.
Note.pngNote:Does not apply to $alphatest.
0x0020 (removed since Source 2007) SURF_WET the surface is wet
Obsolete-notext.pngDeprecated:Legacy Quake II Quake II flag; deprecated in favor of surface properties.
0x0020 (in all games since Source 2007) SURF_NOPORTAL the surface can not have a portal placed on it Set via %NoPortal
0x0040 (removed since Half-Life 2 (Xbox)) SURF_FLOWING scroll towards angle
Obsolete-notext.pngDeprecated:Legacy Quake II Quake II flag; deprecated in favor of material proxies.
0x0040 (in all games since Half-Life 2 (Xbox)) 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, as well as several other parameters
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 Alien Swarm or newer or Source 2013.

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 lightmaps, with the fourth being used when bumpmapping is disabled.
0x1000 SURF_NOSHADOWS Don't receive shadows Using Slammin' Source Map Tools or Mapbase 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 several different parameters. Can also set via %nopaint in Portal 2 Portal 2. This flag is checked before $nodecal.
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?: Seems to be used at runtime
Cpp.pngCode: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. Additional flags can be set via Source Model Skin Editor Source Model Skin Editor.

Todo: 
  • Document any additional flags used by third-party titles
  • Test flags not available via $contents
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 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. Due to this, it is non-solid.
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 (in supported games). 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 Source 2007) CONTENTS_MIST (none) Unknown purpose; only set by %CompilePlayerControlClip. In Quake II, this was simply a nonsolid brush.
0x00000040 (in all games since Source 2007) CONTENTS_BLOCKLOS block AI line of sight Blocks line of sight for NPCs and bots. Blocks VIS unless detail contents are also present.
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. Strangely, this is set by %CompileNonSolid, rather than CONTENTS_MIST or CONTENTS_AUX.
0x00000100 CONTENTS_TESTFOGVOLUME (none) Likely was used for %CompileFog early in Half-Life 2's development, but this behavior was removed. VVIS has some code for special handling of this, but there is no way for a brush to have this contents unless the user manually adds the contents to the VMF.
0x00000200 CONTENTS_UNUSED (none)
0x00000400 (removed since Alien Swarm) 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 Alien Swarm) CONTENTS_BLOCKLIGHT Not actually unused; comment is vestigial.
Confirm:Is this in Left 4 Dead engine branch 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 Day of Defeat: SourceTeam Fortress 2Left 4 Dead seriesLeft 4 Dead series, but only able to be set via %CompileTeam in Left 4 Dead seriesLeft 4 Dead series and newer if using vanilla VBSP. See that command's page for how to implement the command in older games' VBSPs.

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.) Applied at runtime.
----------------- ----------------- 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. Some NPCs, such as hostages pass through this.
0x00040000 (removed since Portal 2) CONTENTS_CURRENT_0 currents can be added to any other contents, and may be mixed Effectively identical to trigger_push (with a speed of 1?[confirm]) traveling the specified direction. Mix these to go in diagonals.
0x00080000 (removed since Portal 2) CONTENTS_CURRENT_90
0x00100000 (removed since Portal 2) CONTENTS_CURRENT_180
0x00200000 (removed since Portal 2) CONTENTS_CURRENT_270
0x00400000 (removed since Portal 2) CONTENTS_CURRENT_UP
0x00800000 (removed since Portal 2) CONTENTS_CURRENT_DOWN
0x00040000 (in all games since Portal 2) CONTENTS_BRUSH_PAINT N/A (source code not public)
0x00080000 (in all games since Counter-Strike: Global Offensive) CONTENTS_GRENADECLIP N/A (source code not public)
0x00100000 (in all games since CS:GO Danger Zone) CONTENTS_DRONECLIP N/A (source code not public)
0x00200000 N/A N/A (not defined) Unused in all first-party games
0x00400000
0x00800000
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.[Obsolete-notext.png 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. Some entities, such as physics models, apply this flag at runtime, but it should theoretically work if defined explicity.
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 or which have %CompileDetail materials. 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. Automatically given to any brushes in a func_ladder or which have %CompileLadder materials.
0x40000000 CONTENTS_HITBOX use accurate hitboxes on trace
0x80000000 N/A N/A (not defined) Unused in all first party games
Cpp.pngCode:0x00000200, 0x00200000, 0x00400000, 0x00800000, and 0x80000000 can reliably be used for custom contents flags in mods shipping custom DLLs (and preferably custom VBSP).

See also