12 KiB
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.EXECRUSADER.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 <mission> [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 <mission>-warp <mission> <x> <y> <z>- optional
-mapoff <delta>and-egg <id>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.EXEroutes throughGame_RunNewGameFlowCRUSADER.EXEroutes throughGame_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 <arg> |
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 <text> |
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 <mission> |
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 <mission> <x> <y> <z> |
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 <n> |
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 <delta> |
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 <id> |
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:
-warpalways consumes one numeric mission argument.- The parser then peeks at the next argv token.
- If that token is missing or begins with
-, the game takes the mission-only path and printsWarping to mission %d.. - Otherwise the parser consumes the next three argv tokens as X, Y, and Z, stores them in
1480:0ac8,1480:0aca, and1480:0acc, and printsWarping 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 override1478:084e= Y override1478:0850= Z override
That means the recovered syntax is positional:
-warp <mission>-warp <mission> <x> <y> <z>
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:
- Compute the target map from the embedded mission-to-map table plus
-mapoff. - If X is unset (
0xffff/-1), use the egg teleporter path. - If X is set but
-eggis also nonnegative, still use the egg teleporter path. - Only when X/Y/Z are present and the egg override is still negative does the game bypass egg lookup and call
NPC_Teleportdirectly.
No Remorse’s direct consumer branch is especially clear:
1020:029echecks whether X is still-11020:02a5/1020:02d0check whether-eggis nonnegative1020:02d7..02ebcallNPC_Teleportonly 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 <mission> <x> <y> <z> -mapoff <delta>
with -egg omitted.
Why that matters:
-eggkeeps the code on the teleporter/egg path- the direct-coordinate form falls into
NPC_Teleport - the inspected
NPC_Teleportlane 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-groundorfind a safe spawnrescue
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:065ais 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 <arg>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
pathcomponent toFilespec_GetFullPath - it uses the mutable filename template at
1478:07a0, which iseusecode.flx, as the fixedfilenamecomponent - 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 <arg>expects a directory/resource-root style path argument for the standardeusecode.flxarchive 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.
Current best answer from that follow-up is:
-ubehaves 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_presentoverwrites that root directly when-uis 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
-setverconsumer after reassigning the resolved string-copy branch to-u
Current best read:
-setver <text>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.EXEhandler 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 <mission> [x y z]syntax. - No Remorse uses the same
-eggprecedence rule over X/Y/Z. - No Remorse reaches the same direct
NPC_Teleportstyle 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.