FuncGodot RangerFuncGodot

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


Godambler
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

FuncGodot Ranger

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.

An image displaying where to find the GitHub Code Download. It shows a green button that says 'Code' with an open menu. At the bottom of the menu is a button that says 'Download Zip'.

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.

An image displaying where to find the GitHub Stable Release. It shows a circled location on the right side of the GitHub repository page that says 'Releases'.

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.

Godot Project Settings window, Plugins tab. FuncGodot is listed and enabled.

Next section

FuncGodot Ranger

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.

Location of func_godot_local_config.tres in the Godot project File System.

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.

FuncGodotLocalConfig resource inspector.

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

FuncGodot Ranger

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.

FuncGodot FGD Resource List.


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.

func_godot_fgd.tres location.

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.

FuncGodotFGDFile resource properties.

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.

FuncGodotFGDFile base FGD example.

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.

FuncGodotFGDFile default FGD.


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

FuncGodotMap GDScript method showing application of 'func_godot_properties' and callback of '_func_godot_apply_properties' and '_func_godot_build_complete'.

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.

Func Base Class FuncGeo Solid Class

This is our FuncGeo entity's properties as they appear in TrenchBroom.

func_geo brush entity properties 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.

Generated FuncGeo node in Godot

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

Next section

FuncGodot Ranger

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:

Solid Entity Example

// 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:

FuncGodotMapSettings properties

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.

Default texture

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

Clip texture Skip texture

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

FuncGodot Ranger

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 logo

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:

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

TrenchBroom Config 2

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.

TrenchBroom Config 3

Now you should be ready to start mapping for Godot with TrenchBroom!

TrenchBroom Config 3


J.A.C.K.

J.A.C.K. logo

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.

J.A.C.K. Config 1

Once exported, you'll need to add your game to the Game Configurations list. Be sure to add your newly exported FGD as well.

J.A.C.K. Config 2 J.A.C.K. Config 3

Lastly you'll want to set your Base Game and Source Maps directories.

J.A.C.K. Config 4

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

J.A.C.K. Config 5


NetRadiant Custom

NetRadiant Custom logo

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:

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

NetRadiant Custom setup 1

You'll be prompted to find your game's engine path. Use your Godot project's root folder.

NetRadiant Custom setup 2

Lastly, you'll want to go to Edit > Preferences > Settings > Brush, then change New map Brush Type to Valve 220.

NetRadiant Custom setup 2

Now you should be ready to start mapping for Godot with NetRadiant Custom!

NetRadiant Custom setup 3

Next section

FuncGodot Ranger

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.

Building the map 1

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.

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

Building the map 2

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.

32x32 Quake Unit Block 1x1 Godot Unit Block

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.

TrenchBroom screenshot depicting 2 layers named Texas and Massachusetts and 2 groups of brush entities named Richardson and Arkham.

If Use Trenchbroom Groups Hierarchy is disabled, your built FuncGodotMap scene structure will look something like this:

Scene tree showing a flat entity hierarchy

However, if you build your FuncGodotMap with Use Trenchbroom Groups Hierarchy enabled, you'll get this instead:

Scene tree showing a multi level entity hierarchy based upon the map layers and groups


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.

FuncGodotMap buttons

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

FuncGodot Ranger

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.


PropertyTypeDescription
Export Func Godot SettingsBoolButton to save the local machine project configuration settings in your game's user:// folder.
Fgd Output FolderString, Global DirectoryGlobal 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 FolderString, Global DirectoryGlobal 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 FolderString, Global DirectoryGlobal directory path where your NetRadiant Custom gamepacks are saved. On Windows this is the gamepacks folder in your NetRadiant Custom installation.
Map Editor Game PathString, Global DirectoryGlobal 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 FolderStringRelative 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 FactorFloatScale 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 Ranger

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.


PropertyTypeDescription
Export FileBoolUsed as a button to build and export the FGD file. Automatically sets to off after exporting.
Map Editor
Model Key Word SupportedBoolSome 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 NameStringFGD output filename without the extension.
Base Fgd FilesArray[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 DefinitionsArray[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.


PropertyTypeDescription
Entity Definition
ClassnameStringEntity 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.
DescriptionStringEntity description that appears in the map editor. Not required.
Func Godot InternalBoolEntity does not get written to the exported FGD. Entity is only used for FuncGodotMap build process.
Base ClassesArray[Resource]Array of FuncGodotFGDBaseClass resources to inherit Class Properties and Class Descriptions from.
Class PropertiesDictionaryKey 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 DescriptionsDictionaryMap editor descriptions for the previously defined key value pair properties. Not required for added properties but recommended.
Meta PropertiesDictionaryAppearance 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 ClassStringNode 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 PropertyStringOptional. 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.


PropertyTypeDescription
Spawn TypeSpawnTypeDetermines how FuncGodot generates both the mesh and the collision in regards to vertice positioning and combining.
  • WORLDSPAWN : Builds the geometry of this entity without regard to its center position. Upon build completion all geometry will be offset by this entity's true position. Recommend only use with worldspawn entity.
  • MERGE WORLDSPAWN : This entity's geometry is merged with the worldspawn entity and this entity is removed. Behavior mimics func_group in modern Quake compilers.
  • ENTITY : This entity is built as its own object. It finds the center of the entity by averaging the positions of all vertices, using the global result of this as its position.
    NOTE: This is not always the center of the mesh's AABB.
Origin TypeOriginTypeDetermines how this Solid Class utilizes the "origin" key value pair to find its position. Only valid if Spawn Type is set to ENTITY.
  • IGNORE : Ignore origin property and only use averaged brush vertices for positioning.
  • ABSOLUTE : Use origin property for position center, ignoring brush vertice positions.
  • RELATIVE : Calculate position center using origin as an offset to averaged brush vertice positions.
Visual Build
Build VisualsBoolControls whether a MeshInstance3D is built for this Solid Class.
Use In Baked LightBoolSets generated MeshInstance3D to be available for UV2 unwrapping after FuncGodotMap build. Utilized in baked lightmapping.
Shadow Casting SettingShadowCastingSettingShadow casting setting allows for further lightmapping customization. See the Godot documentation for more information.
Build OcclusionBoolAutomatically build OccluderInstance3D nodes for this entity. See the Godot documentation on Occlusion Culling for more information.
Render LayersInt, 3D Render FlagsThis Solid Class' MeshInstance3D will only be visible for Camera3Ds whose cull mask includes any of these render layers.
Collision Build
Collision Shape TypeCollisionShapeTypeControls how collisions are built for this Solid Class.
  • None : No collision shape is built. Useful for decorative geometry like vines, hanging wires, grass, etc...
  • Convex : Will build a Convex CollisionShape3D for each brush used to make this Solid Class. Required for non-StaticBody3D nodes like Area3D and RigidBody3D.
  • Concave : Will build a single Concave CollisionShape3D from the entire set of brushes. Skips brush faces textured with the FuncGodotMapSettings' Skip Texture.

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 LayerInt, 3D Physics FlagsThe physics layers this Solid Class can be detected in.
Collision MaskInt, 3D Physics FlagsThe physics layers this Solid Class scans.
Collision PriorityFloatThe 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 MarginFloatThe collision margin for the Solid Class' collision shapes. Not used in Godot Physics. See Shape3D documentation for details.
Scripting
Script ClassScriptAn 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.


PropertyTypeDescription
Scene
Scene FilePackedSceneAn optional scene file to instantiate on map build. Overrides Node Class and Script Class.
Scripting
Script ClassScriptAn optional script file to attach to the node generated on map build.
Build
Apply Rotation On Map BuildBoolToggles 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.


PropertyTypeDescription
Target Map EditorTargetMapEditorModifies whether the entity definition uses the studio or model keyword, and how it applies display model scaling. Options are GENERIC or TRENCHBROOM.
Models Sub FolderStringOptional display model export sub folder relative to the game path and models folder set in FuncGodotLocalConfig.
Scale ExpressionStringScale 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 PropertyBoolModel 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 FileBoolCreates a .gdignore file in the model export folder to prevent Godot importing the display models. Only needs to be generated once.

Next section

FuncGodot Ranger

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.

FuncGodotMap GDScript method showing application of 'func_godot_properties' and callback of '_func_godot_apply_properties' and '_func_godot_build_complete'.

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 TypeFGD Value TypeNotes
Intinteger
Floatfloat
Stringstring
BoolchoicesAutomatically sets up options "No" and "Yes" with values "0" and "1" respectively.
Vector2stringVector2 key values are represented as string "X Y". Can accept floating point values.
Vector2istringVector2i key values are represented as string "X Y". Can only accept integer values.
Vector3stringVector3 key values are represented as string "X Y Z". Can accept floating point values.
Vector3istringVector3i key values are represented as string "X Y Z". Can only accept integer values.
Vector4stringVector4 key values are represented as string "W X Y Z". Can accept floating point values.
Vector4istringVector4i key values are represented as string "W X Y Z". Can only accept integer values.
ColorstringColor 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.
DictionarychoicesReturns an Int or String on map build.
Dictionaries are a special property case. See the Choices section for more information.
ArrayflagsReturns 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

FuncGodot Ranger

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.


PropertyTypeDescription
Export FileBoolButton to export / update this game's configuration in the TrenchBroom Game Config Folder.
Game NameStringName of the game in TrenchBroom's game list.
IconTexture2DIcon for TrenchBroom's game list.
Map FormatsArray[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 PatternsArray[String]Textures with names matching these patterns will be hidden from TrenchBroom. Useful for hiding PBR maps and animation frames.
Fgd FileFuncGodotFGDFileFGD 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 ScaleStringScale expression that modifies the default display scale of entities in TrenchBroom. See the TrenchBroom Documentation for more information.
Default Uv ScaleVector2Scale of textures on new brushes and when UV scale is reset.
Editor Hint Tags
Brush TagsArray[Resource]TrenchBroomTag resources that apply to brush entities.
Brushface TagsArray[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.


PropertyTypeDescription
Tag NameStringName to define this tag. Not used as the matching pattern.
Tag AttributesArray[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 TypeTagMatchTypeDetermines 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 PatternStringA 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 NameStringA string that filters which textures recieve these attributes. Only used with a TagMatchType of Texture.

Next section

FuncGodot Ranger

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.


PropertyTypeDescription
Export FileBoolButton to export / update this gamepack's configuration in the NetRadiant Custom Gamepacks Folder.
Gamepack NameStringGamepack folder and file name. Must be lower case and must not contain special characters.
Game NameStringName of the game in NetRadiant Custom's gamepack list.
Base Game PathStringDirectory path containing your maps, textures, shaders, etc... relative to your project directory.
Fgd FileFuncGodotFGDFileFGD 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 ShadersArray[Resource]NetRadiantCustomShader resources for shader file generation.
Texture TypesPackedStringArraySupported texture file types.
Model TypesPackedStringArraySupported model file types.
Sound TypesPackedStringArraySupported audio file types.
Default ScaleStringDefault scale of textures in NetRadiant Custom.
Clip TextureStringClip texture path that gets applied to weapclip and nodraw shaders.
Skip TextureStringSkip 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.


PropertyTypeDescription
Texture PathStringPath to texture without extension, eg: `textures/special/clip`.
Shader AttributesArray[String]Array of shader properties to apply to faces using Texture Path.

Next section

FuncGodot Ranger

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

SignalDescription
build_completeEmitted 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_failedEmitted when the build process fails.
unwrap_uv2_completeEmitted when the UV2 unwrapping is completed.

Properties

PropertyTypeDescription
Map
Local Map FileString, Local FileLocal path to Quake map file to build a scene from.
Global Map FileString, Global FileGlobal path to Quake map file to build a scene from. Overrides Local Map File.
Map SettingsFuncGodotFGDMapSettingsMap settings resource that defines map build scale, textures location, and more.
Build
Print Profiling DataBoolIf true, print profiling data before and after each build step.
Block Until CompleteBoolIf true, stop the whole editor until build is complete.
Set Owner Batch SizeIntHow 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.


PropertyTypeDescription
Inverse Scale FactorFloatRatio 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 FgdFuncGodotFGDFileResource file that translates map file classnames into Godot nodes and packed scenes.
Entity Name PropertyStringDefault 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 DirStringBase 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 ExtensionsArrayFile extensions to search for texture data.
Clip TextureStringOptional 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 TextureStringOptional 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 WadsArray[Resource]Optional QuakeWADFile resources to apply textures from. See the Quake Wiki for more information on Quake Texture WADs.
Materials
Material File ExtensionStringFile extension to search for Material definitions.
UnshadedBoolIf true, all materials will be unshaded, ignoring light. Also known as "fullbright".
Default MaterialMaterialMaterial used as a template when generating missing materials.
Default Material Albedo UniformStringSampler2D uniform that supplies the Albedo in a custom shader when Default Material is a ShaderMaterial.
Normal Map PatternStringAutomatic PBR material generation normal map pattern.
Metallic Map PatternStringAutomatic PBR material generation metallic map pattern.
Roughness Map PatternStringAutomatic PBR material generation roughness map pattern.
Emission Map PatternStringAutomatic PBR material generation emission map pattern.
Ao Map PatternStringAutomatic PBR material generation ambient occlusion map pattern.
Height Map PatternStringAutomatic PBR material generation height map pattern.
Save Generated MaterialsBoolSave 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 SizeFloatTexel 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 HierarchyBoolIf 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

FuncGodot Ranger

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:

Image showing how node rotation is calculated by the FuncGodotMap.

Anyway, just make sure to give a little bit more thought to your naming conventions.

Next section

FuncGodot Ranger

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

FuncGodot Ranger

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

FuncGodot Ranger

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