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, perb4089291). * .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>
337 lines
17 KiB
Markdown
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.
|