FGD stands for Forge Game Data. It is the file extension for Hammer's game definition files. They define all of the entities of a game so mappers can select them from within the editor. It is a key point to understand that an FGD is nothing more than a reference. You cannot create or modify entities by editing a FGD, you merely give Hammer different information about what it expects to find within the game. Sometimes editing reveals hidden or unused features or even entities, but they were always there and could be used even without the updated FGD. For Custom FGD files to work in hammer, they must be added through tools > options.
While Hammer was originally called Worldcraft, it was developed under the name The Forge (hence the name Forge Game Data). However, due to trademark issues, the name Forge couldn't be used for the final version of Hammer. Still, the file extension stayed.
The FGD file follows a fairly simple format. It is a script file that sets up entity structures and relationships for Hammer. The various parts of the Half-Life 2 FGD (found in your SDK binary directory, for example:
(path_to_steam)/SteamApps/SteamUsername/sourcesdk/bin/orangebox/bin) are explained below.
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======= // // Purpose: Half-Life 2 game definition file (.fgd) // //=============================================================================
Comments are defined simply by starting a line with //. They can be preceded by spaces or tabs.
If the game you are writing your FGD for has a lot in common with another game (Half-Life 2 and Counter-Strike: Source, for example), you can include a file that has all of the common structures defined in it. The FGDs for Half-Life 2 and Counter-Strike: Source both include the base.fgd file, and the FGD for Half-Life 2 Deathmatch includes the halflife2.fgd file.
@BaseClass base(BaseNPC) = TalkNPC [ UseSentence(string) : "Use Sentence" UnUseSentence(string) : "Un-Use Sentence" ]
A BaseClass is used to setup structures that are used by several different entities. They are referenced in an entity structure by adding base(BaseClassName) to the main definition line of the structure. The BaseClass structure is defined just like a normal entity, in all respects. The only difference is that it doesn't appear in the entity lists in Hammer. (We'll discuss the complete entity structure below).
@PointClass base(Targetname, Origin) studio("path/model.mdl") = example_entity : "example" [ spawnflags(flags) = [ 32 : "A flag" : 0 // 0 means the flag is not-ticked by default 64 : "Another flag" : 1 // 1 means the flag is ticked by default ] foobarname(string) : "Name" : : "Name of foobar" foobargroup(string) : "Group" : "Squad1" : "Name of foobar group" foo(float) "Floating point number" : "100.7" : "Decimal points = fun" something(integer) readonly: "first number" : 0 : "This is a number which can't be manually edited" something2(choices) : "second number" : 0 : "Your choice of numbers!" = [ 0 : "Default" 1 : "Something" 2 : "Another Thing" ] // Outputs output OnSomethingHappened(void) : "Fires when something happens" output OnSomethingElse(void) : "Fires when something else happens" // Inputs input DoSomething(void) : "Do something" ]
Above is a generic example of an entity structure as defined in the FGD. Let's break it down bit by bit, starting with the first line:
- @PointClass - The class type of an entity tells Hammer how this entity can be placed.
- @PointClass - This entity exists at a certain non-arbitrary point. It is typically referred to as a "point entity". The entities are placed within Hammer by using the Entity tool (Shift+E).
- @NPCClass - This is a special form of point entity tailored for NPC (non-player character) entities. It is useful in conjunction with the npcclass property type, below.
- @SolidClass - This entity's area is defined by the solid (also referred to as a brush) that it is attached to. It is typically referred to as a "brush entity" or "solid entity".
- @KeyFrameClass - Used for move_rope and keyframe_rope. This causes the NextKey property to be linked up when the entity is copied.
- @MoveClass - Used for path_track and similar entities. This causes the target property to be linked up when the entity is copied.
- @FilterClass - One of the special filter classes used to define what entities will be able to interact with another in some way. This mainly causes the entity to be shown in properties with the filterclass type.
- base(Targetname, Origin) - Things between the type declaration and the "=" character help to define properties of the entity and how it will act and be displayed in Hammer. There are a number of different things that can used here. (More than one of these can be used, each separated by a space.)
- base( BaseClass1, BaseClass2, ... ) - This lets you attach previously defined BaseClasses (see above) to an entity. You can specify multiple BaseClasses, separated by a comma.
- color( rrr ggg bbb ) This setting will change the color of the wireframe box in the Hammer 2D views. If this isn't present, the color will default to magenta. The values specified here are the RGB values of a color, and each number has a range from 0 to 255.
- iconsprite( "path/sprite.vmt"" ) - If this is used, the specified sprite will be shown in the Hammer 3D view instead of a flat-shaded colored box. This will work along-side the studio() or studioprop() commands.
- sphere( propertyname ) - If an entity has a radius of effect, like a sound for example, a sphere will be displayed in Hammer's 2D and 3D views. You need to specify the property that will control the sphere size. If no property is specified, it will look for a radius property. Multiple spheres can be defined for one entity.
- studioprop( "path/model.mdl" ) - If this is used, the entity will be displayed in the 3D view as the specified model. If no model is specified, the value of the entity's "model" property will be used, if available. Multiple models can be defined.If you have an entity with the "angles" property that you want to be able to rotate in Hammer using the mouse (as opposed to only through property editing) you may need to add this modifier.The appearance is affected by the skin and rendercolor properties, similar to prop_dynamic.
- studio( "path/model.mdl" ) - Similar to studioprop(), but the bounding box around the entity will ignore this model. This is useful for models visible only in Hammer.
- line( 255 255 255, property1, property2 ) - Draws a line between two entities specified by the two properties. The first color value appears non-functional.
- frustum( fov,near,far,color,-1 ) - Creates a rectangular cone extending from the entity. FOV defines the spread angle (0-180). Near and far define at what distances will be highlighted. The color value defines what color the cone will be shown with. All values can either be literals, or property names.
- size( -x,-y,-z,+x,+y,+z ) - Defines the size of the default cube used when no model or sprite is specified.
- example_entity : "example" - This is the entity's name followed by a description. The description is displayed in Hammer when you click on the Help button inside the entity property dialog. For visual ease, the description can span multiple lines by joining "blocks of text" with the plus (+) character. For example:
@PointClass = example_entity :
- "This is an example description for"+
- "this example entity. It will appear"+
- " in the help dialog for this entity"
- entity properties go here
- entity properties - Everything between the main set of [ / ] brackets is used to define the entity's properties, including their inputs and outputs. Individual property structures consist of a name, a type declaration, a short description, a default value, and a long description. The most common properties are:
- string - This creates a property of the string type.
- name(string) : "Short description" : "Default" : "Long description"
- integer - This creates a property of the integer type.
- name(integer) : "Short description" : 1 : "Long description"
- float - This creates a property of the float type. Although it deals with numbers, the structure of it is similar to the string type. The default value must have quotes around it.
- name(float) : "Short description" : "1.5" : "Long description"
- There are also two common special case property types, choices and flags, that follow a slightly different format.
- choices - A property of this type lets you setup a number of distinct choices. Their format is similar to the other types:
name(choices) : "Short description" : "1" =
- 0 : "something"
- 1 : "something else (default)"
- 2 : "something completely different"
- You can also use strings (or floats) as values, instead of integers, like this:
name(choices) : "Short description" : "models/something02.mdl" =
- "models/something01.mdl" : "something"
- "models/something02.mdl" : "something else (default)"
- "models/something03.mdl" : "something completely different"
- flags - The flags property type lets you setup what will appear in the Flags portion of the entity property dialog. It is setup similar to the choices property type. The flags are all powers of 2 - 20, 21, 22, etc, and their values are either 0 (off) or 1 (on). If no default is specified for a flag, it is considered to be off.
- 1 : "something clever" : 1
- 2 : "something else" : 0
- 4 : "you said what now?" : 0
- 8 : "nothing" : 1
- Note that spawnflags is always the name of this property.
- There are also a number of special purpose property types that modify the entity properties dialog UI to allow for easy browsing for files or easier manipulation of complex properties (like colors or angles).
- axis - adds a relative 2 point axis helper
- angle - adds an angle widget for this property to the entity dialog UI.
- color255 - adds a button that brings up the color choosing UI, which takes the color you select and translated it into the three number RGB value. Allows extra parameters (i.e. brightness)
- color1 - adds a color button, but uses a float [0,1] to represent RGB. Allows extra parameters (i.e. brightness)
- filterclass - marks property as being the name of the filter to use
- material - adds a button that brings up the material browser.
- node_dest - adds an eyedropper to select a node in the 3d view
- npcclass - adds a drop-down selection list populated by entities of the NPCClass type.
- origin - origin
- pointentityclass - adds a drop-down selection list populated by entities of the PointClass type.
- scene - adds a button that brings up the file browser, letting you browse for scene files.
- sidelist - adds a side selection eyedropper that allows you to choose sides (multiple with ctrl).
- sound - adds a button that brings up the file browser, letting you browse for sound files.
- sprite - adds a button that brings up the file browser, letting you browse for sprite files. It is advised that you use the material datatype instead; it has the same functionality, but it uses the material browser.
- studio - adds a button that brings up the file browser, letting you browse for model files.
- target_destination - marks property as another entity's targetname.
- target_name_or_class - marks property as another entity's targetname or classname.
- target_source - marks property as being the name that other entities may target.
- vecline - adds an absolute 1 point axis helper, similar to the origin marker.
- vector - 3d vector
Other file sections
Material Exclusion Lists
It seems these lists define paths that Hammer's Material Browser will not use when presenting you with a palette of textures to choose from. It should have no effect on what files are actually available to a custom map.
@MaterialExclusion [ // Names of the sub-directories we don't want to load materials from "debug" "engine" "hud" "vgui" ]
This permits customizing the automatic Visgroups tab of the Filter Control toolbar. The first title is the name of the 'parent', and the next is the 'children'. Finally comes a list of entity classes that will be placed in the visgroup. If the parent already exists, the new entry will be merged with the previous (including the default list of groups). This permits creating trees with multiple levels of grouping. If a visgroup becomes entirely empty, it will not appear in the list.
@AutoVisGroup = "Parent" [ "Child 1" [ "entity name 1" "entity name 2" ] "Child 2" [ "entity name 3" "entity name 4" ] ]
@AutoVisGroup = "Brushes" [ "Triggers" [ "trigger_once" "trigger_multiple" ] "Tool Brushes" [ "func_areaportal" "func_viscluster" ] ] @AutoVisGroup = "Tool Brushes" [ "Vis Clusters" [ "func_viscluster" ] ]