
What IS FuncGodot?
FuncGodot is a plugin for Godot 4 that allows users to generate Godot scenes using the Quake MAP file format. Map files can be made in a variety of editors, the most commonly recommended one being TrenchBroom. It is a reworking and rewrite of the Qodot plugin for Godot 3 and 4.
It is not a framework.
FuncGodot will not make your game for you. FuncGodot does not make doors, it does not make players, it does not make buttons. You make the entities and FuncGodot will instantiate them and apply the properties you gave to them in your map file and entity definitions: the rest is up to you.
It is not a BSP Compiler.
FuncGodot does not compile maps into BSP files. It has no concept of vis, no concept of lit, no concept of bsp. It will not automatically cull faces. Godot does not work like the early BSP engines. You cannot use FuncGodot to map for Godot the same way you map for Quake. What you map is what you get. This makes it more consistent and reliable than a compiled BSP, since you get to choose what faces get culled, how your mesh is separated, and how your collision is generated.
FuncGodot is, at its core, an interpreter.
FuncGodot is a map parser and geometry generator, utilizing entity definition resources in order to translate map files' entities and their properties into Godot nodes and packed scenes. It can be used for purposes as simple as only generating CSG geometry from the map file to purposes as complex as completing your entire level in your chosen map editor and only needing to click build in Godot. How much FuncGodot builds for you is dependent on how much work you put into defining how to build your maps. What you put in is what you get out.
Understanding this concept will hopefully put you on the right path forward to being able to use this wonderfully flexible tool to make some incredible games.
This manual assumes some familiarity with the Godot Engine and your map editor of choice. This manual will only cover them insofar as how they relate to the FuncGodot work flow.

Who MADE FuncGodot?
FuncGodot was created by Hannah "Embyr" Crawford, Emberlynn Bland, and Tim "RhapsodyInGeek" Maccabe, reworked from the Godot 4 port of Qodot by Embyr, with contributions from members of the FuncGodot, Qodot, Godot, and Quake Mapping Communities.
Both plugins are based on the original Qodot for Godot 3.5 created by Josh "Shifty" Palmer.
Next section
Installing FuncGodot
Preliminary Requirements
FuncGodot's official requirement is currently Godot 4.2. We will always aim to keep FuncGodot compatible with the latest Godot 4.x release. If you manage to make it work on an older release of Godot 4, awesome! But you're on your own if you run into issues.
FuncGodot is written in pure GDScript and as such has no other dependencies.
This manual assumes you have an intermediate level of knowledge with Godot and your chosen map editor.
Map Editor Compatibility
FuncGodot directly supports the following editors with configuration resources:
- TrenchBroom 2024
- NetRadiant Custom 1.6
FGD outputs have also been tested with these editors:
- J.A.C.K.
FuncGodot is designed to be as map editor agnostic as possible. If you use an editor that can output Quake or Half-Life 1 format map files, please let us know on GitHub or Discord so we can try our best to either support it directly or document the configuration process!
Downloading the Plugin
There are 3 places to download FuncGodot. The first two places are both found on the FuncGodot GitHub Repository. The first location is the Code Download, and it is always the most up to date version of the plugin. It includes all merges, including both feature updates and bug fixes. Sometimes this version can be significantly up to date, but may also contain less refined features than the other options below.
The second location is the GitHub repository's Releases. This is the second most up to date download and is considered the official "Stable Release" of the plugin.
The final location is the Godot Asset Library. While the intent is to keep the Asset Library release in line with the GitHub Stable Release, sometimes these releases can be "desynced" for one reason or another. We're a small team of volunteers here, so please be patient with us!
Our intent is to keep the Stable Releases as reliable as possible, so typically only critical fixes will be pushed with some urgency while new features or quality of life improvements tend to simmer a bit more in the code base.
In any case, pick the download option that suits you best. If you downloaded the plugin from GitHub, extract the func_godot folder to your Godot project's addons folder. If you downloaded from the Asset Library, it should do this for you automatically. Once the plugin is copied to your project, remember to enable the plugin in your Project Settings.
Next section
Project Configuration
Directory Structure
Designing a directory structure for your game is its own art, and the layout of your project files can depend greatly on the kind of game you're making. That said, it is generally recommended you create an organization that splits off your TrenchBroom resources from the rest of your Godot assets.
If you're using TrenchBroom, you may already be aware it has a handy backup feature where it creates an autosave folder to periodically save backups of your map file. Less useful is the tendency for Godot to import these backups as well.
However, Godot has its own handy feature to combat this. Any directory with a .gdignore file will not be scanned and imported by Godot. To save yourself some headache later, open the autosave sub-directory in your operating system's file explorer. If using Windows, make sure you have File Name Extensions enabled under the View tab. Create a new text document in the sub-directory and rename it .gdignore, exactly like that with the .txt extension removed.
And just like that, we won't have to deal with Godot constantly importing hundreds of backup map files from our project! You can do this for any directory that you don't want Godot to import files from, such as the folder that contains all of your display models intended to be used only with your map editor.
FuncGodot Local Config
FuncGodot has the option of using a FuncGodotLocalConfig resource to create local project wide settings for your other FuncGodot resources. These settings are applied only to your machine, in order to better facilitate working with a team that may not have the same drive or directory setup or even the same map editor as you yourself use.
You won't create the FuncGodotLocalConfig resource for your project, as this resource doesn't actually save anything to itself directly. Instead you will use the pre-made func_godot_local_config.tres resource found in the addons/func_godot/ folder.
Local Config Properties
Viewing this resource's properties in the inspector, you'll be greeted with some options. We'll ignore the Export Func Godot Settings property for now.
For the FGD Output Folder, you'll want to locate your map editor's game configuration folder or installation folder. Create a sub folder for your game's configuration and set the FGD Output Folder to that sub-folder. This might look something like C:/GameDev/TrenchBroom/Games/MyGame/ or C:/GameDev/J.A.C.K/MyGame/. This tells FuncGodot where to save generated configuration and FGD files when you click on their export button.
The Trenchbroom Game Config Folder is the location of your game's TrenchBroom Game Config folder. This might (but doesn't have to be) the same as your FGD Output Folder. When you export your TrenchBroomGameConfig resource, it will automatically export the FGD file to this folder as well, overriding the FGD Output Folder property.
The Netradiant Custom Gamepack Folder is a little different, in that it should point to your NetRadiant Custom's gamepacks folder (eg: C:/GameDev/NetRadiant Custom/gamepacks/). This will also override the FGD Output Folder when you export your NetRadiantCustomGamepackConfig resource, as NetRadiant Custom splits up gamepack configurations across several folders and files.
The Map Editor Game Path refers to what your Map Editor considers the location of your project. This might look something like C:/GameDev/MyGodotProject/ or C:/GameDev/MyGodotProject/trenchbroom/. The intended use for this is to streamline certain FGD resource paths, like the FuncGodotFGDModelPointClass's model export location.
The Game Path Models Folder is the default folder path relative to your Map Editor Game Path that tells FuncGodot where to save generated model files to. For example, with a Map Editor Game Path value of C:/GameDev/MyGodotProject/trenchbroom/ and a Game Path Models Folder value of models, the generated model file will be saved to C:/GameDev/MyGodotProject/trenchbroom/models/. Currently only used by FuncGodotFGDModelPointClass.
The Default Inverse Scale Factor setting doesn't affect FuncGodotMapSettings resources or how the map builds. It currently only affects scaling display models for FuncGodotFGDModelPointClass definitions in map editors other than TrenchBroom.
Exporting the Project Config
Remember that Export Func Godot Settings property I told you to ignore earlier? Once you have your settings in place, go ahead and click it. It will automatically generate a MyGameFuncGodotConfig.json file in your Godot project's user data folder.
NOTE: You need to run your project at least once before attempting to export settings, so that the user:// folder can be created by Godot! Otherwise you will run into an error and the config file will not export!
This is how we keep local settings local. Upon opening your project, FuncGodot will automatically update func_godot_local_config.tres to load the data from the generated JSON file found in your user data folder, and setting the resource's Export property to true will overwrite that file with the new settings. These settings are not saved to source control, allowing teams to work together more easily and more flexibly.
Next section
Forge Game Data
FGD stands for "Forge Game Data", leftover from when the Half-Life 2 level editor Hammer used to be the Half-Life 1 editor Worldcraft, and before that when it was a Quake tool called Forge.
FuncGodot utilizes FuncGodotFGD Resources to act as a translation guide for the map build process. These resources are largely separated into two different types: the FuncGodotFGDFile and the FuncGodotFGDEntityClass. Think of the FGD File as a dictionary, and the FGD Entity Classes as the entries.
FGD File Resource
Some of you may only want to build map geometry with some control over collision and occlusion, and prefer to add all of your lights, actors, scripting, etc... in Godot directly. To that end there is a basic default func_godot_fgd.tres included with FuncGodot. You can find it under addons/func_godot/fgd/func_godot_fgd.tres.
This is the default FGD file set in the FuncGodotMapSettings resource. The basic entity definitions included with it are Worldspawn, func_detail, func_detail_illusionary, func_illusionary, and Phong. We'll go over what each of these entity types are a little farther below.
But what if you want to add your own custom entity types? It's always best practice to create your own FGD File resource and NEVER a good idea to just modify the pre-existing default FGD File. Any time FuncGodot is updated, it will overwrite the func_godot_fgd.tres that comes with it and erase any changes you've made to that resource. While the goal is to keep the default FGD File as basic as possible, we cannot guarantee it won't be changed at some point in the future.
That said, it is possible to include the default FuncGodot FGD File into your own as a Base FGD. Create a new FuncGodotFGDFile resource and examine it in the inspector.
The Export File property does exactly what you might think: it generates and saves your FGD file to the Map Editor Game Config Folder set by the FuncGodot Local Config. Use this whenever you need to update your FGD.
The next property, Model Key Word Supported, is dependent upon which map editor you use. Point class entities in map editors can have display models assigned to them according to their FGD definitions. Most map editors seem to use the "studio" key word to define the model path, but TrenchBroom instead optionally allows the "model" key word while also including additional display options and expressions. When set to false, FuncGodot will omit entity definition meta properties using the "model" key word, in order to prevent errors in your chosen map editor. When exporting the FGD File through a TrenchBroom Game Config resource the setting will be overridden to true. See the Valve Developer Wiki for more information.
Fgd Name should be self evident: this will be your exported FGD's filename, minus the file extension. Best practice would be to set this to either your game's name or its acronym.
Base Fgd Files is an array of FuncGodotFGDFile resources that will be prepended to our final FGD file output. It is not necessary to export these base FGD Files; only the FGD File they are added to needs to be exported and the rest will be built by and merged into what you could consider your "Master FGD File".
NOTE: This is not where you would put your FuncGodotFGDBaseClass resources! Those are not the same as FuncGodotFGDFile resources and are considered entities! More information on FuncGodotFGDBaseClass found below.
To add the func_godot_fgd.tres as a base FGD file to your custom FGD file, all you need to do is locate func_godot_fgd.tres and drag and drop it onto the Base Fgd Files array in the inspector.
The last property is Entity Definitions. This is where you'll drop all of your custom entity resources to be built or instanced by FuncGodot. Let's take a look at what a populated one looks like by viewing the default func_godot_fgd.tres in the inspector.
Entity Class Definitions
In terms of how to map with the Quake Map File > FuncGodot > Godot pipeline, it's best to think of the entities in Quake design terms. That is to say, everything is an entity: the player, the enemies, the ambient sounds, the doors, the lifts, the trigger volumes, the map geometry itself... all of these should be thought of as entities.
All map editors and FuncGodot support at least 2 different kinds of entities: Solid (Brush) Entities and Point Entities. Using FuncGodotFGDSolidClass and FuncGodotFGDPointClass resources, you can generate any type of Godot node and apply any script to it.
Every entity is comprised of 2 things: Metadata and Key Value Pairs.
Metadata tells the map editor how to display your entity, things like bounding box color or display models for Point Entities, but have no effect in Godot.
Key Value Pairs on the other hand can be thought of as your entity's properties. In a map file, all entities are comprised of Key Value Pairs. Each entity will always have a classname; this classname is what FuncGodot uses to determine what node or packed scene is generated and how upon building the FuncGodotMap.
The FuncGodotMap attempts to call two methods on each entity at the end of the build process. As an added advantage of using these calls, you can guarantee that all FuncGodotMap generated nodes now exist and can reference each other.
Modifying Entities on Map Build
If you decide you want to make modifications to your generated entities on map build using any of the following methods, you'll need to make sure that your entity's script is set as a @tool
script.
The first method call is to _func_godot_apply_properties(entity_properties: Dictionary)
. Because _func_godot_apply_properties
passes the entity properties in the function, you do not need to declare a func_godot_properties dictionary in your node script; instead, just apply your properties as needed in this callback.
After every entity has called _func_godot_apply_properties
, FuncGodot will cycle through all of them again and attempt to call _func_godot_build_complete()
as a deferred call. Since we're calling this method deferred after every entity has already called the previous method, we can guarantee any nodes generated by our entities in _func_godot_apply_properties
can be referenced during _func_godot_build_complete.
Additionally upon building, all of the entity's key value pairs will be added to the generated node's func_godot_properties
Dictionary (provided that the property is set as an exported variant).
We'll examine this FuncGeo class as a demonstration of the relationships between the FuncGodotFGDBaseClass, the FuncGodotFGDSolidClass, the func_geo brush entity in the map editor, and the final generated Godot FuncGeo StaticBody3D node.
The image on the left depicts a Base Class resource that contains other base classes to accumulate Class Properties. The image on the right is a Solid Class resource containing that Base Class and defines our FuncGeo entity.
This is our FuncGeo entity's properties as they appear in TrenchBroom.
The generated FuncGeo node's properties in the inspector. See how our Func Godot Properties Dictionary matches our Class Properties from our map editor.
With FuncGodot, your entity does not necessarily need a tool script. And even if you provide it a tool script, it does not need a func_godot_properties
dictionary. FuncGodot will still generate and instantiate these entities without providing any properties. However, to take full advantage of FuncGodot's power it is highly recommended that you provide your nodes with both.
See the chapters on FuncGodotFGDEntityClass resources and Entity Key Value Pairs for more information.
Default Entities
All default FuncGodot entities, except for Phong, are FuncGodotFGDSolidClass entities. All of the SolidClass entities are very similar, mostly differing in occlusion and collision.
- Phong : A FuncGodotFGDBaseClass that provides _phong and _phong_angle properties to most of the entities below. See the Wikipedia article on Phong Shading for quick primer.
- worldspawn : A geometry class that mimics the Worldspawn entity found in Quake and Half-Life. In the FuncGodot implementation, Worldspawn generates a single StaticBody3D with a child MeshInstance3D and multiple convex CollisionShape3D children. It also generates an OccluderInstance3D with an ArrayOccluder3D.
Under normal circumstances, there can only ever be one Worldspawn entity in a map file. While there technically are ways to create multiple Worldspawn entities this manual will not explore that possibility. - func_geo : Identical to Worldspawn, with the exception being that you can (and should) create multiple func_geos. See Why Not Worldspawn? for more information.
- func_detail : Almost identical to func_geo, with the exception that they do not generate OccluderInstance3D children.
- func_illusionary : Geometry that has no collision. It generates a Node3D, a MeshInstance3D child, and an OccluderInstance3D child.
- func_detail_illusionary : Identical to func_illusionary, except that it does not generate an OccluderInstance3D child.
NOTE: Some map editors are strict about entity definition order! To stay safe, make sure that any entity classes that inherit from a base class come after that base class. This includes other base classes! Otherwise you may run into issues where properties are not properly inherited.
Next section
Textures
How Textures Work In FuncGodot
If you take a look at a .map file, you'll see that it's just a text file describing the makeup of your map and doesn't actually store any other data, including texture images. Let's look at this example of a Solid Entity in a map file:
// entity 1
{
"classname" "func_detail"
// brush 0
{
( -32 -64 -16 ) ( -32 -63 -16 ) ( -32 -64 -15 ) __TB_empty [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1
( -64 -32 -16 ) ( -64 -32 -15 ) ( -63 -32 -16 ) __TB_empty [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1
( -64 -64 -32 ) ( -63 -64 -32 ) ( -64 -63 -32 ) special/clip [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1
( 64 64 32 ) ( 64 65 32 ) ( 65 64 32 ) __TB_empty [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1
( 64 32 16 ) ( 65 32 16 ) ( 64 32 17 ) special/clip [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1
( 32 64 16 ) ( 32 64 17 ) ( 32 65 16 ) special/clip [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1
}
}
This is a func_detail entity from the default FuncGodot.fgd. As you can see, the map file structure is pretty straight-forward. This particular map uses the Valve 220 format, having additional options for UV mapping. Each line in a brush definition describes a face on the brush, and within that you can see that our texture is defined as just its location relative to the game's texture folder or map's WAD file.
But if that's the case, how does FuncGodot know what file to use?
FuncGodot Map Settings have several properties that help define and apply textures to your meshes on build:
- Base Texture Dir : Root folder where your Godot map textures are located
- Texture File Extensions : The extensions to search for if no matching material is found
- Texture Wads : Array of WAD resources to search through
- Material File Extension : Format for custom texture materials, can be .tres, .res or .material
- Default Material : The default material that FuncGodot builds your map's materials from
- Default Material Albedo Uniform : If the default material is a ShaderMaterial rather than StandardMaterial3D, this is the shader uniform that provides the albedo texture
- Save Generated Materials : Save automatically generated materials to disk, allowing reuse across multiple FuncGodot maps. FuncGodot will skip saving materials using clip, skip, or missing textures.
NOTE: once saved, materials will no longer inherit from the Default Material. If you want to make any changes to their settings you will have to either do so manually or delete the materials and allow FuncGodot to rebuild and resave them.
FuncGodot's first step is to search the Base Texture Dir for a prebuilt material as defined by the brush face's texture name in the format defined by Material File Extension.
If it does not find this prebuilt material, it will search the Base Texture Dir for the Texture2D resource by the brush face's texture name using any one of the extensions defined by Texture File Extensions. If it finds the Texture2D, it will create a copy of the Default Material and apply the Texture2D as the duplicated material's albedo.
If it does not find the Texture2D, then it will use the default_texture.png found in the addons/func_godot/textures/ folder.
Once the material generation is completed, you can optionally have FuncGodot save generated materials so they can be reused by multiple FuncGodotMaps. Otherwise each FuncGodotMap will have its own unique material for each texture used in the map.
Automatic PBR Generation
You may have noticed that we skipped over a few settings before, all of them with the suffic "Map Pattern". FuncGodot has the ability to automatically generate PBR materials on build. Each of the "Map Pattern" properties tell FuncGodot's Texture Loader how to find each PBR map for our texture.
What's with all the %s everywhere?
It's a placeholder token that gets replaced during texture loading. Each pattern requires two %s tokens. The first token is for the texture's name as it appears in the map file. The second token is for the file extension; this is replaced as the Texture Loader cycles through the Map Settings' Texture File Extensions searching for your texture. So if Texture Loader is looking for the normal map of a texture with the name "rock" and our Map Settings' Normal Map Pattern is "%s_normal.%s" and it is currently checking for the "png" Texture File Extension, then it will be looking to see if the texture resource "rock_normal.png" exists, and if so it will be applied to the Map Settings' Default Material if it is a StandardMaterial3D.
Clip and Skip Textures
Mapping for Quake Godot
We started off this manual with the point that FuncGodot is not a BSP compiler. If we map like we do in traditional Quake mapping...
... we don't get the same result.
Instead we need to change our approach.
For those not familiar with traditional Quake mapping, the finished MAP gets compiled into a BSP file to be read by the engine. The compiling process calculates visibility between all of the rooms of your map and removes all faces that won't be viewed due to being outside the map. That means maps must be sealed completely, but you're also allowed to be lazy with brush texturing since if a face is "outside" the map it will get culled.
With Godot we need to think of these brushes as what they'll become in-engine: composited MeshInstance3Ds and CollisionShape3Ds. If we want to achieve the culled result on the left, we'll need to change the way we do things on the right.
Skip It
The Clip and Skip textures are arguably our most important textures when mapping for Godot. You can assign any texture's name to the Clip and Skip properties of the FuncGodotMapSettings resource. But what do they do?
The Clip texture will remove any face textured with it from the generated MeshInstance3D. The Skip texture behaves the same way if the Solid Entity's Collision Type is set to Convex. However, if the Solid Entity's Collision Type is set to Concave, this also removes the Skip textured faces from the generated CollisionPolygonShape3D.
Just keep in mind the general rule of thumb: if you want your entities to collide with the brush, use Clip...
... and if you want them to pass through, use Skip (with Concave collision).
WAD Files
FuncGodot provides the option to use Texture WAD files for your map materials. It's generally not recommended if it can be helped, but support for loose texture images varies from map editor to map editor.
To use a WAD file with your FuncGodotMap just add your imported WAD resource to the map node's Texture Wads array.
The neat thing about how FuncGodot handles map textures is that we can technically use a completely different folder in TrenchBroom and even different image formats than the location and formats we keep them in Godot. This can be useful for advanced users, but you may want to just keep all of your textures unified.
Why Are My Textures Blurry!?
You may be encountering at least one of two issues: texture compression and / or material sampling settings.
Make sure your texture resource is set to either Lossless or VRAM uncompressed. Please refer to the Godot documentation on texture compression.
If you had created your own materials for your map, check that the material's or texture's Sampling Filter is set to Nearest Mipmap. Please refer to the Godot documentation on texture filtering.
Next section
Map Editor Configuration
In order to map for Godot in your chosen map editor, you'll need to tell your map editor about your game. Each map editor has its own method of doing this. While FuncGodot can import any map file using the Quake Map format, official support is currently limited to only those that support the FGD format.
TrenchBroom
TrenchBroom is the most commonly recommended editor for FuncGodot, with multiple resources dedicated to configuring it. The primary configuration resource is the TrenchBroomGameConfig, with the TrenchBroomTag providing additional quality of life options in the editor.
You'll need a TrenchBroom Game Config resource in order to build and export a game configuration file for TrenchBroom. Let's take a look at the resource properties:
Most of these properties should be fairly obvious in their purpose. The FGD File should be your master FGD that contains all of your other base FGDs and entities. Entity Scale only scales the display models.
Brush Tags and Brushface Tags are strictly for TrenchBroom and have no effect in Godot. They can affect shortcut keys and have transparency effects applied to them, along with a few other features. FuncGodot comes with a few pre-made common tags. Feel free to use them in your own GameConfig resources.
Exporting the Game Config will use the directory set in your Local Configuration's Trenchbroom Game Config Folder. Consult the TrenchBroom Manual's Game Configuration documentation for more information. Once you've exported your Game Config, open up TrenchBroom and click New Map. You should now see your project in the games list.
You'll need to set the game path so that TrenchBroom can find your game's textures and any models if you created some for it. Open TrenchBroom's preferences and set your game's path to the one you set to Map Editor Game Path with the Local Configuration.
Now you should be ready to start mapping for Godot with TrenchBroom!
J.A.C.K.
Due to how games are configured in J.A.C.K., FuncGodot does not have any dedicated resources for it but the process is still fairly simple.
Make sure your Local Configuration's FGD Output Folder is pointing to your game's folder in J.A.C.K.'s game configuration folder. When you export an FGD file, FuncGodot will print in the Godot Output where it was saved to.
Once exported, you'll need to add your game to the Game Configurations list. Be sure to add your newly exported FGD as well.
Lastly you'll want to set your Base Game and Source Maps directories.
When it comes to textures, something to keep in mind is that you do not have to use the same exact texture files from your project. You can set up a WAD file for use with J.A.C.K. but then in your Godot project have loose texture files and premade materials. As long as the relative texture paths match without the file extensions, FuncGodot will be able to select the correct textures. That said, FuncGodot does support using WAD files with your maps. Use whichever method is right for your project.
And with that, you should be all set to start mapping in J.A.C.K.!
NetRadiant Custom
NetRadiant Custom receives FuncGodot support through both local configuration and dedicated resources. The primary configuration resource is the NetRadiantCustomGamepackConfig. The NetRadiantCustomShader resource offers additional options for texture display in the editor. It is highly recommended that you familiarize yourself with NetRadiant Custom before attempting to use it with FuncGodot.
You'll need a NetRadiant Custom Gamepack Config resource in order to build and export a gamepack configuration for NetRadiant Custom. Let's take a look at the resource properties:
The Gamepack Name is the most important one to get right. This will be the name of your gamepack folder, your base game folder, and your gamepack file. The Gamepack Name MUST be all lower case with NO special characters. Bad things can happen otherwise!
The Game Name and Fgd File properties should be fairly obvious. Make sure that the FGD file you choose is the master FGD that contains all of your other base FGDs and entities.
The Base Game Path is the folder containing your maps and textures, relative to your project directory without res://. Leave this blank to use your project's root directory. If you do use a separate mapping folder within your project make sure that you follow the same formatting as the Gamepack Name: all lower case and no special characters.
The Netradiant Custom Shaders array is a resource array for... NetRadiantCustomShader resources! These will be compiled into a .shader file included with the rest of your gamepack configuration. Simply empty the array if you don't wish to use any special shaders. This only affects NetRadiant Custom and has no effect on your Godot shaders and materials.
The Texture Types, Model Types, and Sound Types arrays are the lists of compatible file types that NetRadiant Custom will attempt to look for. It's generally fine to leave this as is and is offered for the sake of more advanced users.
The Default Scale sets the default texture scale.
The Skip and Clip Texture properties set the texture paths for a number of different shader settings in the gamepack, including caulk> and nodraw.
Exporting the Gamepack Config will use the directory set in your Local Configuration's NetRadiant Custom Gamepacks Folder. After you've built the gamepack, open up NetRadiant Custom.
Once open, you'll want to go to Edit > Preferences > Global > Game. If you did everything correctly so far you should find your game in the list. Select it and then select Okay. NetRadiant Custom will need to restart.
You'll be prompted to find your game's engine path. Use your Godot project's root folder.
Lastly, you'll want to go to Edit > Preferences > Settings > Brush, then change New map Brush Type to Valve 220.
Now you should be ready to start mapping for Godot with NetRadiant Custom!
Next section
Building Maps
You've configured FuncGodot. You've configured your map editor. You've made your first test map of what will undoudbtedly be countless thousands. It's time to build.
When you get back into Godot, create a new scene. In that scene make your root node a base Node type. Call it whatever you'd like.
After that create a FuncGodotMap node as a child of this node.
Why do we make the FuncGodot Map a child and not the root? When a FuncGodot Map builds its scene it frees all of its children, including manually placed or edited nodes. Any work you did within the FuncGodot Map's branch of your Scene Tree will be erased when you rebuild the map (and you will rebuild it). Instead, do your post build customizations as siblings to the FuncGodot Map rather than children.
Let's take a look at our FuncGodot Map's properties.
Not much here. We have Local Map File and Global Map File. These point to the map file you want to build. The Global Map File will override the Local Map File. If you're working with a team and using source control it's probably best to stick with Local (res://) so you don't have to have matching drive and directory structures leading to the map files. The Global option is there partly as a potential Runtime build option.
The Map Settings property points to a FuncGodotMapSettings resource. FuncGodot uses this resource to define how your maps get built. Not all maps need to use the same Map Settings; it's possible to get clever and use different Map Settings resources on the same map file and get completely different results like referencing completely different textures or completely different entities utilizing common relative texture paths or class names.
Lastly we have some Build options. You can generally leave these alone, but they can be helpful if you find yourself having unexpected problems.
Let's take a quick peek at our Map Settings.
We went over most of these properties in the Textures Chapter, so we'll just go over the the ones we didn't cover: Inverse Scale Factor, Entity Fgd, UV Unwrap Texel Size, and Use Trenchbroom Groups Hierarchy.
The Entity Fgd property should be fairly obvious; like the map editor configurations, make sure this is the master FGD that contains all of your base FGDs and entity definitions. UV Unwrap Texel Size is for lightmapping; consult the Godot documentation for more information.
Inverse Scale Factor
One of the most impactful properties is the Inverse Scale Factor. It tells FuncGodot how big or small your map should be built. As it's an inverse scale, this means larger numbers will build smaller maps. How do you decide on the right inverse scale for your game though? To figure it out, it helps to know what you're scaling against.
In Godot, units are measured by meters. By default the modeling program Blender is as well. Quake maps however are all measured in Quake Units. Incidentally, a pixel in a map texture rendered at 100% scale on a brush face is equal to 1 Quake Unit.
How many pixels does a meter equal out to? 137? 22? The truth is that it's arbitrary; it really depends on what you want the average resolution of your game to be at. The FuncGodot Map Settings default to 32 because this puts a 1.5-2 meter tall player at a similar texture resolution to Quake. Feel free to experiment with this value to find the right scale for your game.
NOTE: Accounting for the Inverse Scale Factor in your class scripts will better allow you to design your entities within the map editor, i.e: using Quake Units to determine a moving platforms travel distance in your map editor and on import letting your node script translate that value into Godot Units using your Inverse Scale Factor.
Use Trenchbroom Groups Hierarchy
TrenchBroom has some unique features in the form of Layers and Groups (not to be confused with func_group, but also they're func_groups; they're weird). They add a convenient level of organization to the map making process.
In some cases mappers may want to design their maps in such a way as too create a hierarchy for their nodes using TrenchBroom Layers and Groups. FuncGodot offers this option using the Use Trenchbroom Groups Hierarchy property.
Let's say you created two layers and two groups of brush entities, both groups on separate layers.
If Use Trenchbroom Groups Hierarchy is disabled, your built FuncGodotMap scene structure will look something like this:
However, if you build your FuncGodotMap with Use Trenchbroom Groups Hierarchy enabled, you'll get this instead:
Building
You have your map file selected. You have your map settings ready. You've decided on an inverse scale factor and, if you're using TrenchBroom, you've decided whether you want a flat or multi-level scene tree hierarchy. It's time to build the map. With your FuncGodotMap node selected the toolbar at the top of the editor should change.
The Build button will build the map scene and apply all the appropriate ownership and settings to the map scene.
Unwrap UV2 can be used after the build process; it cycles through every Solid Entity with the Use In Baked Light property enabled in their definition and unwraps the UV2 of their MeshInstance3D children. If you're using baked lightmaps you'll need to press this button after every build but before every lightmap bake.
Go ahead and perform a Build and marvel in your master level craftsmanship.
Congratulations! You've built your first FuncGodot Map!
Next section
FuncGodotLocalConfig
Local machine project wide settings. Can define global defaults for some FuncGodot properties.
DO NOT CREATE A NEW RESOURCE!
This resource works by saving a MyGameFuncGodotConfig.json configuration file to your game's user:// folder and pulling the properties from that config file rather than this resource. Use the premade addons/func_godot/func_godot_local_config.tres instead.
NOTE: You need to run your project at least once before attempting to export settings, so that the user:// folder can be created by Godot! Otherwise you will run into an error and the config file will not export!
Handling local project configuration settings in this way means they need to be set individually on every machine you load your project onto. These settings are not saved to source control. The benefit is that this allows teams to more easily work together even with drastically different tool installation paths.
Property | Type | Description |
Export Func Godot Settings | Bool | Button to save the local machine project configuration settings in your game's user:// folder. |
Fgd Output Folder | String, Global Directory | Global directory path that FGD files save to when exported from their properties. Overridden when exported from a game configuration resource like TrenchBroomGameConfig. |
Trenchbroom Game Config Folder | String, Global Directory | Global directory path where your TrenchBroom game configuration should be saved to. Consult the TrenchBroom Manual's Game Configuration documentation for more information. |
Netradiant Custom Gamepacks Folder | String, Global Directory | Global directory path where your NetRadiant Custom gamepacks are saved. On Windows this is the gamepacks folder in your NetRadiant Custom installation. |
Map Editor Game Path | String, Global Directory | Global directory path to your mapping folder where all of your mapping assets exist. This is usually either your project folder or a subfolder within it. |
Game Path Models Folder | String | Relative directory path from your Map Editor Game Path to a subfolder containing any display models you might use for your map editor. Currently only used by FuncGodot FGD Model Point Class. |
Default Inverse Scale Factor | Float | Scale factor that affects how FuncGodot FGD Model Point Class entities scale their map editor display models. Not used with TrenchBroom, use TrenchBroom Game Config 's Entity Scale expression instead. |
Next section
FuncGodot FGD Resources
FuncGodotFGDFile
Resource file used to express a set of FuncGodotFGDEntity definitions. Can be exported as an FGD file for use with a Quake map editor. Used in conjunction with a FuncGodotMapSettings resource to generate nodes in a FuncGodotMap node.
Property | Type | Description |
Export File | Bool | Used as a button to build and export the FGD file. Automatically sets to off after exporting. |
Map Editor | ||
Model Key Word Supported | Bool | Some map editors do not support the "model" key word and require the "studio" key word instead. If you get errors in your map editor, try changing this setting. This setting is overridden when the FGD is built via the Game Config resource. |
FGD | ||
Fgd Name | String | FGD output filename without the extension. |
Base Fgd Files | Array[Resource] | Array of FuncGodotFGDFile resources to include in FGD file output. All of the entities included with these FuncGodotFGDFile resources will be prepended to the outputted FGD file. |
Entity Definitions | Array[Resource] | Array of resources that inherit from FuncGodotFGDEntityClass. This array defines the entities that will be added to the exported FGD file and the nodes that will be generated in a FuncGodotMap. |
FuncGodotFGDEntityClass
Base entity definition class. Not to be used directly, use FuncGodotFGDBaseClass, FuncGodotFGDSolidClass, or FuncGodotFGDPointClass instead.
Property | Type | Description |
Entity Definition | ||
Classname | String | Entity classname. This is a required field in all entity types as it is parsed by both the map editor and by FuncGodot on map build. |
Description | String | Entity description that appears in the map editor. Not required. |
Func Godot Internal | Bool | Entity does not get written to the exported FGD. Entity is only used for FuncGodotMap build process. |
Base Classes | Array[Resource] | Array of FuncGodotFGDBaseClass resources to inherit Class Properties and Class Descriptions from. |
Class Properties | Dictionary | Key value pair properties that will appear in the map editor. After building the FuncGodotMap in Godot, these properties will be added to a func_godot_properties Dictionary that gets applied to the generated node, as long as that node is a @tool script with an exported func_godot_properties Dictionary. See Entity Key Value Pairs for more information. |
Class Property Descriptions | Dictionary | Map editor descriptions for the previously defined key value pair properties. Not required for added properties but recommended. |
Meta Properties | Dictionary | Appearance properties for the map editor, eg: size, color, studio, model, etc... See the Valve Developer FGD and TrenchBroom documentation for more information. |
Node Generation | ||
Node Class | String | Node to generate on map build. This can be a built-in Godot class or a GDExtension class. For GDScript classes use the built-in Godot class they extend from (eg: MyCustom2 > MyCustom1 > Node3D would be "Node3D"). Use the Script Class property found in Solid Class and Point Class to apply your custom GDScript classes to generated nodes. For Point Class entities that use Scene File instantiation leave this blank. There is no restriction on what Node Classes can be generated. |
Name Property | String | Optional. Specifies a class property belonging to this entity that will be used to name the generated node upon map build. The node is renamed to "entity" + name_property prior to being added to the SceneTree and applying func_godot_properties .Overrides the Entity Name Property setting in FuncGodotMapSettings. NOTE: Node names should be unique, otherwise you may run into unexpected behavior! |
FuncGodotFGDBaseClass
Special inheritance class for Solid Class and Point Class entity definitions. Useful for adding shared or common properties and descriptions. Does not have any unique properties on its own but is defined separately to facilitate FGD building and lookup.
FuncGodotFGDSolidClass
FGD SolidClass entity definition, used to define brush entities. A MeshInstance3D will be generated by FuncGodotMap according to this definition's Visual Build settings. If FuncGodotFGDSolidClass Node Class inherits CollisionObject3D then one or more CollisionShape3D nodes will be generated according to Collision Build settings.
Property | Type | Description |
Spawn Type | SpawnType | Determines how FuncGodot generates both the mesh and the collision in regards to vertice positioning and combining.
|
Origin Type | OriginType | Determines how this Solid Class utilizes the "origin" key value pair to find its position. Only valid if Spawn Type is set to ENTITY.
|
Visual Build | ||
Build Visuals | Bool | Controls whether a MeshInstance3D is built for this Solid Class. |
Use In Baked Light | Bool | Sets generated MeshInstance3D to be available for UV2 unwrapping after FuncGodotMap build. Utilized in baked lightmapping. |
Shadow Casting Setting | ShadowCastingSetting | Shadow casting setting allows for further lightmapping customization. See the Godot documentation for more information. |
Build Occlusion | Bool | Automatically build OccluderInstance3D nodes for this entity. See the Godot documentation on Occlusion Culling for more information. |
Render Layers | Int, 3D Render Flags | This Solid Class' MeshInstance3D will only be visible for Camera3Ds whose cull mask includes any of these render layers. |
Collision Build | ||
Collision Shape Type | CollisionShapeType | Controls how collisions are built for this Solid Class.
See the Godot documentation to make an informed decision on what collision type would work best for this entity for your game's needs. |
Collision Layer | Int, 3D Physics Flags | The physics layers this Solid Class can be detected in. |
Collision Mask | Int, 3D Physics Flags | The physics layers this Solid Class scans. |
Collision Priority | Float | The priority used to solve colliding when penetration occurs. The higher the priority is, the lower the penetration into the SolidClass will be. This can for example be used to prevent the player from breaking through the boundaries of a level. |
Collision Shape Margin | Float | The collision margin for the Solid Class' collision shapes. Not used in Godot Physics. See Shape3D documentation for details. |
Scripting | ||
Script Class | Script | An optional script file to attach to the node generated on map build. |
FuncGodotFGDPointClass
FGD Point Class entity definition, used to define point entities. PointClass entities can use either the Node Class or the Scene File property to tell a FuncGodotMap what to generate on map build.
Property | Type | Description |
Scene | ||
Scene File | PackedScene | An optional scene file to instantiate on map build. Overrides Node Class and Script Class. |
Scripting | ||
Script Class | Script | An optional script file to attach to the node generated on map build. |
Build | ||
Apply Rotation On Map Build | Bool | Toggles whether entity will use angles, mangle, or angle to determine rotations on FuncGodotMap build, prioritizing the key value pairs in that order. Set to false if you would like to define how the generated node is rotated yourself. |
FuncGodotFGDModelPointClass
A special type of FuncGodotFGDPointClass entity that can automatically generate a special simplified, scaled, and reoriented GLB model file for the map editor display. Not supported by editors without GLB / GLTF support.
Property | Type | Description |
Target Map Editor | TargetMapEditor | Modifies whether the entity definition uses the studio or model keyword, and how it applies display model scaling. Options are GENERIC or TRENCHBROOM. |
Models Sub Folder | String | Optional display model export sub folder relative to the game path and models folder set in FuncGodotLocalConfig. |
Scale Expression | String | Scale expression applied to model. Only used by TrenchBroom. See the TrenchBroom Documentation for more information. To set the scale for other editors, set the Default Inverse Scale setting in FuncGodotLocalConfig. |
Generate Size Property | Bool | Model Point Class can override the size meta property by auto-generating a value from the meshes' AABB. Proper generation requires scale_expression set to a float or Vector3. WARNING: Generated size property unlikely to align cleanly to grid! |
Generate GD Ignore File | Bool | Creates a .gdignore file in the model export folder to prevent Godot importing the display models. Only needs to be generated once. |
Next section
Entity Key Value Pairs
Key Value Pairs are the most powerful aspect of FuncGodot. All of the Class Properties set in a FuncGodotFGDEntity definition get added to the corresponding entity placed in the map editor.
Key Value Pairs are defined in a FuncGodotFGDEntityClass resource's Class Properties dictionary. A Class Property is defined with a key String and a value of many of the Godot Variant Types (see Property Types below for a full list). The value set becomes both the default value and the Variant type the FuncGodotMap applies to that property on map build.
Additionally, you can define a property description. With the exception of Choices and Bit Flags, property descriptions are created by matching a key from Class Properties to the Class Property Descriptions dictionary and setting a String value for the description.
The result as it appears in TrenchBroom:
If you plan on using J.A.C.K. you may want to use the descriptions as proper names for the keys rather than actual descriptions. The same entity's properties as they appear in J.A.C.K.:
Once the corresponding node is generated by a FuncGodotMap, these key value pairs are then applied to the generated node's func_godot_properties dictionary. Additionally, if you add undefined key value pairs in your map editor, these too will be added to your node's func_godot_properties dictionary.
NOTE: Entity keys that are not given values will have their default values applied to the generated node's func_godot_properties dictionary.
Applying Key Values
It's pretty easy to apply entity key value pairs to nodes generated by FuncGodot. You have one property and two methods that you can use: the Dictionary func_godot_properties
, the method _func_godot_apply_properties(entity_properties: Dictionary)
, and the deferred method _func_godot_build_complete()
.
After the entity is built, FuncGodot will check if the entity contains a func_godot_properties
Dictionary, and if it exists it will apply the translated key value pairs as a Dictionary to this variable. In order for the application to persist at Runtime or after closing your scene, you'll need to make sure the variable is an @export
variable.
Use _func_godot_apply_properties
to apply your key value pairs to your node, as they are passed through the _func_godot_properties
argument in the function.
_func_godot_build_complete
is a deferred call that happens after every entity has called _func_godot_apply_properties
, making it safe to reference any nodes generated during _func_godot_apply_properties
.
You are allowed to limit yourself to only the application methods you're interested in. Mix and match these options as you see fit for your entities.
Property Types
FuncGodot supports many of the Godot Variant types. Consult the key values section of the FGD page on the Valve Developer Wiki for more information on FGD value types.
Godot Variant Type | FGD Value Type | Notes |
Int | integer | |
Float | float | |
String | string | |
Bool | choices | Automatically sets up options "No" and "Yes" with values "0" and "1" respectively. |
Vector2 | string | Vector2 key values are represented as string "X Y". Can accept floating point values. |
Vector2i | string | Vector2i key values are represented as string "X Y". Can only accept integer values. |
Vector3 | string | Vector3 key values are represented as string "X Y Z". Can accept floating point values. |
Vector3i | string | Vector3i key values are represented as string "X Y Z". Can only accept integer values. |
Vector4 | string | Vector4 key values are represented as string "W X Y Z". Can accept floating point values. |
Vector4i | string | Vector4i key values are represented as string "W X Y Z". Can only accept integer values. |
Color | string | Color key values are represented as string "R G B". In some Map Editors they may offer a color picker. Alpha is always set to 1.0. If alpha requires specification, use an additional float property. |
Dictionary | choices | Returns an Int or String on map build. Dictionaries are a special property case. See the Choices section for more information. |
Array | flags | Returns an Int on map build to be used as a bit mask. Somewhat complicated to set up and only flexibly supported in TrenchBroom. See the Bit Flags section for more information. |
Choices
The choices key value type allows you to open a dropdown menu of predefined options in your map editor. They are defined in Godot by choosing a value type of dictionary, with each key being the option text and each value being the property value. Keys are always Strings, but values can be either Int or String.
Normally the default value is set in Class Properties, but for Choices we can't do this (not without a fair amount of trouble). Instead we use Class Property Descriptions to set a default value. We do this by creating an Array with 2 elements: the first element is a String serving as the description; the second element is the default choice and should be either an Int or String matching one of the option values defined in Class Properties.
Once written to the FGD you should get a something like this in your map editor:
NOTE: While Bool types always generate a choices key value type, you don't need to set them up any differently than any other property. FuncGodot will automatically format Bool types for you on FGD export.
Bit Flags
Bit flags are the most complex key value type to set up, but offer a lot in simplifying complex comparisons and systems in your game scripts.
To set up a bit flags property, choose Array as the value's Variant type. Each element of the Array will be an Array as well, representing a single Flag. Each Flag Array is composed of 3 elements: a String serving as the Flag Description, an Int declaring the Flag's Bit Value, and an Int representing the Flag's default state.
Bit Flag properties do not utilize descriptions so there is no need to add one to the entity's Class Property Descriptions dictionary.
Once exported, you should get something like this:
>
Left, Trenchbroom; Right, J.A.C.K.; Not shown: NetRadiant Custom because I'm lazy, but it's pretty similar to J.A.C.K. in this regard.
Even though Godot uses 64 bit signed integers, map editors only seem to offer support for up to 24 bit flags. This is largely an artifact of the Quake engine, specifically its Quake C programming language. QuakeC doesn't have an integer type and instead used a 32 bit floating point number. The result was that only 24 bits remained to be used in bitwise operations. The Half-Life engine inherited this limitation, and subsequent Quake and Valve map editors designed their bit flag menus with this limitation in mind.
In TrenchBroom this isn't too much of a problem as you can have multiple bit flag key value pairs. Unfortunately other map editors are designed to only support one group of flags that they assume to be spawnflags, no matter what they're called in the FGD. J.A.C.K. will just overwrite spawnflags. NetRadiant Custom will throw errors if it detects flag values with matching bits and be unable to open. All key value types of flags will be compiled into the entity's Flags property and saved in the map file with the key "spawnflags".
If you're using another map editor other than TrenchBroom, you can still use multiple flags key value pairs or inherit them across multiple Base Classes. Just make sure each flags property applied to an entity has a unique bit value and expect FuncGodot to build it as a compiled spawnflags bitmask.
Next section
TrenchBroom Resources
TrenchBroom has the strongest support from FuncGodot, and as such is the recommended map editor for use with the plugin. FuncGodot has optional support for TrenchBroom Layers and Groups, and TrenchBroom supports multiple bit flag key value pairs. To aid with TrenchBroom support, FuncGodot offers two different resources.
TrenchBroomGameConfig
Defines a game in TrenchBroom to express a set of entity definitions and editor behaviors.
Property | Type | Description |
Export File | Bool | Button to export / update this game's configuration in the TrenchBroom Game Config Folder. |
Game Name | String | Name of the game in TrenchBroom's game list. |
Icon | Texture2D | Icon for TrenchBroom's game list. |
Map Formats | Array[Dictionary] | Available map formats when creating a new map in TrenchBroom. The order of elements in the array is the order TrenchBroom will list the available formats. The initialmap key value is optional. |
Texture Exclusion Patterns | Array[String] | Textures with names matching these patterns will be hidden from TrenchBroom. Useful for hiding PBR maps and animation frames. |
Fgd File | FuncGodotFGDFile | FGD resource to include with this game. If using multiple FGD resources, this should be the master FGD that contains them in the base_fgd_files resource array. |
Entity Scale | String | Scale expression that modifies the default display scale of entities in TrenchBroom. See the TrenchBroom Documentation for more information. |
Default Uv Scale | Vector2 | Scale of textures on new brushes and when UV scale is reset. |
Editor Hint Tags | ||
Brush Tags | Array[Resource] | TrenchBroomTag resources that apply to brush entities. |
Brushface Tags | Array[Resource] | TrenchBroomTag resources that apply to brush faces. |
TrenchBroomTag
Pattern matching tags to enable a number of features in TrenchBroom, including display appearance, menu filtering options, and keyboard shortcuts. This resource gets added to the TrenchBroomGameConfig resource. It does not affect appearance or functionality in Godot. See the TrenchBroom Documentation on Tags under the Game Configuration section for more information.
Property | Type | Description |
Tag Name | String | Name to define this tag. Not used as the matching pattern. |
Tag Attributes | Array[String] | The attributes applied to matching faces or brush entities. Only "_transparent" is supported in TrenchBroom, which makes matching faces or brush entities transparent. |
Tag Match Type | TagMatchType | Determines how the tag is matched. If set to TagMatchType.TEXTURE, the tag applies to any brush face with a texture matching the Texture Name. If set to TagMatchType.CLASSNAME, the tag applies to any brush entity with a classname matching the Tag Pattern. |
Tag Pattern | String | A string that filters which flag, param, or classname to use. * can be used as a wildcard to include multiple options. For example, a Tag Pattern of "trigger_*" with a TagMatchType Classname will apply this tag to all brush entities whose classnames begin with "trigger_". |
Texture Name | String | A string that filters which textures recieve these attributes. Only used with a TagMatchType of Texture. |
Next section
NetRadiant Custom Resources
FuncGodot has limited support for NetRadiant Custom. All standard entity types and shaders are supported. Patches are unsupported at this time, and bit flag key values are restricted to a single spawnflags key. FuncGodot offers two resources to help configure NetRadiant Custom gamepacks.
NetRadiantCustomGamepackConfig
Builds a gamepack for NetRadiant Custom.
Property | Type | Description |
Export File | Bool | Button to export / update this gamepack's configuration in the NetRadiant Custom Gamepacks Folder. |
Gamepack Name | String | Gamepack folder and file name. Must be lower case and must not contain special characters. |
Game Name | String | Name of the game in NetRadiant Custom's gamepack list. |
Base Game Path | String | Directory path containing your maps, textures, shaders, etc... relative to your project directory. |
Fgd File | FuncGodotFGDFile | FGD resource to include with this gamepack. If using multiple FGD resources, this should be the master FGD that contains them in the base_fgd_files resource array. |
Netradiant Custom Shaders | Array[Resource] | NetRadiantCustomShader resources for shader file generation. |
Texture Types | PackedStringArray | Supported texture file types. |
Model Types | PackedStringArray | Supported model file types. |
Sound Types | PackedStringArray | Supported audio file types. |
Default Scale | String | Default scale of textures in NetRadiant Custom. |
Clip Texture | String | Clip texture path that gets applied to weapclip and nodraw shaders. |
Skip Texture | String | Skip texture path that gets applied to caulk and nodrawnonsolid shaders. |
NetRadiantCustomShader
Resource that gets built into a shader file that applies a special effect to a specified texture in NetRadiant Custom.
Property | Type | Description |
Texture Path | String | Path to texture without extension, eg: `textures/special/clip`. |
Shader Attributes | Array[String] | Array of shader properties to apply to faces using Texture Path. |
Next section
FuncGodot Map Node
A scene generator node that parses a Quake map file using a FuncGodotFGDFile. Uses a FuncGodotMapSettings resource to define map build settings.
To use this node, select an instance of the node in the Godot editor and select Quick Build, Full Build, or Unwrap UV2 from the toolbar. Alternatively, call manual_build() from code.
Signals
Signal | Description |
build_complete | Emitted when the build process succesfully completes. |
build_progress(step, progress) | Emitted when the build process finishes a step. Progress is a value between 0.0 and 1.0. |
build_failed | Emitted when the build process fails. |
unwrap_uv2_complete | Emitted when the UV2 unwrapping is completed. |
Properties
Property | Type | Description |
Map | ||
Local Map File | String, Local File | Local path to Quake map file to build a scene from. |
Global Map File | String, Global File | Global path to Quake map file to build a scene from. Overrides Local Map File. |
Map Settings | FuncGodotFGDMapSettings | Map settings resource that defines map build scale, textures location, and more. |
Build | ||
Print Profiling Data | Bool | If true, print profiling data before and after each build step. |
Block Until Complete | Bool | If true, stop the whole editor until build is complete. |
Set Owner Batch Size | Int | How many nodes to set the owner of, or add children of, at once. Higher values may lead to quicker build times, but a less responsive editor. |
FuncGodotMapSettings
Reusable map settings configuration for FuncGodotMap nodes.
Property | Type | Description |
Inverse Scale Factor | Float | Ratio between map editor units and Godot units. FuncGodot will divide brush coordinates by this number when building. This does not affect entity properties unless scripted to do so. See Inverse Scale Factor for more information. |
Entity Fgd | FuncGodotFGDFile | Resource file that translates map file classnames into Godot nodes and packed scenes. |
Entity Name Property | String | Default class property to use in naming generated nodes. This setting is overridden by name_property in FuncGodotFGDEntityClass. Naming occurs before adding to the SceneTree and applying properties. Nodes will be named "entity_" + name_property .NOTE: Node names should be unique, otherwise you may run into unexpected behavior! |
Textures | ||
Base Texture Dir | String | Base directory for textures. When building materials, FuncGodot will search this directory for texture files with matching names to the textures assigned to map brush faces. |
Texture File Extensions | Array | File extensions to search for texture data. |
Clip Texture | String | Optional path for the clip texture, relative to Base Texture Dir. Brush faces textured with the clip texture will have those faces removed from the generated MeshInstance3D but not the generated CollisionShape3D. |
Skip Texture | String | Optional path for the skip texture, relative to Base Texture Dir. Brush faces textured with the skip texture will have those faces removed from the generated MeshInstance3D. If the FuncGodotFGDSolidClass collision_shape_type is set to concave then it will also remove collision from those faces in the generated CollisionShape3D. |
Texture Wads | Array[Resource] | Optional QuakeWADFile resources to apply textures from. See the Quake Wiki for more information on Quake Texture WADs. |
Materials | ||
Material File Extension | String | File extension to search for Material definitions. |
Unshaded | Bool | If true, all materials will be unshaded, ignoring light. Also known as "fullbright". |
Default Material | Material | Material used as a template when generating missing materials. |
Default Material Albedo Uniform | String | Sampler2D uniform that supplies the Albedo in a custom shader when Default Material is a ShaderMaterial. |
Normal Map Pattern | String | Automatic PBR material generation normal map pattern. |
Metallic Map Pattern | String | Automatic PBR material generation metallic map pattern. |
Roughness Map Pattern | String | Automatic PBR material generation roughness map pattern. |
Emission Map Pattern | String | Automatic PBR material generation emission map pattern. |
Ao Map Pattern | String | Automatic PBR material generation ambient occlusion map pattern. |
Height Map Pattern | String | Automatic PBR material generation height map pattern. |
Save Generated Materials | Bool | Save automatically generated materials to disk, allowing reuse across FuncGodotMap nodes. NOTE: Materials do not use the Default Material settings after saving. |
UV Unwrap | ||
Uv Unwrap Texel Size | Float | Texel size for UV2 unwrapping. Actual texel size is uv_unwrap_texel_size / inverse_scale_factor. A ratio of 1/16 is usually a good place to start with (if inverse_scale_factor is 32, start with a uv_unwrap_texel_size of 2). Larger values will produce less detailed lightmaps. To conserve memory and filesize, use the largest value that still looks good. |
TrenchBroom | ||
Use Trenchbroom Groups Hierarchy | Bool | If true, will organize Scene Tree using Trenchbroom Layers and Groups. Layers and Groups will be generated as Node3Ds. All structural brushes will be moved out of the Layers and Groups and merged into the Worldspawn entity. Additionally, any Layers toggled to be omitted from export in TrenchBroom will be freed on map build before the Layers' children can apply func_godot_properties or call _func_godot_apply_properties() and _func_godot_build_complete() . |
Next section
Naming Patterns
Recall that every entity has a classname that we define in our Entity Definition resource. One important consideration to make is that naming conventions matter. The first word of an entity's name up until the first underscore will be provided its own group in the map editor. Taking advantage of this can help keep your entities organized in a few spots and in some editors provide convenient filtering options.
When combined with brush tags in TrenchBroom configurations, this feature gains additional powers like in-editor transparency and keyboard shortcuts.
FuncGodot has a pair of prebuilt TrenchBroomTag resources for func* and trigger* brush classes. Feel free to use these either directly or as a base for your own brush tags.
Additionally, your map editor will also handle Point Class orientation through the key value pairs angle and mangle differently depending upon the classname. Setting the mangle for an entity type in the "light_*" group or with the "info_intermission" classname will have altered orientation behavior. To see the differences, try to parse the code block in FuncGodotMap that handles translating Quake angles into Godot rotations:
Anyway, just make sure to give a little bit more thought to your naming conventions.
Next section
Why Not Worldspawn?
First things first... What IS Worldspawn?
As mentioned before, FuncGodot comes with a set of example Entity Definitions, including one for the worldspawn class that comes built-in to every Quake map file. But what is worldspawn?
Every Quake map file contains a list of entities containing a set of key value pairs. Some optionally include brush definitions. In Quake, the entity's classname is also the spawn function that is called upon map start. The very first entity that needs to load is the world, so entity 0 is always worldspawn. There can also only ever be one Worldspawn in a Quake map (with one weird exception I'll mention later).
Simply put, Worldspawn is just another entity. It's not even a Solid Entity by default. It needs to be defined in your FGD just like any other entity, too, or else it will revert to a simple Node3D with a mesh and no collision. The only special behavior Worldspawn has is that its position will always be the FuncGodotMap's position, unlike other Solid Entities.
The example Worldspawn entity is defined as a Solid Class StaticBody3D with convex collision, and the general understanding is that it's a built in mechanic of FuncGodot. Some of you need to have your stage geometry cut up for occlusion or per-collider purposes. In Tim's game They Came From Dimension X, worldspawn was changed into a WorldEnvironment that instantiates a LightmapGI while also handling default music playback and other map-wide settings. You might think of a completely different use case for it.
NOTE: Setting Worldspawn as a Point Class may have undefined side effects due to being able to place a second Worldspawn in your map. It is recommended that any Worldspawn definition be a Solid Class.
So why not Worldspawn?
Occlusion Culling
Performance on larger or heavily populated maps mostly. Godot culls objects by the VisualInstance; in the case of our maps, this means mesh by mesh. In order to get better performance we'll need to split our map up into smaller chunks.
Meshes are generated on a per-entity basis: every brush in a Solid Entity is merged into a single mesh. Since Worldspawn is an entity, any brush that is a part of Worldspawn gets merged into the same mesh. If we want to split up our mesh, we need to split our Worldspawn into separate entities.
Remember: FuncGodot is not a BSP compiler. This means mapping for Godot like you're mapping for Quake is counterproductive. Instead, make sure you give some thought to how you'll split up your geometry entities, and how the brush vertices meet with each other. In exchange for full automation, FuncGodot instead gives you full control.
Surface "Materials"
A common question a lot of Godot devs have is how do I get the texture of the surface my character is stepping on or shooting? and the answer is... you don't! Well, the short answer anyway. Since Godot's CollisionObjects are completely separate from the MeshInstance3Ds, there's no real good performant way to actually do it surface by surface. Any possible solutions that involve getting the stage mesh's texture on a particular face are just not worth it. But why work against the engine when you can work with it?
If we can control how our stage geometry is split up, we can also provide that stage geometry with key value properties, including one that supplies a Material Type that can easily be passed to any character stepping on or shooting it. This is something that can't be done with a singular Worldspawn entity.
How Do I Live Without Worldspawn?
You'll want to create a Solid Class entity that matches the Worldspawn entity definition. It's recommended that you change the Spawn Type to ENTITY though. Feel free to also add any Class Properties you feel would benefit your game's design. The world geometry solid class entity used in Tim's games is typically called func_geo. He never shuts up about it.
A World Alongside Worldspawn
It would also help to create your own new worldspawn entity definition that doesn't build visuals or collision, so that you can more easily tell if that stage geometry was given its own func_geo or was accidentally left as worldspawn. Keep in mind that a Quake map file's first entity will always be worldspawn, and that all map editors will only allow you to have one that they make automatically.
With that in mind... why not a WorldEnvironment? Let's take a look at an example of how you might repurpose a Worldspawn for one.
In TrenchBroom we can have our `worldspawn` settings set up like this in our FGD. We're assuming you know how this is done by now, but if not please go back and reread the section on Entities near the beginning of the manual.
Then in Godot, when the map is built and the Worldspawn's func_godot_properties
dictionary is set, it runs the _func_godot_apply_properties(props)
method.
@tool
extends WorldEnvironment
class_name Worldspawn
const LIGHT_LAYER_MASK: int = 31
@export var func_godot_properties: Dictionary = {}
func _func_godot_apply_properties(props: Dictionary) -> void:
# WORLD ENVIRONMENT
var env: Environment = Environment.new()
# Base settings
env.set_fog_enabled(false);
env.set_tonemapper(Environment.TONE_MAPPER_FILMIC)
env.set_glow_enabled(false)
# Background
env.set_background(Environment.BG_COLOR);
if props.has("color_bg"):
env.set_bg_color(props["color_bg"]);
else:
env.set_bg_color(Color());
# Ambient light
env.set_ambient_source(Environment.AMBIENT_SOURCE_COLOR);
if props.has("color_ambient"):
env.set_ambient_light_color(props["color_ambient"]);
else:
env.set_ambient_light_color(Color.hex(0xFFFFFFFF));
if props.has("ambient_light"):
env.set_ambient_light_energy(props["ambient_light"]);
else:
env.set_ambient_light_energy(0.0);
env.set_ambient_light_sky_contribution(0.0)
# Brightness setup
env.set_adjustment_enabled(true)
env.set_adjustment_brightness(1.0)
set_environment(env)
It doesn't stop there, by the way. You may have noticed a number of key value pairs in our TrenchBroom entity: lit_bounces, lit_denoiser, etc... Instead of manually creating the lightmap for each map, we can have our Worldspawn entity programmatically create and modify the LightmapGI node any time the map is built. To do this, we'll use the _func_godot_build_complete()
method, automatically called as a deferred call at the end of the build process.
func _func_godot_build_complete() -> void:
# Find existing lightmap, else build a new one
var lit: LightmapGI
if get_owner().has_node("lightmap"):
lit = get_owner().get_node("lightmap")
else:
lit = LightmapGI.new()
lit.set_name("lightmap")
get_owner().add_child(lit)
lit.set_owner(get_owner())
lit.get_parent().call_deferred("move_child", lit, 0);
lit.set_layer_mask(LIGHT_LAYER_MASK)
# Bake Quality
if func_godot_properties.has("lit_quality"):
lit.set_bake_quality(func_godot_properties["lit_quality"] as LightmapGI.BakeQuality)
else:
lit.set_bake_quality(LightmapGI.BakeQuality.BAKE_QUALITY_MEDIUM);
# Bounces
if func_godot_properties.has("lit_bounces"):
lit.set_bounces(func_godot_properties["lit_bounces"] as int)
else:
lit.set_bounces(3);
# Lightmapper Probes Subdivision
if func_godot_properties.has("lit_probes_subdiv"):
lit.set_generate_probes(func_godot_properties["lit_probes_subdiv"] as LightmapGI.GenerateProbes)
else:
lit.set_generate_probes(LightmapGI.GenerateProbes.GENERATE_PROBES_SUBDIV_8);
# Use Denoiser
if func_godot_properties.has("lit_denoiser"):
lit.set_use_denoiser(func_godot_properties["lit_denoiser"] as bool);
else:
lit.set_use_denoiser(true);
That's right: during the build process you can have your entities' properties affect other entities or nodes outside of the FuncGodotMap node. This is somewhat advanced Godot scripting, as you do need to understand a bit more about when objects will exist in the SceneTree, but it's an extremely powerful tool at your disposal.
Hopefully this little essay asking you to question the role of Worldspawn has gotten you thinking a bit more outside the box in regards to what you can do with FuncGodot. Be sure to join our Discord community and let us know what you did with your Worldspawn!
Next section
Conditional Models in TrenchBroom
Let's say we want to add a misc_model or prop_dynamic entity class. Wouldn't it be nice if we could change a property and have our map editor reflect that change?
TrenchBroom allows you to modify certain meta property options through the use of an entity's own properties. There is a great example of this in the TrenchBroom version of Quake's FGD file. Let's look at an example with item_health, which uses spawnflags to determine if the item becomes a Medkit, a Rotten Medkit, or a Megahealth.
@PointClass
size(0 0 0, 32 32 56)
base(Appearflags)
model(
{{
spawnflags & 2 -> ":maps/b_bh100.bsp",
spawnflags & 1 -> ":maps/b_bh10.bsp",
":maps/b_bh25.bsp"
}}
) =
item_health : "Health pack"
[
spawnflags(flags) =
[
1 : "Rotten" : 0
2 : "Megahealth" : 0
]
]
We can see that the pattern is essentially property expression -> model path
. While this is fine done via flags, it might be better to use a choices if you have a lot of models you wish to choose from. A good template might be:
model(
{{
model_id == 1 -> "path": "path/to/model1.glb",
model_id == 2 -> "path": "path/to/model2.glb",
model_id == 3 -> "path": "path/to/model3.glb",
"path": "path/to/model0.glb" // default value
}}
) = point_entity : "Example point entity description"
[
model_id(choices) : "An example model enumerator" : "0" =
[
0 : "Model 0"
1 : "Model 1"
2 : "Model 2"
3 : "Model 3"
]
]
We achieve this with a dictionary property we can call model_id and by adding an element to our Meta Properties dictionary with the key model and the String value {{ model_id == 1 -> "path": "path/to/model1.glb", model_id == 2 -> "path": "path/to/model2.glb", model_id == 3 -> "path": "path/to/model3.glb", "path": "path/to/model0.glb" }}
.
This doesn't affect the Godot entity that gets built. You'll still need to make your own script that handles the model swaps upon building in Godot. Should be pretty trivial to use a match statement utilizing your entity's model_id property though!
Next section
Helpful Links
Godot and FuncGodot
Official FuncGodot Discord
If you've got questions on FuncGodot or Godot, we've got some extremely helpful community members who are generally happy to answer them. Be respectul and patient: we're all volunteers, doing this on our free time and out of a love for the community.
FuncGodot Repositories
The official repositories contain helpful example projects that can show you how you might design your own games to take advantage of FuncGodot.
Godot 4 Latest Stable Documentation
This may seem obvious or sarcastic, but this is probably the best source for almost all of the answers to almost all of your questions. This is your best friend. Most FuncGodot questions people have are really just Godot questions that don't involve FuncGodot at all. If you need to know how to do something in Godot, it's in this manual (literally).
RhapsodyInGeek's GitHub Repositories
Tim often shares a lot of his work on GitHub, most of it licensed under Creative Commons Zero and MIT. Not all of it can be dragged and dropped into your own projects, but hopefully you'll come away from them learning something new.
Valve Developer Community Wiki's FGD Page
This is an extremely helpful resource in learning how FGD files work, and not just for Valve games or Hammer: it covers how FGD files are used by other editors too. If you want to take advantage of some more advanced features of FuncGodot's entity and configuration systems, it's helpful to study up on the FGD language that powers it.
TrenchBroom and Quake
Dumptruck_ds's TrenchBroom Tutorials
Some of these tutorials are a little bit dated as some features have changed a little, but overall these will teach you not only the fundamentals but get you acquainted with some of the more advanced techniques and improve your TrenchBroom workflow. You can also learn more about Quake map scripting, which might inspire some design patterns for your own game.
Slipseer's TrenchBroom Tutorials
YouTube channel with some great tutorials. Not a lot on here, but what's here can definitely level up a novice mapper's skill set.
Slipgate Sightseer
A very active and well done Quake modding and mapping site. Easy to navigate layout. Run by the best in the business. Check it out, even if just to get inspired by all the possibilities with TrenchBroom mapping. It's not just a lot of brown blocks (though those are cool, too).
id Software GitHub Repository
An incredible source for study. John Carmack began a trend a long while back of releasing the source code for id Software games, and this repository stretches as far back as Wolfenstein 3D. The most relevant repositories for you might be the Quake 1, 2, and 3 sources. Also provided are the Quake 1 QC files, the code for almost the entirety of the gameplay.
Quake Mapping Discord
Discord server where the best of the best hang out. If you have questions on Quake or TrenchBroom, mapping or modding, the people here can teach you everything you want to know about it.
J.A.C.K. and Half-Life
Lymphoid's Half-Life Mapping Tutorials
Not as hilarious as Dimbeak's tutorials but Lymphoid's videos are a few years more relevant and have a fairly slower pace. Not everything is applicable to the J.A.C.K. > FuncGodot > Godot pipeline, but what can't be used directly could still be useful in knowing for your own implementations.
Vhetutor's Tutorials
Many of these tutorials are for Hammer, but they give pretty great overviews of how scripted sequences are designed in a Half-Life map. Once again, not directly applicable but these tutorials could be very informative in trying to design your own scripted sequences, no matter your map editor.
The Whole Half-Life
A site dedicated to Half-Life level design and modding. Deep dive into the knowledge base of Half-Life modding, raid its vaults, and escape with new design patterns that you can use for your FuncGodot workflow.
Half-Life Source Code
Another incredible source for study. Half-Life does a lot of really interesting things with its design. Definitely take a peek through and see what you can learn.
Useful Tools
Aseprite
The most important game dev tool you will ever purchase. It's a wonderful pixel paint program that trivializes sprite work and animation.
Krita
Free and open source paint application that serves really well as an Adobe Photoshop alternative. I use this for my higher res image assets and concept art.
Material Maker
Really incredible open source procedural materials authoring tool made with Godot, available at the variable cost of name-your-own-price. Highly recommended by the community.
Next section
Frequently Asked Questions
Why are my textures blurry?!
Can I do...
How does FuncGodot handle source control?
Why am I getting an error trying to export my Local Configuration?
Why are my new entities not building? Why can't I find them in my map editor?
Help! I manually added some nodes to my FuncGodotMap and when I hit build again they all disappeared!
How do I split up my map? It only comes out as one big mesh
I'm getting a lot of overdraw, why doesn't FuncGodot get rid of unseen faces?
Why are my textures blurry?!
Why are my textures blurry?!
Please don't skim the manual.
Can I do...
Yes.
How does FuncGodot handle source control?
All resources that need to access or reference global paths go through the FuncGodot Local Config settings that are local to each machine. The various tool and project paths do need to be set per machine. Additionally, the FuncGodotMap has the option for using a local path to map files.
Why am I getting an error trying to export my Local Configuration?
You need to run your project at least once so that Godot can create the user:// folder. This can be any scene. After the first run, you'll be able to export your Local Config.
Why are my new entities not building? Why can't I find them in my map editor?
Double check to make sure you set a Classname in the entity resource before you exported the FGD. If this doesn't exist, FuncGodot will skip adding it to the FGD file and will only generate a Node3D.
Help! I manually added some nodes to my FuncGodotMap and when I hit build again they all disappeared!
FuncGodotMap nodes will always erase every child they have when rebuilt. There's no practical way for FuncGodot to confidently differentiate what it built, what was programmatically built as a result of its build, and what was hand placed by the user. If you feel the need to manually place nodes you should do so outside of the FuncGodotMap node in order to not lose any work.
How do I split up my map? It only comes out as one big mesh
You're still mapping like you're compiling for the Quake engine. You need to map like your target is the Godot Engine.
I'm getting a lot of overdraw, why doesn't FuncGodot get rid of unseen faces?
You're still mapping like you're compiling for the Quake engine. You need to map like your target is the Godot Engine.
Why are my textures blurry?!
...