BioWare Atari
BioWare Info BioWare Games Support Forums Visit the BioWare Store
Neverwinter Nights Home
Neverwinter Nights Home

2. File Format Conceptual Overview

[Printer Friendly]

2.1. General Description

A GFF file represents a collection of data. C programmers can think of this collection as a struct. Pascal programmers can think of it as a record. Each item (properly called a Field) of data has: a text Label, a data type, and a value. C programmers can think of Fields as member variables in a C struct.

The labelling of Fields is the key to GFF being able to maintain backward and forward compatibility between different file formats.

The above concepts are best illustrated by an example.

Example of GFF usage

Let us use a simplified example of a Waypoint object. A Waypoint has a Tag that is used for scripting purposes, and it has a location. In C++ code, a Waypoint might be defined as follows:




class TWaypoint

{

  TString m_sTag;

  float m_fPositionX;

  float m_fPositionY;

  float m_fPositionZ;

};



(Notes: In the above declaration, we have purposefully omitted member function declarations because they are irrelevant to this example. Also, assume that a string class called TString has already been defined)

Suppose we have an instance of a Waypoint tagged "ShopEntrance", located at (3.2, 5.7, 0.0) in some Area.

When saved to GFF, it would "look" like this:


"Tag"        string  "ShopEntrance"

"PositionX"  float   3.200

"PositionY"  float   5.700

"PositionZ"  float   0.000

Now suppose we decide to add a MapNote property, which is a string that appears when the player mouses over a Waypoint in the game's minimap, and a HasMapNote property to specify whether the Waypoint appears on the minimap in the first place. The C++ declaration for the Waypoint object might now be:


class TWaypoint

{

  TString m_sTag;



  bool m_bHasMapNote;      // this was added

  TString m_sMapNoteText;  // this was added



  float m_fPositionX;

  float m_fPositionY;

  float m_fPositionZ;

};

If we try to load our old Waypoint instance from before, the program would still correctly load the Tag and X, Y, Z coordinates because it reads them from the GFF file by finding their Labels and reading the associated data. The fact that we just inserted some extra data inbetween the Tag and coordinates is inconsequential. Reading Fields from a GFF file does not depend at all on the physical position of Fields' bytes relative to each other within the file.

In this example, it is a simple matter from a programming perspective to notice that the old Waypoint instance does not have a MapNoteText or HasMapNote property stored on it in the GFF file. On seeing this, it is equally simple to set default values for those properties if their GFF Fields were not found.

2.2. Field Data Types

Allowed GFF Field types are listed in the table below.

Table 2.2a: Field Type Descriptions

Field Type Size (in bytes) Description
BYTE 1 Unsigned single byte (0 to 255)
CExoLocString variable Localized string. Contains a StringRef DWORD, and a number of CExoStrings, each having their own language ID.
CExoString variable Non-localized string
CHAR 1 Single character byte
CResRef 16 Filename of a game resource. Max length is 16 characters. Unused characters are nulls.
DOUBLE 8 Double-precision floating point value
DWORD 4 Unsigned integer (0 to 4294967296)
DWORD64 8 Unsigned integer (0 to roughly 18E18)
FLOAT 4 Floating point value
INT 4 Signed integer (-2147483648 to 2147483647)
INT64 8 Signed integer (roughly -9E18 to +9E18)
SHORT 2 Signed integer (-32768 to 32767)
VOID variable Variable-length arbitrary data
WORD 2 Unsigned integer value (0 to 65535)
Struct variable A complex data type that can contain any number of any of the other data types, including other Structs.
List variable A list of Structs.

A few of these data types merit additional explanation.

Void data

The Void type is used to store a stream of raw bytes as a single item of data under a single label. Possible applications include storage of raw image or sound data. It is never a good idea to use the void type to directly dump a data structure (such as a user-defined C struct) from memory to disk. The other primitive data types should be used to store each structure element instead.

CExoString

The CExoString type is a simple character string.

The suggested maximum allowed length is 1024 characters, which is a limit defined primarily to conserve network bandwidth in the case of strings that need to be passed from server to game client.

CExoStrings are generally not used for text that the player might see, since it would be the same text regardless of the player's native language. Instead, CExoStrings are used largely for developer/designer-only text, such as Tags used in scripting.

CExoLocString

A CExoLocString is a string type used to store text that may appear to the user and has a number of features designed to allow users to see text in their own language.

1) StringRef: A CExoLocString always contains at least a single integer called a StringRef (or StrRef). A StrRef is an index into the user's dialog.tlk file, which contains text that has been localized for the user's language.

2) Embedded Strings with Language IDs: If the StrRef is -1, then dialog.tlk is not used, and instead, the localized text must be embedded within the CExoLocString. A CExoLocString may contain zero or more normal strings, each paired with a language ID that identifies what language the string should be displayed for.

In the presence of both embedded strings and a valid StringRef, the behaviour is up to the application. In the toolset, embedded strings take precedence, assuming that there is an embedded string for the user's language. As with CExoStrings, embedded strings in CExoLocStrings should be no more than 1024 characters.

The following is a list of languages and their IDs:

Table 2.2b: Language IDs for LocStrings

Language ID
English 0
French 1
German 2
Italian 3
Spanish 4
Polish 5
Korean 128
Chinese Traditional 129
Chinese Simplified 130
Japanese 131

3) Gender: In addition to specifying a string by Language ID, substrings in a LocString have a gender associated with them. 0 = neutral or masculine; 1 = feminine. In some languages, the text that should appear would vary depending on the gender of the player, and this flag allows the application to choose an appropriate string.

The Struct Data Type

In addition to the primitive data types listed above, GFF has a compound data type called a Struct. A Struct can contain any number of data Fields. Each Field can be any one of the above listed Field types, including a Struct or List.

Regardless of what Fields are packed into a Struct, there is always a single integer value associated with the Struct, which is the Struct ID. This ID is defined by the programmer who is writing out GFF data, and can be used to identify a Struct without having to check what Fields it contains. In many cases, though, the programmer already knows--or can assume--the Struct structure simply by the context in which the Struct was found, in which case the ID is unimportant.

Every GFF file contains at least one Struct at the top level of the file, containing all the other data in the file. The Top-Level Struct does not have a Label. The Top-Level Struct has a Struct ID of 0xFFFFFFFF in hex.

The List Data Type

A List is simply a list of Structs. Like all GFF Fields, a List has a Label.

Structs that are elements of a List do not have Labels.

2.3. Field Labels

Every Field has a Label, a text string that identifies it. This Label can have up to 16 characters.

When a program writes out a structure in memory to disk as a GFF file, each field in that memory structure is written out using the most appropriate GFF Field data type, and with a GFF Label associated with it.

It is this labelling of data elements that makes GFF useful for storing data structures that are subject to change. When new information is added to a data structure, old GFF files can still be read because the old data is fetched by Label rather than by offset. That is, no assumptions are made as to where one variable is relative to another in the file.

Go to Page (Previous Page - Index, 2, 3, 4 - Next Page)

 

 

Dragon Age: Origins Preorder
Neverwinter Nights 2 Forums
Hide/Show

English
Deutsch
Français
Español
Italiano

Hide/Show

View Latest Screenshots 

View Latest Screenshots
Hide/Show

Multiplayer Games at Neverwinter Connections

Today
Schedule a Game...



Current time is: (set time)
Sat, 07 November 2009 11:51PM

Hide/Show

Buy Premium Modules

Top NWN: HotU Modules:
1. Good vs Evil III
2. More...

Top NWN: SoU Modules:
1. Good vs Evil III
2. More...

Top CEP Modules:
1. The Lord of Terror The Diablo Campa...
2. More...

Top Modules - NWVault:
1. Hall of Fame
2. More...

Total Modules: 4423

Hide/Show

4,824,091 BioWare Users:
  230 Logged In
  14 Hidden
  1416 Guests

1491 Playing Online
  100% NWN
  100% NWN: SoU
  100% NWN: HotU

446 Registered Guilds

8,714,534 posts in forums

Newest Forum Topics:
1. On various Dexterity issues (Dragon Age: Origins General Discussion)

2. You play Mass Effect way too muc... (Mass Effect 2 General Discussion (No Spoilers Allowed))

3. DA Lower FPS (Dragon Age: Origins Technical Assistance (Self Help))

4. Dual Wield Rogues (Dragon Age: Origins General Discussion)

5. Cinematics: Sound effects are of... (Dragon Age: Origins Technical Assistance (Self Help))