# pod-launch The supervising launch **entry-point** for the two DOSBox titles (BattleTech / Red Planet 4.10). TeslaConsole → TeslaLauncher invokes this exe in the game dir with args selecting game/mode; it is the single authoritative handle for the whole session. See [`../DEPLOYMENT-PLAN.md`](../DEPLOYMENT-PLAN.md). ## Why an exe, not a batch/script The entry-point must **own** the child processes' lifetime, not hand off and exit. `pod-launch`: 1. Creates a **Windows Job Object** with `JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE`. 2. Launches **DOSBox-X** and the **render bridge** *into* the job. 3. **Blocks** on DOSBox for the whole mission. Kill this process (TeslaLauncher force-killing a hung DOSBox on a console command) → the job's last handle closes → the **kernel** kills DOSBox + the renderer. This holds even on a hard `TerminateProcess`, where no cooperative shutdown can run. When DOSBox exits on its own (mission end) the supervisor tears the job down and returns DOSBox's exit code. A batch file / `cmd.exe` / `start` / `Start-Process` can't do this: they decouple from the child, which then survives the parent. Verified: hard-killing the supervisor reaps its child via the kernel (see the job-object cascade test). ## Build Dev (needs the .NET 8 runtime present): ``` dotnet build -c Release ``` Deploy — self-contained single-file, so the air-gapped pod needs no .NET runtime installed: ``` dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true ``` ## Console argument reference `pod-launch [mode] [options]` — the single installed entry-point. The product is installed once; the console activates features by the args it passes. The per-rig layout is fixed at `postinstall` time, so a typical call is just `pod-launch bt`. ### Mode — the primary feature selector (positional, or `--mode `) | Arg | Activates | Status | |---|---|---| | `bt` | BattleTech, networked cockpit (`net_loop.conf`, looped) | wired | | `rp` | Red Planet, networked cockpit (`net_rp.conf`, looped) | wired | | `review` | mission-review PLAYBACK of `last.spl` | recognized, exits 3 (DOS arg TBD) | | `test-plasma` | plasma-display diagnostic | recognized, exits 3 | | `reset-rio` | RIO reset diagnostic | recognized, exits 3 | | `audio-test` | audio test diagnostic | recognized, exits 3 | Camera ship and LIVE mission-review are **not** modes — same `bt`/`rp` boot; the console sets the role per-IP via the egg `hostType` (0 pod / 1 camera / 2 review), see `../CAMERA-REVIEW-NOTES.md`. Default mode: `bt`. ### Feature toggles | Arg | Effect | |---|---| | `--no-sound` | skip the ~4-min AWE32 SoundFont upload — **freezes bt/rp**: no AWE32 = no SOS ticks, and the default confs use the FAST (SOS) clock, so BTL4 hangs in the RIO-reset busy-wait (`L4RIO.cpp` `SetDTR`/`Now()`; root-caused 2026-07-10). Only safe with a SLOW-clock conf (`setenv` arg2=`s`) | | `--mipmap` | mip-filter minified textures (fixes RP floor shimmer; non-authentic) | | `--layout cockpit\|explode` | `cockpit` = borderless VDB head windows (default); `explode` = 7-window debug | | `--no-bridge` | pod only, no GL render window | | `--no-focus` | skip the renderer-topmost / DOSBox-focus pass | ### Window placement (per-rig; normally fixed, overridable per-launch) | Arg | Effect | |---|---| | `--bridge-pos x,y` | main render window position (default `0,0`) | | `--bridge-size w,h` | main render size (default `832,512` — the dPL3 board's native framebuffer res; see `../LAUNCH.md`) | | `--dosbox-xy x,y` | DOSBox window position + focus (default `10,10`) | ### Path / asset overrides (dev / edge — `postinstall` already wires these) `--root ` · `--conf ` · `--dosbox ` · `--renderer ` · `--bridge-script ` · `--awe-rom ` · `--work ` ### Diagnostics `--dry-run` (resolve + print the launch plan, don't launch) · `-h` / `--help` ``` pod-launch bt --root C:\VWE\TeslaRel410\emulator --dry-run ``` ### Exit codes the console reads back - **normal run** → returns **DOSBox's exit code** = the game's **`ExitCodeID`**, passed straight through (the same remote-ops code the pod loop dispatched on). - **`2`** → bad arguments (usage on stderr). - **`3`** → recognized mode not yet wired (reason on stderr). ## Deploy layout it expects (under the game dir / `--root`) ``` pod-launch.exe dosbox-x.exe net_loop.conf net_rp.conf renderer.exe (frozen) roms\awe32.raw ``` `postinstall.bat` lays this out and renders the `net_*.conf` (paths, `realnic`, `WATTCP my_ip = bayIP+100`). This exe just selects + launches. ## TODO (tracked in DEPLOYMENT-PLAN.md OPEN items) - Wire the distinct non-networked modes once their DOS launch args are confirmed: `review` (playback app + `last.spl`) and the diagnostics. (The mode table in `Modes.cs` is the single place to add each.) - Swap the dev `pyw live_bridge.py` for the frozen renderer exe once packaging is decided (freeze vs embedded Python — with David). - Per-rig cockpit head RECTS (currently the `pod_deploy.ps1` defaults).