OBD:Data types

From OniGalore
Unfinished building-60px.jpg

This page is unfinished. Can you fill in any missing information?
If it is not clear which part of the page is unfinished, ask on the talk page.

Click to return to the main OBD page.

Following are the formats used for the various data fields in Oni's resource types.

Resource links

Links between resources are very common in the data and take four forms.

Links by index number

Probably the most common form of inter-resource linking is to store the index number of the connected resource in a 32-bit int. "Index number" is defined as the position of the resource in the instance descriptor table. These index numbers were left-shifted by 8 bits in memory in order to leave room for a bit that could be set at runtime indicating the resource had been loaded. Even though this bit had no relevance when the data was stored on disk, the ints were written to disk as-is. See here for elaboration, or see OBD:ONCC § Body settings for several examples.

Links by name

Many fields store the name of the connected resource as a string which is then looked up at runtime when needed or upon level-load. Search OBD:ONCC for the word "reference" to find several examples.

Links by ID

Not to be confused with links by index number (even though we sometimes call that the instance ID). Various systems have their own set of ID numbers: vocalizations, melee profiles, combat behavior profiles, etc. These are not generally links to level file resources but rather lookups to hardcoded tables.

Raw/separate file offsets

These are 32-bit ints telling the engine how far to index into the raw or separate file to find some data which is part of an instance. As long as the file never exceeds 4 GB then there can't be any issues with using a 32-bit offset. Note the differences in raw/separate utilization between engine versions.

Strings

Strings are generally stored in fixed-size buffers. The sizes of these buffers are listed below. The strings used for dialogue subtitles and for messages are not fixed-size; they are stored in a contiguous chunk in the raw file, with the offsets for each string found in an array in SUBT. Each string's length is not known in advance, but only by reading it as a C string and encountering the null terminator at the end.

16 chars

32 chars

48 chars

63 chars

64 chars

68 chars

128 chars

132 chars

160 chars

256 chars

364 chars

Floating-point numbers

Float

Floats are stored in the standard 4-byte IEEE format, so reading them directly into the memory of a float_t works. These are used for many amounts where floating-point precision is needed, such as percentages, distances and angles.

Vector

Simply a struct of 3 floats stored contiguously. Vectors are used for 3D coordinates of polygons and normals, as well as for scaling.

AABB

Axis-aligned bounding box

2 vectors define a min corner and a max corner

used in

Plane

4 floats define an oriented plane in 3D

(see PLEA for algorithm)

Quaternion

4 floats define a quaternion

(always normalized, i.e., rotation w/o scaling?)

used in

  • OBAN (with translation vector after it)
  • OBOA (with translation vector before it)
  • TRAM (bone rotation for overlay TRAMs, without translation vector)

Translation and rotation

  • 3 floats define a translation
  • 3 others define a rotation (Euler angles)
used in

Transformation matrix

12 floats define a 4x4 transformation matrix

(translation, rotation, scaling, mirroring)

used in

Integers

These are also stored in the standard IEEE format. Most integers in the game data are read as unsigned, but one known exception is the quantized Euler angles in TRAM.

char

Are single-byte ints ever used?

short

16-bit ints are used throughout the game data to save space when 32-bit capacity is not needed.

short with high bit

Used as a simple flag? (in a few places... not sure... ^^ ) (OFGA)

int

Used throughout the game data wherever values were expected to at least potentially exceed 16-bit limits.

long

64-bit ints are found in many places where extra-large numbers were anticipated, such as the checksum field in the .dat's header.

long with high bit

The lower bits are used for an ID, the high bit is a flag.

Used in:

long with high byte

The lower bytes are used for an ID, the high byte is a group ID.

Used for MELE moves

Quantized float

Used for quantized Euler angles in TRAM.

other stuff

Lots of funny stuff in PAR3, maybe...

Funny stuff in OTLF, too...

Bitsets

The most common size of a bitset, aka flag set, is 32 bits.

1 byte

2 bytes

4 bytes

8 bytes

Used for the instance descriptor flags in the .dat and for keypress events in FILM. Used for storing flags for AI behaviors in ONCC.

Booleans

If Bungie West wanted to store a single boolean value then they held it in a 1-byte field, aka 'char' (a series of values would be stored in a bitset).

Misc.

32-bit color

stored as BB GG RR AA (byte swapped)

Used in:

4-character codes

4CCs for short, also known as tags to many game modders, are used to announce the packing version of .dat files, to label template descriptors in the same, and in various BINA raw/sep parts.

Pathfinding grids

See OBD:AKVA/0x24.

Padding

Bungie West frequently placed padding into their template structs for cache alignment purposes to speed up the reading of the data. This padding can range in size from 1 byte (typically following a 1-byte boolean field) to 28 bytes (preceding pointer fields which were 4 bytes).