This note documents the currently opened live `REGRET.EXE` startup lane around `Game_Start` and the later helper that performs the actual new-game mission hop.
The immediate goals of this pass were:
- name the directly involved startup helpers in Ghidra
- annotate the startup-state globals that feed the new-game path
- explain why No Regret appears to set the start map twice
## Named Functions
The following previously-unnamed functions are now promoted in the live `REGRET.EXE` database.
| Address | New name | Why the name is justified |
|------|------|------|
| `1058:0bbe` | `HandleCommandlineArgs` | Matches the already-recovered Remorse-side parser role. It compares argv entries against a startup-option table and writes `g_warpToLevelNoArg`, the difficulty override, map offset, egg override, and the extra startup-video flag. |
| `1030:032d` | `Game_RunNewGameFlow` | This is the full No Regret new-game helper. It plays the ORIGIN/ANIM01 intro lane, opens the difficulty modal when not warping, rebuilds the world/avatar state, and then performs the actual mission-start teleporter hop or the debug `-warp` path. |
| `1030:022e` | `Game_DrawCenteredStartupSplash` | Called immediately before the teleporter hop in both the normal and `-warp` startup lanes. It fades black, clears the active gameplay state, centers one startup screen object, and redraws the viewport. |
| `11c8:0d96` | `Game_EnterFrontendMenuViewport` | Used before modal-gump dispatch. It clears the gameplay-style viewport flag, expands the mouse Y range to the taller menu height, and refreshes the screen object. |
| `11c8:0d39` | `Game_RestoreGameplayViewport` | Used after the modal/front-end phase. It restores the gameplay-style viewport state, notifies NPC update lanes, restores the shorter mouse Y range, and refreshes the screen object again. |
## Game_Start Structure
`Game_Start` in No Regret still looks like the top-level frontend entry point.
High-level shape:
1. Freeze the current gameplay/process state enough to enter a frontend/modal lane.
2. Enter the taller frontend viewport mode and dispatch the startup modal gump.
3. Handle non-new-game modal results such as exit/other menu actions.
4. For the new-game path, clear world/gameplay state, rebuild the avatar and starter items, and do an early teleporter hop to map `1`, egg `0x1e`.
5. Fade/reset again and hand back into the wider startup framework.
The key early selector is still:
-`1008:1446 PUSH 0x1`
-`1008:1448 PUSH 0x1e0001`
-`1008:144e CALLF 0x1030:0000`
That early site is real, but it is not the only startup teleporter call that matters.
## Actual New-Game Mission Start
The function now named `Game_RunNewGameFlow` is the important second lane.
It is called from at least two concrete places:
-`CreditsProcess_Run` at `1008:0056`
- another startup/control lane at `1058:0a2a`
That already shows it is not dead duplicate code. It is a standalone startup helper reused by the frontend.
Its normal no-warp branch does all of the following in one place:
1. Play the ORIGIN/ANIM01 intro-video lane.
2. Open the difficulty-selection modal.
3. Reinitialize NPC/world/tracker state.
4. Apply any command-line difficulty override.
5. Recreate starter inventory items.
6. Draw the centered startup splash.
7. Perform the actual mission-start teleporter hop.
The effective mission-start selector is:
-`1030:05c3 PUSH 0x1`
-`1030:05c5 PUSH 0x1e0001`
-`1030:05cb PUSH CS`
-`1030:05cc CALL 0x1030:0000`
This is the selector that redirected real new games only after the script was updated to patch it together with the earlier `Game_Start` site.
## Startup Globals
These data roles are now annotated in the live Ghidra session.
| Address | Current best role |
|------|------|
| `1480:1453` | Startup-world transition flag. `Game_Start` clears it before the early menu-start teleporter hop. `Game_RunNewGameFlow` sets it during world/NPC rebuild and clears it again immediately before the actual mission-start teleporter hop. |
| `1480:0ac8` | Optional command-line warp X override. `0xffff` means no direct coordinate warp is requested. |
| `1480:0aca` | Optional command-line warp Y override. |
| `1480:0acc` | Optional command-line warp Z override. |
| `1480:0ace` | Command-line difficulty override parsed by `HandleCommandlineArgs`. If greater than zero, the new-game flow copies it into `g_difficultyLevel` before the teleporter hop. |
| `1480:0ad0` | Command-line `-mapoff` additive map offset used by the debug `-warp` path. |
| `1480:0ad2` | Command-line egg override used by the `-warp` path. When negative or `0x001e`, the code falls back to the default startup egg. |
| `1480:0ad4` | Extra startup-video behavior flag parsed by `HandleCommandlineArgs`. Clear means the ORIGIN/ANIM01 lane is played once; set means the same lane is repeated until `1480:95f0` becomes nonzero. |
| `1480:95f0` | Startup-video loop exit latch used by `Game_RunNewGameFlow` and `CreditsProcess_Run`. |
## Command-Line Warp Controls
The startup parser exposes more real gameplay-side command-line controls than just `-warp`.
Currently proven from the recovered parser strings and control flow:
-`-warp`
-`-skill`
-`-mapoff`
-`-egg`
-`-debug`
-`-demo`
-`-setver`
-`-asylum`
The same executables also contain the runtime status strings:
-`Warping to mission %d.`
-`Warping to mission %d @ x:%d y:%d z:%d.`
-`Defaulting to skill level %d`
-`Destination Egg = %d`
That parser behavior is now tight enough to promote the actual syntax:
-`-warp <mission>` = mission-only manual warp
-`-warp <mission> <x> <y> <z>` = direct coordinate warp
The key parser detail is that there are no separately recovered `-x`, `-y`, or `-z` switches in this lane. After `HandleCommandlineArgs` parses the mission number, it checks the next argv token. If the next token is missing or begins with `-`, the parser takes the mission-only path and prints `Warping to mission %d.`. Otherwise it consumes the next three argv tokens as X, Y, and Z and prints `Warping to mission %d @ x:%d y:%d z:%d.`.
There is one important precedence rule in `Game_RunNewGameFlow`: `-egg` wins over the coordinate override path. When X is present but the egg override is nonnegative, the code still routes back into the egg-based teleporter lane. The direct `NPC_Teleport` path only runs when X/Y/Z are present and the egg override is still negative.
That is the same 17-word sequence already recovered from No Remorse at `1478:0488`, so the two games currently match on the embedded mission-to-base-map table even though the surrounding startup control flow differs.
The executable patch was needed because the stock new-game path still hardcodes the startup selector payload `(map = 1, egg = 0x1e)` in code. No Regret does that twice, once in `Game_Start` and once again in `Game_RunNewGameFlow`.
The command-line warp lane is different:
- it only runs when `g_warpToLevelNoArg != -1`
- it uses a debug/manual warp flow rather than the ordinary fresh-game path
- it computes the target map from an embedded mission-to-map table plus `-mapoff`
- it can also change the destination egg
- it can apply explicit X/Y/Z destination overrides through `-warp <mission> <x> <y> <z>`
So a command line could likely have reproduced the practical destination change for a manual debug warp session, but not the ordinary fresh-game mission-1 behavior that the patch script changed.
For maps with no usable teleport egg, the parameter-only workaround is now clearer too: use `-warp <mission> <x> <y> <z>` together with `-mapoff`, and do not pass `-egg`. That path bypasses the egg lookup and calls `NPC_Teleport` directly. The current inspected teleport lane does not show any automatic `snap-to-ground` rescue, so this only works if the supplied coordinate triple is already valid for the target map.
Current best distinction:
- executable patch = changes the stock fresh-game startup behavior
- command-line warp args = invoke a separate manual/debug startup path that can land on a different mission/map/egg and likely a different coordinate triple
## Likely Reason Map 1 Is Set Twice
The most likely explanation is that No Regret preserved two valid entry paths into an in-engine gameplay state instead of refactoring them into one shared startup selector.
Evidence for that read:
-`Game_Start` contains an early teleporter hop immediately after rebuilding the avatar and starter items.
-`Game_RunNewGameFlow` is a separate, live helper called from `CreditsProcess_Run` and another startup/control lane.
-`Game_RunNewGameFlow` owns the full intro-video, difficulty-modal, world-reset, and real mission-start sequence.
- Both paths call the same local teleporter wrapper with the same literal `(1, 0x1e, 1)` payload.
Current best model:
- the early `Game_Start` hop is a frontend/bootstrap entry into a playable engine state
- the later `Game_RunNewGameFlow` hop is the authoritative mission-start step for a real new game after the intro/difficulty flow
- both kept their own literal selector instead of sharing one startup-map global or helper constant
So the duplication looks more like split control-flow ownership and startup code reuse than a deliberate “set it twice just in case” pattern.
## Practical Patch Implication
For No Regret, changing the fresh-game destination map must update both hardcoded selectors:
- early `Game_Start` selector at `1008:1448`
- actual mission-start selector at `1030:05c5`
Patching only the early site is insufficient because the later new-game helper can silently overwrite that choice during the real mission-start sequence.