Files
EscapistsReintroduced/docs/local-singleplayer-admission.md
T

31 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Ordinary offline single-player admission
The ordinary native diagnostic `logs_2026-09-19_08-13-59/console.log:295–296` reports authority, RplMode.None, one local controller, and a 36-character all-zero UUID sentinel. The value is syntactically valid but null. Installed `SCR_PlayerIdentityUtils.GetPlayerIdentityId` tests raw `IsEmpty()`, so this initialized null string bypasses its PeerTool empty-string fallback and previously made successor roster binding fail.
`ERR_LocalAdmission` supplies a successor-owned round key only inside a mode created as RplMode.None. It is selected from the existing real native `OnPlayerAuditSuccess_S` callback. The context must be authoritative, retain the current successor mode, have exactly one connected player, and match that player's positive ID and current manager controller to the actual local controller. If the native helper returns a non-null identity, that value is retained. Otherwise native `UUID.GenV4()` supplies one local-round key. This is life/result bookkeeping, not a Bohemia/platform identity or authentication assertion. No identifier/name bytes are logged. In the explicit ordinary diagnostic only (`-errOrdinaryScenario core` or `chat`), the first context refusal records boolean authority/controller checks, session mode and player count so native standalone API timing can be distinguished from an invalid context without relaxing admission.
The helper pins mode, controller, connection and selected key. Repeated callbacks do not reset spawn attempts, replace the body or bind another life. A backend identity appearing later does not replace the pinned key. The existing roster's used-life and extraction result rules continue to operate on that same value. A disconnect, replaced controller, extra connection or changed session context latches failure. Pending assignment checks reject immediately; the existing mode tick also detects context changes after spawning. The mode reports an explicit preparation failure or normal defeat, rather than adopting another controller into that local identity. Returning the context to its previous values cannot reopen the old helper. A new mode owns a fresh helper/key; terminal cleanup clears the old key/controller while retaining its closed state.
A helper constructed in Listen/Dedicated is inert: it always returns the native identity unchanged, including null, and its validation cannot block that mode. The existing native reconnect path is unchanged for those modes. A generated offline key skips native reconnect restoration; it is never written into the native reconnect map, global identity utility, backend, persistence IDs or role state. Controller replacement within the offline round requires a new scenario rather than claiming account continuity. Existing WORKBENCH-only fixture identity handling remains unchanged.
No new audit callback, login request, permission grant, persistent setting, command or repeating timer is introduced. Admin authorization still uses the existing native player-role check. The native base spawn callback remains called unchanged, including its own persistence behavior. This change does not fix or suppress unrelated ordinary-game GUI errors.
## Source/API evidence
Read-only installed sources:
- `scripts/Game/Utilities/SCR_PlayerIdentityUtils.c:20–45`: cached native identity read and empty-string-only PeerTool fallback.
- `scripts/Core/generated/Types/UUID.c:12–27,67,106–131`: null includes empty/all-zero/invalid strings; `IsNull()` is the prescribed check; `GenV4()` is the native random UUID API.
- `scripts/Game/generated/Network/PlayerManager.c`: connected count, current controller, connection state and player-role APIs are separate.
- `scripts/Game/Respawn/Logic/SCR_AutoSpawnLogic.c:15–18` and `SCR_SpawnLogic.c:294–300`: native audit callback starts load/spawn; unavailable persistence can proceed to ordinary spawning.
The detailed design audit and inspected-source hashes were prepared under `/tmp/erri-offline-identity-design`; no original Escapists implementation or platform account data was used.
## Validation and remaining limits
`python3 tests/test_local_admission.py` executes the actual context/resolver/failure/cleanup method bodies with substituted opaque native handles and UUID generation. It covers strict None-only context, missing/mismatched/replaced controllers, counts/IDs, one-time generation, repeated callbacks, late backend values, sticky failure, fresh mode and unchanged network pass-through even after Stop. It does not prove native UUID entropy/format or network authentication. Existing admission rules still check phase, used life, reserved position, exact request/controller and owned preload cleanup; the new context check runs at request and finalization boundaries.
Native compilation and the corrected ordinary player spawn are pending for this patch. Required next checks: actual generated non-null key and controlled prisoner in the ordinary header scenario, death without another local life, terminal result attribution, fresh-round reset, and unchanged Core/companion/lifecycle fixtures. Context-change and replacement-controller fault tests must use disposable local state without altering a real network session or fabricating backend/audit success. Manual input, clean ordinary runtime and real multi-client reconnect/permissions remain separate acceptance requirements.
Native `game-2026-09-19-082733` compiles this helper in the regular game, observes the actual backend null sentinel, creates its local-round key once and completes normal prisoner admission. No context refusal occurs; the real controller/roster marker and 15-second ready interval pass with no errors. Repeated callback/context-failure behavior has source-policy coverage; remote sessions and native failure injection remain separate.