Files
firestorm/OPTIONS-INI.md
T
8bfaf9b9ad Publish V5.1.0b_RC2: rebuilt binaries, repacked props, RC2 documentation
RC2 build, verified to launch on the Windows box and copied back into the
deployment at MW4/. Supersedes RC1 (a0331e78), which predates everything in
sections 12-17 of the test checklist.

Binaries and content
--------------------
* MW4.exe / MW4pro.exe rebuilt from CoreTech GameOS + MW4Application. Carries
  the display work that landed after the RC1 build: -tident, the full
  gos-displays.txt start-up trace with the CLASH and CTCL-type reports, the
  HSH_EnterFullScreen2 panel re-entry fix, the -tmr cameraship ladder, and the
  updated -help text.
* Launcher / autoconfig / mw4print / ctcls / MissionLang / ScriptStrings
  relinked in the same pass.
* props.mw4 + props.dep fully repacked (deleted first, not incremental), so the
  23-entry time list, the restored 7-minute default and the V5.1.0b2 console
  title are actually in the package rather than only in the source tree.
* mw4-help.txt regenerated from the new exe; the diff is the proof the built
  binary carries the documentation changes.

Documentation, renamed to RC2
-----------------------------
* RELEASE-NOTES-5.1.0b_RC1.{md,html} -> ..._RC2.{md,html}, both hand-maintained
  in step, ASCII + CRLF so they open correctly in Notepad on a pod.
  - New "Already testing RC1?" block at the top. RC1's notes already described
    -tident and the CLASH report, but the RC1 BINARY does not contain them, so
    anyone comparing the two needed that stated explicitly.
  - Time limits corrected to 23 entries (1-15, 20, 25, 30, 45, 60, 120, 180,
    240) with the 7-minute default restoration called out.
  - New section on the cameraship Map/Armor screen: background but no overlays
    is -ctcltype 2 on a cameraship, not a video card. Includes the
    "CTCL type =" log line and -tmr 3 as the follow-up check.
  - -fps description corrected: the per-second column is a 5% low and the 1% /
    0.1% lows are in the session summary. The old text described behaviour that
    had already been changed.
  - Switch table gained -tmr; known issues gained stereo-only audio and the
    single-monitor -tident caveat; upgrade checklist now names V5.1.0b2.
* testing-checklist-5.1.0b1.txt -> testing-checklist-5.1.0b_RC2.txt, with a
  build-requirements header and new sections 12-17 covering -tident, the
  display trace (including a deliberate -tmon clash to exercise the CLASH
  report), the panel re-entry fix, cameraship/-tmr, 240-minute missions and a
  -help verification pass.
* OPTIONS-INI.md: TimeList_Index is documented as no longer driving the console
  lobby default (the script uses a literal since the list was expanded) while
  TimeList_Value remains live; added a table of the files the game writes next
  to MW4.exe. Also repaired the CP949/CP1252 damage in that file - it carried
  literal 0xA1 0xE6 arrows, 0x97 em dashes and ~20 '?' characters where dashes
  had been lost. Now pure ASCII.
* README.md points at the RC2 notes.

Source
------
MW4Application.cpp help text: -fps now matches what gos-fps.txt actually
prints, and -ctcltype states that a cameraship must use 3 and what goes wrong
when it does not. Audited all 80 switches parsed in the file against the help
array - none missing, and no game-facing switch is parsed anywhere else.

Deployment housekeeping
-----------------------
* dgVoodoo.conf: ScalingMode = stretched_ar, which is the setting the release
  notes require and which fails SILENTLY when wrong. FPSLimit was left at 20
  from bench testing and would have shipped a 20 fps cap to every Win10/11 pod
  - raised to 60.
* banner.txt reset from a test string to the shipped placeholder.
* Removed two stray screen000*.bmp captures and the duplicate dbstruct.txt
  (db_schema.sql is the current name, per b4089291).
* .gitignore: gos-displays.txt and gos-fps.txt are truncated on every launch
  and are per-machine, so they are no longer mirrored.

Not yet done: multi-monitor pod testing of this binary. -tident, the re-entry
fix and -tmr have not been exercised on real MFD hardware - that is what the
new checklist sections are for.

Co-authored-by: Claude Opus 5 (Anthropic) <noreply@anthropic.com>
Co-authored-by: GitHub Copilot <copilot@github.com>
2026-08-07 13:07:43 -05:00

337 lines
17 KiB
Markdown

# options.ini reference
Complete reference for `options.ini`, the runtime configuration file that sits next to
`MW4.exe`.
Compiled 2026-07-25 by reading the actual read sites in the source. Every key below was
verified against code; keys that are shipped but **not** read by any code are called out
explicitly rather than silently documented as working.
For command-line switches, run `MW4.exe -help` (writes `mw4-help.txt` next to the exe).
---
## How the file is loaded
`options.ini` is a standard INI file read through the engine's own notation-file reader:
```cpp
Stuff::NotationFile startup_ini("options.ini", NotationFile::Standard, true);
Stuff::Page* page = startup_ini.FindPage("graphics options");
page->GetEntry("bitdepth", &Environment.bitDepth);
```
Consequences of this design that matter in practice:
- **Section and key lookup is by name.** A misspelled key is not an error -- `GetEntry`
simply returns false and the compiled-in default is kept. **There is no warning.** This
is why several shipped keys silently do nothing (see "Dead settings" below).
- **The file is read at startup**, in `GetGameOSEnvironment` / `InitializeGameEngine`.
Changing it while the game runs has no effect.
- **Parts of it are written back.** `[server]` in particular is re-saved from the in-game
host UI, and `[special commands] killgame` is cleared on use. Hand edits to those
sections can be overwritten.
- A few sections are read via the Win32 profile API (`GetPrivateProfileInt` /
`GetPrivateProfileString`) instead -- noted per section.
### Related but separate files
| File | Purpose |
|---|---|
| `options.ini` | This document. Main game configuration. |
| `options-game.ini`, `options-cam.ini`, `options-mr.ini` | Per-role variants copied over `options.ini` by the pod launcher for game pods, cameraships, and mission-review machines. Same format. |
| `options-*-var.ini` | Site-local variant overlays kept in the dev tree. |
| `c:\ctcl.ini` | Arcade console configuration (pod IP list, launch command lines, voice macros). Hardcoded path. Not covered here. |
| `banner.txt` | mw4print bottom-of-sheet banner text. Plain text, first line only. |
### Files the game writes next to `MW4.exe`
Not configuration -- these are outputs, listed here because they are the first place to look
when something is misconfigured.
| File | Written when | Contents |
|---|---|---|
| `gos-displays.txt` | Every launch (truncated each time) | Full display start-up trace: Windows topology, DirectDraw enumeration, role selection with reasons, `-tmon` overrides, desktop left-to-right order, the CTCL role, and an explicit CLASH warning if two roles land on one device. Copy it before relaunching after a failure. |
| `gos-fps.txt` | Only with `-fps` | Per-second frame pacing (average, 5% low, worst frame, hitch count) plus a whole-session summary with 1% / 0.1% lows. Buffered, so a hard crash loses the tail. |
| `mw4-help.txt` | Only with `-help` | The full command-line reference; opened in Notepad, and the game then exits. |
---
## `[graphics options]`
Read in `MW4Application.cpp` (`GetGameOSEnvironment`) and `MWOptions.cpp`.
| Key | Type | Shipped | Effect |
|---|---|---|---|
| `bitdepth` | int | 16 | Display colour depth. The pods run 16; on modern Windows the DirectDraw 16-bit path additionally needs the `DWM8And16BitMitigation` compatibility shim. |
| `antialias` | bool | false | Full-screen antialiasing (`Environment.AntiAlias`). |
| `screenwidth` | int | 800 | Horizontal resolution, read by `MWOptions`. |
| `screenheight` | int | 600 | Vertical resolution. |
**Read but overridden in this build -- editing has no effect:**
| Key | Why |
|---|---|
| `videodriverindex` | The `GetEntry` call is commented out and `Environment.FullScreenDevice` is forced to `0`. Use the `-tmon` command-line switch to assign display devices instead -- run `MW4.exe -tident` first to find out which number is which monitor, as Windows Display Settings numbers do not match. |
**Present in the shipped file and consumed by renderer subsystem initialisers**
(`MidLevelRenderer::InitializeClasses`, `gosFX`, `ElementRenderer`, `Compost`), which are
handed the same notation file: `noblend`, `shadowmode`, `mipbias`, `loadradius`,
`compositing`, `lod`, `maxlights`, `hidesky`, `effectlod`, `detailtexture`, `multitexture`,
`lightmaps`, `culturals`, `footsteps`, `fancywater`, `movietextures`, `simplelighting`,
`missionmusic`, `vertexlighting`, `fontsmall`, `fontmedium`, `fontlarge`, `fontlarge2`,
`fontlarge3`.
These are stock MechWarrior 4 renderer/quality settings. They are passed through to the
engine libraries rather than read in game code, so their exact clamping lives in those
libraries. The shipped values above are the tested pod configuration; change them one at a
time.
---
## `[sound options]`
| Key | Type | Shipped | Effect |
|---|---|---|---|
| `hardwaremixing` | bool | false | Use DirectSound hardware mixing (`Environment.soundMixInHardware`). The 2016 release build enabled this (`true`); the current tree ships `false`. |
| `lowendsound` | bool | false | Stock low-quality audio path. |
| `radius` | float | 1.0 | 3D sound attenuation radius multiplier. |
---
## `[special commands]`
| Key | Type | Shipped | Effect |
|---|---|---|---|
| `killgame` | bool | false | **Self-clearing kill switch.** If true at startup, the game sets it back to false, saves `options.ini`, and immediately calls `ExitGameOS()`. Intended as a remote "do not start" flag for a pod. |
| `autotorsocenter` | int | 2 | Torso auto-centring mode (`VehicleInterface::perminateTorsoMode`). 0 = off, 1 = slow, 2 = fast. |
**Read but overridden in this build -- editing has no effect:**
| Key | Why |
|---|---|
| `huddamagemode` | `GetEntry` commented out; forced to `false`. |
| `hudtargetdamagemode` | `GetEntry` commented out; forced to `false`. |
---
## `[server]`
Multiplayer host defaults. **This section is written back** by the host configuration UI --
do not hand-edit it while the game is running.
Verified read: `playerlimit` (`Adept/Application.cpp`, both `GetEntry` and `SetEntry`).
The remaining keys form the persisted `NetMissionParameters` set and correspond
one-to-one with the in-game host options:
`defaultservername`, `dedicated`, `visibility`, `joininprogress`,
`joininprogresscutoff`, `joininprogresscutofftime`, `heaton`, `forcerespawn`, `splashon`,
`weaponjamon`, `ammobayfireon`, `advancemodeon`, `armormodeon`, `splashpercentage`,
`unlimitedammo`, `friendlyfirepercentage`, `allowzoom`, `allow3rdperson`,
`allowdeadtochat`, `reportstats`, `serverrecycle`, `recycledelay`, `playmissionreview`,
`deadmechcantsee`, `deadmechcantseeotherteam`, `ruletype`, `usemapcycle`, `maxplayers`,
`maxbots`, `allowdecaltransfer`, and the `allowed*1` / `allowed*2` bitmasks
(`allowedmech`, `allowedbeam`, `allowedmissile`, `allowedprojectile`, `allowedsubsystem`).
Notes:
- `allowed*1` / `allowed*2` are 32-bit hex masks covering items 0-31 and 32-63
respectively. `ffffffff` = everything permitted.
- `maxplayers` and `maxbots` are serialised to clients as **5-bit fields**, so the maximum
usable value is **31**. Writing 32 truncates to 0. See `RAISING-PLAYER-CAP.md`.
- In arcade (CTCL) mode these are overwritten at mission launch by
`CTCL_DefaultHostSetup`, so this section mainly affects standalone hosting.
---
## `[joystick]`
Read and written by `Adept/control_mapping.cpp`. Also stores control bindings, which is why
the file is saved from the controls UI.
| Key | Type | Shipped | Effect |
|---|---|---|---|
| `bithrottlecenter` | float | 0.3 | Bidirectional throttle centre dead zone. |
| `bithrottlelow` | float | 0.25 | Bidirectional throttle low dead zone. |
| `bithrottlehigh` | float | 0.06 | Bidirectional throttle high dead zone. |
| `onethrottlecenter` | float | 0.3 | One-way throttle centre dead zone. |
| `onethrottlehigh` | float | 0.06 | One-way throttle high dead zone. |
| `onewaythrottle` | bool | false | Treat the throttle axis as forward-only. |
---
## `[Cameraship Params]`
Read by `CamerashipParams::LoadOptions` (`VehicleInterface.cpp`). Controls the automatic
spectator camera on cameraship pods. All distances are world units, all times are seconds,
all offsets are axis offsets applied to the camera or its look-at point.
**Behaviour**
| Key | Type | Effect |
|---|---|---|
| `AllowChatDisplay` | bool | Show chat on the cameraship view. |
| `AllowBOTs` | bool | Allow the camera to follow bots. |
| `DisplayCameraStates` | bool | Overlay the current camera state (debug aid). |
| `DegreesPerSec` | float | Camera orbit rate. Accepted range: strictly between -180 and 180. |
**Timing**
| Key | Effect |
|---|---|
| `TimeScoringInterval` | Interval between scoring cut-ins. |
| `TimeScoringDuration` | How long a scoring cut-in is held. |
| `TimeScoringAtEnd` | Scoring display duration at mission end. |
| `TimeIdleChange` | Idle time before the camera picks a new subject. |
| `TimeStandard` | Duration of the standard shot. |
| `TimeDeathWatching` | Duration of the death-watch shot. |
| `TimeDeathTransition` | Transition time into the death shot. |
| `TimeFixedTracking` | Duration of the fixed-tracking shot. |
| `TimeSideShot` | Duration of the side shot. |
| `TimeFrontShot` | Duration of the front shot. |
| `TimeOverShoulder` | Duration of the over-the-shoulder shot. |
**Framing**
| Key | Effect |
|---|---|
| `DistGroundLevel`, `DistGroundLevelShift` | Ground clearance and its shift. |
| `DistStandard`, `HeightStandard`, `HeightStandardLookAt` | Standard shot distance/height/look-at height. |
| `OffsDeathWatchingX/Y/Z` | Death-watch camera offsets. |
| `OffsFixedTrackingX/Y/Z` | Fixed-tracking camera offsets. |
| `DistSideShot`, `OffsSideShotX`, `OffsSideShotY`, `OffsSideShotHeadY` | Side shot framing. |
| `DistFrontShot`, `OffsFrontShotHeadY`, `OffsFrontShotCameraY` | Front shot framing. |
| `OffsOverShoulderHeroX/Y/Z`, `OffsOverShoulderEnemyY` | Over-the-shoulder framing. |
---
## `[Battle Tech Misc]`
Read by `CamerashipParams::LoadOptions` (`VehicleInterface.cpp`). **Several key names in
this section do not describe what they do** -- they appear to be deliberately obscured. The
mapping below is from the source and is the authoritative meaning.
| Key | Type | Range / clamp | Actually sets |
|---|---|---|---|
| `SecsMissionReplay` | int | `<0` or `>=100` -> 60 | `g_nSecsMissionReplay` -- mission replay duration. |
| `SecsMissionReport` | float | `<0` or `>=30` -> 15 | `g_fSecsMissionReport` -- mission report screen duration. |
| `AutoPowerUpLevel` | float | clamped to 0.0-1.0 | `g_fAutoPowerUpLevel` -- auto power-up threshold. |
| `NeedFlushLevel` | float | clamped to 0.0-1.0 | `g_fNeedFlushLevel` -- heat level at which flush is advised. |
| `TimeMsgSender` | float | clamped to 0.1-5.0 | `g_fTimeMsgSender` -- how long a message sender name is shown. |
| `TimeList_Index` | int | `<0` -> 0, `>=20` -> 3 | `g_nTimeList_Index` -- selected entry in the lobby time-limit dropdown. **No longer used by the console lobby:** since the list was expanded to 23 entries (1-15, 20, 25, 30, 45, 60, 120, 180, 240) `ConLobbyMission.script` uses a literal index for the 7-minute default, so the script stays independent of the exe. Still read by the legacy non-MSL path. |
| `TimeList_Value` | int | `<0` or `>=100` -> 7 | `g_nTimeList_Value` -- lobby time limit in minutes. Still live: it is the mission length handed to the host, and what `[RookieMission] TimeLimit=-1` resolves to. |
| `RuleBook` | int | 0 or 1 | **(!)** **`g_nMechVariant`** -- mech variant feature flag. Nothing to do with a rule book. |
| `DawnWar` | int | 0 or 1 | **(!)** **`g_nMechLabOp`** -- mechlab operation flag. |
| `BiggieSizeIt` | int | 0 or 1 | **(!)** **`g_nMechPodNum`** -- mech pod count flag, used by the console lobby to enable the larger roster (`USE_O_MORE_PODS`). |
| `CanYouHearTheFootSteps` | int | 0 or 1 | **(!)** **`g_nBlackMech`** -- black mech flag. |
### WARNING -- the shipped file misspells two of these
The shipped `options.ini` contains:
```
secmissionreplay=30.0
secmissionreport=15.0
```
but the code reads **`SecsMissionReplay`** and **`SecsMissionReport`** (note the `s` in
`Secs`). The shipped keys therefore do nothing and the compiled defaults are used. If you
want these to take effect, correct the spelling.
### Other keys in this section
| Key | Read by | Notes |
|---|---|---|
| `MinShift` | `logreport.cpp` via `GetPrivateProfileInt`, default 0 | Torso shift minimum used by the match report. |
| `lrpt` | `logreport.cpp` via `GetPrivateProfileString`, **and written back** | Opaque report cache/registration value. Do not hand-edit. |
---
## `[RookieMission]`
Read by `CTCL_SetCDSP` (`MW4Shell.cpp`) at startup and exposed to the console lobby as
script globals. Defines what the arcade "Rookie Mission" / Default button loads. The whole
section is optional; omitting it uses the defaults below.
| Key | Type | Default | Effect |
|---|---|---|---|
| `MissionName` | string | `ScarabStronghold - Attrition` | Mission loaded by default. |
| `GameType` | int | 2 | Game type index (2 = Attrition). |
| `TimeLimit` | int | -1 | Minutes. `-1` = use the server's current time setting (`TimeList_Value`). |
| `Visibility` | int | 0 | 0 clear, 1 light, 2 medium, 3 heavy. |
| `Weather` | int | 0 | 0 off, 1 rain. |
| `TimeOfDay` | int | 0 | 0 day, 1 night. |
| `Radar` | int | 0 | 0 novice, 1 off, 2 bars, 3 unlimited. |
| `HeatOn` | int | 0 | Heat management. |
| `FriendlyFire` | int | 0 | Percentage; 0 = off, 100 = full. |
| `SplashDamage` | int | 0 | Splash damage on/off. |
| `UnlimitedAmmo` | int | 1 | Unlimited ammo on/off. |
| `WeaponJam` | int | 0 | Weapon jamming on/off. |
| `AdvanceMode` | int | 0 | Advanced gyro on/off. |
| `ArmorMode` | int | 0 | Advanced armor on/off. |
| `NoReturn` | int | 0 | No respawn (respawn limit) on/off. |
---
## `[battle tech print]`
Read by **mw4print.exe**, not by the game. Uses `GetPrivateProfileInt`. All values are in
the printer's logical units; the defaults are in `recscore.cpp`.
Page layout: `PaperMarginL`, `PaperMarginT`, `PaperMarginR`, `PaperMarginB`,
`TopImageHeight`, `GapColumn`, `ImageTitleHeight`, `GapTopImageTable`.
Table layout: `CellMarginLR`, `CellMarginTV`, `TableTextHeight`, `GapFFA`, `GapTableMH`.
Mission highlights: `MHHeight`, `MHTextHeight`, `GapMHText`.
Text block: `TextMarginL`, `TextMarginT`, `TextMarginR`, `TextMarginB`, `TextHeight`,
`InfoTextHeight`.
| Key | Notes |
|---|---|
| `BannerText` | **Legacy fallback only.** The banner is now read from `banner.txt` (first line) next to `mw4print.exe`; this key is only consulted if that file is missing or empty. It was moved because the game rewrites `options.ini` and dropped unknown keys. |
---
## Dead settings
These appear in the shipped `options.ini` but are **not read by any code** in this tree.
They are stock MechWarrior 4 leftovers. Editing them does nothing.
### `[network options]` -- entire section is dead
`connectiontype`, `connectionspeed`, `packetsize`, `defaultconnection`, `playericon`,
`teamicon`.
Verified: no `GetEntry`/`GetPrivateProfile*` call anywhere references these key names. The
connection type actually used at runtime comes from `conDefault.connectiontype`, which is
populated from the multiplayer connection wizard, not from this file.
### Individual dead keys
| Key | Section | Why dead |
|---|---|---|
| `videodriverindex` | `[graphics options]` | Read call commented out; device forced to 0. |
| `huddamagemode` | `[special commands]` | Read call commented out; forced false. |
| `hudtargetdamagemode` | `[special commands]` | Read call commented out; forced false. |
| `secmissionreplay` | `[battle tech misc]` | Misspelled; code reads `SecsMissionReplay`. |
| `secmissionreport` | `[battle tech misc]` | Misspelled; code reads `SecsMissionReport`. |
---
## Practical notes
- **Back up `options.ini` before experimenting.** The game rewrites parts of it, and an
unknown key is silently ignored rather than reported, so a typo produces no diagnostic --
just default behaviour.
- **Per-role files.** On a pod, the launcher copies `options-game.ini`, `options-cam.ini`
or `options-mr.ini` over `options.ini` depending on the machine's role. Edit the role file,
not the live one, or your change will be overwritten at next launch.
- **The 2016 release drop** shipped `hardwaremixing=true`, `BiggieSizeIt=1` and
`RuleBook=1`, where the current dev tree ships different values. If you are chasing a
behavioural difference against that release, compare these first.
- **Case.** Section and key names are matched case-insensitively by the notation reader, but
the spelling must otherwise be exact.