MDB Format - KCreator/Earth-Defence-Force-Documentation GitHub Wiki

All offsets are relative to the beginning of their table entries.
Since the header is always at the beginning of the file, the offsets there are also absolute file offsets.

File format largely derived from EDF5, and EDF6. EDF4.1 might have unknown differences.

Header: 48 (0x30) bytes

Offset Size Type Description
0x00 4 char[4] Magic, always MDB0
0x04 4 uint32 Version: 0x14 for EDF4.1/EDF5, 0x20 for EDF6
0x08 4 uint32 Name table count
0x0C 4 uint32 Name table offset (always 0x30)
0x10 4 uint32 Bone count
0x14 4 uint32 Bone table offset
0x18 4 uint32 Object count
0x1C 4 uint32 Object table offset
0x20 4 uint32 Material count
0x24 4 uint32 Material table offset
0x28 4 uint32 Texture count
0x2C 4 uint32 Texture table offset

Name table: 4 (0x04) bytes

Offset Size Type Description
0x00 4 uint32 UTF-16 string offset

Bone table: 192 (0xC0) bytes

Offset Size Type Description
0x00 4 int32 Bone index
0x04 4 int32 Parent bone index (-1 for no parent)
0x08 4 int32 Next sibling bone index (-1 for none)
0x0C 4 int32 First child bone index (-1 for none)
0x10 4 int32 Bone name (name-table index)
0x14 4 int32 Child bone count
0x18 1 uint8 Unused bone participation metadata (exact original meaning unverified).
0x19 1 int8 Unused Signed bone semantic/role metadata; no reader of the copied role integer has been found
0x1A 1 uint8 (Boolean encoding) Loader stores (raw value == 1), so only literal 1 becomes true. True when Bound box values are present, but not a confirmed relation found.
0x1B 5 uint8[5] Zero padding/alignment
0x20 64 (0x40) float32[16] Local transformation matrix (4x4): position, rotation and scale in parent-bone space
0x60 64 (0x40) float32[16] Inverse bind-pose matrix used for GPU skinning
0xA0 16 (0x10) float32[4] Mesh bounding-box size; W is normally 1
0xB0 16 (0x10) float32[4] Mesh bounding-box offset; W is normally 1

Matrices are Y-up for the default world orientation.

The bounding box is a child of this bone and inherits its rotation and position. The offset + size interpretation has been independently validated in Blender: it exactly encloses the visible mesh of tested humanoid models. Bounds on ordinary models appear to be determined by vertices weight-painted to the bone. Some UI elements have bounding boxes without weight paint; a current hypothesis is that a mesh sharing the bone's name supplies the bounds in that case.

The loader retains 0x18 in the resource-bone record, but normal animation/render-bone construction does not copy it. It is copied only while allocating/resizing the resource-bone array, no comparison has been found, and controlled edits had no in-game effect. It should currently be treated as unused, legacy or authoring metadata rather than a runtime rendering flag. Observed: 3 throughout the ordinary deform/mesh-weighted hierarchy, 2 throughout a separate hierarchy rooted at A_under_geo, and 0 on nonessential/control/helper nodes. Controlled in-game edits produced no visible or functional change. The field is retained in the resource record but is not copied into standard animation-bone records, and no runtime consumer has been found.

0x19 is sign-extended and copied into every animation-bone record, but preservation alone does not prove consumption. High-level enemy, human, aim and weapon initialization resolves important bones through hashed name lookups using names supplied by configuration data. Identifiable IK setup uses CAS values such as v_weapon_grip_ik_target and configured lists such as ik_control_info; those paths do not select bones through 0x19. The executable also contains Havok Behavior foot-IK support, so an optional consumer cannot be completely excluded, but the signed left/right foot and helper patterns may simply be skeleton-semantic metadata generated for the animation toolchain. MOVSX during animation-bone construction proves that file values 250..255 become runtime values -6..-1. Observed examples: 0 on ordinary/sub-deform bones, 1 on aim_center, 4 on its child aim_target, -1 (file 255) on palm/weapon/IK-like helpers, and -5/-4 (file 251/252) on the right/left floor-contact feet. Editing hand and foot values produced no visible effect on the tested enemy.

0x1A Observed true on ordinary deform bones and the A_under_geo hierarchy; false on root, aim, and palm/helper nodes. The normalized flag is copied into animation-bone; its consumer and meaning have not yet been identified. Bounding float4s are copied independently.

Texture table: 16 (0x10) bytes

Offset Size Type Description
0x00 4 int32 Texture index
0x04 4 uint32 Texture name (UTF-16 string offset)
0x08 4 uint32 Texture filename (UTF-16 string offset)
0x0C 4 uint32 Reserved, always zero

Material table: 32 (0x20) bytes

Offset Size Type Description
0x00 2 uint16 Material index
0x02 1 uint8 Render priority (usually 0, often higher on transparent objects); exact ordering semantics unverified
0x03 1 uint8 Render layer (normally 0; observed as 1 on loading-screen/tank_catapi assets and 2 on transparent/UI materials); exact semantics unverified
0x04 4 int32 Material name (name-table index)
0x08 4 uint32 Shader name (UTF-16 string offset)
0x0C 4 uint32 Material-parameter table offset
0x10 4 uint32 Material-parameter count
0x14 4 uint32 Material-texture/sampler table offset
0x18 4 uint32 Material-texture/sampler count
0x1C 1 uint8 Engine render-participation flags. Bit 0 enables it as a shadow caster when true. Normally 3; value 2 is observed on UI and barrier (transparent) materials. Other bits have no confirmed readers
0x1D 3 uint8[3] Ignored/padding.

Material Parameters: 32 (0x20) bytes

Offset Size Type Description
0x00 4 float32 Value 1 / X
0x04 4 float32 Value 2 / Y
0x08 4 float32 Value 3 / Z
0x0C 4 float32 Value 4 / W
0x10 4 float32 Value 5; not used by the known parameter types
0x14 4 float32 Value 6; not used by the known parameter types
0x18 4 uint32 Parameter name (ASCII string offset)
0x1C 1 uint8 Type: 0=Float, 1=Vector2, 2=RGB, 3=RGBA
0x1D 1 uint8 Component/value count
0x1E 2 uint16 Zero padding

Some value slots can contain nonzero data even when the parameter type/component count does not use them.

Material Textures: 28 (0x1C) bytes

Offset Size Type Description
0x00 4 int32 Texture-table index
0x04 4 uint32 Shader texture-slot/type name (ASCII string offset)
0x08 2 uint16 Sampler override flags; see bit assignments below
0x0A 2 int16 Filter selector used when flag 0x0001 is set
0x0C 1 uint8 Texture address mode U used when flag 0x0002 is set
0x0D 1 uint8 Texture address mode V used when flag 0x0002 is set
0x0E 1 uint8 Texture address mode W used when flag 0x0020 is set
0x0F 1 int8 Maximum anisotropy used when flag 0x0010 is set
0x10 4 float32 Minimum LOD used when flag 0x0008 is set
0x14 4 float32 Maximum LOD used when flag 0x0008 is set
0x18 4 float32 Mipmap LOD bias used when flag 0x0004 is set

Sampler override flag assignments:

Flag Overridden field(s)
0x0001 Filter
0x0002 Address U and V
0x0004 Mipmap LOD bias
0x0008 Minimum and maximum LOD
0x0010 Maximum anisotropy
0x0020 Address W

These sampler meanings are confirmed end-to-end. The loader expands the compact values into the exact 52-byte D3D11_SAMPLER_DESC layout and passes it to ID3D11Device::CreateSamplerState.

Object table: 16 (0x10) bytes

Offset Size Type Description
0x00 4 int32 Object index
0x04 4 int32 Name (name-table index)
0x08 4 uint32 Mesh count
0x0C 4 uint32 Mesh-info table offset

Mesh info: 40 (0x28) bytes

Offset Size Type Description
0x00 1 uint8 Topology selector: loader maps 0 to runtime value 4 and nonzero to 5. These match D3D11 triangle-list and triangle-strip enum values
0x01 1 uint8 Is skinned mesh (value == 1)
0x02 1 int8 Number of bone influences per vertex, normally 0-4. The runtime sign-extends this field
0x03 1 uint8 Reserved/alignment, normally zero
0x04 4 int32 Material index (-1 for none)
0x08 4 uint32 Unknown/reserved, normally zero
0x0C 4 uint32 Vertex-layout table offset
0x10 2 uint16 Vertex stride: total byte size of one vertex record
0x12 2 uint16 Vertex-layout element count
0x14 4 uint32 Vertex count
0x18 4 int32 Mesh index
0x1C 4 uint32 Vertex-data offset
0x20 4 uint32 Index count
0x24 4 uint32 Index-data offset

Vertex layout info: 16 (0x10) bytes

Offset Size Type Description
0x00 4 uint32 Vertex storage type
0x04 4 uint32 Byte offset within one vertex record
0x08 4 uint32 Semantic channel/index, for example texcoord0 versus texcoord1
0x0C 4 uint32 Semantic name (ASCII string offset)

Vertex types:

Type Data type Size
1 float32[4] 16 bytes
4 float32[3] 12 bytes
7 float16[4] 8 bytes
12 float32[2] 8 bytes
21 uint8[4] 4 bytes

Index data: 2 bytes per index

Offset Size Type Description
0x00 2 uint16 Unsigned vertex index

Vertex data: Variable length

Offset Size Type Description
0x00 Vertex count x vertex stride byte[] Interleaved vertex records. Element formats and offsets are described by the mesh's vertex-layout entries

Strings: Variable length

Offset Size Type Description
0x00 Variable char[] / UTF-16LE[] Null-terminated ASCII and UTF-16LE strings referenced by the tables above