M2 root — the MD20 body¶
The model payload — the client's own M2Root. Unlike the chunked formats it is
offset-addressed: fields carry no FourCC; their wire positions come from the
entity's canonical wire_order, which is also the order they are listed in
below. Pre-Legion this is the .m2 file; Legion+ it is the content of the
chunked shell's MD21 chunk.
Rather than repeat eleven near-identical class listings, this page documents the
generic model: M2Root is the abstract base; the per-version layout below
is shown generically as M2Root⟨version⟩. A field whose availability is
version-restricted carries an expansion badge naming the range of clients
that have it (both ends inclusive); a field with no badge exists in every
version. The badges are generated from the C++ sources, so they cannot drift.
Two wire fields are managed for you and hidden from Python: the leading MD20
magic, and WotLK+'s num_skin_profiles (stamped from the assembly's
skins vector on write).
The M2Root base¶
M2Root
¶
An MD20 model body, abstract over the client version. Construct a concrete version with M2Root.for_version(expansion); the per-version M2Root* classes are subclasses. See https://wowdev.wiki/M2.
for_version staticmethod¶
for_version(expansion: Expansion) -> M2Root⟨version⟩Construct the concrete M2Root for a client version — the abstract M2Root is never instantiated directly. The return type narrows per expansion (a typed overload per Expansion member), so for_version(Expansion.Wotlk) returns a M2RootWotlk; a runtime Expansion value yields the AnyM2Root union.
validate
¶
Check the logical integrity contracts this file must satisfy to LOAD in the client, which write() deliberately never enforces. Call it before writing when you want to know the result will load. A file read from a client and left unmodified reports no errors; warnings mark states real client files ship.
Returns:
| Type | Description |
|---|---|
ValidationReport
|
every violated contract, each with its member path |
ensure_valid
¶
Validate and raise on the first error instead of returning a report — the assert-style face of validate().
Returns:
| Type | Description |
|---|---|
None
|
nothing; raises when validate() finds any error |
Fields¶
Header & identity¶
The layout format version, the model's name and its global flags.
Sequences & animation¶
The animation sequences, global loops and the animation-id lookup tables.
Bones¶
The bone hierarchy and the key-bone lookup.
Geometry¶
The global vertex list and the pre-WotLK embedded LOD views.
Textures & materials¶
Texture definitions, UV animations, color/alpha and transparency animations, and the materials.
Attachments & events¶
Attachment points and timed events.
attachments
property
¶
attachments: list[M2Attachment⟨version⟩]
Attachment points (weapons, effects, name plates).
Lights & cameras¶
Model lights and cameras, with their lookups.
Global flags¶
GlobalFlags
¶
Bases: IntFlag
M2 global flags: tilt behavior, the texture-combiner-combo gate, physics participation and exporter-era markers.
Attributes:
| Name | Description |
|---|---|
TiltX |
Tilt the model over X (flying mounts). |
TiltY |
Tilt the model over Y. |
UseTextureCombinerCombos |
The texture_combiner_combos block trails the header (TBC+). |
LoadPhysData |
Request the .phys file (MoP+). |
Unk0x80 |
Unset stops demon-hunter tattoos glowing (WoD+). |
CameraRelated |
Camera related (WoD+). |
NewParticleRecord |
Cata: particle records are the 492-byte layout even below v272. |
TextureTransformsUseBoneSequences |
Texture transforms animate on the bone's sequence (Legion+). |
ChunkedAnimFiles |
The .anim files are chunked (Legion+). |