FGD files tell Hammer what entities exist in the engine, and what keyvalues, inputs, outputs, and flags they have. If information for an entity is missing from an FGD, it can be manually added through Hammer without it. FGD info is not required in order to use anything, but it does help make the process of mapping much more simple. See below for info on adding new FGD info.
To add a non-FGD entity, simply type its full name into the classname box, like you would with any other entity. Point entities will show the "obsolete" sprite. Because the entity is not in the FGD, Hammer will not show any keyvalues, inputs, outputs, or flags associated with the entity either.
To add a missing keyvalue, click the SmartEdit button to turn it off. Any keyvalue names should now look less descriptive. Values may also look different. The right section for editing a keyvalue will also look different.
Click Add to add a new keyvalue. In the key field, add the name of the keyvalue. The name should be the one used by the engine, not Hammer (for example, Response Contexts would be ResponseContext). The page that linked you here probably said what the name is, that you want to insert. The value field should be self-explanatory.
Click Delete to delete a keyvalue from Hammer's view.
If you are using 3ds Max and Wall Worm for your level editor, you can add keyvalues by selecting any WallWormMDL node and clicking the KeyValues button in the Wall Worm Connection rollout of the Modify Tab. This will add a Keyvalues rollout to add values not available in an entity.
Inputs and Outputs
Inputs and outputs can be added similarly to entities; simply type the name of the input or output into the appropriate box, as if it were recognized. Hammer will show the text in red because it's not in the FGD. The engine will still recognize the input/output, as long as the entity is capable of sending/receiving it, and the spelling is correct. Remember that the capitalization matters!
Flags are kind of strange. To add non-FGD flags, use the steps above to add a keyvalue called
spawnflags. The value of this should be the sum of every number associated with the flags you want. The associated numbers are listed on entity pages.
For example, if you have a
trigger_multiple that should have both Pushables (4) and Physics Objects (8) set,
spawnflags should be 12. In the rare case an entity page does not list the numbers associated, check the cpp or h file for the entity.
All entity flags are consolidated like this into a single
spawnflags keyvalue. This keyvalue is normally hidden when SmartEdit is enabled but may appear in red if a bug occurs. The reason flags are done like this is because compressing all these boolean values into a single integer saves a significant amount of memory. The numbers used by flags are all unique powers of 2, which means two combinations will never add up to the same number.
New FGD Entries
Pages for entities not in FGDs often will have code to add them into the FGD. If they do not, here's how to do it yourself. All of this information should be put into an FGD file in your game's
bin/ folder (the same folder Hammer.exe is in). You can put the new information into a new FGD or an existing one. A new FGD must be added through the Tools, Options menu in Hammer, or through
@include "newfilename.fgd" in an existing FGD that is used by Hammer.
The first part of defining an entity is the SearchKey. SearchKeys can do a few different things for entities.
@PointClass- For point entities.
@NPCClass- For NPCs.
@SolidClass- For brush entities.
path_trackand similar entities.
@FilterClass- For filter entities.
base() parameter lets you add BaseClasses to an FGD entry. More info about those is below. There are many other parameters that can be defined. See FGD for a full list.
The next part after all parameters is an
= sign, followed by the entity classname, then a
: and an entity description inside
@PointClass base(BaseEntityHL2only,BaseAnimatingHL2Only) = blob_element : "A blob particle usually created through npc_blob." [ ]
- The BaseClasses are custom ones (discussed below).
]are required. Between them is where we will define any keyvalues, inputs, outputs, or flags unique to this entity.
First, put the non-SmartEdit name of the keyvalue (discussed above), followed by what the value should be (integer, targetname, string etc). If you're unsure what to put, check an entry for a similar keyvalue. The type should go in
To do: There's a list somewhere of every available type...
The next part is a
:, and then the SmartEdit name of the keyvalue inside
: and specify a default value for this keyvalue. If there should not be a default, just put a space and move to the next part.
: and then a description of the keyvalue in
". This is the text that will appear in the Help box.
choices is a special type of keyvalue that is used for drop-down menus. It works a little different than other keyvalues. Below are examples of keyvalue entries:
something2(choices) : "second number" : 0 : "Your choice of numbers!" = [ 0 : "Default" 1 : "Something" 2 : "Another Thing" ]
foobarname(string) : "Name" : : "Name of foobar"
Default. When the entity is placed in Hammer, it will automatically make
Squad1 the value for
foobargroup(string) : "Group" : "Squad1" : "Name of foobar group"
Inputs and Outputs
First, put the word
output, followed by the name of the input or output.
Similar to keyvalues, put the type of parameter the input accepts in
). For outputs, put the type of parameter that they send to the parameter box (if not overridden by the mapper). (Outputs that generate parameters are a very rarely used thing. Most do not send parameters to the parameter box.)
If no parameters are involved, put
Follow with a
:, and a description of the input/output in
output OnSomethingHappened(void) : "Fires when something happens"
output OnLeaveQueue(targetname_destination) : "Fires when an NPC leaves the queue. Parameter is the NPC that left."
input DoSomething(void) : "Do something"
Defining flags is similar to a choices keyvalue. Start with
spawnflags(flags) =. The flags should be inside
First put the power of 2 associated with the flag (discussed above), then a
:, then the name of the flag as it should appear in Hammer. Follow this with another
: and then a
1 for if the flag should start off or on.
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 ]
BaseClasses are a special kind of SearchKey. These are essentially templates for entity info. These allow for FGDs to be significantly less tedious to create and modify.
Here is a (trimmed) example BaseClass for the entity defined above:
@BaseClass = BaseEntityHL2Only [ targetname(target_source) : "Name" : : "The name that other entities refer to this entity by." parentname(target_destination) : "Parent" : : "The name of this entity's parent in the movement hierarchy. Entities with parents move with their parent." input Kill(void) : "Removes this entity from the world." input SetParent(string) : "Changes the entity's parent in the movement hierarchy." input AddOutput(string) : "Adds an entity I/O connection to this entity. Format: <output name> <targetname>:<inputname>:<parameter>:<delay>:<max times to fire (-1 == infinite)>. Very dangerous, use with care." input FireUser1(void) : "Causes this entity's OnUser1 output to be fired." input FireUser2(void) : "Causes this entity's OnUser2 output to be fired." input FireUser3(void) : "Causes this entity's OnUser3 output to be fired." input FireUser4(void) : "Causes this entity's OnUser4 output to be fired." input Use(void) : "Same as a player invoking +use; may not do anything. Can also be invoked by creating an output that does not specify an input." output OnUser1(void) : "Fired in response to FireUser1 input." output OnUser2(void) : "Fired in response to FireUser2 input." output OnUser3(void) : "Fired in response to FireUser3 input." output OnUser4(void) : "Fired in response to FireUser4 input." ]
A BaseClass can include flags as well. All that needs to be done to include this info for an entity is to put the name of the BaseClass in the base parameter.