Skip to content


PackBSP progress: When collisions occur

As mentioned in my last post, one of the interesting things about the files in a Source game is that they use multiple search paths. While this makes it easy to do things like override content, it also makes for a bit of a headache. This post is an attempt to sketch out how I want to handle things in my rewrite of PackBSP to avoid errors.

How PackBSP will check file locations

Basically, there are three types of places you can find a file. In the map, in a normal folder on the disk, or inside an archive file, like a GCF. Technically there’s another variation (pak/vpk files) but for sanity’s sake I’m going to ignore them until I need to some form of add L4D support. So given a relative path (like “materials/floor/tile.vmt”) which version should I parse (for its direct dependencies) and what should get embedded into the map? In answering this question I got the above diagram. Essentially, certain conditions are sufficiently creepy that the program cannot progress: The user has a sloppy work environment and needs to put things in order. These correspond to the red “halt” boxes.

  1. If you have file in the map and on the drive that has the same name but different contents, something is wrong. Since Bspzip doesn’t have consistent support for removing or replacing already-packed files, PackBSP probably can’t fix the problem. The user should start with a “fresh” copy of their map.
  2. If the map contains a file that conflicts with another in the standard archives, that’s a bad idea, because it can cause non-map-related graphical glitches for clients that persist even when the server switches to another map.
  3. If a disk conflicts with an archive file, the developer’s intention is unclear: We can’t pack the disk-version, because then eventually we’ll end up with the case we just looked at in the last paragraph. But if we ignore it, we run the risk of creating a final-product that is unexpectedly different from what the mapper is seeing during their pre-release testing.

Fortunately, these ambiguous cases should be few and far between, and arguably PackBSP would just be “being a good citizen” of the SDK tools when refusing to work without them being resolved.

“I override skins and things all the time as a player, why can’t I do it as a mapper?”

Suppose in Counter-Strike or TF2 someone creates a Halloween map with custom “zombie” player-skins, anyone who starts the game and joins that map will see the effect. Sounds cool, right? Unfortunately, these materials generally don’t get cleared out afterwards, so players are stuck seeing the zombie skins even though the Halloween map is long-over.

“Why check the map’s contents against the disk?”

Two reasons. Firstly, I want to be able to detect and avoid cases where PackBSP thinks it is injecting a new file but is actually failing because an incompatible version is already present. In a sense, we want to make sure the map file being modified is “clean” to start with. Secondly, a patched WVT materials.

“WVT-patch materials?”

There’s probably a better name for them, but when someone uses a “blend” material in Hammer on a non-displacement surface, it causes a sort of incompatibility. Hammer automatically works around this by spontaneously generating a custom material, copying over the relevant settings, and inserting the new material into the map when it is first compiled.

Patching WVT material: maps/ctf_examplemap/nature/blendsandgrass008a_wvt_patch

The real problem occurs when you are using a custom blend material which depends one or more custom textures. Hammer has  inserted the material, but the texture(s) are still missing and won’t look good when you distribute your map. So when we encounter a WVT-patch, we need to read it (even if it’s already inside the map) to make sure we catch any custom textures as well.

Posted in Programming.

Tagged with .