-
Notifications
You must be signed in to change notification settings - Fork 0
dat Files and Formats
Navigation: Home - Data formats - dat Files and Formats
flowchart LR
subgraph world["World data"]
map["map.dat"]
attrib["attrib.dat"]
event["event.dat"]
end
subgraph entities["Entities & rules"]
monsters["monsters.dat"]
items["items.dat"]
spells["spells.dat"]
roster["roster.dat"]
end
attrib -- selects tileset --> map
map -- bit 0x80 --> event
event -- OP_12 --> monsters
items -- use byte --> spells
roster -- equips --> items
roster -- knows --> spells
MM2-local inventory and current format status for data files in this workspace.
[TOC]
Canonical set in project root (same bytes are mirrored under EXTRACTED/ and MM2BOOT/):
-
attrib.dat- 3840 bytes -
event.dat- 95687 bytes -
items.dat- 5120 bytes -
map.dat- 30720 bytes -
monsters.dat- 6656 bytes -
roster.dat- 8320 bytes -
spells.dat- 256 bytes -
str.dat- 7808 bytes
The GOG DOS build wraps some .DAT files in the same custom LZW codec
used by the PC .4/.16 graphics (lzw_decompress traced to MM2.EXE @0x2A42; see 54-pc-dos-graphics-formats.md).
Detection/decompression: Python tools/pc_dat_lzw.py (canonical LZW impl
shared via tools/mm2_lzw.py); C++ editor/src/core/PcDatLzw.{h,cpp}, wired
into AttribFile/MonstersFile/StrFile/MapFile/EventFile's load().
| GOG file | Container | Result vs Amiga file |
|---|---|---|
ATTRIB.DAT |
flat (u32 LE size + LZW, whole file) |
byte-identical to attrib.dat
|
MONSTERS.DAT |
flat |
byte-identical to monsters.dat
|
STR.DAT |
flat | decodes cleanly to 7707 bytes (Amiga is 7808 — different platform string table, not a decode error) |
MAP.DAT |
table: u16 LE[60] offset table (one 512-byte screen blob per entry, each u32 LE size + LZW) |
reassembled 60 screens byte-identical to map.dat
|
EVENTSI.DAT + EVENTSO.DAT
|
table: u32 LE[71] offset table each (indoor / outdoor halves of the 71 event.dat locations; mutually exclusive per slot) |
merged (71x6-byte BE header + concatenated blobs) reproduces event.dat to within 18/95687 bytes — all single-byte platform content differences (same offsets/lengths; verified 0x02 Amiga vs 0x01 PC at each diff), not decode errors |
ITEMS.DAT |
plain (not compressed) |
byte-identical to items.dat
|
ROSTER.DAT / SPELLS.DAT / DEFAULT.DAT
|
plain (not compressed) | different size from the Amiga file (e.g. SPELLS.DAT 192 bytes vs spells.dat 256) — a structural/record-layout difference between platforms, out of scope here |
Both table containers reuse the MONSTERS.4/.16 combat-atlas convention:
entry[0] == table_byte_size (also slot 0's blob offset) for MAP.DAT
(which never has an empty first screen); EVENTSI.DAT/EVENTSO.DAT instead
use a fixed 71-slot count since slot 0 can legitimately be empty in either
half. entry[k] == 0 always means "no blob for slot k".
The editor's EventFile::load() tries plain event.dat first, then falls
back to EVENTSI.DAT+EVENTSO.DAT auto-merge if only those exist. Saving
from the editor always writes plain Amiga-format .dat files (round-trip
back to the GOG-compressed shape is not wired into the editor's save path);
tools/pc_dat_lzw.py --compress re-compresses the flat container for
offline round-trip testing, reusing the verified LZW compressor from
tools/encode_pc_gfx.py.
Cross-validated with:
- MM2 asset filename references in binary (
items.datappears withspells.datnear code offset0x29868) - Legacy reverse code:
C:\_20260421_\D-REC\development\Amiga\Smite-and-Magic\Blitz3d\b3dmm2\Item_ED.bb
Layout:
- 256 records
- 20 bytes per record (
0x14) - Record fields:
-
0x00..0x0B- item name (12-byte ASCII, space-padded) -
0x0C- separator/pad (editor writes0) -
0x0D- usable-by bitmask -
0x0E- bonus packed nibble (hi=bonus_type,lo=bonus_amount) -
0x0F- effect packed nibble (hi=effect_type,lo=effect_amount) -
0x10- damage byte -
0x11- pad/unused byte (editor writes0) -
0x12..0x13- gold (uint16little-endian on disk; shop price in gp; game byte-swaps each record word on load, asm0x26030)
-
Notes:
-
5120 = 256 * 20, which matches the editor loader/saver loops. - Item names align 1:1 with
b3dmm2/items.txt.
Cross-validated with:
- MM2 executable ASM (
EXTRACTED/mm2.asm,EXTRACTED/mm2.capstone.asm) - New C codec in
EXTRACTED/decomp/mm2_roster_codec.h+.c
Layout:
- 64 records
- 130 bytes per record (
0x82) - Key fields:
-
0x00..0x0A- character name (11-byte ASCII) -
0x0B- town/inn byte (low7=town,bit7=party flaginferred) -
0x0C- sex -
0x0D- alignment (current) -
0x0E- race -
0x0F- class -
0x10..0x15- current core stats -
0x27- current endurance -
0x28..0x39- equipped items (6 slots x 3 bytes) -
0x3A..0x4B- backpack items (6 slots x 3 bytes) -
0x4C..0x57- spellbook bytes -
0x58..0x61- SP/HP/Gems words (little-endian) -
0x62..0x65- XP (little-endian dword) -
0x66..0x69- Gold (little-endian dword) -
0x6A..0x73- base alignment/stats/level/spell-level/endurance -
0x74..0x75- HP current (word) -
0x76..0x81- unresolved tail bytes
-
Notes:
- Loader/saver round-trips unknown spans byte-for-byte.
- The codec treats numeric multibyte fields in
roster.datas little-endian on disk.
Cross-validated with:
- MM2 executable ASM loader path (allocates/reads
0x1A00bytes formonsters.dat) - MM2 accessor routine around
0x99C8(mulu #$1a, then copies exactly 26 bytes) - C codec in
EXTRACTED/decomp/mm2_monsters_codec.h+.c
Layout:
- 256 records
- 26 bytes per record (
0x1A) - Record shape currently modeled as:
-
0x00..0x0D- monster name (14-byte fixed field) -
0x0E..0x19- 12-byte stat/behavior payload (still being field-lifted)
-
Notes:
- This is sufficient for byte-perfect load/edit/save and safe round-tripping.
- Field-level semantics for the 12-byte payload remain TODO pending deeper combat call-site traces.
Encoding:
- Byte transform: decoded char =
(encoded + 0x1C) & 0xFF -
0x01acts as newline/line break
Observed content:
- Contains many in-game text strings (jokes, prompts, shop/guild text, menu/help text).
Cross-validated with:
- MM2 executable ASM (flat load into
A4-$EEF4, 3D hood reads page 0 @0x2900) -
editor/src/core/MapFile.{h,cpp}— 60 screens × 512 bytes - Collision
0x80event alignment vsevent.dattriplets
Layout:
- 60 map screens
- 512 bytes per screen (
0x200) - Per screen:
-
0x000..0x0FF— page 0 (visual): 16×16 grid; four 2-bit wall fields per cell (N/E/S/W) -
0x100..0x1FF— page 1 (collision): same geometry;(dark<<1)|wallper direction; bit0x80= event flag
-
Notes:
-
30720 = 60 × 512, which matches the editor loader/saver loops. - Row 0 on disk = south; MM2ED and wiki grids draw north-up.
- Full field decode: map.dat format.
- event.dat (95687 bytes) — 71 location records; see 06-event-dat-format.md, 07-event-script-opcodes.md, 08-event-runtime.md
- spells.dat (256 bytes) — see 19-spells-and-item-use.md
- attrib.dat (3840 bytes) — see 12-attrib-dat-format.md
These files still need additional field-level work against ASM call sites:
- (none of the primary
.datcontainers remain fully TODO)
Working rule:
- Use ASM first (
EXTRACTED/mm2.capstone.asm,EXTRACTED/mm2.asm) to identify true runtime reads/writes. - Use legacy Blitz3d reverse code as a cross-check.
- Resolve conflicts in favor of observed assembly behavior.
| Page | Why |
|---|---|
| items dat Format | 256 items |
| map dat Format | Visual + collision pages |
| Events by Location | 71 per-map script pages |
| event dat Format | event.dat container |
| MM2ED Editor | Edit in GUI |
- Docs Wiki Hub ← full doc index
- Getting Started ← read this first
- Overview
- Workspace Notes
- Open Questions
- Full Analysis
- Game Remake
- Startup and Init
- Runtime Memory Map
- Main Loop and Map
- Exploration Input and Options
- Party and Session
- Game State Struct
- Data Hunk mm2 data 00
- Time Era Calendar
- GFX Loading
- ANM TV Format
- PC DOS graphics
- SNES graphics
- 3D View and Game Screen
- Amiga 3D Render Process
- Scripted Scene Graphics
- Event Graphics Opcodes
- Title Screen Assets
- Title Screen Animation
- Format inventory
- items.dat
- monsters.dat
- roster.dat
- attrib.dat
- map.dat
- spells & item use
- event.dat
- Events by location ← 71 maps
- Events hub (numbered)
- Event Script Opcodes
-
Event Script DSL ←
.mm2evtauthoring - Event Text Rendering
- Event Graphics Opcodes
- Combat Overview
- Combat System
- Encounter Tables
- Spell Cast ASM
- monsters.dat abilities
- Spells and item use
- Town Services
- Spell Sources
- Character Mechanics
- Skills and Hirelings
- Commerce Formulas
- Commerce World Services
- Mount Farview Class Quest
- Class Quest HP Bug
- Event Runtime
- Event to String Path
- Embedded Exe Strings
- Copy Protection
- Time Era Calendar
- Game State Struct
- MM1 Overview ← hub + decode status
- MM1 MAZEDATA format
- MM1 to MM2 outdoor
- MM1 WALLPIX by sector
- MM1 art & graphics
- MM1 items / monsters (status)
- MM1 map walker ↗
- MM1 2D maps gallery
- MM1 WALLPIX gallery