Expand description
§nwnrs-gff
nwnrs-gff reads and writes GFF V3.2, the structured container format
underlying a large portion of NWN gameplay data.
§Scope
- parse typed GFF roots, structures, fields, and values
- preserve authored field order so stable editing remains possible
- write typed GFF documents back to binary form
- provide a compact typed vocabulary on which higher-level crates can build
The principal entry points are read_gff_root, write_gff_root, and
GffRoot.
§Example
use std::io::Cursor;
use nwnrs_gff::{GffRoot, GffValue, read_gff_root, write_gff_root};
let mut root = GffRoot::new("UTC ");
root.put_value("Tag", GffValue::CExoString("nw_chicken".to_string()))?;
let mut bytes = Cursor::new(Vec::new());
write_gff_root(&mut bytes, &root)?;
bytes.set_position(0);
let decoded = read_gff_root(&mut bytes)?;
assert_eq!(decoded.file_type, "UTC ");
assert_eq!(decoded.fields().len(), 1);§Public Surface
GffRootGffStructGffFieldGffFieldKindGffValueGffCExoLocStringGffErrorGffResultread_gff_rootwrite_gff_rootmerge_root_preserving_provenance
§Core Model
GffRootcarries the outer file tag, version, root struct, and optional source provenanceGffStructis an ordered labeled field map keyed by unique labelsGffFieldseparates field metadata fromGffValueGffValuedoes not collapse field kinds into one lossy generic scalar typeGffCExoLocStringpreserves both the top-levelstr_refand the explicit localized override entries
§Binary Layout
The crate models GFF V3.2.
0x00 file_type[4] e.g. "UTC ", "ARE ", "GIT "
0x04 file_version[4] "V3.2"
0x08 struct_offset u32
0x0C struct_count u32
0x10 field_offset u32
0x14 field_count u32
0x18 label_offset u32
0x1C label_count u32
0x20 field_data_offset u32
0x24 field_data_size u32
0x28 field_indices_offset u32
0x2C field_indices_size u32
0x30 list_indices_offset u32
0x34 list_indices_size u32
total header size: 56 bytesAfter the header:
+----------------------+
| struct table | struct_count * 12
+----------------------+
| field table | field_count * 12
+----------------------+
| label table | label_count * 16
+----------------------+
| field data blob | variable
+----------------------+
| field index array | i32[]
+----------------------+
| list index array | i32[]
+----------------------+Struct table entry:
i32 id
i32 data_or_offset
i32 field_countField table entry:
u32 field_kind
i32 label_index
i32 data_or_offsetImportant indirections:
- if a struct has
field_count == 0, it has no fields - if a struct has
field_count == 1,data_or_offsetis the direct field index - if a struct has
field_count > 1,data_or_offsetis a byte offset into the field-index array - list fields point into the list-index array
- complex field kinds point into the field-data blob
§Field-Kind Semantics
Inline 32-bit payloads:
ByteCharWordShortDwordIntFloat
Out-of-line payloads in the field-data blob:
Dword64Int64DoubleCExoStringResRefCExoLocStringVoid
Recursive payloads:
StructList
The practical point is that “GFF value” is not one uniform storage class. Reconstruction requires honoring the original split between inline scalars, out-of-line payloads, and recursive references.
§Invariants
- the order of fields inside each
GffStructis preserved explicitly - the root
file_typeandfile_versionremain first-class typed fields - each
GffValueretains its declared GFF field kind - writes are derived from the typed representation rather than from an unstructured map
- labels must be unique within a struct
- complex fields preserve raw payload bytes when that is needed for stable rewrites
merge_root_preserving_provenanceexists because naive merge logic tends to destroy stable ordering and untouched raw structure
§See also
nwnrs-git, which layers typed area-instance semantics over raw GFF datanwnrs-erf, which often carries GFF payloads in NWN archives
§Why This Crate Exists
GFF is one of the places where reverse engineering turns into systems design.
The difficult part is not only learning the table layout. It is deciding which
properties are structural enough to model:
- order
- typed field kind
- label identity
- recursive structure
- raw payload fidelity
This crate chooses to preserve all of those explicitly so higher layers can
lift GFF into domain types without pretending the underlying container is a
schema-free blob.
Modules§
- prelude
- Common imports for consumers of this crate.
Structs§
- GffC
ExoLoc String - A
CExoLocStringvalue. A localized string may either reference a TLK entry viastr_refor carry inline language-specific overrides inentries. - GffField
- A labeled GFF field.
Labels are stored on the containing
GffStruct; this type only wraps the typed value. - GffRoot
- A complete GFF document.
- GffStruct
- A GFF structure containing labeled fields.
Enums§
- GffError
- Errors returned by GFF readers and writers.
- GffField
Kind - The primitive and compound value kinds supported by GFF. These correspond directly to the numeric field type ids stored in the binary format.
- GffValue
- A typed GFF field value.
The enum variants mirror the canonical
GFF V3.2field kinds.
Functions§
- merge_
root_ preserving_ provenance - Applies
editedontotargetwhile retaining provenance already present on matching parsed fields and structures. - read_
gff_ root - Reads a complete GFF document from
reader. - write_
gff_ root - Writes a complete GFF document to
writer.
Type Aliases§
- GffResult
- A result alias for GFF operations.