# Crusader Command-Line Parameters ## Scope This note consolidates the currently recovered startup/debug argument set across the retail Crusader executables. The current strongest parser/control-flow evidence now comes from both live targets: - `REGRET.EXE` - `CRUSADER.EXE` Two conclusions matter most for the recent startup-map work: - the executable patch was still required to change the stock fresh-game start map - the built-in manual/debug warp lane is real, and its direct-coordinate form is `-warp [x y z]` That direct-coordinate syntax is now confirmed in both retail games, not just Regret. ## Short Answer If the question is `could the normal first-mission executable hack have been replaced by parameters all along?`, the answer is still no. The stock new-game path hardcodes map `1`, egg `0x1e` in code. The parameterized warp path is a separate startup/debug branch that only runs when `-warp` is present. If the question is `can the executable already warp into another map without patching files?`, the answer is yes. The current best-proven forms are: - `-warp ` - `-warp ` - optional `-mapoff ` and `-egg ` modifiers The important restriction is that `-egg` beats X/Y/Z. If you supply a nonnegative egg override, the game routes through the teleporter-egg path and does not use the direct-coordinate teleport. That precedence rule is also now confirmed in both retail games: - `REGRET.EXE` routes through `Game_RunNewGameFlow` - `CRUSADER.EXE` routes through `Game_Start` For the specific `-u` question, the current live No Remorse answer is now yes. The regular non-Japanese `CRUSADER.EXE` still contains a real `-u` lane, and the current best read is no longer `unresolved leftover token`. In this build it is a live startup override for the usecode/EUSECODE load source. ## Parameter Table | Argument | Current best syntax | Confidence | Current best effect | |------|------|------|------| | `-?` | `-?` | Medium | Help/usage-style startup path. The option is present in the parser table, and the nearby startup strings include `You DO need help!`. The exact REGRET-side case-to-string tie was not re-closed in this pass. | | `-u` | `-u ` | High | Live in retail `CRUSADER.EXE`. The parser copies the following token into `1478:065a`, and `startup_apply_u_override_if_present` later uses that buffer as a startup usecode/EUSECODE load-source override. The JP build matches the same interpretation. | | `-debug` | `-debug` | High | Live parser branch. Raises the debug-print threshold, prints `Debugging mode ON.`, and enables the known movie-player timing overlay / debug-print lane. | | `-setver` | `-setver ` | Medium | Still present in the broader Crusader parser-family tables, but the earlier CRUSADER-side assignment of the string-copy branch now belongs to `-u`. Treat the exact retail `CRUSADER.EXE` `-setver` behavior as still unresolved here; the older version/banner read is now best treated as REGRET-weighted rather than closed for both games. | | `-asylum` | `-asylum` | High | Joke/no-op style switch. Current best recovered effect is printing `Enabling ENHANCED mode. (NOT!)` with no stronger gameplay-side state change recovered in this pass. | | `-warp` | `-warp ` | High | Enables the manual/debug warp lane by setting `g_warpToLevelNoArg`. The runtime then computes `target_map = mission_table[mission] + mapoff`. | | `-warp` with coordinates | `-warp ` | High | Direct coordinate warp. After parsing the mission number, the parser checks the next argv token. If it is present and does not begin with `-`, the next three argv tokens are parsed as X, Y, and Z. | | `-skill` | `-skill ` | High | Parses a difficulty override into `1480:0ace`. The parser clamps `0` up to `1`, then `Game_RunNewGameFlow` copies the value into the difficulty level before the mission-start hop. | | `-mapoff` | `-mapoff ` | High | Adds an offset to the mission-table result inside the manual/debug warp path. It does not affect the stock fresh-game selector when `-warp` is absent. | | `-egg` | `-egg ` | High | Sets the destination egg override used by the warp path. When the value is nonnegative, it takes precedence over the direct-coordinate teleport branch. | | `-demo` | `-demo` | High | Sets `1480:0ad4`, prints `Demo mode.`, and changes the ORIGIN/ANIM01 startup-video behavior in `Game_RunNewGameFlow`. | | `-laurie` | `-laurie` | High | Separate from the main `HandleCommandlineArgs` switch table. This is the broader cheat/debug-enablement argument already documented in the live No Remorse notes. | ## Warp Syntax And Precedence The current best evidence-backed parser behavior is now confirmed in both `REGRET.EXE` and `CRUSADER.EXE`. In the No Remorse live database, the exact matching parser case is `HandleCommandlineArgs` at `1048:0adc`, and the matching consumer branch is in `Game_Start` at `1020:029e` / `1020:02d0`. In the Regret live database, the matching parser case is `HandleCommandlineArgs` at `1058:0cd2`, and the matching consumer branch is in `Game_RunNewGameFlow` at `1030:0628` / `1030:069a`. The shared behavior is: 1. `-warp` always consumes one numeric mission argument. 2. The parser then peeks at the next argv token. 3. If that token is missing or begins with `-`, the game takes the mission-only path and prints `Warping to mission %d.`. 4. Otherwise the parser consumes the next three argv tokens as X, Y, and Z, stores them in `1480:0ac8`, `1480:0aca`, and `1480:0acc`, and prints `Warping to mission %d @ x:%d y:%d z:%d.`. For No Remorse the corresponding X/Y/Z globals are the earlier siblings: - `1478:084c` = X override - `1478:084e` = Y override - `1478:0850` = Z override That means the recovered syntax is positional: - `-warp ` - `-warp ` This pass did not recover any separate literal `-x`, `-y`, or `-z` switches in the startup parser. At runtime, both games apply the same precedence: 1. Compute the target map from the embedded mission-to-map table plus `-mapoff`. 2. If X is unset (`0xffff` / `-1`), use the egg teleporter path. 3. If X is set but `-egg` is also nonnegative, still use the egg teleporter path. 4. Only when X/Y/Z are present and the egg override is still negative does the game bypass egg lookup and call `NPC_Teleport` directly. No Remorse’s direct consumer branch is especially clear: - `1020:029e` checks whether X is still `-1` - `1020:02a5` / `1020:02d0` check whether `-egg` is nonnegative - `1020:02d7..02eb` call `NPC_Teleport` only when X/Y/Z are present and egg override is still negative ## Eggless Maps And The Non-Patching Workaround This directly answers the recent map-254 style question. There is a parameter-only route into maps with no usable destination egg, but it is not `-egg`. The working shape is: - `-warp -mapoff ` with `-egg` omitted. Why that matters: - `-egg` keeps the code on the teleporter/egg path - the direct-coordinate form falls into `NPC_Teleport` - the inspected `NPC_Teleport` lane writes the exact map/X/Y/Z values and moves the camera there - the currently inspected teleport path does not show any automatic `snap-to-ground` or `find a safe spawn` rescue So the non-patching workaround for an eggless map is `known-good coordinates`, not `some hidden eggless-map flag`. If the supplied X/Y/Z values are bad, the game can still strand the avatar in empty space even though the warp itself succeeded. ## What `-u` Does In Retail `CRUSADER.EXE` The live non-Japanese No Remorse database now closes `-u` much more tightly than the older note. In `HandleCommandlineArgs`, the retail parser case at `1048:0a46` consumes the next argv token and copies it into the fixed startup buffer at `1478:065a`. The only recovered consumer of that buffer in the same retail executable is `startup_apply_u_override_if_present` at `1420:0cdf`. Recovered behavior in that helper: - check whether `1478:065a` is non-empty - if empty, leave the default startup path alone and return - if non-empty, route startup through an alternate load/resolve path using the copied string - store the resulting far pointer in `1478:6611/6613` - set the loaded-state byte at `1478:6615` - rebuild the cumulative slot-base words at `1478:8c7c..8c82` That is strong retail No Remorse evidence for this meaning: > `-u ` is a live startup override for the usecode/EUSECODE load source. What is still not fully closed from this static pass is the exact Filespec path syntax for the copied token. What is now materially tighter: - the helper does **not** treat the argv token as the final archive filename - it uses the token as the `path` component to `Filespec_GetFullPath` - it uses the mutable filename template at `1478:07a0`, which is `eusecode.flx`, as the fixed `filename` component - it forces that template's first byte to `'e'` before the existence probe and final load call So the safest current retail read is: - `-u ` expects a directory/resource-root style path argument for the standard `eusecode.flx` archive family - it does **not** currently look like a free-form arbitrary filename override But the important uncertainty is now only `exact naming rules`, not `whether the switch is real`. In the regular non-Japanese `CRUSADER.EXE`, the switch is clearly still live. This also aligns with the already-stronger JP Win32 result, where the matching `-u` lane was recovered as the same kind of usecode override. For the deeper runtime-side investigation of whether `-u` replaces or augments the stock usecode root, and what game systems that replacement feeds, see [docs/usecode-startup-override.md](docs/usecode-startup-override.md). Current best answer from that follow-up is: - `-u` behaves like a replacement of the live usecode runtime root, not an additive overlay - the replaced root is then used by normal item-event dispatch, usecode process creation, interpreter bytecode stepping, and gameplay-side scripted capability checks The current best replacement-vs-addition answer is also now stronger: - there is one live root at `1478:6611/6613` - `startup_apply_u_override_if_present` overwrites that root directly when `-u` is present - later event/process/interpreter consumers read the replacement root through the same global pair So the safest current retail read is `full runtime root replacement for the session`, not `load one extra add-on script beside stock usecode`. ## What `-setver` Most Likely Does `-setver` should now be treated more cautiously in this consolidated note. For retail `CRUSADER.EXE`, the string-copy branch that had previously been grouped under `-setver` is now better closed as the live `-u` handler described above. That means the older `displayed version/build string override` reading is no longer closed for the non-Japanese No Remorse executable itself. Current evidence bundle: - the option name is still present in the broader Crusader parser-family tables - older REGRET-side evidence still points toward a startup/UI presentation role rather than gameplay control - but this pass did not directly re-close the exact retail No Remorse `-setver` consumer after reassigning the resolved string-copy branch to `-u` Current best read: - `-setver ` still looks more like a presentation/version banner switch than a gameplay/startup-map selector - but that statement is now provisional for consolidated retail notes until the retail `CRUSADER.EXE` handler is isolated directly The exact retail No Remorse `-setver` branch is therefore an open cleanup item again, while `-u` is now the closed string-consuming retail startup override. ## No Remorse Cross-Check Summary The main recent uncertainty was whether Regret had gained an extra direct-coordinate warp feature that No Remorse lacked. The live `CRUSADER.EXE` pass now closes that question. Current best answer: - No Remorse supports the same positional `-warp [x y z]` syntax. - No Remorse uses the same `-egg` precedence rule over X/Y/Z. - No Remorse reaches the same direct `NPC_Teleport` style fallback when coordinates are present and the egg override is still negative. So the parameter-only workaround for eggless maps is not Regret-specific. The same approach should work in No Remorse too, as long as the supplied coordinates are valid for the chosen target map.