# Player lifecycle and pending admission New free-spawn characters are damage-protected while their admission ticket waits for the owner's scene, inventory and native asset preload. Protection ends when the verified spawn is finalized; failed/cancelled tickets restore their prior damage state and clean up the unassigned body. This is tied to the actual body and ticket, not a connection-ID timer. Existing reserved-body reconnects retain their native handoff and vulnerability policy. Admitted prisoners now survive lethal damage as treatable unconscious casualties. If everyone is unconscious and neither treatment nor recovery progresses for 30 seconds, the round ends in defeat. See [recovery rules](recovery.md) for medical behavior and reconnect reservations. The death/spectator paths below remain as fallbacks for deleted bodies and administrative/native lifecycle events. ## Unconscious teammate camera An admitted player who becomes unconscious now gets a local third-person spectator camera without losing possession of the injured body. Teammates can continue treatment, including the existing epinephrine recovery path. Native healing restores the player's own camera automatically; the round's all-unconscious failure timer is unchanged. The server selects conscious, friendly players whose controlled bodies belong to the current round. It excludes the unconscious observer's own body, unfinished admissions and stale/replaced bodies. If the target becomes unavailable, it selects another valid teammate. With no conscious teammate, the camera remains near the casualty's own body. Press **Left/Right arrow** to cycle teammates without administrator rights; holding an arrow does not repeatedly switch targets, and open menus suppress cycling. `/esc spectate next` and `/esc spectate previous` remain available as chat alternatives. Native manual-camera look and zoom controls orbit the target at a bounded distance; there is no free-flight or target possession. The follow view also handles teammates in vehicles and traces camera clearance against terrain and objects. Default screen effects hide while a manual camera is active and return with the normal player camera. Existing dead/late-join spectator reasons retain their prior eligibility and wording. The new unconscious reason explains treatment and recovery rather than telling a living player to wait for the next round. Closing the round clears the selected target and the existing forced target/vehicle streaming leases. The owner's original `ESCT_SpectatorComponent`, `ESCT_OrbitPlayerManualCameraComponent`, and `ESCT_OrbitDistanceManualCameraComponent` were inspected read-only. The successor extends its existing observer instead of importing the original editor mode, fade dependencies or epinephrine-based camera exclusion. Their SHA-256 values are respectively `543891977028488a149498ab777477b4cc415e35d54d63d239a9358ae08393be`, `f11166bc01dc63b5503f74f40d7901f683c004b2f92b913fbdf8104d923e8c9b`, and `6245587ac6fad9819bd3098d14cb2f000539557cb4f0781f25611ad10be26354`. The successor keeps one round-owned life record per authenticated account. A connection number is only the current binding to that record. A new life can enter during prison, radio search or radio defence; extraction and terminal phases refuse new admission. Successful initial assignment spends the life. Cancelling an unassigned preload never restores or spends a life. Native reconnect reservation and handoff remain separate from new-character admission. A returning account may reclaim its surviving reserved actor through Reforger's reconnect system. A dead actor remains a spent life; unconsciousness is not death. Reserved living actors remain participants while their connections are absent. These policies are implemented, but real remote reconnect and reservation-expiry acceptance remains unfinished. ## Weapon retention on unconsciousness **Esc → Co10 Escape Reintroduced → Mission → Keep weapon when unconscious** offers Enabled/Disabled buttons. Enabled is the default, including for older settings files. Administrators can also use `/esc mission keepweapon set 1` or `0`. The preference persists in the server profile and is captured at each knockout; changing it does not alter a casualty already being treated. Enabled retains the actual held firearm, including its magazine and attachments, and selects it again after revival. It never creates a replacement or takes a gun acquired by another inventory. Disabled allows the normal ground drop. Grenades, gadgets and mounted weapons are excluded. The native test verifies inventory retention and the same rifle in hand after waking; it does not qualify the unconscious ragdoll's hand pose. Revival inside a vehicle leaves the gun in inventory rather than forcing an equip animation. ## Optional self epinephrine **Esc → Co10 Escape Reintroduced → Mission → Self epinephrine (Space)** lets administrators enable self-injection. It defaults to Disabled, including when loading older settings files. `/esc mission selfepi set 1` or `0` changes the same saved preference immediately, including for existing casualties. When enabled, an unconscious prisoner can press and release **Space** to consume one epinephrine injector from their own inventory. Standard epinephrine is preferred when usable; combat epinephrine is also supported. Each retains its normal medical effect: standard epinephrine restores resilience over time and cannot replace lost blood or stop bleeding. No injector is supplied automatically, and a genuinely dead body cannot use this action. The casualty hint explains the shortcut while enabled. Keys held during knockout, chat or menus must be released before a fresh press can inject. ## Placement Prison placement searches a 4×4 lattice with axis coordinates -4.5, -1.5, 1.5 and 4.5m relative to the authored center. The four inner positions are checked first, then eight edge positions, then four corners. Neighboring centers are 3m apart and remain 1.5m inside walls positioned at ±6m. The inner and edge positions are within 5m of the prison center. Terrain height and slope, physical scene/character occupancy, and pending reservations can reject a slot. Connection IDs 1 and 13 receive no special or shared position. Disconnected physical bodies still obstruct the native query. If every candidate is occupied or reserved, admission retries once per second within a budget of thirty active, eligible admission attempts. Missing faction/respawn prerequisites and rejected native spawn requests consume the same budget. Once exhausted, the existing SPAWN_UNAVAILABLE spectator path explains that no prisoner could be spawned; no unsafe fallback is used and no life is consumed. Mission preparation does not spend attempts, and an already-pending native request cannot spend another attempt. A temporary obstruction can still clear before the budget expires. Later arrivals first search bounded clear ground near a conscious friendly survivor outside a vehicle, with terrain-height and line-of-sight checks, then try the same prison grid. Placement does not imply a navigable route or safe proximity to enemies. Both late-join anchors and spectator follow targets now require the exact current round body through `ERR_PlayerRoster.CurrentActor`, in addition to the existing living/friendly checks. A controlled replacement, unfinished admission or recycled connection ID cannot supply a survivor target. Spawn anchors still require consciousness and the existing placement checks; living unconscious canonical prisoners remain eligible spectator targets. If no valid spawn anchor remains, the prison-grid fallback is unchanged. The previous 25-point grid passed reservation enumeration but exhausted at eight actual actors (archive `native-2026-09-19-062251`). Adding a ring to 49 candidates while keeping the central positions first still exhausted at nine (`native-2026-09-19-062847`). Diagnostics showed character world bounds about 4×4m; the old 1.5m lattice left adjacent candidates inside those conservative query bounds. The replacement 3m lattice changes packing rather than weakening the query or lowering the required population. All sixteen candidates still pass through the unchanged clearance predicate. The prisoner fixture must populate one real player plus eleven additional physical actors before capacity is accepted; this new packing awaits that native result. Manual crowding, movement, collision and spawn usability remain required. ## Finalization and cleanup The server records each initial free-spawn admission in a ticket bound to the mission instance, account, connection, controller, native request, exact request data object and created actor. Immediately before native assignment it rechecks current phase, account binding, connection, spent life, controller and request ownership, absence of another controlled entity, actor health and placement. Horizontal drift is limited to 0.6m and vertical drift to 1m, allowing ordinary settling while refusing displaced or fallen preloads. The reserved location is checked against current terrain and physical occupancy again. A refused ticket permits cleanup only of its owned unpossessed actor. An unknown or repeated request cannot claim an arbitrary actor for deletion. Stop, disconnect and closed-admission phases remove reservations, cancel the native repeated finalization callback and remove their pending actors. Pending/retry metadata is cleared before cancellation emits a response, so the response's failure callback cannot schedule a fresh admission. Cleanup rechecks actual player control: `ERR_Actors.DeleteSpawned` refuses any entity currently controlled by a player, regardless of its original ownership. The native handler interception applies only to successor game modes or an existing handler whose owning respawn system still carries successor spawn logic during teardown. Other scenarios retain vanilla behavior. Delayed entity-loss observation also checks the captured controller and ignores a living actor that was reacquired before the callback runs. ## Validation status `python3 tools/check.py` includes `tests/test_player_admission_policy.py`. It executes the actual source-local finalization and life-policy bodies plus the actual reservation rejection predicate through the existing C++ policy harness. Coverage includes every phase/life/connectivity/controller/request/identity combination, missing identities, displacement boundaries, radial distance, vertical reservation separation and own-reservation exclusion. The harness substitutes vector arithmetic and opaque identity equality; it does not emulate Enfusion collision, replication, native spawning or reconnect behavior. `ERR_NativeLifecycleProbe` is an opt-in WORKBENCH fixture integrated by the central runner as `-errBaseSmoke 1 -errSmokeOutcome lifecycle`. It checks native prison capacity, physical character occupancy, actual local-controller handler rejection, exact request ownership, deferred deletion, cancellation without another life, delayed observer metadata protection and a native displaced actor. Movement checks wait 750ms and deletion checks wait 1000ms rather than assuming immediate native updates. Synthetic ticket creation is confined to WORKBENCH and never changes the real prisoner's life record or possession. The native lifecycle fixture in [050403](evidence/native-2026-09-19-050403/report.json) completes 54 assertions, including an ordinary initial prisoner spawn. It finds 20 remaining clear positions around that prisoner. No script/VM exception occurs; seven inherited vanilla resource errors remain. Earlier reserved member-name and reflected-container failures are preserved in the validation archive. Normal Core/companion escape and restart regression remains a separate check. Remote 12-player concurrent join, slow client preload, disconnect during preload, recycled connection IDs, reconnect reservation handoff/expiry and spectator streaming cleanup remain separate multiplayer acceptance work. `tests/test_participant_selection.py` executes the actual `CurrentActor`, `SpawnPosition` and server observer-selection methods with engine enumeration, geometry and streaming represented by adapters. It covers unregistered and pending actors, missing identity, disconnect, mismatched connection/body, recycled IDs, dead/foreign bodies, accepted canonical targets, cycling, loss of a previously selected target, unconscious following and unchanged prison/geometry fallback. This closes a source-proven membership omission; it does not establish native possession or multiplayer streaming behavior for the revision. `tests/test_spawn_retry_budget.py` executes the actual `DoSpawn_S` method with native controller, respawn, geometry and scheduler adapters. It covers persistent blocked positions, missing prerequisites, thirty-attempt exhaustion, temporary recovery, request rejection, preparation waiting, spent/late life refusal and unchanged pending requests. The counter change has source-local regression evidence only until the next native integration run; this does not qualify slow remote clients or real multiplayer admission. The combined unconscious-camera/weapon revision passed eighteen native Workbench assertions on 24 September 2026: real player incapacitation, current manual camera activation, unchanged possession/living body, no-target fallback, physical-target tracking and movement, native FullHeal recovery, restoration of the player camera, repeated knockout, default-enabled retention of the exact rifle, the same rifle equipped after revival, and normal ground drop with retention disabled. There were no script/runtime failures, and runner cleanup and unchanged-source verification succeeded. Existing RHS/WCS and vanilla resource errors remain in the log, so this is not an error-free engine log. A WORKBENCH-only target stand-in exercises camera tracking because this runner has one real player; it does not establish remote multiplayer streaming. The actual server selection/client policy regressions cover self-exclusion, conscious teammates, canonical identity, target loss, recovery, inactive rounds and delayed unconscious metadata. Arrow input edge/hold/menu behavior and firearm categories have source-policy tests; the new menu controls have structural and command-route checks. The complete repository checks passed. Evidence is in `.local/analysis/unconscious-weapon-2026-09-24`. ## Delayed native preload completion (1 October 2026) The server's scene deadline now reaches the existing owned-ticket rejection even while a remote native preload completion is delayed. Rejection cannot assign a character, consume a life, or revive a stale ticket after a late acknowledgement. The ordinary verified admission path remains intact. Actual-method red/green regressions pass; the normal generated route independently verifies ordinary native admission. Remote timeout timing remains a multiplayer test requirement. [Evidence and scope](mission-hq-fixes-2026-10-01.md). ## Empty-server restarts (14 October 2026) By default, when the last player disconnects, the next server tick ends the mission through the normal native end/reload sequence. This includes players who leave before admission finishes. Living reconnect reservations do not keep a completely empty mission running. While another player remains connected, the existing reserved body and reconnect behavior still applies. Administrators can disable this behavior using **Mission → Restart after last disconnect** to preserve the round for reconnects, subject to the idle timer and normal round endings. A fresh mission with no connections restarts after five hours of real elapsed time by default. **Mission → Restart while empty (hours)** accepts 0 to disable the timer or 1–168 hours. The interval starts at mission initialization or the last disconnect, and is reset while players are connected. Both controls save immediately for this and future missions; interval changes use the elapsed empty time rather than restarting the timer. Mission time and time-multiplier settings do not change this interval. Connected players, including spectators and players loading in, prevent the empty-server restart. The check also runs during preparation; it stops with the mission's services. Both restart reasons are written to the server log. `test_empty_server_restart.py` executes the production restart check and tick wrapper, covering independent disabled/enabled settings, interval boundaries, live changes, repeated empty rounds, last disconnect, connections between ticks, preparation, authority and duplicate-end prevention. Settings and menu tests cover migration defaults, persistence, invalid values, failed saves and routing. The restart uses the existing native end/reload path. These offline checks do not establish live dedicated-server disconnect/reload timing.