MM — Theater Map Layout (.MM)¶
FA_2.LIB contains 75 .MM files. Each defines a theater — the complete scene
description for a group of missions: terrain reference, weather, object
placements, waypoints, and terrain tile overrides. Format is plain ASCII
text with a keyword/argument syntax, CRLF line endings.
Tools¶
fx¶
fx mm info <file.MM> # scene summary (alias of fx mission)
fx mm unpack <file.MM> [-o out] # export to editable text
fx mm pack <file> [-o out.MM] # re-encode (byte-identical)
File Layout¶
Plain text; keyword/argument lines, blocks terminated by a lone . line.
Sections appear in this order:
- File header — global scene parameters
sidesblock — faction alignment tabletime/historicalera— time of day and eraobjblocks — static object placementsspecialblocks — named map labels (cities, bodies of water)tmapentries — sparse terrain tile overridestmap_namedentries — named tile positions (present in some files)waypoint2blocks — AI/scripted waypoint sequences (present in some files)tdicblocks — per-tile collision/passability bitmaps
Header Keywords¶
| Keyword | Arguments | Description |
|---|---|---|
textFormat |
(none) | File type marker — always the first line |
map |
<name>.T2 |
Terrain map file to load |
layer |
<name>.LAY <index> |
Cloud/atmosphere layer file and slot index |
clouds |
<int> |
Cloud density (0 = none) |
wind |
<speed> <direction> |
Wind speed and bearing |
view |
<x> <y> <z> |
Initial camera world-space position |
Sides Block¶
Defines faction alignment. Four variants across all 75 files:
| Keyword | Entry count | File count |
|---|---|---|
sides |
18 | 9 |
sides2 |
19 | 32 |
sides3 |
24 | 9 |
sides4 |
64 | 25 |
Each entry is a tab-indented hex byte: $00 = neutral/friendly, $80 =
hostile to the player.
The table is a flat array indexed by faction code: entry i = hostility of
side code i. The number suffix (2/3/4) is a format version indicating how
many faction codes are defined — each version is a strict superset of the
previous (sides2[0–18] == sides3[0–18] == sides4[0–18];
sides3[0–23] == sides4[0–23]). Theaters added in later FA versions use a
higher-numbered variant to cover newly introduced faction codes.
The nationality field in obj blocks is not an index into this table —
it is a cosmetic UI code (country flag/emblem in briefings) and can exceed 162,
far beyond the 64-entry maximum.
Object Block (obj)¶
Each obj block defines one static scene object. Terminated by a lone . line.
| Field | Arguments | Description |
|---|---|---|
type |
<name>.OT |
Object type reference |
pos |
<x> <y> <z> |
World-space position |
angle |
<yaw> <pitch> <roll> |
Orientation in degrees |
flags |
<hex> |
Object state/behaviour flags (see below) |
speed |
<int> |
Initial speed |
alias |
<int> |
Unique object ID (negative integers) |
nationality |
<int> |
Primary faction code |
nationality2 |
<int> |
Secondary faction code |
nationality3 |
<int> |
Tertiary faction code |
name |
<str> |
Display name |
color |
<int> |
Color index |
icon |
<int> |
Map icon ID (-1 = no icon) |
react |
<hex> <hex> <hex> |
Hostile faction bitmask: three 16-bit words covering faction codes 0–47 (bit n set = react to faction n as hostile) |
searchDist |
<int> |
AI detection radius |
skill |
<int> |
AI skill level |
tdic |
<int> |
Tile dictionary index |
special |
(none) | Marks object as a special/scripted entity |
w_for |
<int> |
Waypoint owner reference |
map_obj_success_flags |
<alias> <hex> |
Looks up entity by alias, then writes the hex value into entity ot_flags bits 5–7: entity+1 = (value) \| (entity+1 & 0xffffff1f). Used to set or restore per-object mission-objective state. The mission save handler (FUN_00495e80) serialises current bit 5–7 state back using this keyword. |
flags Bit Survey¶
8 distinct values observed across all 75 files (8,373 obj blocks total):
| Value | Bits | Object types | Count |
|---|---|---|---|
$0 |
— | Decorative buildings, flags, landmarks (no game logic) | 471 |
$1 |
0 | Fuel depots, bunkers, strips, flags (friendly?) | 968 |
$3 |
0, 1 | Mobile military units — all .NT (AA guns, SAMs, fighters) |
232 |
$401 |
0, 10 | Fuel depots, control towers, strips, flags | 5,524 |
$403 |
0, 1, 10 | Mobile military units — all .NT |
241 |
$601 |
0, 9, 10 | Named structures (carrier KING.OT, houses, factory) | 24 |
$4003 |
0, 1, 14 | Runways (STRIP1, DTSTRP, STRIP5, STRIP7) | 906 |
$4403 |
0, 1, 10, 14 | Runways (STRIP4, STRIP) | 2 |
Bit meanings:
- Bit 0 ($1) — inferred — present on all non-decorative objects; likely
"active / participates in game logic"
- Bit 1 ($2) — inferred — set on mobile units (.NT) and runways;
"mobile or functional structure"
- Bit 14 ($4000) — inferred — set only on runway strips; "landing surface"
- Bit 9 ($200) — confirmed — @Reaction@12 (0x464040): when set, entity
is immediately rejected as a valid AI target (returns '\x1f' rejection
code, same as non-targetable or dead). Only 24 objects carry this flag
($601): carrier KING.OT, houses, and factory types. Semantics: "protected
from AI targeting / not auto-targetable" — used for mission-critical scene
objects enemies should not autonomously engage.
- Bit 10 ($400) — confirmed — _Reaction_12 (0x464040) and
_MaskEvents_4 (0x463ea0): drives civilian/light-type event handling. Set on
fuel depots, control towers, runway strips, and flags ($401). Shared
semantic with NT.md bit 10. Semantics: "civilian or non-combat structure"
— participates in game logic (bit 0 set) but uses lighter event-system
dispatch paths.
Example¶
obj
type STRIP1.OT
pos 890323 0 462935
angle 0 0 0
nationality3 185
flags $4003
speed 0
alias -10100
.
Special Block (special)¶
Named geographic labels shown on the theater map (cities, seas, landmarks).
Same field set as obj but without type.
special
pos 1816892 0 1071944
name East Falkland
color 48
icon -1
flags $0
.
Terrain Tile Data¶
tmap — sparse tile overrides. Only non-default tiles appear; the grid is
otherwise implied from the .T2 terrain file.
tmap <col> <row> <tile_id> <variant>
colandroware multiples of 4 (grid coordinates in 4-unit steps)tile_idis an index into the terrain tile setvariantis a sub-tile selector (0–3 observed)
tmap_named — named tile positions. Like tmap but with a symbolic key
encoding the position:
tmap_named k<col3><row3> <col> <row>
The key k<col3><row3> zero-pads column and row to 3 digits each (e.g.
k000004 = col 0, row 4). The explicit <col> and <row> arguments are
always identical to the values encoded in the key — they are redundant.
Present in maps that reference these tiles from scripts or other systems.
Waypoint Block (waypoint2)¶
waypoint2 <count>
w_index <int>
w_flags <int>
w_goal <int>
w_next <int>
w_pos2 <unk> <unk> <x> <altitude> <z>
w_speed <int>
w_wng <int> <int> <int> <int>
w_react <int> <int> <int>
w_searchDist <int>
w_preferredTargetId <int>
w_name <str>
[next waypoint entry...]
count is the number of waypoint entries that follow. Each entry begins with
w_index. w_pos2 has 5 arguments; the first two are always 0 0 in observed
files.
Tile Dictionary (tdic)¶
Follows the tmap section. Each tdic block defines a 4×8 binary
passability/collision grid for a tile variant.
tdic <id>
<b0> <b1> <b2> <b3>
<b0> <b1> <b2> <b3>
... (8 rows)
Values are 0 (passable) or 1 (blocked). <id> observed as 256 in all cases.
Engine Notes¶
World-Space Coordinate System — confirmed¶
?MAPWorldToScreen (MAPWorldToScreen) maps 3D world-space positions to 2D map
screen coordinates:
screen_x = DAT_00536508 + (world_x - worldCenter) / mapScale;
screen_y = DAT_0053650a + (DAT_00536528 - world_z) / mapScale;
world_x/world_zare the first and third components of the int[3] world position vector (Y =world_zin the map's X/Z plane;world_y= altitude, not used for map display)worldCenter/DAT_00536528— world-space map center (origin) for X and Z axes (set at theater load time)DAT_00536508/DAT_0053650a— screen center pixel coordinatesmapScale— world-units-per-pixel scale factor (runtime zoom level); larger = more zoomed out
The Z-axis inversion (origin_z - world_z) means positive world-Z maps to
upward on screen, consistent with the engine's +Z = northward convention.
pos and view values in MM files are in these same world-space integer units.
World-space unit = 1 foot (confirmed). Calibrated via JT.md seeker-range
cross-check: AIM9X lobe 1 max ^50000 = 8.2 nm; 50,000 feet / 6,076 ft/nm
≈ 8.23 nm ✓. The FA engine uses feet throughout for all world-space coordinates.
Round-Trip Notes¶
fx mm pack (the mission codec) re-emits the keyword stream byte-identically,
including CRLF line endings and tab indentation; tests/test_mission.cpp
asserts byte preservation over both .M and .MM inputs.
Open Questions¶
1. w_goal semantics¶
Only 0 and 1 observed across all 75 files (192 waypoints total). w_goal 0
always appears with w_flags 1 and w_speed 0 (stationary anchor/spawn
point); w_goal 1 appears with w_flags 0, a non-zero speed, and a w_react
bitmask (active patrol waypoint). Exact goal-type semantics need a trace of the
waypoint consumer in the game executable.
Status: open — re-static (#54)
Related¶
Formats: T2 — terrain height/color/type maps referenced via
map; LAY — cloud layer files referenced via layer; M —
.M individual missions placed within a theater; CAM — campaign
definitions that group .MM theaters; BRF — .OT object type
definitions referenced by obj blocks.