Skip to content

CLI Reference

All commands follow the pattern fx <subsystem> <subcommand> [args].

Quick Reference

fx lib     ls / unpack / extract / pack / patch   # .LIB archive management
fx pic     info / unpack / pack         # .PIC images (dense, sparse, JPEG)
fx seq     dump / unpack / pack         # .SEQ cutscene timelines
fx audio   info / unpack / pack         # .11K / .5K / .8K raw PCM audio
fx ot      info / unpack / pack         # object type definitions
fx pt      info / unpack / pack         # aircraft type definitions
fx nt / jt / see / ecm / gas ...        # other type definitions
fx mission info / unpack / pack         # .M / .MM mission and map files
fx sh      info / unpack                # .SH 3D shapes → Wavefront OBJ
fx raw     info / unpack / pack         # .RAW in-game screenshots ↔ PNG
fx sms     dump                         # FA.SMS symbol map → CSV
fx t2      info / dump / heightmap      # .T2 terrain maps (heights, textures)
fx plt     info / dump                  # .P pilot save file
fx pal     info / dump                  # .PAL VGA palettes
fx inf     dump                         # .INF aircraft tech sheets
fx hud     dump / set                   # .HUD layout overlays
fx lay     dump / gradient / set        # .LAY sky/atmosphere layers
fx fnt     info / unpack / pack         # .FNT bitmap fonts (x86 glyph recompiler)
fx mus     dump                         # .MUS music sequencer bytecode
fx bi      dump / decompile             # .BI disassembler + BI→AI decompiler
fx ai      compile                      # .AI → .BI compiler

lib — Archive

fx lib ls      <file.LIB>
fx lib unpack  <file.LIB> [output_dir]
fx lib extract <file.LIB> <NAME> [NAME ...] [-o output_dir]
fx lib pack    <dir>      <output.LIB>
fx lib repack  <src.LIB>  <output.LIB>
fx lib patch   <src.LIB>  <name> <file> <output.LIB>

fx lib ls <file.LIB>

List the contents of a .LIB archive.

> fx lib ls FA_2.LIB
Name           Flags      Size
-------------  -----  --------
_AFTB2.11K     dcl       26488
BALTIC.TXT     dcl        3421
PALETTE.PAL    dcl        2310
...
5405 file(s)

Flags: raw = uncompressed, lzss = LZSS, pxpk = PxPk, dcl = PKWare DCL.

fx lib unpack <file.LIB> [output_dir]

Extract and decompress all files. Output defaults to the archive stem.

fx lib unpack FA_2.LIB out/FA_2
fx lib unpack FA_3.LIB          # extracts to ./FA_3/

Entry names are written through ealib_safe_name: the characters & * ? " < > | / \ : each become _ (e.g. the looping-audio prefix in &AFTB2.11K extracts as _AFTB2.11K), so output filenames are identical on every platform and a crafted archive cannot write outside the output directory. File paths on the command line follow the operating system's case rules (exact case required on Linux); entry names inside archives are case-insensitive everywhere.

fx lib extract <file.LIB> <NAME> [NAME ...] [-o output_dir]

Extract one or more named entries. Output defaults to the current directory; use -o to redirect. Name matching is case-insensitive.

fx lib extract FA_2.LIB BALTIC.TXT
fx lib extract FA_2.LIB F16C_0.PIC F15C_0.PIC -o pics

fx lib pack <dir> <output.LIB>

Pack all files in dir into a new .LIB. Files are stored uncompressed (flags=0) and ordered by name, so the same input directory produces a byte-identical archive on every platform. The game accepts both raw and compressed entries.

fx lib repack <src.LIB> <output.LIB>

Rebuild the container from its own directory: payloads stay raw (still compressed), entry metadata is copied verbatim, and every offset — including the directory's terminator entry — is recomputed from scratch. Output is byte-identical to the input for well-formed archives; the fa_repack_roundtrip integration test (FX_FA_ROOT mode) proves that against every .LIB in a real install.

fx lib patch <src.LIB> <name> <file> <output.LIB>

Replace one named entry without touching the rest of the archive.

fx lib patch FA_2.LIB BALTIC.TXT edits/BALTIC.TXT FA_2_mod.LIB
fx lib patch FA_3.LIB F16C_0.PIC F16C_mod.PIC FA_3_mod.LIB

See also: fa/formats/LIB.md

pic — Images

fx pic info   <file.PIC>
fx pic unpack <file.PIC> [-p PALETTE.PAL] [-o output.png]
fx pic pack   <file.png> [-p PALETTE.PAL] [-o output.PIC]
fx pic repack <file.PIC> [-o output.PIC]

fx pic info <file.PIC>

Print the PIC header: format, dimensions, palette and span offsets.

fx pic unpack <file.PIC> [-p PALETTE.PAL] [-o output.png]

Decode to PNG. Handles all three sub-formats: JPEG, dense (format 0), and sparse (format 1). -p is required for paletted PICs; omit for JPEG.

fx pic pack <file.png> [-p PALETTE.PAL] [-o output.PIC]

Encode to a dense PIC (format 0) with a full 256-color inline palette. Pixels with alpha < 128 map to transparent (index 0xFF). Always provide the same PALETTE.PAL used during unpack.

fx pic repack <file.PIC> [-o output.PIC]

Byte-identical structural repack: re-derives every region from the parsed header and re-emits the file by construction (whole-file passthrough for JPEG PICs). Without -o it verifies only — exit 0 means the file re-emits byte-identically; a byte no documented region accounts for fails the repack instead of being silently copied.

See also: fa/formats/PIC.md · fa/formats/PAL.md

seq — Cutscene timelines

fx seq dump   <file.SEQ>
fx seq unpack <file.SEQ> [-o out.txt]
fx seq pack   <in.txt>   -o <out.SEQ>

fx seq dump <file.SEQ>

Pretty-print all events to stdout.

fx seq unpack / pack

Round-trip editable text. Output is byte-identical to originals.

See also: fa/formats/SEQ.md

audio — PCM audio

fx audio info   <file.11K|.5K>
fx audio unpack <file.11K|.5K> [-o out.wav] [-r hz]
fx audio pack   <in.wav>       -o <out.11K|.5K> [-r hz]

Sample rate is inferred from the file extension (.11K = 11025 Hz, .5K = 5512 Hz). Override with -r. Input WAV for packing must be mono and 8-bit.

See also: fa/formats/11K.md

ot / nt / pt / jt / see / ecm / gas — Type definitions

All seven type definition formats share the same subcommand pattern:

fx <type> info   <file>
fx <type> unpack <file> [-o out.txt]
fx <type> pack   <in.txt> -o <out>
Command Format Contents
fx ot .OT Generic object type
fx nt .NT NPC / crew type
fx pt .PT Plane type (aircraft aerodynamics + avionics)
fx jt .JT Jettison / weapon type
fx see .SEE Seeker (missile guidance) type
fx ecm .ECM ECM pod type
fx gas .GAS Gas / smoke type

info prints every field annotated with the schema tables from fa/formats/OT.md and its extensions; each extension section restarts its schema at the section's first field. Version-dependent fields can shift label alignment mid-section — see the format specs' Open Questions.

> fx pt info F16C.PT
File: F16C.PT  (219 fields, 20 tables)

--- OT/General Section (struct_type=5) ---
  [  0] struct_type              = 5            (5)  ; 1=OT 3=NT 5=PT 7=JT
  [  3] names                    = ot_names -> "F-16C"  ; ptr -> short, long, filename
  [  6] shape                    = shape -> "f16.SH"  ; ptr -> .SH filename
  ...
--- NT/Npc Extension (struct_type>=3) ---
  [ 60] npc_flags                = 0            (0)  ; u32 bitfield; bits 18-20/25-26 control AI state
  ...
--- PT/Plane Extension (struct_type>=5) ---
  [ 69] pt_flags                 = 32767        (32767)  ; $1=Jet $2=Hook $4=TwoSeat $8=Helo $10=Eject $20=VTOL $40=Carrier $80=Bay
  ...
--- Pointer Tables ---
  :ot_names
    "F-16C"
    ...

See also: fa/formats/BRF.md · fa/formats/OT.md · fa/formats/NT.md · fa/formats/PT.md · fa/formats/JT.md · fa/formats/SEE.md · fa/formats/ECM.md · fa/formats/GAS.md

mission / mm — Mission and map files

fx mission info   <file.M|.MM>
fx mission unpack <file.M|.MM> [-o out.txt]
fx mission pack   <in.txt>     -o <out.M|.MM>

fx mm is an alias for .MM map files. Round-trips byte-identically for all 592 mission files in FA_2.LIB.

See also: fa/formats/M.md · fa/formats/MM.md

sh — 3D shapes

fx sh info   <file.SH>
fx sh unpack <file.SH> [-o out.obj]

fx sh info <file.SH>

Print scale factor, bounding box (feet), vertex count, face count, and texture names.

fx sh unpack <file.SH> [-o out.obj]

Export geometry to Wavefront OBJ with usemtl directives for texture references. Open in Blender, MeshLab, or any 3D viewer.

65 of 1275 FA shape files use x86 machine code for rendering (particle effects, AC130, etc.) and produce no OBJ output. All others extract cleanly.

See also: fa/formats/SH.md

cb8 — FMV video

fx cb8 info   <file.CB8>
fx cb8 frames <file.CB8> [-o output_dir]
fx cb8 unpack <file.CB8> [-o output_dir]
fx cb8 repack <orig.CB8> <png_dir> [-o out.CB8]

fx cb8 info <file.CB8>

Print video dimensions, frame count, frame rate, and total duration.

> fx cb8 info JANELOGO.CB8
video: 320 x 240, 466 frames, 15.0 fps, 31.07 s
audio: 11025 Hz PCM, 400 sync ticks/frame

fx cb8 frames <file.CB8> [-o output_dir]

Decode every frame to a PGM image (raw 8-bit palette indices) in output_dir (default: current directory). Files are named frame0000.pgm, etc. Every frame is a self-contained key frame; frames decode in any order.

fx cb8 unpack <file.CB8> [-o output_dir]

Decode every frame to a colour PNG through its embedded per-frame palette (no external PAL applies to CB8). Files are named frame0000.png, etc.

fx cb8 repack <orig.CB8> <png_dir> [-o out.CB8]

Rebuild a movie around edited frames: the PNGs (one per original frame, same dimensions, ≤ 256 distinct colours each) are re-encoded as CB8 key frames with rebuilt per-frame palettes and codebooks, while the DRBC header, every audio chunk, the stream order, and the VooM timing carry over from orig.CB8 verbatim. The unpack→repack loop is pixel-exact; byte identity is a non-goal (the encoder chooses its own codebook packing).

See also: fa/formats/CB8.md

raw — Screenshots

fx raw info   <file.RAW>
fx raw unpack <file.RAW> [-o out.png]
fx raw pack   <file.png> [-o out.RAW]

fx raw info <file.RAW>

Print the capture header: magic and dimensions (width and height are u16 big-endian at +8/+10 — confirmed against captures at four resolutions).

fx raw unpack <file.RAW> [-o out.png]

Convert an in-game screenshot (Ctrl-Alt-Shift-V, written to the install directory) to PNG using the file's embedded 8-bit palette.

fx raw pack <file.png> [-o out.RAW]

Convert a PNG back to a RAW screenshot: the embedded palette is rebuilt from the image's distinct colours in first-seen order (max 256; alpha ignored). The PNG→RAW→PNG loop is pixel-exact.

See also: fa/formats/RAW.md

sms — Symbol map

fx sms dump <FA.SMS> [-o out.csv]

fx sms dump <FA.SMS> [-o out.csv]

Export all 3,829 MSVC C++ mangled symbols from FA.SMS to a two-column CSV (va,name), sorted by virtual address with ties broken by name — the output is byte-identical on every platform. Without -o, prints to stdout. The CSV uses LF line endings on every platform (previously CRLF on Windows).

> fx sms dump FA.SMS -o symbols.csv
FA.SMS -> symbols.csv (3829 symbols)

The CSV can be imported directly into Ghidra (Script Manager -> ImportSymbolsScript) or IDA Pro to auto-label all known functions and data symbols.

See also: fa/formats/SMS.md

t2 — Terrain map

fx t2 info      <file.T2>
fx t2 dump      <file.T2> [--leaves]
fx t2 heightmap <file.T2> <out.png>

fx t2 info <file.T2>

Print the theater name and texture atlas, grid dimensions, leaf grid, the leaf elevation-band range, and the surface class distribution (water vs land, top land classes by count). Grid is width × height per the engine's field map, and the distribution counts the per-tile summary records (the authored far-LOD array — see fa/formats/T2.md § Data Payload).

> fx t2 info UKR.T2
Theater:    UKR (Ukraine)
Atlas:      ukr.PIC
Grid:       26 x 25 (650 tiles)
Leaves:     208 x 200 (8 per tile side)
Elevation:  leaf bands 0..6
Surface:    water 195 (30.0%)  land 455 (70.0%)
Land classes:
  0xD0  21 tiles (3.2%)
  0xD2  36 tiles (5.5%)
  ...

fx t2 dump <file.T2> [--leaves]

CSV of the terrain records to stdout — x,y,surface_class,elevation, texture_variant, row-major. By default dumps the per-tile summary array; --leaves dumps the full-resolution leaf grid (8×8 leaves per tile).

fx t2 heightmap <file.T2> <out.png>

Export the leaf elevation bands as a grayscale PNG, one pixel per leaf (e.g. 256×256 for a 32×32-tile theater). Bands are normalized to the file's own maximum so the relief is visible.

T2 files are stored in FA_2.LIB; unpack the archive first.

See also: fa/formats/T2.md

plt — Pilot save

fx plt info <file.P>
fx plt dump <file.P>

fx plt info <file.P>

Print pilot identity fields and active campaign state from a .P pilot save file.

> fx plt info PLT441.P
File:       PLT441.P  (9696 bytes)
Name:       Maverick
Callsign:   MAVERICK
Rank:       Captain
Voice:      ^ACID.5K
Nose art:   NOSE01
Left decal: LEFT03
Right decal:RIGHT03
Portrait:   PILOT02

Campaign:   UKRAINE.CAM  (Ukraine Crisis)
Aircraft:   F16C.PT
Pool:       F16C.PT, F15C.PT
Ordnance:
  AIM9M.JT         x4
  AIM120.JT        x2
  MK82.JT          x6
Sensors:    F16CSEE.SEE

fx plt dump <file.P>

Print the confirmed stats block (kill tallies, mission counters, weapon accuracy at 0x1F800x21F7). Decoding the remaining gap regions is tracked in #29.

Pilot save files (.P) are stored in the FA install directory alongside FA.EXE. The stats block (offsets 0xB0–0x0D7E) is not yet decoded; only the identity and campaign blocks are read.

See also: fa/formats/P.md

pal — VGA palettes

fx pal info <file.PAL>
fx pal dump <file.PAL> [-o out.png]

fx pal info <file.PAL>

Print the entry count and header details of a 256-color 6-bit VGA palette.

fx pal dump <file.PAL> [-o out.png]

Render the palette as a swatch-grid PNG for visual inspection.

See also: fa/formats/PAL.md

inf — Aircraft tech sheets

fx inf dump <file.INF>

fx inf dump <file.INF>

Print the technical info sheet: aircraft metadata and the briefing-room scene data (RTF text section and scene parameters).

See also: fa/formats/INF.md

hud — HUD layout overlays

fx hud dump <file.HUD>
fx hud set  <file.HUD> <gauge.field=value ...> [-o out.HUD]

fx hud dump <file.HUD>

Print the HUD overlay DLL's gauge parameter table, advisory icon labels, and asset-string references as JSON.

fx hud set <file.HUD> <gauge.field=value ...> [-o out.HUD]

Edit gauge parameters (keys as fx hud dump prints them, e.g. speed_tape.dx=-40) and advisory icon labels (icon_aicon_d, up to 8 characters). Everything else — asset strings, PE container, unmodelled bytes — carries over verbatim; with no edits the output is byte-identical (proven over all 46 install HUDs).

> fx hud set F16C.HUD speed_tape.dx=-40 icon_d=BAY -o F16C_mod.HUD
F16C.HUD -> F16C_mod.HUD (4608 bytes, 2 edit(s))

See also: fa/formats/HUD.md

lay — Sky/atmosphere layers

fx lay dump     <file.LAY>
fx lay gradient <file.LAY> [-o output.png]
fx lay set      <file.LAY> <key=value ...> [-o out.LAY]

fx lay dump <file.LAY>

Print the sky and atmosphere lookup-table structure of a .LAY overlay DLL.

fx lay gradient <file.LAY> [-o output.png]

Render the atmosphere gradient tables to a PNG.

fx lay set <file.LAY> <key=value ...> [-o out.LAY]

Edit header scalars (sky_angle_scale, below_angle_scale) and per-layer fields addressed as layerN.<field> — the scalar names fx lay dump prints, plus cloud_pic / sky_pic (up to 22 characters). The gradient ramps are editable through the library API only. The layer count and end sentinel cannot change; unmodelled bytes carry over verbatim, so with no edits the output is byte-identical (proven over all 24 install LAYs).

> fx lay set DAY1.LAY layer0.fog_density=9 sky_angle_scale=123 -o DAY1_mod.LAY
DAY1.LAY -> DAY1_mod.LAY (20992 bytes, 2 edit(s))

See also: fa/formats/LAY.md

fnt — Bitmap fonts

fx fnt info   <file.FNT>
fx fnt unpack <file.FNT> [-o output_dir]
fx fnt pack   <orig.FNT> <dir> [-o out.FNT]

fx fnt info <file.FNT>

Print glyph count and font metrics from a font overlay DLL.

fx fnt unpack <file.FNT> [-o output_dir]

Extract every glyph as an image into the output directory, plus a metrics.csv (ascii,char,width,height). The CSV uses LF line endings on every platform (previously CRLF on Windows).

fx fnt pack <orig.FNT> <dir> [-o out.FNT]

Rebuild the font DLL from an unpack directory: printable glyphs re-read from glyph_sheet.png (white = set), widths and height from metrics.csv, and each glyph recompiled to x86 with the original compiler's canonical encoding. Everything else in the container carries over from orig.FNT verbatim; an unedited unpack→pack loop is byte-identical. Edited glyph code must fit the original code region.

See also: fa/formats/FNT.md

mus — Music sequencer bytecode

fx mus dump <file.MUS>

fx mus dump <file.MUS>

Disassemble the in-flight music sequencer bytecode: playlists, transitions, and opcode listing.

See also: fa/formats/MUS.md

bi — Compiled AI bytecode

fx bi dump      <file.BI>
fx bi decompile <file.BI>

fx bi dump <file.BI>

Disassemble compiled .BI AI bytecode to readable mnemonics with cross-referenced label annotations and resolved CALL_BY_NAME targets.

fx bi decompile <file.BI>

Recover recompilable .AI source from .BI bytecode (printed to stdout) — the inverse of fx ai compile. The reconstructed source recompiles byte-identically to the input, so fx ai compile and fx bi decompile form a round-trip for any BI fx produced. Only the fx CALL_BY_NAME bytecode dialect is accepted; the stock game BIs use the original toolchain's CALL_DIRECT thunks and are rejected (use fx bi dump for those). Labels are synthesized (L####) and comments are not recovered.

See also: fa/formats/BI.md

ai — AI script compiler

fx ai compile <file.AI> -o <file.BI>

fx ai compile <file.AI> -o <file.BI>

Compile a plain-text .AI script to the Phar Lap PE .BI bytecode format the game's AI interpreter loads. All nine stock flight AIs compile to valid bytecode.

See also: fa/formats/AI.md, fa/formats/BI.md

fbc — Video frame index

fx fbc info <file.FBC>
fx fbc ls   <file.FBC>

fx fbc info <file.FBC>

Frame count, total frame-data bytes, and the file size the paired .VDO is expected to have (816-byte header plus the sum of all frame sizes).

fx fbc ls <file.FBC>

Per-frame table: frame number, byte size, and the frame's byte offset inside the paired .VDO.

See also: fa/formats/FBC.md, fa/formats/VDO.md

vdo — Briefing video

fx vdo info   <file.VDO> [file.FBC]
fx vdo export <file.VDO> <file.FBC> [-o dir]

Read-only decoder for RATVID .VDO mission-briefing movies (the codec is a per-pixel copy-mask delta scheme; see the format spec). Both subcommands need the paired .FBC frame-size index to locate frame boundaries.

fx vdo info <file.VDO> [file.FBC]

Resolution, frame rate, and paired-audio sample rate from the header. Supply the .FBC to also report the frame count.

fx vdo export <file.VDO> <file.FBC> [-o dir]

Decode every frame to frame%04u.png in the output directory (default .). Frames are inter-coded, so they are decoded in sequence.

See also: fa/formats/VDO.md, fa/formats/FBC.md

bin — Lookup tables

fx bin info <file.BIN>

fx bin info <file.BIN>

Identify the table from the filename (the bytes carry no structure — see the spec) and check the size against the documented inventory. Exits nonzero on a size mismatch for a known table.

See also: fa/formats/BIN.md

cam — Campaign DLLs

fx cam info    <file.CAM>
fx cam strings <file.CAM> [-n MIN]

fx cam info <file.CAM>

Validate the MZ + Phar Lap PL container and report the CODE section geometry plus the embedded-string count.

fx cam strings <file.CAM> [-n MIN]

Dump the campaign's embedded string tables (mission list, aircraft types, weapon pool, state keys) — printable runs of at least MIN characters (default 3), one per line on stdout.

See also: fa/formats/CAM.md

txt — In-game text

fx txt info <file.TXT>

fx txt info <file.TXT>

Classify the file (campaign description / UI layout template / plain text), summarize its directive structure (sections, page breaks, buttons, pictures), and confirm the parse round-trips byte-identically.

See also: fa/formats/TXT.md

cfg — Game configuration

fx cfg info <EA.CFG>

fx cfg info <EA.CFG>

Dump the 347-byte CONFIG struct: input devices, sound and volume settings, preference flag words, pilot/callsign/squadron strings, and the three untraced pass-through fields — then confirm the byte-identical round-trip.

See also: fa/formats/CFG.md

dat — Network configuration

fx dat info <NET.DAT|MODEM.DAT|SERIAL.DAT>

fx dat info <file.DAT>

Dump the 3,552-byte CN_INFO struct shared by all three transport configs: version, callsign, active transport, serial/modem parameters, phone-book usage, and the TCP/IP address fields — then confirm the byte-identical round-trip (checksum and unmapped regions pass through verbatim).

See also: fa/formats/DAT.md

effect — GRAPHIC effect-spawn data

fx effect types                    # effect type -> class / .SH shape
fx effect dump  <table.bin> [-n N]  # decode N 0x30-byte parameter records
fx effect spawn <record.bin>        # decode a 17-byte MSG 0x8003 spawn record

fx effect types

Print the effect type → class / .SH shape classification (types 0x000x2A) recovered from _GRAPHICInit@0. Needs no game data.

fx effect dump <table.bin> [-n N]

Decode N consecutive 0x30-byte effect-parameter records from a raw buffer (the table sliced from the executable, or a fixture) — intensity, frame count, sub-type / ground-burst flag, debris count/spread, sound-variant count, pitch.

fx effect spawn <record.bin>

Decode a 17-byte MSG 0x8003 network spawn record — type, F24.8 position, owner, flags.

See also: fa/formats/EFFECT.md

mnu — Menu DLLs

fx mnu info    <file.MNU>
fx mnu strings <file.MNU> [-n MIN]

fx mnu info <file.MNU>

Validate the MZ + Phar Lap PL container and report the CODE section geometry plus the embedded-string count.

fx mnu strings <file.MNU> [-n MIN]

Dump the embedded menu label strings — printable runs of at least MIN characters (default 3), one per line on stdout.

See also: fa/formats/MNU.md

mt — Mission briefing text

fx mt info <file.MT>

fx mt info <file.MT>

Extract the section-1 header facts (mission id, source name, title, mission type), count the sections (2 = briefing, 3–5 = debrief outcomes), and confirm the parse round-trips byte-identically.

See also: fa/formats/MT.md, fa/formats/TXT.md

pts — Aircraft screen assets

fx pts info <file.PTS>

fx pts info <file.PTS>

Validate the MZ + Phar Lap PL container and report the CODE section geometry plus the referenced ICON*.PIC aircraft icon.

See also: fa/formats/PTS.md

rgn — Installer region maps

fx rgn info <file.RGN>
fx rgn dump <file.RGN>

fx rgn info <file.RGN>

Record count, rectangle count, and the byte-identical round-trip check.

fx rgn dump <file.RGN>

Per-record table: name, vertex count, and coordinates.

See also: fa/formats/RGN.md

ssf — Installer scripts

fx ssf info <file.SSF>
fx ssf dump <file.SSF>

fx ssf info <file.SSF>

Per-keyword statement counts and the byte-identical round-trip check.

fx ssf dump <file.SSF>

Every statement with its source line, keyword, and unquoted arguments.

See also: fa/formats/SSF.md

esa — Installer archive

fx esa ls      <SETUP.ESA>
fx esa info    <SETUP.ESA>
fx esa extract <SETUP.ESA> <NAME> [NAME ...] [-o dir]
fx esa unpack  <SETUP.ESA> [-o dir]
fx esa repack  <SETUP.ESA> <out.ESA>

fx esa ls <SETUP.ESA>

The directory: each entry's name, label, flags, method (PKWA/NULL), and uncompressed/stored sizes.

fx esa info <SETUP.ESA>

Entry and method counts, directory size, total uncompressed bytes, and the byte-identical repack check.

fx esa extract <SETUP.ESA> <NAME> [-o dir]

Extract named entries — PKWA entries are DCL-decoded, NULL entries copied. fx esa unpack does the same for every entry.

fx esa repack <SETUP.ESA> <out.ESA>

Rebuild the container from its own directory (payloads kept stored); byte-identical for a well-formed archive.

See also: fa/formats/ESA.md

install — Install the game from its discs

fx install plan   <disc-dir> [disc-dir ...] [-d dir] [options]
fx install run    <disc-dir> [disc-dir ...] -d <dir> [options]
fx install verify <disc-dir> [disc-dir ...] -d <dir> [options]

Executes the .SSF installer scripts against SETUP.ESA — what SETUP.EXE does, portably — and copies the game to a directory of your choosing. It needs your own discs: nothing is shipped.

A disc is a directory: point it at an ISO mount, an extract of one, or the drive itself, in any order. Which disc is which is decided by content, not by volume label. A full install copies everything, including the CD-resident LIBs the game would otherwise stream off the disc, so no disc is needed to play.

Option
-d <dir> the install directory (required for run/verify)
--full / --minimal the full install, or the minimal one (no FA_4B.LIB, the digital-music archive). Default: full
--verify after run, byte-compare every file back against the disc
--overwrite replace files already in the destination. Files SKIP_ON_REMOVE marks as the game's own — pilots, missions, EA.CFG, screen captures — are preserved even so
--no-cd-resident skip the CD-resident LIBs (a ~110 MB install that still needs a disc)
--patch <fae102.exe> after installing, apply the 1.02F updater in place — bring the 1.00F disc install up to the 1.02F build the reconstruction database describes (fa/formats/RTP.md). Runs after --verify, so verification still checks the fresh 1.00F tree against the disc
--any-media proceed on media whose build cannot be fingerprinted
--json machine-readable plan (the shape fxe's first-run reads). Under --json, stdout carries the plan and nothing else; the scan banner, progress, and diagnostics all go to stderr

fx install plan <disc-dir>…

The dry run — it writes nothing. Prints the media's build, which script was chosen, every file with its action (copy / keep / skip), the byte total, and every script directive that was not acted on, with the reason. Reading this before an install is the point of it.

fx install run <disc-dir>… -d <dir>

Performs the install. Payloads stream, so a 989 MiB install runs in a few MB of memory; each file is written to a .part and renamed once complete, so an interrupted run leaves nothing that looks finished.

$ fx install run /run/media/you/FA_1_00F /run/media/you/FA_1_00F1 -d ~/games/fa --verify
disc 1: /run/media/you/FA_1_00F
disc 2: /run/media/you/FA_1_00F1

media:   1.00F  (the 1.02F patch is not applied; the symbol database describes 1.02F)
script:  FINSTALL.SSF
...
installed 1036798285 bytes to ~/games/fa (build 1.00F)
verifying against the disc...
verified: every installed byte matches the disc

The discs carry the 1.00F build, while the reconstruction database describes the patched 1.02F one — fx install always prints which build it wrote, and --patch <fae102.exe> upgrades the fresh install to 1.02F in place (the four modified game files; the multiplayer msapi.dll is a follow-up, RTP.md #54). See fa/formats/ESA.md § File Inventory and fa/formats/RTP.md.

Everything above is exercised against the retail discs by the fa_disc_install integration test — see development.md § Real-media install mode.

fx install verify <disc-dir>… -d <dir>

Re-derives every file from the disc and byte-compares it against the install. Unlike run, it plans as though the destination were empty, so it checks everything a fresh install would write — including the files an install would otherwise preserve. Editing a mission will therefore be reported: that .MT no longer matches the disc, which is true.

See also: fa/formats/SSF.md § Engine Notes, fa/formats/ESA.md

patch — Apply the 1.02F updater

fx patch inspect <patch.exe>
fx patch apply   <patch.exe> --source <dir> --out <dir> [--file NAME] [--no-checksum]

Applies the Pocket Soft .RTPatch payload carried by the FA updater (fae102.exe) to reconstruct the 1.02F game files from the 1.00F originals — the build the discs ship versus the build the reconstruction database describes. It needs your own 1.00F files as the source; nothing is shipped.

fx patch inspect <patch.exe>

Locate the RTPatch container overlay and list every record — filename, mode (modify/new), source and target sizes, and the source rolling checksum — plus any files the installer relocates to a system directory.

fx patch apply <patch.exe> --source <dir> --out <dir>

Reconstruct each patched file from the matching original in --source and write it to --out. Each source is verified against the record's checksum first, so a wrong 1.00F version is skipped rather than corrupted; --no-checksum forces the apply and --file NAME limits it to one target. The reconstruction is byte-identical to the shipped 1.02F build.

$ fx patch apply fae102.exe --source ~/games/fa --out ~/games/fa-1.02f
  [ ok ]  FA.EXE          1319424 bytes
  [ ok ]  FA.SMS          106706 bytes
  ...
4 patched, 0 skipped, 0 failed

See also: fa/formats/RTP.md

mc — Mission condition DLLs

fx mc info    <file.MC>
fx mc strings <file.MC> [-n MIN]

fx mc info <file.MC>

Validate the MZ + Phar Lap PL container and report the CODE section geometry plus the embedded-string count.

fx mc strings <file.MC> [-n MIN]

Dump the embedded strings — including the imported mission-condition API names — one per line on stdout.

See also: fa/formats/MC.md

hgr — Hangar screen DLLs

fx hgr info    <file.HGR>
fx hgr strings <file.HGR> [-n MIN]

fx hgr info <file.HGR>

Validate the MZ + Phar Lap PL container and list the referenced PIC assets (hangar background layers and the selection-icon atlas).

fx hgr strings <file.HGR> [-n MIN]

Dump the embedded strings, one per line on stdout.

See also: fa/formats/HGR.md

dlg — Menu dialog DLLs

fx dlg info    <file.DLG>
fx dlg strings <file.DLG> [-n MIN]

fx dlg info <file.DLG>

Validate the MZ + Phar Lap PL container and report the CODE section geometry (the control dispatch table) plus the embedded-string count.

fx dlg strings <file.DLG> [-n MIN]

Dump the dialog's embedded control label strings, one per line on stdout.

See also: fa/formats/DLG.md

xmi — Extended MIDI

fx xmi info   <file.XMI>
fx xmi export <file.XMI> [-s N] -o <out.mid>

fx xmi info <file.XMI>

Report the sequence count, and per sequence its timbre count and chunk inventory (TIMB, EVNT, …).

fx xmi export <file.XMI> [-s N] -o <out.mid>

Export sequence N (default 0) to a Standard MIDI File (format 0): the AIL delay encoding becomes SMF variable-length deltas and each note-on's XMI duration becomes a scheduled note-off. One-way translation, not a round-trip.

See also: fa/formats/XMI.md, fa/formats/MUS.md