Official GDF Scripting Documentation
Script Version 1.0

By: Joe Riedel
Email: jmriedel@planetquake.com
Tread URL: www.planetquake.com/tread

Copyright © 1999 Prospect Vector

 
What is GDF Scripting?

GDF scripting stands for Game Definition File scripting. GDF is the name of the language used to define entities and other information about a game, allowing Tread to create the proper files needed to build and run maps for that specific game.

An Intro to Entities

Games based on Quake technology and its derivatives use essentially two different things. Textures (the graphics and images used to paint walls) and entities. Entities are objects that have an x, y, z location in 3D space, and have specific attributes that describe what they are and characteristics of their behavior.

These attributes are called keys, and they are the building blocks of entities. An entity has a location in space, and one or more keys that describe it. The game engine uses these keys and location information to place objects of that entity type. 

How Tread works with entities

To Tread, entities are things with a position and a list of keys. Tread could require someone to place an entity and fill in every key for that specific entity. However, that would defeat one of Treads major design goals: ease of use. Tread allows users to pick entities by a list of intelligent names and place those entities in space. When Tread creates an entity in a map it is given default keys and values for those keys. It also allows the user to visually edit the keys of each entity. 

The question becomes “What default keys and values does Tread give entities?” 
Tread could give each entity the same keys and values, but that becomes essentially useless when you deal with a wide range of entities as in Quake2 and Half Life.

Welcome to GDF Scripting

To solve this problem, Tread employs a custom scripting language previously introduced as GDF. The GDF language describes each entity, it’s keys and values, along with other information needed to allow Tread to easily support many different types of entities and edit them.

Why GDF?

Besides the obvious reasons of showing off our great talent, GDF was created to allow custom MODs to all the games it supports. And it made it a lot easier for us to create the scripts for all the games Tread supports rather than code the stupid things in C++.

Screw all this talk, let’s code some stuff.

Okay, at this point I hope you understand what’s going on, otherwise you’ll never get through the next sections.

Multiple Game Support

Tread supports multiple games. To accommodate this feature GDF has a few things that describe the different attributes of each game. Each GDF script file is capable of describing more than one game, although we strongly recommend that you don’t do that. Things will get messy fast if you do.

Scripts Away

Due to the fact that each file is capable of describing more than one game, GDF requires an opening block that defines the names of each game you plan to script. You cannot use a game in the script if its name has not been declared. The first and foremost statement in the script should be a $DefNames block.

Syntax: $DefNames [ “GAME” ]

Although not required to be next, usually the following block is called a $DefGlobal block. The $DefGlobal block defines global information about a game. Here is an example written by our good friend we call V:

// Defines global info for Quake
$DefGlobal [ "Quake" ]
{
	def_solid  : "func_door"
	def_point  : "info_player_start"
	palette    : "quake.pal"
	def_gft    : "QUAKE_MAP"
	def_pakdir : "id1"
}

First we define what game we are going to define in the global block. In this case it is Quake. Let’s go line by line and explain each:

	def_solid  : "func_door"

This line tells Tread the default solid entity to create. This is used, for example, when you link brushes to an entity. In this case when editing a map for Quake, Tread will automatically create a func_door entity when linking brushes.

	def_point  : "info_player_start"

This tells Tread the default point entity to create. When you first start Tread and go to make an entity it will default to making an info_player_start in this case.

 	palette    : "quake.pal"

The palette descriptor tells Tread the default palette to use. If a texture package does not contain a palette that Tread can find, all the textures in the package use the default palette specified here.

	def_gft    : "QUAKE_MAP"

This line tells Tread the Game File Type. When Tread exports the .MAP file for a map, it determines the format based on this descriptor. This descriptor also tells Tread what module to use to run the map file. This is important. If it’s a Quake map it will run the Quake game builder programs to build the level. Valid values for this descriptor are QUAKE_MAP, QUAKE2_MAP, or HEXEN2_MAP.

	def_pakdir : "id1"

This descriptor defines information that Tread uses to assign texture packages to games. This should point to the sub directory were the textures are stored for the game. This sub directory should be the directory of the textures minus the game directory. In this case we have “id1”. Let’s walk through an example of this.

Let’s assume we have Quake in C:\GAMES\QUAKE.

The Quake.wad file for this game should be in the C:\GAMES\QUAKE\ID1 directory. We should tell Tread that the game directory is C:\GAMES\QUAKE in the setup dialog.

Simply subtract the two.

C:\GAMES\QUAKE\ID1 – C:\GAMES\QUAKE leaves us with ID1.

Since the Quake game is defined with a pak directory of ID1, Tread assigns all packages that have that result to the Quake game. They will not show up anywhere else.

Tread also allows GLOBAL textures. If a texture package could not be assigned to a game, it is always visible.

Worldspawn Keys & Contents/Surfaces Flags:

The $DefGlobal block also defines keys that define the global world. In the case of Quake based games they are keys added to the worldspawn entity. You can insert anything valid in a $DefEntity in here. They will all effect the global worldspawn entity.

Contents/Surface flags are defined using $DefFlags. $DefFlags define switchable flags. These flags can each be turned off and on. The values of the flags ored or anded into/out of the final value of the key.

To define surface or contents flags Tread reserves special namespaces for each: CONTENTS_77X and SURFACE_77X. When defined in the $DefGlobal block they will define the flags that can be applied to faces.

$DefEnt

The $DefEnt block defines an entity. Here’s the basic syntax:

$DefEnt [ "CLASSNAME" : "SMARTNAME" (: @VIRTUAL) ] : [ "BASE_CLASS" ] : [ "GAME" ]
{
	keys…
}

CLASSNAME: The classname of the entity. This MUST always be a valid string. This is written out to a .map file as the classname key.

SMARTNAME: The name displayed to the user.

@VIRTUAL: Specifies that the class is purely virtual. It will never show up in a list of valid entities. GDF supports class inheritance, as will be discussed in the next line. If the class is purely virtual, then the smart name MUST be NULL.

BASE_CLASS: The base class of this class. If a base class is defined then this class inherits all the keys and attributes of the base class. If there is no base class for this class, there should be [] in place. For example, here is an entity with no base class:

$DefEnt [ “MyAss” : “Joe’s Ass” ] : [] : [ “Quake2” ] {}

GAME: The name of the game(s) the entity is defined in. This can be a colon delimited list i.e. [ “QUAKE” : “QUAKE2” : “QUAKE3” ].

In between the opening and closing braces can be any number of def_att, def_key, $DefFlags, or $DefOptions blocks. I will discuss these next.

def_att : “name” : “value”

The def_att defines an “attribute” of an entity. Attributes are things that govern the way Tread deals with entities. They govern how they are drawn, and they govern how Tread allows users to use the entities. There are currently only two attributes you can define: size, and owner.

The size attribute tells Tread the size to draw the entity. It should be in the form “X Y Z”, as follows:

def_att : “size” : “32 32 32”

The owner attribute tells Tread a very important piece of info: whether the entity can own brushes. If it can, then Tread only displays the entity in the link dialog. An entity that can own brushes is called a solid entity. An entity that cannot own brushes is called a point entity. The way point entities are created vs. the way solid entities are created differ greatly.

Switching into entity mode, and clicking to drop entities of the selected class type creates point entities.

Right clicking on a group of brushes and selecting “link to entity” creates solid entities.

def_att : “owner” : true/false

def_key : type : “name” : “smartname” : “value”

Defines a key. A key can have the following types: string, integer, vector, color. These types do not effect the resulting key written to the map file. In a map, all keys consist of two string, a name and a value. Instead these types tell Tread how to assist in editing the keys. 

String: Allows the user to enter the key into an edit box. No input is restricted.

Integer: Allows the user to enter only numbers as the key value.

Vector: The key is a Q/Q2 direction. That is 0-360 specifies an X/Y angle, -1 is straight up and 1 is straight down. Or maybe that’s backwards, I forget, but you get the idea. Tread presents the user with a moveable angle dialog.

Color: The value is assumed to be a R G B value with each component being 0-1 for lowest/fullest intensity respectively.  Tread presents the user with the standard windows color picker to choose the color.

NAME: Defines the keyname.
SMARTNAME: The name the user sees.
VALUE: The default value the key is given. If no default value is desired “” (empty quotes) should be used.

$DefOptions/$DefFlags

The blocks define a key with specific predefined values. These values can be either bit flag combinations, or the key can have just one value out of a set of predefined values.

The $DefOptions and $DefFlags blocks are exactly the same syntactically. However, they present the user with different things. If a $DefOptions is used, the user can select a single key value out of a drop-down list. If a $DefFlags block is used, then the user can toggle each key bit in the value.

I will use $DefFlags for the examples. 

$DefFlags [ “NAME” : “SMARTNAME” ]
{
	def_flg…
}

NAME: The name of the key.
SMARTNAME: The name presented to the user.

def_flg : “NAME” : NUMMERIC-VALUE : true/false

Used in both options and flags blocks.

NAME: The name displayed to the user.
NUMERIC-VALUE: The value of this flag. If in an options block, the key will become this value if this is chosen. If in a flags block, the bits in this value will be set on/off.
TRUE/FALSE: This is the default value of the flag. If in an options block, the first one set true will be the default value of the key. If in a flags block, the bits in the number will be set adding to the default value of the key.

@FORCE-DERIVATION

The @FORCE-DERIVATION symbol can be put in the place of any value parameter in a def_att or def_key clause. Doing this forces any derrived class to re-define the key or attribute.

Automatic Script Upgrading: Entity Rekeying

Tread does an automatic update to maps we call entity re-keying. We found this useful, and we assume it will eventually become useful to the community. Essentially as entities are loaded each key is checked for a corresponding key in the definition. If there is no key for that entity class in the definition the key is removed. Any keys not in the entity that are in the definition are then added to the entity with the default values. If the entity class does not have a definition it is discarded.

What this allows for is for keys to be added/removed or changed, and to have maps be automatically migrated to the new script. This means you don’t have to delete and re-add a zillion entities if a single key changes types or names.

Wrapping it up

That covers this version of the GDF scripting language. The language is changing slightly and some new key types are being added to accommodate Half-Life. This should not effect scripts written now.

Thanks for using Tread, and keep Quakin’. Now, go forth and script!

Joe Riedel