Format reference · .ota

Maps, missions & their variants

See how a text file gives one terrain multiple scenarios, starting positions and resources, then follow the keys and orders that shape a mission.

Syntax
TDF text sections
Pairs with
A matching TNT
Coordinates
Map pixels · X east / Z south
Variants
Sequential Schema N sections

One landscape, several scenarios

Established [02 R-MAP-01], [08 "Mission placement record"]. A Total Annihilation map is a pair of files in maps/ with the same basename: a binary .tnt with the terrain (tnt.md) and a text .ota with everything else — the map’s name, environment values (wind, tides, gravity, water), starting positions, and for single-player missions the placed units, features, victory conditions, and each unit’s scripted orders.

OTA files use the TDF syntax (tdf.md). The top-level section is [GlobalHeader], containing global properties and one or more [Schema N] subsections. A schema is a variant of the map: multiplayer maps have one or more schemas of type Network 1Network 4 (selectable variants of the same terrain — different metal/resources/features); missions typically have three (Easy, Medium, Hard).

Change the scenario, keep the terrain

Explore schemas

Same basin. Different starts and resources.

Original schematic: two land banks around a central waterway12
SURFACE METAL3
HUMAN METAL1000
HUMAN ENERGY1000
Switch between two variants from an original example.ota. The schematic uses a 4096 × 3072-pixel coordinate plane: east is +X, south is +Z. The terrain drawing is explanatory; no matching TNT or playable map is supplied. Positions and resource values are read from the fixture’s inspection data.

Read the section tree

An abbreviated original example; download the complete text to inspect both schemas and their start records.

[GlobalHeader]
{
  gravity=112;
  SCHEMACOUNT=2;           // Editor count; retail discovers sections itself.
  [Schema 0]
  {
    Type=Network 1;
    SurfaceMetal=3;
    HumanMetal=1000;
    HumanEnergy=1000;
    [specials]
    {
      [special0]
      {
        specialwhat=StartPos1;
        XPos=768;
        ZPos=640;
      }
      // special1 supplies StartPos2 in the complete example.
    }
  }
  // Schema 1 supplies Network 2 in the complete example.
}

Structure:

[GlobalHeader]
 ├─ global keys (name, planet, environment, size, ...)
 └─ [Schema 0], [Schema 1], ... (probed upward until missing)
     ├─ schema keys (Type, aiprofile, metal/energy, meteor settings)
     ├─ [units]    { [unit0]    { Unitname/XPos/ZPos/Player/InitialMission ... } ... }
     ├─ [features] { [feature0] { Featurename/XPos/ZPos } ... }
     └─ [specials] { [special0] { specialwhat=StartPosN; XPos; ZPos } ... }

Keys & placement records

Coordinates and size

Established. XPos/ZPos are map pixels: X eastward, Z southward (see conventions in README.md). The Pass authors size=7 x 4; but its TNT is 3584×1632 pixels, about 7×3.2 in 512-pixel squares. size is an editor description, not a source of runtime dimensions. YPos is an integer placement coordinate, scaled like X/Z into 16.16. At creation, non-mobile units snap X/Z to the footprint grid and replace Y with the terrain probe; mobile units keep the authored X/Y/Z through that fixup. It is therefore incorrect to discard Y for every placement [08 R-ENTRY-01 §6].

Global keys ([GlobalHeader])

KeyMeaning
missionnameDisplay name as authored by editors. Inert in the OTA: the executable’s two readers of this key read the campaign file’s MISSION<n> section; a skirmish map’s display name is its file name (translated) [02 R-MAP-01 §3], [02 R-MAP-01 §9]
missiondescriptionDescription shown in selection screens (default No description available; lower-cased and passed through the translation table, original spelling kept when no translation exists) [02 R-MAP-01 §3]
planetPlanet type string (selects the briefing globe art). The historical 272-file survey found: Green planet, Red Planet, Lava, Metal, Ice, Lush, Archipelago, Slate, Lunar, Water World, Wet Desert, Acid, Crystal, Desert, Urban, and empty. Unrecognized values fall back silently.
missionhintHint text (missions). Parsed into a camps\hints\<hint>.TXT path that nothing reads — inert [02 R-MAP-01 §1]
briefTXT basename in camps/briefs/ with the mission briefing text
narrationWAV basename in camps/briefs/ narrating the briefing
glamourPCX basename; the loader stores \<glamour>.PCX and the glamour display rebuilds bitmaps\glamour\<glamour>.PCX from it [02 R-MAP-01 §1]
glamoursoundWAV played over the glamour shot
lineofsight1 = true line-of-sight rules, 0 = off
mapping1 = normal fog-of-war mapping rules
tidalstrengthEnergy per tidal generator
solarstrengthNominally energy per solar collector. Authored throughout the historical 275-map survey and inert: the executable has no string for it, so a solar collector’s output is its own EnergyMake and the map cannot scale it.
lavaworld1 = “water” is lava (affects effects/pathing visuals)
waterdoesdamage, waterdamageAcid water: flag and damage rate
nosealeveltriggerNon-zero makes water opaque to projectiles and debris: the submerged-impact and debris-water tests return early [06 §8.2], [04 R-COB-04 §2]. Unrelated to the sea level value, which has no OTA key [02 R-MAP-01 §3]
killmulKill score multiplier, default 0.0. Parsed to a float and read by the end-of-battle score helper — Score += trunc(Kills × killmul), truncated separately from the time term [08 R-CAMP-01 §7], [08 R-CAMP-01 §11]. It is not inert: the doc-02 reader census that reported it so missed the score helper.
timemulTime score multiplier, default 0.0; three retail campaign maps author -1. Parsed to a float and read by the same score helper — Score += trunc(float(unsigned tick / 60) × timemul), truncated separately from the kill term [08 R-CAMP-01 §7], [08 R-CAMP-01 §11]. It is not inert: the doc-02 reader census that reported it so missed the score helper.
minwindspeed, maxwindspeedWind energy range (wind generators). Any non-negative value is used as authored, including 0; canonical terrain substitutes 100/2000 only for negative values or an unparsed global header. Legacy (0x1020) terrain always uses its own wind words [02 R-MAP-01 §6]. The historical survey found both keys on every map
gravityGravity for ballistic weapons, converted as trunc(g × 65536 / 900) to 16.16 world units per tick². Every retail map authors it; 192 of 275 use 112. The built-in runtime value 8155 is used for a negative authored value on canonical terrain, or for legacy terrain whose own gravity word is zero; a nonzero legacy gravity word is converted instead; an omitted key reads as 0 and yields gravity 0 [02 R-MAP-01 §6].
numplayersRecommended player counts, comma list (2, 4, 6, 8, 10). Stored as a string and inert (reader census: none); the lobby derives its count from the [specials] census [02 R-MAP-01 §3]
sizeMap size in 512-pixel squares (36 x 16). Inert: no string in the executable
memoryRecommended RAM. Stored as a string and inert (reader census: none)
useonlyunitsTDF filename (with extension) in camps/useonly/ restricting buildable units
nomovieSkip mission movie
MaxUnitsPer-player unit cap for this map (retail: 200–400; most common 250; 184 of 275 author it). Read only on the campaign path (default 200); skirmish and multiplayer take the limit from the setup record [02 R-MAP-01 §2], [08 R-SKIR-01 §6]
SCHEMACOUNTNominally the number of [Schema N] sections (1–4). Inert: the executable formats Schema %i and probes upward until a section is missing, so the count is discovered, not read.

Schema keys ([Schema N])

KeyMeaning
TypeNetwork 1Network 4 for multiplayer variants; Easy / Medium / Hard for mission difficulty variants. Compared case-insensitively (32-byte read); selection order and the StartPos-count rule are [02 R-MAP-01 §4]
aiprofileAI profile TXT basename in ai/; an empty or absent value loads ai\default.txt [02 R-MAP-01 §5]
SurfaceMetalMetal extraction concentration on ordinary ground; seeded into every plot cell as a signed byte (retail authors 1–255) [03 R-TERR-01 §1]
MohoMetalNominally the extraction concentration for moho mines. Authored throughout the historical 275-map survey and inert: only SurfaceMetal scales extraction, and a moho mine’s advantage is its own larger ExtractsMetal.
HumanMetal, HumanEnergyPlayer starting resources
ComputerMetal, ComputerEnergyAI starting resources
MeteorWeapon, MeteorRadius, MeteorDensity, MeteorDuration, MeteorIntervalMeteor storms (weapon name from tdf.md; defaults in gamedata/METEOR.TDF). Enable rule: only an empty MeteorWeapon disables the shower. Zero radius/density/duration/interval do NOT disable — they substitute all five values from the [Default] record and the shower stays enabled. A map authoring nonzero parameters with no weapon key is disabled with its parameters discarded.
Reader behavior

A missing section ends the search

The loader probes section names in order. With Schema 0, Schema 1 and Schema 2 present:

  1. Schema 0 → found
  2. Schema 1 → found
  3. Schema 2 → found
  4. Schema 3 → missing; stop

3 schemas discovered. SCHEMACOUNT is not read.

An original section-discovery experiment, separate from the downloadable file. Toggle the middle section and vary the authored count. Retail formats Schema %i and stops at the first missing section; SCHEMACOUNT has no reader. See [02 R-MAP-01 §3].

Mission end conditions

Missions declare their win/lose conditions as [GlobalHeader]-level keys (in the historical survey they sit at the global level, not inside a schema). The trigger vocabulary, with historical occurrence counts from a 272-file OTA survey, and the meaning the executable gives each key ([08 R-TRIG-01 §4] owns the behaviour; only the grammar is restated here):

KeyUsesSideMeaning
KillEnemyCommander=1;7victorya Player=2 unit whose type is its side’s commander is removed
DestroyAllUnits=1;90victoryPlayer=2 has no live units (polled, not latched)
KillAllMobileUnits=1;9victorythe last Player=2 unit with BMcode=1 is removed
BuildUnitType=ARMSY;8victoryPlayer=1 owns a finished unit of the type; name only, no count
CaptureUnitType=CORGATE;32victorya Player=2 unit of the type is captured; name only, no count
KillAllOfType=CORKROG;40victorythe last Player=2 unit of the type is removed; name only
KillUnitType=CORLAB, 1;32victoryN Player=2 units of the type removed (%[a-zA-Z],%i)
MoveUnitToRadius=ARMCOM, 1942, 1519, 100;18victorya selectable, finished Player=1 unit of the type (or ANYTYPE) within radius pixels (planar, inclusive) of the de-projected X, Z
UnitTypePassesX=ARMTSHIP, 6000; / UnitTypePassesZ=ARMCOM, 800;4victorya Player=1 unit of the type (or ANYTYPE) whose footprint cell is within two cells of X>>4 (Z>>4)
VictoryTimerRunsOut=3600;4victorygame tick >= seconds × 30; value must be > 0
CommanderKilled=1;123defeata Player=1 unit whose type is its side’s commander is removed
AllUnitsKilled=1;163defeatPlayer=1 has no selectable, finished unit (script-locked units do not count)
AllUnitsKilledOfType=ARMGATE;52defeatthe last unit of the type in Player=1 or Player=2 is removed; name only
UnitTypeKilled=ARMMOHO, 1;18defeatN units of the type, any owner, removed
DeathTimerRunsOut=1200;21defeatgame tick >= seconds × 30; value must be > 0
AnyUnitPassesX=4500; / AnyUnitPassesZ=60;3defeata Player=2 unit’s footprint cell is within two cells of X>>4 (Z>>4); value must be >= 0

Grammar facts the executable fixes: a flag key with value 0 is absent; each key builds at most one condition, in the vocabulary order above regardless of authored order; the argument scanset %[a-zA-Z] is letters only, so a type name containing a digit is truncated at the digit and never matches; ANYTYPE is recognised only by MoveUnitToRadius, UnitTypePassesX and UnitTypePassesZ; the four “name only” keys store the whole value, so BuildUnitType=ARMSY, 1; matches nothing. Win means every victory key holds at once (AND); lose means any defeat key holds (OR). The loader builds these records for a skirmish too, but only campaign sessions poll them [08 R-TRIG-01 §1]. Note which side each defeat key watches: CommanderKilled and AllUnitsKilled are about the player’s units, not the enemy’s.

Established (reference-install survey, 2026-09-12): the ordinary retail mount plan yields 277 physical OTA entries but 275 winning logical OTA paths. Counting the winning bytes once per path gives 163 authored AllUnitsKilled keys, all with value 1. Of 176 winning maps containing an Easy, Medium or Hard schema, 146 author the key and 30 omit it. The 13 winning campaign TDFs contain 175 sequential mission references to 175 distinct maps; 145 of those maps author the key. The additional difficulty-schema map is maps/example.ota, which no campaign references. Thus the inherited 163 count describes the whole winning map set, while 176 counts difficulty-schema maps; the former claim that all 176 authored the key is withdrawn. Neither physical-entry totals nor difficulty-schema classification establish campaign reachability. Retail’s injection of a default defeat condition when none is authored is a separate behavior [08 R-TRIG-01 §6].

A mission with no Player=2 unit at all, whose only victory key is the injected or authored DestroyAllUnits, is won at the first 30-tick poll, with the end latch written five polls later. An authored scenario that needs to run indefinitely should keep one Player=2 unit alive and out of reach (Immunity=1; only excludes it from the documented automatic target searches until made selectable; it is not invulnerability).

[specials] — start positions

Ten start positions exist, StartPos1StartPos10, placed in the multiplayer schema. The engine keeps only specialwhat values whose first eight characters are StartPos (case-insensitive); the suffix is parsed as an integer (a decimal digit run) when its first character is a digit, otherwise it takes a running counter that starts at 1 and advances only on the non-numeric labels, in file order (StartPos5, StartPosA, StartPosB gives the lettered labels 1 and 2). The stored index is the value minus one when positive — so StartPos0 and StartPos1 collide on index 0, and StartPosA collides with both [08 R-TRIG-01 §9] [08 R-TRIG-01 §12]:

[special0]
	{
	specialwhat=StartPos1;
	XPos=560;
	ZPos=240;
	}

[features] — placed features

[feature0]
	{
	Featurename=WaterAquaOre3;   // feature section name (tdf.md)
	XPos=362;
	ZPos=427;
	}

These add to the features already embedded in the TNT’s cell grid.

[units] — placed units (missions)

[unit13]
	{
	Unitname=CORCS;
	Ident=;                      // optional unique ID for order references
	XPos=3216;
	YPos=0;                      // authored Y; non-mobile fixup probes terrain
	ZPos=1184;
	Player=2;                    // owning player (1 = human)
	HealthPercentage=100;
	Angle=0;                     // facing in degrees
	Kills=0;                     // editor-authored; placement parser ignores it
	InitialMission=w 900,p 1416 852,;
	}

Less common unit keys in retail missions (occurrence counts from the full census; all flags are =1; when present):

KeyUsesMeaning
CreationCountdown2088Parsed as an integer and inert (no reader; units are always created at battle entry). Always 0 in retail
InitialGroup262Parsed as an integer into a 4-bit field (retail values patrol, Rockos read as 0) and inert — no reader found [08 R-TRIG-01 §11]
BuildPriority213Parsed as an integer and inert
AIIgnore23Parsed and inert
Immunity22Suppresses primary automatic target acquisition and the AI nearest-hostile search until make-selectable clears the state; not damage immunity [08 “Mission placement record”], [06 §3.1].
AIPriorityTarget9Parsed and inert
MissionCriticalUnit6Parsed and inert
OffMapUnit3No string in the executable — inert
KillsWritten by editors on every unit; inert — the placement parser has no reader, so veterancy cannot be authored

Player=0 is read as 1. A Player value with no matching active slot (after the one-based fixup, slot index 10 or more, an inactive slot, or a slot with no human/computer/remote controller) is fatal: the executable reports Player number %d invalid for unit %s and exits [08 R-TRIG-01 §9]. A [feature] block with a missing name or a negative XPos/ZPos is dropped.

InitialMission — the order mini-language

Established. The interpreter runs once after all mission units have been created, during campaign entry or a between-missions restore. It builds the ordinary order queues; it does not run as a separate script on each tick [04 §3.6], [08 R-ENTRY-01 §6].

Every comma terminates a command. Arguments within a command are separated by whitespace; a comma between coordinates would instead start a new, usually ignored token. The table describes well-formed inputs. Unknown leading characters are skipped, and many argument scans do not check their conversion count, so malformed operands have no general zero-default rule. Most verbs accept either case, with the uppercase-led W build-dispatch quirk described in [04 §3.6].

SyntaxMeaning
m X ZQueue move to the point.
a X ZQueue numeric ground attack; both coordinates must parse.
a UNITTYPEQueue attack-by-type when the catalog type resolves; an unknown type queues nothing.
b UNITTYPE N X ZQueue a counted build. An actor with a mover (BMcode == 1) gets mobile build at X/Z; an actor without a mover gets building build and no position. A factory may author only name/count. Product lookup must succeed.
bw NQueue stockpile production.
p X Z [SECONDS]Queue one patrol point with optional timeout (zero when omitted); more points use further comma-separated p commands.
w SECONDS [N]Queue wait; the optional integer is the wait-for-unit selector.
wa [NAME]Queue wait-for-attack on the named unit; missing/unresolved name falls back to self.
g NAMEQueue guard of the first matching spawned Ident/Unitname; an unresolved name queues nothing. Numeric text is still a name, not an InitialGroup selector.
i NAMESend an immediate attach request to board the named carrier; no order is queued.
o MOVE FIREWrite the standing move/fire fields, retaining each operand’s low two bits. Missing or malformed operands retain that field’s prior value; no order is queued.
u X ZQueue unload at the point.
dQueue the self-destruct front gate.
sQueue make-selectable.

Established — numeric boundary. Coordinates and durations first parse into single precision, then promote before multiplication by 65,536 or 30 and truncation toward zero. Positional orders carry literal zero Y. For example w 0.7 installs 20 ticks, not 21 [08 R-ENTRY-01 §6].

Established (scanner and caller trace) — prefixes and failed fields. Each command’s argument scan advances through one byte string. Leading whitespace is skipped; a successful conversion consumes its numeric or name prefix rather than requiring a whole whitespace-delimited token. The first conversion that cannot match stops the scan, and its destination and all later destinations retain their previous contents. A later valid-looking word cannot bypass that failure.

  • Integer fields use signed decimal scanning: optional sign, then a decimal digit run. Accumulation and negation wrap to 32 bits; they do not saturate or retry as floating point. For example, 2.5 converts the integer prefix 2 and leaves .5 for the next conversion; 2x leaves x, which makes a following numeric conversion fail. 0x10 supplies decimal zero, not hexadecimal sixteen. Missing digits fail without assigning the field.
  • Floating fields accept decimal digits with an optional sign, decimal point and e/E exponent (d/D is not an exponent here). At least one mantissa digit is required; nan and inf are not accepted spellings. The scanner can consume an exponent marker and sign without exponent digits after a valid mantissa; the converter then retains the mantissa value. Conversion stores binary32 and does not turn a binary32 overflow into a failed scan: signed infinity can reach the ordinary subsequent numeric conversion. This is not a saturation rule.
  • Names consume the allowed prefix: letters, digits, underscore and dot, except wa, whose scanset omits underscore. A hyphen or other excluded byte ends the name and remains at the current scan position. Empty name conversion leaves its destination untouched. The numeric-attack caller requires two successful floats, otherwise it tries the name form; wa requires one successful name, otherwise it selects self.

Established — caller initialization matters. Build and stockpile counts start at 1; wait duration and wait selector start at zero; patrol timeout starts at zero; standing move/fire operands start from the unit’s current values. Failed fields retain these initial values where supplied. Move, unload, patrol and mobile-build coordinate temporaries are not all initialized before scanning, and most callers ignore the conversion count. Their failed-coordinate results therefore cannot be reconstructed from OTA text alone. A checked host must identify its chosen handling as policy, rather than inventing a universal zero default [04 §3.6], [08 “Argument parsing”], [08 R-ENTRY-01 §6].

Established — selection postlude. Queuing at least one order clears the unit’s selectable state. Unless the string contains numeric attack, patrol, self-destruct or make-selectable, the interpreter appends a final make-selectable order. Thus an explicit s can unlock the unit before the rest of its queue completes, but absence of s does not imply a permanent lock. Whether later player orders replace the queue is ordinary order behavior, not an extra OTA script-control rule [04 §3.6].

Established — name scope. Named-unit lookups walk the sparse array of successfully created placements in file order, testing Ident and then Unitname on each record case-insensitively. The first match wins; forward references work because all placements are created before interpretation. Failed allocations leave skipped holes [08 "Argument parsing"].

Which keys the engine reads

The generated key → consumer table [02 R-KEYS-01 §5] lists every [GlobalHeader], [Schema N], placed-object and trigger key the loader reads, with accessor, stored width, default and consumer; [02 R-MAP-01 §3] and [02 R-MAP-01 §5] give the read order and the retail authoring census.

Established. The OTA loader does not consume SolarStrength, MohoMetal, SCHEMACOUNT, size, missionname or placement Kills and OffMapUnit. A spelling elsewhere in the executable does not establish an OTA reader: missionname, for example, belongs to campaign metadata [02 R-MAP-01 §3], [08 R-TRIG-01 §9].

Schema sections are found by formatting Schema %i and probing upward from 0 until a section is missing (no retail OTA has a gap; retail schema counts are 1, 2, 3 or 4). Keys are read from one section at a time — the accessors never fall through to the parent section — so a global key inside [Schema N] or a schema key at global level is invisible [02 R-MAP-01 §3]. The difficulty and network vocabulary is the literal set Easy, Medium, Hard, Network 1, Network 2, Network 3, Network 4; the placement blocks are labelled MISSIONUNIT DATA, MISSIONFEATURE DATA and MISSIONRULE DATA, and the raw map payload sections Raw Plot Data and Raw Feature Data. The loader’s own diagnostics name its failure modes: No GlobalHeader block in mission file!, No suitable schema type in mission file!, Old TED format no longer supported!, and Hey, joker! Mission file %s is corrupt (no header found).

Unknowns and caveats

  • nomovie’s reader is the end-of-campaign movie gate; which cinematic it suppresses is doc 07/08 territory [02 R-MAP-01 §3].
  • Established: Angle uses the integer accessor, wraps the degree value multiplied by 65,536 to signed 32-bit, divides by 360 with truncation toward zero, then stores the low 16 bits. Fractional authoring never survives as a fraction [08 "Mission placement record"]. Model-facing conventions belong to the unit/model contract, not an additional OTA transform.
  • No environment key is read at both levels: each is read from exactly one section, see “Which keys the engine reads” above.
  • Unknown: run-specific coordinate values consumed after failed, unchecked argument conversions, and outcomes of overlong commands that overwrite temporary token storage. The scanner’s prefix, integer wrap, name termination and stop-on-failure rules are established above; another scanner trace cannot supply untouched temporary values. Nanolathe’s local sequential scanner now implements those rules, with zero as explicit host policy for untouched uninitialized coordinates and a bounded token length. These policies are documented in DESIGN_SESSIONS_AI_SAVE C13.
  • Unknown: exact rounding for adversarial decimal inputs through retail’s intermediate floating converter has not been established. Its grammar, binary32 store and signed-infinity overflow result are established above; a trace of the converter’s digit reduction and rounding arithmetic would settle remaining last-bit differences. Nanolathe currently uses Go’s binary32 decimal conversion at that boundary, marked as host implementation rather than a claim of proven equality for every decimal string.
  • Malformed-input outcomes for an OTA (syntax error fatal, missing GlobalHeader, unknown unit name skipped, bad Player fatal, unknown feature name fatal, missing TNT fatal) are tabulated in [02 R-MALF-01 §2].
  • The mission open path’s six diagnostics, including the misspelled Hey, joker! There is no mission defintion for this mission: %s, are recorded in the executable spec doc 02 §6 “Mission-file diagnostics”.

Sources & evidence

This page adapts the owning research at the pinned engine revision. Download the complete source snapshot. Bracketed evidence IDs refer to the owning research ledger; observations and implementation policy retain their original scope.

  • Historical key/command surveys cite 272 and 275 OTA files, and 176 campaign missions. The winning-path survey in “Mission end conditions” reconciles the current 275-map/175-campaign-map scope with the 176 maps containing difficulty schemas; it does not retrospectively establish the provider set of the older 272-file survey. Counts do not override loader evidence or turn physical entries into winning paths.
  • OTA File Content Description, TA Design Guide — variable catalog, schema and InitialMission documentation with retail excerpts: https://units.tauniverse.com/tutorials/tadesign/tadesign/otadesc.htm
  • Verified against maps/The Pass.ota from totala2.hpi, plus a key census of all 272 retail OTA files (base, patch, Core Contingency, Battle Tactics, bonus maps). The executable key tables, rather than that survey alone, establish what the loader consumes.
  • Nanolathe boundaries: formats/ota.go retains the TDF tree and exposes metadata, including inert editor fields; internal/mission/load.go and internal/mission/initial_mission.go own runtime reads and interpretation. Authored checks include formats/retail_test.go, internal/mission/load_test.go, and internal/mission/initial_mission_arguments_test.go.