Files
EscapistsReintroduced/docs/preparation-status.md
T

14 lines
4.3 KiB
Markdown

# Mission preparation presentation
The successor now places persistent status text inside the native respawn loading placeholder while its own mission remains `PREPARING`. Normal preparation displays **Preparing mission** and the existing shared explanation that the prisoner will spawn when sites and equipment are ready. A replicated preparation failure changes the title to **Mission could not start**, displays the shared restart/administrator guidance, and hides the loading spinner. The administrator's existing `/esc status` response retains the specific cause. This is presentation only: it neither retries preparation nor authorizes spawning or restart.
Previously the scenario inherited the vanilla opaque loading splash, but the only successor preparation/failure guidance was a 15-second hint. No native mission task is created before the first successful phase transition. Failed preparation stops admission and cannot activate the normal survivor observer path which removes the loading placeholder. The new status therefore belongs to that existing loading surface instead of relying on an expiring hint or a player camera.
`ERR_PreparationStatus.c` extends the installed `SCR_RespawnSystemComponent.UpdateLoadingPlaceholder(float dt)` callback. Vanilla's `DeployMenuSystem` already invokes it; no new timer is added. The adapter compares vanilla's protected `m_pGameMode` field (assigned from `owner` by `SCR_RespawnSystemComponent.OnInit(IEntity owner)`) with the exact current `ERR_GameMode`; it runs only for that owner, with a live native placeholder, outside a console application and during `PREPARING`. It preserves the superclass update and all other modes. The newly authored child layout uses its own identity, `{BCCAE287751344D9}UI/layouts/ERR/PreparationStatus.layout`, and native default fonts; it adds no vanilla resource reference.
The adapter remembers the exact placeholder, owned status widgets and original spinner visibility. Replacing or deleting the placeholder, moving the owned child away, leaving preparation, or calling native `DestroyLoadingPlaceholder` clears the child and cached text. A hidden spinner is restored to its recorded visibility when still alive. Normal native placeholder destruction remains responsible for its own audio and parent-widget lifecycle. No camera, audio, input, actor, mission state or inventory is changed by the adapter.
`tests/test_preparation_status.py` executes the actual presentation and cleanup methods through widget/native-boundary adapters. It checks unchanged behavior for unrelated/console modes, persistent text without repeated creation or text writes, preparation-to-failure changes, stale state clearing, missing UI resources/children, parent replacement, deleted weak widget references, reparenting, phase exit, native destruction and restoration of an initially hidden spinner. It also executes the actual native observation probe's continuous-time, reset and timeout rules. These are source-policy checks, not native rendering evidence.
The existing opt-in Core `startup-failure` fixture now waits up to 30 seconds for actual production-created loading widgets. It requires the expected title and shared body text, correct parent ownership, visible nonzero-sized title/body/root widgets, a visible loading parent and a hidden native spinner. It observes these continuously for 17 seconds, exceeding the old hint duration, then requests `$logs:err-preparation-failure` and waits another half-second before its original negative-path assertions complete. It does not create or update the widgets itself. The deliberate faction setup error remains a native ERROR and must retain the negative fixture's failed/error verdict; a successful UI assertion does not turn that run into a clean mission startup. The first native compilation rejected an assumed `GetOwner()` API, which this native respawn system does not expose. That call has been replaced with its installed vanilla `m_pGameMode` owner field; the second native run compiled and passed the continuous 17-second checks on the actual title/body/root widgets, parent ownership and hidden spinner. Its captured Workbench image was a blank blue editor viewport, so it provides no visual proof that the status is readable in an ordinary player view. Ordinary-player visual inspection remains pending; the deliberately failed setup still retains its negative engine-error verdict.