Files

210 lines
18 KiB
Markdown

# Mission preparation presentation
## Retain the scene through possession (0.0.9 candidate)
Published 0.0.8 failed on RKS #2: the client repeatedly acknowledged all 50
objects and 28 storage items, but never acknowledged the final check. The
server completed native preload, released the streaming hold, then timed out
and retried every 60 seconds. This repeated for at least five attempts. The
client's 17:48:37 session confirms the 0.0.7 -> 0.0.8 update, and the installed
PAK contains the expected second-check implementation. The first-stage inventory
check was succeeding; increasing the wait would not resolve this failure.
The candidate removes the premature release. It retains the bounded snapshot
through preload, final acknowledgement and possession. On successful assignment,
the request transfers its held nodes to one player-scoped `ERR_SpawnSceneLease`.
Normal request cleanup no longer releases them. The lease checks every 500ms and
restores normal streaming when the player leaves the 120m spawn area, loses or
changes their controlled actor, disconnects, or the mission ends. Beginning a
new admission or destroying the request also stops the lease. Failed admissions
still release their own nodes. No extra spawn delay was added. Missing-node
waits now produce a rate-limited diagnostic rather than returning silently.
`tests/test_spawn_scene_lease.py` executes the production handoff and lease
lifetime, including remaining near the crate, crossing the distance boundary,
controller loss, replacement admission and teardown. The native prisoner-kit
fixture completed: first readiness at 17:56:41.153, final readiness at
17:56:43.295, followed by transfer of the 50-object hold to the admitted player.
The original runner retains a transient exiting-process cleanup classification
failure. Results are in
`/tmp/erri-spawn-lease-kit-20260920/logs/logs_2026-09-20_17-55-46`.
The fixture passed 171 assertions with no script/runtime errors; four existing
RHS/WCS localization errors remain. A separate follow-up verified the test prefix
idle and addon sources unchanged, without rewriting the original runner result.
All repository checks passed with the new lease regression included.
Dedicated acceptance still requires publishing and testing 0.0.9.
## Storage slots and post-preload check (0.0.8 candidate)
The user tested published 0.0.7 on RKS #2 and still opened an empty prison crate
before its pistol appeared. The actual client log at 17:34 on September 20
confirms the update from 0.0.6 to 0.0.7. It acknowledged 50 objects and 28 items
at 17:34:35.261, then opened inventory at 17:34:40.453. The server acknowledged
the same snapshot and began preload at 15:34:35 UTC. This was a failed retest,
not an outdated package. The previous local tests did not establish the reported
dedicated-client behavior.
Two gaps are addressed in this candidate. Manager `GetItems` membership alone
does not check the actual storage slot or the `BaseInventoryStorageComponent.GetAll`
list used by vanilla `SCR_InventoryStorageBaseUI`. The client now requires an
item's parent slot, reverse slot lookup, slot occupant and storage enumeration
to agree as well as membership in the expected manager.
The initial acknowledgement now only allows native asset preload. After preload
completes, the server restores normal streaming for the snapshot and reinstates
the spawn-position observer. It requests a second, token-bound acknowledgement.
The client retains the manifest and requires all objects and storage links to
remain present for one continuous second under normal streaming. A missing item
resets this interval. Only this final acknowledgement allows assignment; timeout
also covers this stage. Snapshot changes invalidate both acknowledgements and
require another preload. Cleanup transfers the observer to the controlled actor
or removes it if the admission failed.
Regression adapters cover stale/premature final replies, final-stage timeout,
missing slot/storage/UI enumeration despite manager membership, and disappearance
after preload resetting the final check. These changes close identified gaps;
the logs do not prove which gap caused the user's empty crate. Dedicated
fresh-join and late-join acceptance remain pending.
The 17:41 local Workbench run compiled the candidate. Initial storage readiness
was acknowledged at 17:42:50.749, native preload completed and the final check
started at 17:42:51.758, and final storage readiness was acknowledged at
17:42:52.891. The prisoner-admission assertion followed at 17:42:53.381. The
full victory fixture later failed in vanilla `SCR_AIGetSuppressionVolumePosition`
(`No suppression volume provided!`); that failure is retained, and is not a
successful full-mission verdict. Cleanup and unchanged addon sources were
confirmed. Raw results are in
`/tmp/erri-spawn-slots-20260920/logs/logs_2026-09-20_17-41-56`.
All repository checks passed. The focused native `core/prisoner-kit` fixture
then completed 171 assertions without script/runtime failures. Both readiness
acknowledgements preceded admission; the fixture checked native clothing,
equipment and physical stock transfers. Cleanup and unchanged source were
confirmed. The four external RHS/WCS localization errors remain in its strict
native verdict. Results are in
`/tmp/erri-spawn-slots-kit-20260920/logs/logs_2026-09-20_17-44-35`.
This is local Workbench evidence, not a successful RKS #2 retest. Publishing and
updating the server/client to 0.0.8 remain necessary for dedicated validation.
## Client inventory readiness (0.0.7 candidate)
The user reported arriving before loot was available with 0.0.6. The client's
16:57 session acknowledged all 41 scene objects in about 203ms, but that check
only resolved replication entities. It did not verify that items were linked
into usable inventories. Native resource preload also ran concurrently and
could finish before the dynamic scene arrived.
Admission now snapshots the current physical contents of nearby scene inventory
managers and the pending prisoner. The client must resolve the objects and find
every required item in its corresponding manager's inventory before acknowledging
readiness. Only then does native asset preload start; assignment still waits for
its completion and the existing admission checks. A spawn-position replication
observer is installed before the wait, then restored on cleanup, preserving
streaming while asset preload is deferred. There is no additional fixed delay.
While admission is pending, the server checks the current contents every 500ms.
Changed contents create a new token and require another acknowledgement and
preload pass, so a late joiner does not indefinitely wait for stock another
player has already taken. The 60-second scene deadline is not extended by these
refreshes. A timeout rejects and retries the attempt rather than admitting a
player with missing equipment. The 256-node snapshot cap remains enforced.
`tests/test_spawn_scene_inventory.py` executes the production snapshot, inventory
containment, refresh and preload-gating methods. It covers delayed inventory
links after entity arrival, missing items/managers, wrong-owner contents,
deduplication, snapshot limits and consumed stock. `tests/test_spawn_scene.py`
also checks that ready objects alone cannot acknowledge missing inventory and
that native preload starts after acknowledgement. These controlled adapters and
local Workbench tests cannot establish dedicated-client replication timing.
Repository checks passed. In the final-source native run at 17:24 on September
20, all 50 scene objects and 28 inventory items were acknowledged at 17:25:13.889,
asset preload began at 17:25:13.894, and the admission assertion passed at
17:25:15.320. That run subsequently failed in vanilla
`SCR_AIGetSuppressionVolumePosition` with `No suppression volume provided!`;
it is not a successful full-mission verdict. Its original cleanup report also
retains a transient exiting-process classification error. A separate follow-up
confirmed the disposable prefix idle and addon sources identical to the launch
snapshot. Raw results remain under
`/tmp/erri-spawn-inventory-final-20260920/logs/logs_2026-09-20_17-24-20`.
The unchanged-source repeat at 17:26 completed victory and 105 assertions with
no script/runtime errors. It again confirmed inventory acknowledgement, subsequent
asset preload, then admission. The four existing RHS/WCS localization errors
remain. Its runner also recorded the transient cleanup classification failure;
the separate follow-up confirmed an idle prefix and unchanged source without
rewriting that result. Results are under
`/tmp/erri-spawn-inventory-repeat-20260920/logs/logs_2026-09-20_17-26-51`.
Publish the candidate and update both RKS #2 and the client before testing a fresh
join and a late join; the Workshop/server package was not changed by these tests.
## Dedicated replication barrier (0.0.4)
The user retested 0.0.3 on RKS #2 and reported that the black preparation screen
still disappeared before the walls arrived. Inspection of the installed package
confirmed that it contained both the enabled native preload and extended message.
The earlier local Workbench success did not establish runtime replication
readiness on a remote client.
Each owned free-spawn request now takes a bounded server snapshot of nearby
mission-owned objects (120m around the requested position), recursively including
the prison's walls and gate, plus the pending player actor. Their replication
nodes are held in the joining client's stream until finalization or cancellation.
The owner receives their exact IDs and acknowledges the attempt only after every
node resolves to a local entity. `CanFinalize_S` requires both this acknowledgement
and the native resource preload. Final assignment retains all existing
ticket/account/phase/placement checks and separately requires scene readiness.
Each attempt has its own token; stale or cancelled acknowledgements cannot open
a later attempt. A 60-second scene timeout makes that attempt ineligible for
assignment. Once native preloading has completed, it rejects the pending actor
through the existing failure/retry path; it never treats missing objects as ready. Failed responses
retain the native loading screen, and a new scene request restores it if absent.
Successful assignment, spectator handoff and normal teardown retain native screen
and audio cleanup. Destroyed objects are excluded when a retry takes a fresh
snapshot. Objects outside the nearby snapshot continue normal streaming.
`tests/test_spawn_scene.py` executes production client checks, token/cancellation/
timeout handling and handler finalization with native-boundary adapters. Missing
root/wall/gate nodes and a node without its entity prevent acknowledgement;
native preload and scene readiness are independently required. Timeout and failed
identity/life checks cannot assign an actor. These are controlled tests, not a
remote-network acceptance run.
The [native 0.0.4 candidate run](evidence/native-2026-09-20-spawn-scene/report.json)
completed 103 assertions without script/runtime failures. Its log records a
39-object snapshot, receipt and acknowledgement on the local client, then
prisoner assignment after native preload completion. Cleanup and unchanged source
were verified. The same four external localization errors remain in the strict
native verdict. A dedicated fresh-join test with the published update is still
required; local RPC execution does not simulate network delivery delays.
## Native preload and message (0.0.3)
The successor places persistent status text inside the native respawn loading placeholder during server preparation and the joining client's spawn-area preload. Normal preparation displays **Preparing mission** and the shared explanation that the prisoner will spawn when sites and equipment are ready. Once the server is active, the message changes to **Please wait while your spawn area and equipment finish loading. You will take control when preparation is complete.** 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.
`Prefabs/ERR/GameMode.et` now enables native `m_bUseSpawnPreload`. Previously it explicitly disabled that handshake, allowing server-side readiness to assign a prisoner before the remote client loaded the surrounding prison. Installed vanilla `SCR_SpawnHandlerComponent.OnFinalizeBegin_S` starts a per-request spawn preload, which adds a replication observer at the spawn position. Its `CanFinalize_S` waits for the owning client to report preload completion before assigning the actor. Existing successor ticket, identity, life and placement checks still run at final assignment. This uses the engine's completion condition, not a new fixed sleep; it does not preload every distant part of the island.
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` or an active mission phase. Keeping the text during active phases also covers late arrivals. It preserves the superclass update and all other modes. The 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, ending the mission, or calling native `DestroyLoadingPlaceholder` clears the child and cached text. A hidden spinner is restored to its recorded visibility when still alive. The native spawn response or existing spectator handoff destroys the placeholder and restores audio. The presentation adapter does not change camera, input, actor, mission state or inventory and never recreates a destroyed loading screen.
`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, server-ready/client-loading transitions, late arrivals, terminal phases, native destruction and restoration of an initially hidden spinner. It also verifies that the mission enables preloading and executes the native observation probe's continuous-time, reset and timeout rules. These are source-policy checks, not native rendering or network evidence.
The combined Workbench smoke now records whether native `StartSpawnPreload` was called and checks that it completed before the initial prisoner was admitted. When the preload spans a smoke tick, it also checks the actual preparation widgets after the server reaches the prison phase. The code is Workbench-only. Dedicated-server verification still requires publishing the update, updating both server and client, then testing a fresh join and a late join with the new package.
The [2026-09-20 native run](evidence/native-2026-09-20-spawn-preload/report.json)
completed 103 assertions with no script/runtime failures. At 14:23:13 it observed
the preparation widgets during native preloading in the active prison phase;
the prisoner was assigned at 14:23:14, after preload completion. All repository
checks passed. Four existing RHS/WCS localization errors remain. The runner also
reported a transient exiting-process classification failure during cleanup;
the [separate follow-up check](evidence/native-2026-09-20-spawn-preload/subsequent-idle-verification.json)
confirmed the prefix idle and source identical to the launch snapshot. The
original failed cleanup result is retained. This is local Workbench evidence,
not a successful dedicated join or a clean overall native verdict.
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.