# Format map: source and converter evidence Observed 2026-10-21. Baseline archive: `Microbrush-3-wip-2016-03-10-c.zip`, SHA-256 `f972035324c1ede7e66771c398c035b9a355b569f68ddc30fdc4ed4ed0973982`. Paths and line numbers below are relative to `assets/references/extracted/2016-03-10-c/`. Full member hashes are in the [static source map](../assets/analysis/source-map.json) and [member inventory](REFERENCE_INVENTORY.md). The initial F15–F20 observations below are grammar/writer evidence. E02 now adds [two MB3 DAT layouts](MB3_DAT.md) and [executed converter semantics](CONVERTER.md); those reports supersede the explicit unknowns from E01. ## F15 — Separate the format layers | Layer | Evidence | Current knowledge | | --- | --- | --- | | Editable world text | `data/reference/Mb3 TXT grammar.txt` | Explicit world/brush/plane/Patch9 syntax; conversion semantics still unknown | | Editable world binary | `saveWorldToFile` / `loadWorldFromFile`, conversion BAT files | MB3 DAT boundary and command directions are visible; Both converter layouts recovered; native editor conformance pending (F24/F25) | | Imported map formats | HL1 MAP, HL2 VMF, Q3 MAP grammars | Accepted syntax is described; semantic preservation is limited | | Export mesh | DAT-to-`wfobj` BAT file | Export-only route is shipped; Computed-geometry polygon/quad export recovered (F27) | | Procedural model | `IXModel.ixpl` + `grid cursor.ixpl` | Source writer and opcode catalogue; different from MB3 DAT | | Compiled plugin | `IXPL.exe cso` in build BAT files | Generated `.plugin` output; no compiled sample or layout recovered | | Runtime config/localization | config and key-config grammars; CFG/TXT resources | Typed configuration plus a separate key-sequence language | | Shader container | three `.shader` files | Stage-marked GLSL source with host-dependent uniforms/attributes | The conversion CLI is structurally `Mb3 file formats.exe `. Four text formats convert to `data/temp/load.mb3dat`; saves start from `data/temp/save.mb3dat`, with an additional `wfobj` export. File placement and CLI shape are observed in the BAT files. Argument/exit/log/overwrite behavior is now reproduced in F26/F28; concurrent conversion safety remains unmeasured. ## F16 — MB3 TXT grammar Source: `data/reference/Mb3 TXT grammar.txt:45–101`. - `world(...)` starts with required `computedFeatures true|false`, then optional `stringProperties[...]`, optional `uvProperties[...]`, then zero or more brushes/patches. Their order is constrained by the grammar. - `brush(...)` contains zero or more planes syntactically. The host API says invalid brushes are discarded; syntactic acceptance does not establish geometric validity. - A `plane(...)` has three comma-separated three-component numeric tuples, repeated `s ` entries, repeated `uv (, )` entries, and an optional polygon vector list. - Each UV five-tuple is documented as an axis vector plus scale and shift-before-scaling. The grammar does not specify index bounds, property lookup failure or duplicate property behavior. - `patch9(...)` has four integers and an anchor vector list. If computed points are present, the normals list must also appear, in that order. The grammar imposes no anchor-list length consistency check. - `Core-QuakeWorld.ixpl:17–21` separately requires odd anchor dimensions of at least three and at least two quads per tile per axis. These are API declaration constraints awaiting runtime verification. - The grammar accepts signed integers/floats and exponent forms, ordinary escaped strings, line/block comments and whitespace. Numeric precision and printing are not established. E02 establishes that the plane's three tuples are P0/U/V (origin plus direction vectors), transferred directly by the converter; MAP point order and coordinate transforms are in F27. Selection sets, hidden state, undo history, view state and named worlds do not have explicit fields in this grammar. Their persistence behavior needs controlled save/load tests. E02 supplies single-feature fixtures and actual serializer observations for P6.03. P6.02 edge cases and P5 editor numerical/geometry contracts remain open. ## F17 — Imported dialects and loss boundary | Grammar | Observed syntax | Limits to preserve in the specification | | --- | --- | --- | | HL1 MAP | Entities require one or more string key/value pairs; brush sides use three points, texture name, two bracketed four-number axes, then three numbers | This is the bracketed-axis style in the supplied grammar, not proof of every historical MAP dialect; no line-comment rule is listed | | HL2 VMF | Lowercase/underscore block names; recursive key/value and block trees; world/entity/solid/side/hidden specializations plus generic `OtherStuff` | Recursive syntax can accept data which the converter later drops; quoted strings have no escape production here | | Q3 MAP | Entity key/value pairs, plane brushes, and `patchDef2`; anchors contain five numbers; a plane side has texture name plus eight numbers | No `brushDef`/`brushDef3` specialization appears; dimensions and patch counts are not constrained by the grammar | Sources: `HL1 MAP grammar.txt:30–58`, `HL2 VMF grammar.txt:23–91`, `Q3 MAP grammar.txt:32–83`. `data/strings/English/main menu.txt` explicitly warns that unsupported features, including textures and entities, are dropped on import/save. Therefore grammar recognition is not a preservation guarantee. Native converters need a supported-subset/loss report, and original files must remain separate from rewritten output. The Wavefront route is export only in the shipped menu and BAT scripts. F27 now maps material/UV/index/group policy through managed methods and generated fixtures. No original sample MAP/VMF/OBJ/MB3 file is in the recovered archives; E02 generated controlled samples separately. ## F18 — IXModel writer contract and anomalies Source: `data/sources/include/IXPL/files/IXModel.ixpl`. - `writeHeader:65–70` sends literal `I10MODEL` to `File::writeBytes`, sends integer `20160119`, and resets the next object ID to zero. - `writeStrings:76–84` writes string count, then each string length and bytes. Whether string length counts bytes/code units is a runtime question. - `CMD_*:93–185` declares 92 opcodes, numbered 0–91: node creation, graph/mesh references, attribute/index data, drawing/render state, custom data, animation, waits, and transforms. - Constructors allocate implicit IDs using `next++`. Mesh loading writes target mesh, counts, and data through `File` primitives. `writeShorts:57–62` explicitly emits low then high bytes; this confirms the writer's 16-bit byte order only. It does not prove the host primitive width/endianness for every integer/float. - `File.ixpl:59–70` writes a vec3 as three float operations in x/y/z order. The `File` interrupt namespace is distinct from the Core plugin namespace; do not merge their overlapping numeric IDs. - Older four builds write version `20111101` and declare 90 opcodes (0–89). The latest uses version `20160119` and 92 opcodes. A decoder needs version-specific tables, not one guessed layout. Two source inconsistencies need targeted investigation before calling the writer authoritative: 1. Many `reset*` functions accept `nodeOrMesh` but emit only the reset opcode, unlike their `set*` counterparts (`230–261`). The reader may have implicit targeting, or the writer may be incomplete. Do not invent a serialized target field. 2. `popFile:91` assigns `file` to the last stack entry before erasing that same entry. With nested pushes it appears to retain the popped handle rather than restore the previous handle. The single cursor generator does not demonstrate this case. The cursor generator creates a line mesh from eight positions at ±0.5 through `IXModel`. This supplies a small native replacement target once the actual output contract is validated. No `.ixm` sample is bundled. ## F19 — Config and keymap languages Source: `config file grammar.txt:4–6, 62–118`; `key config grammar.txt:58–91`. The config contract explicitly says last entry wins unless a consumer treats repeated entries as an array, and a nested scope is equivalent to a dotted key. Types include bool, integer/long, float/double, strings, vector/color forms, and string tables. Ordinary and delimiter strings are distinct lexical forms. The text declares `KeyVec4` but the `Entry` alternatives include `KeyRGBA`, not a standalone `KeyVec4` branch: treat this as a grammar discrepancy until tested. Do not apply last-wins globally. The task-priorities plugin collects repeated `task.name`/`task.priority` pairs in order and uses `indexOf`, giving the first matching name priority. This is a consumer-specific repeated-entry rule. Keymaps bind comma-separated key sequences to named or numeric commands; leading minus unbinds. Unknown commands are documented as unbind operations. A terminal asterisk makes a binding nonmodal outside fly mode, with modifier combinations explicitly unsupported. Alt/control/shift modifier order is encoded as `a`, `c`, `s`. Normal operation and basic pass-through have different rules. This needs its own parser and interaction tests rather than translation to a flat shortcut dictionary. ## F20 — Shader container observations `brushes.shader` and `patch9s.shader` have `@vertex330` and `@fragment330` sections and a std140 matrix block; `grid.shader` has the same stage names and many grid/camera/snap uniforms. Host binding, compilation defines and complete matrix conventions remain unknown. `brushes.shader:92–106` uses face IDs 0/1/2/3 to distinguish unselected/main/set-1/set-2 visualization, including screen-space stripe patterns for auxiliary sets. `patch9s.shader:35–41` calculates a lighting value but writes the normal-color expression instead; translating the unused lighting expression as the visible shader would be incorrect. `brushes.shader:71–76` has a `WA_ATI` expression variant. Preserve observable output contracts separately from obsolete driver workarounds. ## Native implementation extension — F30/F31 The [strict TXT profile](RUST_TXT.md) and [native CLI](CLI.md) implement the recovered TXT and DAT structures with explicit compatibility differences and guarded publication. Source grammars and legacy converter behavior above remain historical evidence; native formatting, Unicode handling, computed consistency and loss refusal follow the documented F30/F31 profile. E04 adds fixture/process tests without claiming native-editor conformance.