The Level Design Book
BookResources
  • The Level Design Book
  • ✨What is level design
  • Book 1, Process
    • πŸ—ΊοΈHow to make a level
    • 🧠Pre-production
      • Pacing
      • Research
      • Worldbuilding
      • Scope
    • πŸ”«Combat
      • Enemy design
      • Encounter
      • Cover
      • Map balance
    • πŸ› οΈLayout
      • Flow
        • Circulation
        • Verticality
      • Critical path
      • Parti
      • Typology
        • Gates
    • 🏠Blockout
      • Massing
        • Landscape
        • Composition
        • Prospect-refuge
      • Metrics
        • Modular kit design
        • Doom metrics
        • Quake metrics
      • Wayfinding
      • Playtesting
        • Player persona
    • πŸ“œScripting
      • (stub) Navigation
      • Doors
    • β˜€οΈLighting
      • Three point lighting
      • D6 lighting
      • Lighting for darkness
    • 🏑Environment Art
      • Shape and color psychology
      • Texturing
      • Storytelling
      • Optimization
    • 🌈Release
  • Book 2, Culture
    • 🦜Level design as culture
    • History of the level designer
    • Zero player level design
    • (unfinished pages)
      • History of architecture
      • Structural engineering primer
      • History of environment art
      • History of furniture
      • History of encounter design
  • Book 3, Studies
    • πŸ”How to study a level
    • Single player studies
      • Undead Burg (Dark Souls 1)
      • Assassins (Thief 1)
      • (STUB) The Cradle (Thief 3)
      • (STUB) Sapienza (Hitman)
      • (STUB) Silent Cartographer (Halo 1)
    • Multiplayer studies
      • Chill Out (Halo 1)
      • (STUB) de_dust2 (Counter-Strike)
    • Real world studies
      • Disneyland (California, USA)
      • (STUB) Las Vegas (Nevada, USA)
  • Book 4, Learning
    • πŸŽ’Notes for educators
    • Project plans
      • Classic Combat
      • (Unfinished WIP pages)
        • Modern Combat
        • Modern Stealth
        • Exercise: Direct Lighting
        • Exercise: Whiteboard 2D
        • Level Design Portfolio
        • Design Test: Adaptation
        • Exercise: Layout
        • Exercise: Verticality
  • Appendix
    • Tools
      • TrenchBroom
    • Assets & Resources
      • Recommended talks
      • Recommended books
      • Quake resources
        • How to package a Quake map/mod
      • File formats
        • FGD file format
        • MAP file format
        • MDL file format
    • Communities
    • About this book / authors
    • License / copyright
Powered by GitBook
On this page
  • History
  • Syntax (basic)
  • Entity types and settings (basic)
  • Entity properties (basic)
  • Display models for entities
  • FGD resources and links
  • FGD examples
  • FGD authoring
  • FGD parsers
Export as PDF
  1. Appendix
  2. Assets & Resources
  3. File formats

FGD file format

entity definition file / mapping aid for Quake-era level editors

PreviousFile formatsNextMAP file format

Last updated 1 year ago

FGD is a common text file format used across several Quake-era level editor tools (like ) to define entities.

An entity is basically any game object that isn't static world geometry -- NPCs, items, lights, sounds, doors, player spawns, etc. Anything that can move, change, or react.

Note that an FGD is just an editing aid that adds templates and documentation. It does not implement any in-engine game functionality by itself. It's only there to help level designers understand and configure objects. Technically you don't need an FGD to map for a game; in theory you could simply memorize and validate all the level scripting data manually.

For more about common game object types and behaviors, see .

This page assumes some familiarity with common Quake mapping terms.

History

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.

Because multiple studios, engines, and editor tools have used FGD, there are several different "flavors" of FGD. For example, Valve added syntax to support its unique entity input / output scripting system in Source Engine. There is no formal FGD file specification standard.

This page covers the core FGD syntax used in for Quake 1 / Half-Life engines.

Syntax (basic)

FGD is a text-based format. We recommend using UTF-8 encoding to support more languages. TrenchBroom requires UTF-8 without .

Each entity entry follows this pattern:

// comments begin with "//"
@EntityType EntitySettings() = EntityClassName : "In-Editor Help"
[
    propertyKey(propertyType) : "In-Editor Name" : defaultValue : "In-Editor Help"
]

Here's a simple entity example, a zombie NPC that is 32 map units wide and 64 map units tall, with one property called "Health":

@PointClass size(-16 -16 -32, 16 16 32) = monster_zombie : "A humanoid zombie with 100 health (default)."
[
    health(integer) : "Health" : 100 : "Initial health points. Set to -1 to make the zombie start sleeping."
]

Note how the in-editor help text is very important. Tell the level designer about important functionality that isn't obvious, give advice or tips / tricks.

Entity types and settings (basic)

There are three core FGD entity types: point, solid, and base.

  • @PointClass begins a point entity definition, like an NPC or a light

    • size(minX minY minZ, maxX maxY maxZ) is the axis-aligned bounding box (AABB) size of the point entity, defined as two 3D vectors, the min extent (smallest corner) and the max extent (largest corner)

  • @SolidClass begins a brush entity definition, like worldspawn or func_wall

  • @BaseClass begins an entity base template; you can set entities to "inherit" a common base.

    • base(BaseClassName1, BaseClassName2, ... ) set an entity to include the listed base class(es)... you can also set a base to include a base, so this feature can be quite powerful / useful but beware of recursion

For example, if all monsters in your game have health, then you could create a BaseClass Monster with a health property, and then set all monster types to include that Monster base:

@BaseClass = Monster
[
    health(integer) : "Health" : 100 : "Initial health as a percentage."
]

@PointClass base(Monster) size(-16 -16 -32, 16 16 32) = monster_zombie : "Humanoid zombie"
[
    // zombie will automatically inherit the health property from MonsterBase
]

@PointClass base(Monster) size(-32 -32 -64, 32 32 64) = monster_troll : "Big melee monster"
[
    // troll will automatically inherit the health property from MonsterBase
]

Entity properties (basic)

Entity properties are typed key-value pairs that follow this general pattern:

keyName(type) : "In-Editor Display Name" : defaultValue : "In-Editor Help"

  • Key name: like a variable name, usually a lower case string

    • sometimes with an underscore at the beginning to denote that it is a compiler-time property that won't be present in-game

    • in most level editors, an entity can only have a single flags property and it must be called "spawnflags"

  • Value: whatever the level designer typed into the level editor

An example brush entity definition that demonstrates all four property types:

@SolidClass = func_door : "A simple sliding door"
[
    // note that there is no defaultValue specified below; default is optional
    targetname(string): "Name" : : "Named doors won't open automatically. Leave blank to open automatically."
    
    speed(integer): "Move Speed" : 60 : "How fast the door opens / closes, in map units per second."
    
    _shadow(choices): "Cast Shadows" : 1 : "Should the door block light? default: On" =
    [
        0 : "Off"
        1 : "On"
        2 : "Two Sided"
        3 : "Shadows Only" 
    ]
    
    // in most level editors, flags type MUST be called "spawnflags"
    spawnflags(flags) =
    [
        1 : "Starts Locked" : 0
        2 : "Starts Open" : 0 
    ]
    // a flag follows this syntax:
    // PowerOfTwoNumber : "Flag Label" : DefaultBoolValue
]

Display models for entities

TrenchBroom can display 3D models for point entities, if the FGD file specifies it. This is useful for placing NPCs or props, where previewing model size / rotation / appearance is useful.

  • TB uses Asset Importer (AssImp) which has basic support for most 3D formats (.OBJ, .FBX, etc).

  • For certain model formats like Quake .MDL or Half-Life .MDL, you can also swap textures or preview animation frames based on the entity properties. See below for usage.

Remember: model() is TrenchBroom only, and won't necessarily work in other editors.

The most basic hardcoded usage looks like:

// this path depends on base Game Path in Game Configuration - https://trenchbroom.github.io/manual/latest/#game_configuration
// as well as the Mod Configuration - https://trenchbroom.github.io/manual/latest/#map-setup
model("path/to/model.file")
// "monster_ogre" inherits BaseClass "Monster", size 64x64x88, model path "progs/ogre.mdl"
@PointClass base(Monster) size(-32 -32 -24, 32 32 64) model("progs/ogre.mdl") = monster_ogre : "Ogre" []

However, hardcoding the model settings in the FGD can be too limiting for swappable "prop" entities or NPCs with multiple skins or scripted animation.

To support map-defined per-entity model display settings, TrenchBroom's can parse dynamic FGD placeholders with JSON-like syntax (curly braces, named parameters in quotes):

model({ "path" : MODEL, "skin" : SKIN, "frame": FRAME, "scale": SCALE })

Replace "MODEL" or "FRAME" etc. with the keyvalue property name you want, and TrenchBroom will swap in the actual value for the placeholder.

An example generic "prop" entity that uses placeholders:

@PointClass size(-16 -16 -16, 16 16 16) model({ "path": model }) = prop_static : "Static Prop" 
[
	model(String) : "Model file path" : : "Set this to a 3D model file."
]
// note: this is simplified from the actual FGD
@PointClass base(Monster) size(-16 -16 0, 16 16 72) model({ "path": "models/hgrunt.mdl", "frame": sequence }) = monster_human_grunt : "Human Grunt (camo)" 
[
	sequence(Choices) : "Animation Sequence (editor)" : 0 =
	[
		0 : "walk1"
		1 : "run"
		2 : "victorydance"
	]
]

TrenchBroom's FGD flavor also supports conditional expressions. An example with expressions:

// if entity property "big" is "true" then use a different model spec
model({{
    big == "1" -> { "path": "zombie_big.mdl", "skin": 0, "frame": 13, "scale": 2 },
                  { "path": "zombie.mdl" }
}})

FGD resources and links

FGD examples

FGD authoring

FGD parsers

model(path, skin, frame, scale) displays a 3D model for the entity. This can get a little complicated, see .

Type: there are four (4) basic property types: string, integer, choices (multiple choice integer ), and flags (bitmask).

flags are a set of boolean (true / false) values, stored together as a single number through the magic of math ()

An example of a basic hardcoded model from :

An example with placeholders from :

For more on placeholders and expressions, see

is a great introduction

shows off tips and tricks

goes into detail about Source Engine 1 specific FGD extensions and quirks... not useful for TrenchBroom though

C++ FGD parser example:

C# FGD parser library:

TrenchBroom
Scripting
TrenchBroom
BOM
enumeration
bitmask
Quake.FGD
HalfLife.FGD
Trenchbroom Manual > "Display models for entities":
TrenchBroom default built-in FGDs (via GitHub)
Valve Developer Union: "Anatomy of an FGD (and How to Write Your Own)"
Valve Developer Union: "Advanced FGD Editing Made Easy"
Valve Developer Community: "FGD"
TrenchBroom (via GitHub)
Sledge.Formats (via GitHub)
Display models for entities
LogoTrenchBroom 2023.1 Reference Manual