SSF — EA Installer Script (.SSF)¶
.SSF files are plain-text EA installer scripts that drive the FA
installation process. All three files reside in the Disc 1 root alongside the
installer executable. None are packed into any LIB archive.
Tools¶
fx¶
fx ssf info <file.SSF> # keyword summary + round-trip check
fx ssf dump <file.SSF> # every statement with its arguments
Line storage rides the shared line-preserving engine (lib/src/txt.cpp), so
any input round-trips byte-identically; keywords and their comma-separated
arguments are extracted as an overlay. Disc-1-only format (like
RGN), so the committed fixtures are synthetic; the three retail
scripts are exercised by running the install engine below against the mounted
discs.
Reading a script is half the story. Executing one is fx install, which
resolves these directives against the ESA archive and writes the
game to disk — see Engine Notes:
fx install plan <disc-dir>… [-d dir] [--minimal] [--json] # the dry run
fx install run <disc-dir>… -d <dir> [--verify] [--overwrite]
fx install verify <disc-dir>… -d <dir> # byte-compare the install to the disc
File Layout¶
Plain ASCII text. # begins a comment. Keywords are all-caps.
| Keyword | Arguments | Effect |
|---|---|---|
COMPANY_NAME |
"string" |
Sets company name string (used in registry keys and Start Menu path) |
APP_NAME |
"string" |
Sets application name string |
DEFAULT_PATH |
"\path" |
Suggested install path (no drive letter; installer picks drive) |
INSTALL_SCRIPT |
"file.SSF", "label" |
References a sub-script; label may embed locale tags (":0409:English:0C:French") |
CREATE_FOLDERS |
"[INSTALL_PATH]" |
Creates the install directory |
INSTALL_FILES |
"glob", "archive_label", "dest" |
Copies files matching glob from named archive to destination |
INSTALL_SYSFILES |
"filename", "archive_label" |
Copies a file to %WINDIR%\SYSTEM |
SKIP_ON_REMOVE |
"glob" |
Marks files to skip deletion during uninstall |
REGEXE |
"path\app.exe" |
Registers executable with the OS |
ADD_GROUP |
"Company\App" |
Creates a Start Menu program group |
GROUP_ITEM |
"group\name","path\exe" |
Adds a Start Menu shortcut |
DESKTOP_ITEM |
"name","path\exe" |
Adds a desktop shortcut |
DIRECTX |
"label",major,minor |
Invokes DirectX component install |
File Inventory¶
| File | Role |
|---|---|
SETUP.SSF |
Master installer script — sets app metadata and references the two sub-scripts |
FINSTALL.SSF |
Full install — copies all assets including FA_4B.LIB (digital audio) |
MINSTALL.SSF |
Minimal install — omits FA_4B.LIB; music uses MIDI only |
SETUP.SSF¶
Sets COMPANY_NAME "Jane's Combat Simulations", APP_NAME "Fighters
Anthology", DEFAULT_PATH "\JANES\Fighters Anthology", then references both
sub-scripts:
INSTALL_SCRIPT "MINSTALL.SSF", ":0409:Minimal Install - Midi Music:…"
INSTALL_SCRIPT "FINSTALL.SSF", ":0409:Full Install - Digital Music:…"
Both FINSTALL.SSF and MINSTALL.SSF install:¶
| File/Glob | Archive label | Destination |
|---|---|---|
FA.EXE |
FA_EXECUTABLE_FILES |
[INSTALL_PATH] |
FA.SMS |
FA_EXECUTABLE_FILES |
[INSTALL_PATH] |
*.* |
FA_README |
[INSTALL_PATH] |
*.* |
FA_INTERNET |
[INSTALL_PATH] |
FA_1.LIB |
FA_LIBS |
[INSTALL_PATH] |
*.* |
FA_MISC |
[INSTALL_PATH] |
FA_2.LIB |
FA_LIBS |
[INSTALL_PATH] |
FA_4D.LIB |
FA_LIBS |
[INSTALL_PATH] |
WAIL32.DLL |
FA_SOUND_DRIVER_FILES |
[INSTALL_PATH] |
*.DLL |
COMMDRV_DLLS_FILES |
[INSTALL_PATH] |
FINSTALL.SSF additionally installs:¶
| File/Glob | Archive label | Destination |
|---|---|---|
FA_4B.LIB |
FA_LIBS |
[INSTALL_PATH] |
FA_3.LIB is absent from both manifests — it is CD-resident and loaded directly from the disc at runtime.
Both scripts also install to the Windows system directory:¶
| File | Archive label | Destination |
|---|---|---|
EAREMOVE.EXE |
REMOVER_EXECUTABLE_FILE |
%WINDIR%\SYSTEM |
EAEXEC.EXE |
EXEC_EXECUTABLE_FILE |
%WINDIR%\SYSTEM |
These two are the EA installer's own uninstaller and launcher — the game loads
neither. They are the only entries in SETUP.ESA whose flags field is
0x0221 rather than 0x0211 (ESA § Entry flags),
which is what identifies the field as a destination-class selector.
FA_4B.LIB contains the digital audio tracks (.11K music files). FA_4D.LIB
contains additional assets installed in both configurations.
Files skipped during uninstall (SKIP_ON_REMOVE):¶
*.P (pilot files), *.BKP (pilot backups), *.M (mission files), *.MT
(mission text), *.MM (mission maps), EA.CFG, MODEM.DAT, NET.DAT,
SERIAL.DAT, *.RAW (screen captures), *.GID (WinHelp temp files)
Engine Notes¶
fx install (lib/src/install.cpp) executes these scripts. It is what proves
the format is understood: a spec of a script language is a claim about what the
script does, and the only way to check that claim is to run it and compare the
result against a real installation.
A disc is a directory — an ISO mount, an extract of one, or the drive itself. The engine is three stages, and only the ends touch a disk:
| Stage | ||
|---|---|---|
install_scan |
I/O | directory → loose files + the ESA directory + the parsed scripts |
install_plan |
pure | → an InstallPlan: every file, every directive, every byte |
install_execute / install_verify |
I/O | write it; then byte-compare it back |
The middle stage is a pure function of scanned metadata, which is why the planner is unit-tested and fuzzed with no media at all.
What the engine does with each directive¶
INSTALL_FILES "glob","label","dest" selects every SETUP.ESA entry
carrying label whose name matches glob. The glob is DOS: *.* is
everything, *.DLL is a suffix, anything else is an exact (case-insensitive)
name. Three of the eleven directives use *.* — the label, not the glob, is
doing the selecting.
The destination argument is confined. It comes off the disc, so it is
untrusted like any other parsed field: "[INSTALL_PATH]\..\..\WINDOWS" resolves
to WINDOWS/, not to somewhere above the install directory, and a drive letter
is dropped. The file half is neutralised by
esa_safe_name. The retail scripts only ever say
"[INSTALL_PATH]", so nothing real is given up.
Script choice is data-driven, not label-driven. SETUP.SSF names its two
sub-scripts with localised prose (":0409:Full Install - Digital Music:0C:…"),
so nothing machine-readable says which is the full one. The engine resolves both
and takes the larger set. On the retail disc they differ by exactly one entry,
FA_4B.LIB.
INSTALL_SYSFILES is recorded and never performed: there is no Windows
system directory to write to, and the two files it names belong to the EA
installer rather than to FA.
SKIP_ON_REMOVE is documented as an uninstall hint, but it is also the
only statement in the scripts that says which files the game writes rather
than the installer — pilots (*.P), missions (*.M/*.MT/*.MM), EA.CFG,
screen captures (*.RAW). The engine reads it as a clobber guard: a file
matching one of these globs is never overwritten, even with --overwrite.
EXAMPLE.MT is the sharp case — the archive ships it and *.MT guards it, so a
fresh install writes it and a re-install keeps the one the user edited.
The shell and registry directives (REGEXE, ADD_GROUP, GROUP_ITEM,
DESKTOP_ITEM, DIRECTX) are reported as not honored, with a reason, rather
than silently dropped. On the retail FINSTALL.SSF — 33 statements — that is 8,
plus the 2 INSTALL_SYSFILES. An install that quietly ignores ten directives is
not a documented install.
The CD-resident LIBs are a rule, not a list¶
FA_4C.LIB and FA_7.LIB (Disc 1) and all five Disc 2 LIBs appear in no
script: the game read them off the CD at run time. The engine copies every
loose *.LIB in a disc root that the archive does not supply, which yields
exactly those seven without a hard-coded manifest, and carries to the other EA
titles that share the format. Names are upper-cased on the way in, because the
case a disc shows is a property of the mount, not of the game (an ISO9660 mount
may hand back fa_4c.lib).
What a full install is¶
Running both retail discs through the planner: 27 files, 1,036,798,285 bytes
(989 MiB), of which the archive supplies 20 and the CD-resident rule 7. Two
entries are recorded and skipped (the INSTALL_SYSFILES pair), and
PKCOMP.IDKDECODLL — which no directive references — is never installed at all.
Payloads stream, so peak memory over a 989 MiB install is ~5 MB.
Verified against a real installation¶
The engine's output is compared, file by file, against a licensed 1.02F install
of the game. Of the 19 files a minimal install writes, 14 are byte-identical
and 4 differ — exactly the four the 1.02F patch rewrites (FA.EXE,
FA.SMS, FA_1.LIB, FA_2.LIB). The 19th, README.TXT, that install does not
carry at all. Nothing else diverges: the scripts, the archive, and the glob
semantics are confirmed end to end, and the only divergence is the one the patch
explains. The disc is the 1.00F build; see
ESA § File Inventory for what that means for the symbol
database, which describes 1.02F.
This is a test, not a one-off measurement — the fa_disc_install cross-build
oracle (development.md § Real-media install mode),
run on a bench that has both the discs and an install. It asserts the difference
set is exactly those four files, so an unexpected divergence fails rather than
going unnoticed; when the RTPatch codec lands, the set goes empty. The same test
pins the engine rules above: the script choice, the SKIP_ON_REMOVE clobber
guard (EXAMPLE.MT survives even --overwrite), the two recorded-not-written
INSTALL_SYSFILES, the CD-resident rule, and the fact that a plan is identical
whichever order the discs are named in.
fx install verify re-derives each file from the disc and byte-compares it, so
it also reports a legitimate divergence: edit a mission and it will tell you
that .MT no longer matches the disc.
Related¶
Formats: LIB — the archives the installer copies;
ESA — the archive the INSTALL_FILES labels select entries from, and
the other half of what fx install executes; RGN — installer UI
region maps (POSTER.RGN, BUTTONS.RGN) on Disc 1.