Types
The content tree — the contract for the
data/ tree.
The authoritative shapes live in the modding reference, not here.
It is GENERATED from the same Rust structs the game deserialises, so it cannot
disagree with the loader; a sketch maintained by hand can, and did. This section
used to carry 650 lines of that sketch. By the time it was published it was
already describing a Building.produces: Vec<Produce> field that no longer
exists — which is exactly the drift the generated reference exists to make
impossible.
So: for the shape of any file under data/ — its fields, their types, which are
required, what each one means, and the legal ids a reference field may take —
read the reference. Every page there is also available as markdown by appending
.md, which is the form to hand an agent.
What is NOT in the reference, because it is a property of the TREE rather than of any one type, stays here:
// Every file's top-level value is a `Table<T>`, and carries its provenance.
enum Source { Srd51, Srd52, Original, Phb2024, Dmg2024, Mm2024, Tce, Xge }
struct Table<T> { source: Source, entries: Vec<T> }
Two conventions the reference cannot state, because they are about the FILES rather than the shapes:
- Every field is written explicitly in the data —
Noneand[]included. These are plain#[derive(Deserialize)]types with no serde attributes and no RON extensions, so a missing field fails the parse rather than defaulting. The documented exceptions arequality_overridesand the handful of fields the reference marks with a default. DexMod::NoneandOption’sNoneboth appear inarmor.srd52.ron; serde disambiguates them by the expected type. They are different things that happen to share a spelling.
The sections below are the rules that govern the tree as a whole: how values DERIVE rather than being stored, what is transcribed from the SRD versus interpreted, and how identity works.