srctools.bsp
Read and write parts of Source BSP files.
Data from a read BSP is lazily parsed when each section is accessed.
- class srctools.bsp.BSP_LUMPS(
- value,
- names=None,
- *,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
Enum
All the lumps in a BSP file.
The values represent the order lumps appear in the index. Some indexes were reused, so they have aliases.
- ENTITIES = 0
self.ents
- PLANES = 1
self.planes
- TEXDATA = 2
- VERTEXES = 3
self.vertexes
- VISIBILITY = 4
- NODES = 5
self.nodes
- TEXINFO = 6
self.texinfo
- FACES = 7
self.faces
- LIGHTING = 8
- OCCLUSION = 9
- LEAFS = 10
self.leafs
- FACEIDS = 11
- EDGES = 12
- SURFEDGES = 13
self.surfedges
- MODELS = 14
self.bmodels
- WORLDLIGHTS = 15
- LEAFFACES = 16
- LEAFBRUSHES = 17
- BRUSHES = 18
self.brushes
- BRUSHSIDES = 19
- AREAS = 20
- AREAPORTALS = 21
- PORTALS = 22
Aliases:
UNUSED0
,PROPCOLLISION
- CLUSTERS = 23
Aliases:
UNUSED1
,PROPHULLS
- PORTALVERTS = 24
Aliases:
UNUSED2
,PROPHULLVERTS
- CLUSTERPORTALS = 25
Aliases:
UNUSED3
,PROPTRIS
- DISPINFO = 26
- ORIGINALFACES = 27
self.orig_faces
- PHYSDISP = 28
- PHYSCOLLIDE = 29
- VERTNORMALS = 30
- VERTNORMALINDICES = 31
- DISP_LIGHTMAP_ALPHAS = 32
- DISP_VERTS = 33
- DISP_LIGHTMAP_SAMPLE_POSITIONS = 34
- GAME_LUMP = 35
- LEAFWATERDATA = 36
self.water_leaf_info
- PRIMITIVES = 37
self.primitives
- PRIMVERTS = 38
- PRIMINDICES = 39
- PAKFILE = 40
self.pakfile
- CLIPPORTALVERTS = 41
- CUBEMAPS = 42
self.cubemaps
- TEXDATA_STRING_DATA = 43
- TEXDATA_STRING_TABLE = 44
self.textures
- OVERLAYS = 45
self.overlays
- LEAFMINDISTTOWATER = 46
- FACE_MACRO_TEXTURE_INFO = 47
- DISP_TRIS = 48
- PROP_BLOB = 49
Alias:
PHYSCOLLIDESURFACE
- WATEROVERLAYS = 50
- LEAF_AMBIENT_INDEX_HDR = 51
Alias:
LIGHTMAPPAGES
- LEAF_AMBIENT_INDEX = 52
Alias:
LIGHTMAPPAGEINFOS
- LIGHTING_HDR = 53
- WORLDLIGHTS_HDR = 54
- LEAF_AMBIENT_LIGHTING_HDR = 55
- LEAF_AMBIENT_LIGHTING = 56
- XZIPPAKFILE = 57
- FACES_HDR = 58
self.hdr_faces
- MAP_FLAGS = 59
- OVERLAY_FADES = 60
- OVERLAY_SYSTEM_LEVELS = 61
- PHYSLEVEL = 62
- DISP_MULTIBLEND = 63
- class srctools.bsp.VERSIONS(
- value,
- names=None,
- *,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
Enum
The BSP version numbers for various games.
- VER_17 = 17
- VER_18 = 18
- VER_19 = 19
Aliases:
HL2
,CS_SOURCE
,DOF_SOURCE
- VER_20 = 20
Aliases:
HL2_EP1
,HL2_EP2
,HL2_LC
,GARYS_MOD
,TF2
,PORTAL
,L4D
,ZENO_CLASH
,DARK_MESSIAH
,VINDICTUS
,THE_SHIP
,BLACK_MESA
,BLOODY_GOOD_TIME
- VER_21 = 21
Aliases:
L4D2
,ALIEN_SWARM
,PORTAL_2
,CS_GO
,DEAR_ESTHER
,STANLEY_PARABLE
- VER_22 = 22
Aliases:
INFRA
,DOTA2
- VER_29 = 29
- CONTAGION = 23
- CHAOSSOURCE = 25
- DESOLATION_OLD = 42
- VITAMINSOURCE = 43
- class srctools.bsp.GameVersion(
- value,
- names=None,
- *,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
Enum
Identifies specific games which we need to detect and specially handle.
- NORMAL = 'normal'
- L4D2 = 'l4d2'
- VITAMINSOURCE = 'vitaminsource'
- class srctools.bsp.BSP(
- filename: str | _os.PathLike[str],
- version: VERSIONS | GameVersion | None = None,
A BSP file.
- game_ver: GameVersion
A srctools-specific version to identify some games with unique handling.
- lump_layout: LumpDataLayout
- pakfile: ParsedLump[ZipFile]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- ents: ParsedLump[VMF]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- textures: ParsedLump[List[str]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- texinfo: ParsedLump[List[TexInfo]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- cubemaps: ParsedLump[List[Cubemap]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- overlays: ParsedLump[List[Overlay]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- bmodels: ParsedLump[WeakKeyDictionary[Entity, BModel]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- brushes: ParsedLump[List[Brush]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- visleafs: ParsedLump[List[VisLeaf]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- water_leaf_info: ParsedLump[List[LeafWaterInfo]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- nodes: ParsedLump[List[VisTree]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- visibility: ParsedLump[Visibility | None]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- vertexes: ParsedLump[List[Vec]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- surfedges: ParsedLump[List[Edge]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- planes: ParsedLump[List[Plane]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- faces: ParsedLump[List[Face]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- orig_faces: ParsedLump[List[Face]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- hdr_faces: ParsedLump[List[Face]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- primitives: ParsedLump[List[Primitive]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- props: ParsedLump[List[StaticProp]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- detail_props: ParsedLump[List[DetailProp]]
Allows access to parsed versions of lumps.
When accessed, the corresponding lump is parsed into an object tree. The lump is then cleared of data. When the BSP is saved, the lump data is then constructed.
If the lump name is bytes, it’s a game lump identifier.
- read(
- expected_version: VERSIONS | GameVersion | None = None,
Load all data.
- replace_lump( ) None
Write out the BSP file, replacing a lump with the given bytes.
- Deprecated:
simply assign to the
.data
attribute of the lump.
- create_texinfo(
- mat: str,
- *,
- copy_from: TexInfo,
- fsys: FileSystem,
- create_texinfo( ) TexInfo
- create_texinfo(
- mat: str,
- s_off: AnyVec = FrozenVec(),
- s_shift: float = -99999.0,
- t_off: AnyVec = FrozenVec(),
- t_shift: float = -99999.0,
- lightmap_s_off: AnyVec = FrozenVec(),
- lightmap_s_shift: float = -99999.0,
- lightmap_t_off: AnyVec = FrozenVec(),
- lightmap_t_shift: float = -99999.0,
- flags: SurfFlags = SurfFlags.NONE,
- *,
- fsys: FileSystem,
- create_texinfo(
- mat: str,
- s_off: AnyVec = FrozenVec(),
- s_shift: float = -99999.0,
- t_off: AnyVec = FrozenVec(),
- t_shift: float = -99999.0,
- lightmap_s_off: AnyVec = FrozenVec(),
- lightmap_s_shift: float = -99999.0,
- lightmap_t_off: AnyVec = FrozenVec(),
- lightmap_t_shift: float = -99999.0,
- flags: SurfFlags = SurfFlags.NONE,
- *,
- reflectivity: AnyVec,
- width: int,
- height: int,
Create or find a texinfo entry with the specified values.
The s/t offset and shift values control the texture positioning. The defaults are those used for overlays, but for brushes all must be specified. Alternatively
copy_from
can be provided an existing texinfo to copy from, if a texture is being swapped out.In the BSP each material also stores its texture size and reflectivity. If the material has not been used yet, these must either be specified manually or a filesystem provided for the VMT and VTFs to be read from.
- is_cordoned_heuristic() bool
Guess to see if the map uses cordons.
There’s no definite flag, but we can guess based on the shape of the geometry. Cordoning causes a brush almost the map size units to be created, then the cordon regions carved out of it. So the overall map size will be very close to the max range.
This isn’t certain, since users could manually create brushes this large, but that’s not too likely.
- is_potentially_visible( ) Tuple[bool, bool]
Check if the first leaf can potentially see and hear the second.
Always returns
True
if visibility data has not been computed (self.visibility is None
).
- packfile() Iterator[ZipFile]
A context manager to allow editing the packed content.
When successfully exited, the zip will be rewritten to the BSP file.
- static write_ent_data( ) bytes
Generate the entity data lump.
- Deprecated:
Read and write
BSP.ents
instead.- Parameters:
vmf – This accepts a VMF file like that returned from read_ent_data(). Brushes are ignored, so the VMF must use
*xx
model references.use_comma_sep – This is used to force using either commas, or
0x1D
in I/O.
- static_props() Iterator[StaticProp]
Read in the Static Props lump.
Deprecated, use
bsp.props
.
- write_static_props(
- props: List[StaticProp],
Remake the static prop lump.
Deprecated,
bsp.props
is stored and resaved.
- class srctools.bsp.Lump( )
Represents a lump header in a BSP file.
- class srctools.bsp.GameLump( )
Represents a game lump.
These are designed to be game-specific.
- class srctools.bsp.StaticProp(
- model: str,
- origin: ~srctools.math.Vec,
- angles: ~srctools.math.Angle = NOTHING,
- scaling: ~srctools.math.Vec | float = NOTHING,
- visleafs: ~typing.Set[~srctools.bsp.VisLeaf] = NOTHING,
- solidity: int = 6,
- flags: ~srctools.bsp.StaticPropFlags = <StaticPropFlags.NONE: 0>,
- skin: int = 0,
- min_fade: float = 0.0,
- max_fade: float = 0.0,
- lighting: ~srctools.math.Vec = NOTHING,
- fade_scale: float = -1.0,
- min_dx_level: int = 0,
- max_dx_level: int = 0,
- min_cpu_level: int = 0,
- max_cpu_level: int = 0,
- min_gpu_level: int = 0,
- max_gpu_level: int = 0,
- tint: ~srctools.math.Vec = NOTHING,
- renderfx: int = 255,
- disable_on_xbox: bool = False,
- lightmap_x: int = 32,
- lightmap_y: int = 32,
Represents a
prop_static
in the BSP.Different features were added in different versions.
v5+
allows fade_scale.v6
andv7
allow min/max DXLevel.v8+
allows min/max GPU and CPU levels.v7+
allows model tinting, and renderfx.v9+
allows disabling on XBox 360.v10+
adds 4 unknown bytes (float?), and an expanded flags section.v11+
adds uniform scaling.
- flags: StaticPropFlags
- class srctools.bsp.StaticPropFlags(
- value,
- names=None,
- *,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
Flag
Bitflags specified for static props.
- NONE = 0
- DOES_FADE = 1
- HAS_LIGHTING_ORIGIN = 2
- NO_FLASHLIGHT = 4
Alias:
DISABLE_DRAW
This was nodraw in earlier versions, but it now prevents projected textures from affecting the prop.
- IGNORE_NORMALS = 8
- NO_SHADOW = 16
- SCREEN_SPACE_FADE = 32
Use screen space fading. Obsolete since at least ASW.
- NO_PER_VERTEX_LIGHTING = 64
- NO_SELF_SHADOWING = 128
- NO_SHADOW_DEPTH = 256
Alias:
NO_LIGHTMAP
Disable affecting projected texture lighting. In games supporting lightmapped props (TF2), this instead, disables per-luxel lighting.
- BOUNCED_LIGHTING = 1024
Bounce lighting off the prop.
- value_prim
Return the data for the original flag byte.
- value_sec
Return the data for the secondary flag byte.
- class srctools.bsp.DetailProp(
- origin: Vec,
- angles: Angle,
- orientation: DetailPropOrientation,
- leaf: int,
- lighting: Tuple[int, int, int, int],
- light_styles: Tuple[int, int],
- sway_amount: int,
A detail prop, automatically placed on surfaces.
This is a base class, use one of the subclasses only.
- orientation: DetailPropOrientation
- class srctools.bsp.DetailPropModel(
- origin: Vec,
- angles: Angle,
- orientation: DetailPropOrientation,
- leaf: int,
- lighting: Tuple[int, int, int, int],
- light_styles: Tuple[int, int],
- sway_amount: int,
- model: str,
A MDL detail prop.
- class srctools.bsp.DetailPropOrientation(
- value,
- names=None,
- *,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
Enum
The kind of orientation for detail props.
- NORMAL = 0
- SCREEN_ALIGNED = 1
- SCREEN_ALIGNED_VERTICAL = 2
- class srctools.bsp.DetailPropShape(
- origin: Vec,
- angles: Angle,
- orientation: DetailPropOrientation,
- leaf: int,
- lighting: Tuple[int, int, int, int],
- light_styles: Tuple[int, int],
- sway_amount: int,
- sprite_scale: float,
- dims_upper_left: Tuple[float, float],
- dims_lower_right: Tuple[float, float],
- texcoord_upper_left: Tuple[float, float],
- texcoord_lower_right: Tuple[float, float],
- is_cross: bool,
- shape_angle: int,
- shape_size: int,
A shape-type detail prop, rendered as a triangle or cross shape.
- class srctools.bsp.DetailPropSprite(
- origin: Vec,
- angles: Angle,
- orientation: DetailPropOrientation,
- leaf: int,
- lighting: Tuple[int, int, int, int],
- light_styles: Tuple[int, int],
- sway_amount: int,
- sprite_scale: float,
- dims_upper_left: Tuple[float, float],
- dims_lower_right: Tuple[float, float],
- texcoord_upper_left: Tuple[float, float],
- texcoord_lower_right: Tuple[float, float],
A sprite-type detail prop.
- class srctools.bsp.TexData( )
Represents some additional infomation for textures.
Usually does not need to be constructed directly. Use
BSP.create_texinfo()
orTexInfo.set()
to create this along with the texinfo.- classmethod from_material(
- fsys: FileSystem,
- mat_name: str,
Given a filesystem, parse the specified material and compute the texture values.
- class srctools.bsp.TexInfo(
- s_off: Vec,
- s_shift: float,
- t_off: Vec,
- t_shift: float,
- lightmap_s_off: Vec,
- lightmap_s_shift: float,
- lightmap_t_off: Vec,
- lightmap_t_shift: float,
- flags: SurfFlags,
- info: TexData,
Represents texture positioning / scaling info.
Overlays don’t use the offset/shifts, setting them to
(0, 0, 0)
and-99999.0
respectively.
- class srctools.bsp.Cubemap(origin: Vec, size: int = 0)
A env_cubemap positioned in the map.
The position is integral, and the size can be zero for the default or a positive number for different powers of 2.
- class srctools.bsp.Overlay(
- id: int,
- origin: Vec,
- normal: Vec,
- texture: TexInfo,
- face_count: int,
- faces: List[int] = NOTHING,
- render_order: int = 0,
- u_min: float = 0.0,
- u_max: float = 1.0,
- v_min: float = 0.0,
- v_max: float = 1.0,
- uv1: Vec = NOTHING,
- uv2: Vec = NOTHING,
- uv3: Vec = NOTHING,
- uv4: Vec = NOTHING,
- fade_min_sq: float = -1.0,
- fade_max_sq: float = 0.0,
- min_cpu: int = 0,
- max_cpu: int = 0,
- min_gpu: int = 0,
- max_gpu: int = 0,
An overlay embedded in the map.
- class srctools.bsp.VisTree(
- plane: Plane,
- mins: Vec,
- maxes: Vec,
- faces: List[Face],
- area_ind: int,
- child_neg: VisTree | VisLeaf = None,
- child_pos: VisTree | VisLeaf = None,
A tree node in the visleaf/BSP data.
Each of these is a plane splitting the map in two, which then has a child tree or visleaf on either side.
- class srctools.bsp.VisLeaf(
- contents: BSPContents,
- cluster_id: int,
- area: int,
- flags: VisLeafFlags,
- mins: Vec,
- maxes: Vec,
- faces: List[Face],
- brushes: List[Brush],
- water_id: int,
- ambient: bytes = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
- min_water_dist: int = 65535,
A leaf in the visleaf/BSP data.
The bounds are defined implicitly by the parent node planes.
- contents: BSPContents
- flags: VisLeafFlags
- class srctools.bsp.VisLeafFlags(
- value,
- names=None,
- *,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
Flag
Visleaf flags.
- NONE = 0
- SKY_3D = 1
- SKY_2D = 4
- RADIAL = 2
- HAS_DETAIL_OBJECTS = 8
Alias:
_BIT_4
- _BIT_5 = 16
- _BIT_6 = 32
- _BIT_7 = 64
- class srctools.bsp.LeafWaterInfo( )
Additional data about water volumes.
- class srctools.bsp.Visibility( )
The visibility data produced by VVIS.
Visleafs each have a “cluster” ID. For every pair of cluster IDs, this indicates if the first can see the second, and whether they can hear each other.
- class srctools.bsp.BModel(
- mins: Vec,
- maxes: Vec,
- origin: Vec,
- node: VisTree,
- faces: List[Face],
- phys_keyvalues: Keyvalues | None = None,
- phys_solids: List[bytes] = NOTHING,
A brush model definition, used for the world entity along with all other brush ents.
- class srctools.bsp.Plane( )
A plane.
- class srctools.bsp.PlaneType(
- value,
- names=None,
- *,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
Enum
The orientation of a plane.
- X = 0
- Y = 1
- Z = 2
- ANY_X = 3
- ANY_Y = 4
- ANY_Z = 5
- from_normal = <bound method PlaneType.from_normal of <enum 'PlaneType'>>
- class srctools.bsp.Primitive( )
A ‘primitive’ surface (AKA t-junction, waterverts).
These are generated to stitch together T-junction faces.
- class srctools.bsp.Face(
- plane: Plane,
- same_dir_as_plane: bool,
- on_node: bool,
- edges: List[Edge],
- texinfo: TexInfo | None,
- dispinfo_ind: int,
- surf_fog_volume_id: int,
- light_styles: bytes,
- lightmap_off: int,
- area: float,
- lightmap_mins: Tuple[int, int],
- lightmap_size: Tuple[int, int],
- orig_face: Face | None,
- primitives: List[Primitive],
- dynamic_shadows: bool,
- smoothing_groups: int,
- hammer_id: int | None,
- vitamin_flags: int,
A brush face definition.
- class srctools.bsp.Edge(a: Vec, b: Vec)
A pair of vertexes defining an edge of a face.
The face on the other side of the edge has a RevEdge instead, which shares these vectors.
- class srctools.bsp.RevEdge(ed: Edge)
The edge on the opposite side from the original.
This is implicitly created when an
Edge
is.
- class srctools.bsp.Brush(
- contents: BSPContents,
- sides: List[BrushSide],
A brush definition.
- contents: BSPContents
- class srctools.bsp.BrushSide( )
A side of the original brush geometry which the map is constructed from.
This matches the original VMF.
- srctools.bsp.BrushContents
alias of
BSPContents