Skip to content

Instantly share code, notes, and snippets.

@neogeographica
Last active February 3, 2024 21:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neogeographica/c92539f2365fd3f59526248124b9aa69 to your computer and use it in GitHub Desktop.
Save neogeographica/c92539f2365fd3f59526248124b9aa69 to your computer and use it in GitHub Desktop.
compiling Quake 3 maps with TrenchBroom
These are examples of Quake 3 compilation profiles for use with TrenchBroom.
I'm NOT saying that these examples have the best command-line arguments that are appropriate for your situation. In particular, you may want to fool around with different arguments for the lighting pass. This is just to help get the skeleton of a compile profile in place, which you can then modify.
----------
In any case, to get started the first thing you'll need is a set of compile tools for Quake 3 maps.
If you want to get the tools from netradiant-custom, FYI that project lives here: https://github.com/Garux/netradiant-custom
And you can download releases of netradiant-custom from here: https://github.com/Garux/netradiant-custom/releases
Obviously that comes with a whole map editor as well. :-) But the important thing for the purposes of this setup is that it brings with it some good versions of the q3map2 and mbspc tools. (If you're on Windows, specifically that's "q3map2.exe" and "mbspc.exe".) You can leave those tools where they are, inside your netradiant-custom installation, or you can copy them somewhere else.
You can use some other tools if you like. But FYI I've only tested the command lines in these compile profiles when using the q3map2 tool from netradiant-custom. If you're using a different variant of q3map2 then these arguments may not work, or may work differently.
When starting up TrenchBroom, and going to the Quake 3 game configuration, you should see boxes where you can specify the path to your q3map2 and bspc executables. If you're using the netradiant-custom tools, then you should put the paths to those tools (q3map2.exe and mbspc.exe) in these boxes. If you're using some other tools, then configure the paths to those.
If you don't do this, the example compile profiles here won't work.
The other files in this gist, "CompilationProfiles-simple.cfg" and "CompilationProfiles-supercomplicated.cfg", are examples of Quake 3 compile profiles.
In both of these examples, the map file is allowed to live somewhere outside your Quake 3 game installation (and in fact that is probably preferred).
The "complete" compile profiles in these examples -- the ones that do bsp+vis+light -- start with an "export" task that creates a new map file for compiling; e.g. if you are currently working on something called "foo.map", the first thing that happens is that "foo-compile.map" gets exported. (This lets you take advantage of the TrenchBroom feature for exporting only certain layers from your map.) All subsequent compilation tasks are done on that "foo-compile" map. Then as a final step, the "foo-compile.bsp" is copied to "foo.bsp" in the correct folder inside your Quake 3 installation.
Any non-"complete" compile profile that does an isolated vis, light, or bot-support pass assumes that the exported map and bsp already exist.
----------
OK let's talk about what's going on in these examples.
"CompilationProfiles-simple.cfg" has two profiles defined. The one called "bsp, vis, light w/ samples+bounce+phong" is a complete map compile pass; the other one called "bot support" generates bot support (.aas file) for a compiled map.
"CompilationProfiles-supercomplicated.cfg" is an over-the-top example of having a ton of different compile profiles. There are variants in here to do fast vis, or do different kinds of lighting, or to only run individual bsp/vis/light phases rather than a whole compile pass... stuff like that. It also contains some disabled tasks in the compile profiles; for example the "light - more/better samples test" has a task in it that does 6 samples and another task that does 2 supersamples. Only one of these should be enabled at a time; they are different ways of tackling the same compile stage.
There's so much in the "complicated" config that I have added some "0 task" (empty) profiles just as dividers, to help organize it a bit. You would probably NOT want this many compile profiles, once you've developed a workflow that works for you. This file just shows different possibilities.
To use one of those files, rename it to just "CompilationProfiles.cfg" and then put it in your TrenchBroom configuration folder for Quake 3. If you're on Windows, this folder is located at "C:\Users\<username>\AppData\Roaming\TrenchBroom\games\Quake 3". (For Linux or macOS, see the docs at https://trenchbroom.github.io/manual/latest/#game_configuration_files )
Note that doing this will completely replace any existing compile profiles you have for Quake 3! If you want to save your current profiles then make a backup of any current "CompilationProfiles.cfg" file you have in that folder, before you replace it with one of these.
Once you've done that and restarted TrenchBroom, you can use the compile profile UI to examine and modify the profile.
While you're in the TrenchBroom UI BTW, you can also configure the Parameters used to Launch Engine for Quake 3. I would recommend something like this: +set sv_pure 0 +set fs_game ${MODS[-1]} +devmap ${MAP_BASE_NAME}
{
"profiles": [
{
"name": "bsp, vis, light w/ samples+bounce+phong",
"tasks": [
{
"target": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"type": "export"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -meta -samplesize 8 -skyfix ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -vis -saveprt ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -samples 3 -filter -bounce 8 -bouncegrid -shade ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "bot support",
"tasks": [
{
"parameters": "-threads ${CPU_COUNT - 1} -forcesidesvisible -optimize -bsp2aas ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"tool": "${bspc}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.aas",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.aas",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
}
],
"version": 1
}
{
"profiles": [
{
"name": "bsp, fast vis, simple light",
"tasks": [
{
"target": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"type": "export"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -meta -samplesize 8 -skyfix ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -vis -saveprt -fast ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -filter ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "bsp, fast vis, light w/ samples",
"tasks": [
{
"target": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"type": "export"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -meta -samplesize 8 -skyfix ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -vis -saveprt -fast ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -samples 3 -filter ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "bsp, vis, light w/ samples",
"tasks": [
{
"target": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"type": "export"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -meta -samplesize 8 -skyfix ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -vis -saveprt ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -samples 3 -filter ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "bsp, vis, light w/ samples+bounce+phong",
"tasks": [
{
"target": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"type": "export"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -meta -samplesize 8 -skyfix ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -vis -saveprt ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"enabled": false,
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -samples 3 -filter -bounce 4 -bouncegrid -shade ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -samples 3 -filter -bounce 8 -bouncegrid -shade ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "----------",
"tasks": [],
"workdir": ""
},
{
"name": "bsp",
"tasks": [
{
"target": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"type": "export"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -meta -samplesize 8 -skyfix ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "----------",
"tasks": [],
"workdir": ""
},
{
"name": "fast vis",
"tasks": [
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -vis -saveprt -fast ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "vis",
"tasks": [
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -vis -saveprt ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "----------",
"tasks": [],
"workdir": ""
},
{
"name": "simple light",
"tasks": [
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -filter ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "light w/ samples",
"tasks": [
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -samples 3 -filter ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "light w/ samples+bounce+phong",
"tasks": [
{
"enabled": false,
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -samples 3 -filter -bounce 4 -bouncegrid -shade ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -samples 3 -filter -bounce 8 -bouncegrid -shade ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "----------",
"tasks": [],
"workdir": ""
},
{
"name": "light - more/better samples test",
"tasks": [
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -samples 6 -filter -bounce 8 -bouncegrid -shade -dark ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"enabled": false,
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -super 2 -filter -bounce 8 -bouncegrid -shade -dark ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "light - dirtmap test (uniform)",
"tasks": [
{
"enabled": false,
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -samples 3 -filter -bounce 8 -bouncegrid -shade -dirty -dirtmode 0 ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -samples 3 -filter -bounce 8 -bouncegrid -shade -dirty -dirtmode 0 -dirtscale 2.5 -dirtdepth 24 ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "light - dirtmap test (noisy)",
"tasks": [
{
"enabled": false,
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -samples 3 -filter -bounce 8 -bouncegrid -shade -dirty -dirtmode 1 ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"parameters": "-v -threads ${CPU_COUNT - 1} -game quake3 -fs_basepath ${GAME_DIR_PATH} -fs_game ${MODS[-1]} -light -samplesize 8 -fast -gamma 2 -compensate 4 -patchshadows -samples 3 -filter -bounce 8 -bouncegrid -shade -dirty -dirtmode 1 -dirtscale 2.5 -dirtdepth 24 ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.map",
"tool": "${q3map2}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.bsp",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "----------",
"tasks": [],
"workdir": ""
},
{
"name": "unoptimized bot support",
"tasks": [
{
"parameters": "-threads ${CPU_COUNT - 1} -forcesidesvisible -bsp2aas ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"tool": "${bspc}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.aas",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.aas",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
},
{
"name": "bot support",
"tasks": [
{
"parameters": "-threads ${CPU_COUNT - 1} -forcesidesvisible -optimize -bsp2aas ${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.bsp",
"tool": "${bspc}",
"type": "tool"
},
{
"source": "${WORK_DIR_PATH}/${MAP_BASE_NAME}-compile.aas",
"target": "${GAME_DIR_PATH}/${MODS[-1]}/maps/${MAP_BASE_NAME}.aas",
"type": "rename"
}
],
"workdir": "${MAP_DIR_PATH}"
}
],
"version": 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment