fix(streaming): block login on complete world reveal
Make initial login and portal arrival consume one WorldRevealReadinessBarrier that joins near-tier mesh publication, destination composite uploads, and collision residency before normal world geometry becomes visible. This ports retail SmartBox's blocking-cell completion edge into the asynchronous client instead of exposing a ground-only login. Add focused outdoor, indoor, texture, and invalid-claim tests; update the retail pseudocode, architecture, divergence record, issue ledger, roadmap baseline, and synchronized agent guidance. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
6c3bd4ce4b
commit
b60cb67009
14 changed files with 360 additions and 102 deletions
|
|
@ -11,8 +11,8 @@ namespace AcDream.App.Input;
|
|||
/// Why is this its own class? The auto-entry has four independent
|
||||
/// preconditions (live session reaches <c>InWorld</c>, the player
|
||||
/// entity has been streamed into the world dictionary, the player
|
||||
/// movement controller is constructible, and the terrain under the
|
||||
/// spawn position has streamed in) plus a manual-override path
|
||||
/// movement controller is constructible, and the initial world is fully
|
||||
/// drawable and collidable) plus a manual-override path
|
||||
/// (the user can flip into fly mode before the auto-entry fires —
|
||||
/// their choice wins). All five interact with each other in a way
|
||||
/// that's painful to test through GameWindow but trivial here against
|
||||
|
|
@ -44,7 +44,7 @@ public sealed class PlayerModeAutoEntry
|
|||
private readonly Func<bool> _isLiveInWorld;
|
||||
private readonly Func<bool> _isPlayerEntityPresent;
|
||||
private readonly Func<bool> _isPlayerControllerReady;
|
||||
private readonly Func<bool> _isSpawnGroundReady;
|
||||
private readonly Func<bool> _isWorldReady;
|
||||
private readonly Action _enterPlayerMode;
|
||||
|
||||
private bool _armed;
|
||||
|
|
@ -62,12 +62,10 @@ public sealed class PlayerModeAutoEntry
|
|||
/// PlayerMovementController is set up. Stays true once player mode
|
||||
/// is established; the auto-entry's job is to flip it from false
|
||||
/// to true exactly once.</param>
|
||||
/// <param name="isSpawnGroundReady">True iff the terrain under the
|
||||
/// player's spawn position has streamed into the physics engine.
|
||||
/// #106 gate-2 (2026-06-09): entering player mode earlier integrates
|
||||
/// gravity against an empty world and free-falls the player into the
|
||||
/// void. Retail never has this state — it loads cells synchronously;
|
||||
/// this hold is the async-streaming equivalent of that invariant.</param>
|
||||
/// <param name="isWorldReady">True iff the player's destination is
|
||||
/// complete across render publication, composite textures, and collision.
|
||||
/// Retail keeps position completion behind one blocking cell-load edge;
|
||||
/// acdream's asynchronous domains must converge before entry.</param>
|
||||
/// <param name="enterPlayerMode">Action invoked on the firing
|
||||
/// tick. The same routine the manual Tab handler invokes (fly →
|
||||
/// player transition). Must construct the controller + chase
|
||||
|
|
@ -77,13 +75,13 @@ public sealed class PlayerModeAutoEntry
|
|||
Func<bool> isLiveInWorld,
|
||||
Func<bool> isPlayerEntityPresent,
|
||||
Func<bool> isPlayerControllerReady,
|
||||
Func<bool> isSpawnGroundReady,
|
||||
Func<bool> isWorldReady,
|
||||
Action enterPlayerMode)
|
||||
{
|
||||
_isLiveInWorld = isLiveInWorld ?? throw new ArgumentNullException(nameof(isLiveInWorld));
|
||||
_isPlayerEntityPresent = isPlayerEntityPresent ?? throw new ArgumentNullException(nameof(isPlayerEntityPresent));
|
||||
_isPlayerControllerReady = isPlayerControllerReady ?? throw new ArgumentNullException(nameof(isPlayerControllerReady));
|
||||
_isSpawnGroundReady = isSpawnGroundReady ?? throw new ArgumentNullException(nameof(isSpawnGroundReady));
|
||||
_isWorldReady = isWorldReady ?? throw new ArgumentNullException(nameof(isWorldReady));
|
||||
_enterPlayerMode = enterPlayerMode ?? throw new ArgumentNullException(nameof(enterPlayerMode));
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +115,7 @@ public sealed class PlayerModeAutoEntry
|
|||
if (!_isLiveInWorld()) return false;
|
||||
if (!_isPlayerEntityPresent()) return false;
|
||||
if (!_isPlayerControllerReady()) return false;
|
||||
if (!_isSpawnGroundReady()) return false;
|
||||
if (!_isWorldReady()) return false;
|
||||
|
||||
_armed = false;
|
||||
_enterPlayerMode();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue