revert(teleport): drop the Slice 2 outdoor readiness-gate hold

User-tested: the Slice 2 'hold outdoor until landblock loaded' gate made
EVERY outdoor teleport a ~10 s freeze, because the destination landblock
does NOT load fast during the hold (lbs=0 the whole time — the #138
streaming gap + _datLock starvation from the CreateObject flood). The hold
was band-aiding a broken/slow foundation rather than fixing it, and it never
actually prevented the #145 edge cascade anyway (it force-snapped onto
NO-LANDBLOCK after the timeout regardless).

Reverts ad8c24e..c880973 to the pre-Slice-2 state (00ef47e): outdoor places
immediately again (fast teleports). The genuine bug found along the way —
IsLandblockLoaded queried the wrong key form (& 0xFFFF0000 vs the stored
| 0xFFFF) — is preserved in the history (c880973) and will be re-applied when
we re-introduce a proper hold ON A FIXED FOUNDATION.

Decision (user, 2026-06-21): fix the foundation FIRST — fast/complete
streaming during teleport (#138), the post-teleport lost-collision bug, and
the FPS leak (Work item C) — then revisit the teleport-flow animation. Slice 1
(the pure TeleportAnimSequencer) stays in (dormant, unwired, harmless).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-21 21:46:24 +02:00
parent c8809735f3
commit dd2eb8b39d
6 changed files with 43 additions and 195 deletions

View file

@ -4,63 +4,49 @@ using Xunit;
namespace AcDream.App.Tests.World;
/// <summary>
/// Full truth-table for TeleportArrivalRules.Decide after the §3.4 readiness-gate change.
/// The teleport-arrival readiness decision (#145/#138).
/// <list type="bullet">
/// <item>Unhydratable claim → place immediately via the caller's safety-net (Impossible).</item>
/// <item>Indoor (sealed dungeon / building interior) → hold until the EnvCell floor hydrates.</item>
/// <item>Outdoor → place IMMEDIATELY on the server-authoritative position. Holding is futile —
/// streaming does not progress while the player is held in PortalSpace, so the
/// destination can't stream in during a hold. The stale source landblock is dropped at
/// recenter (GameWindow.OnLivePositionUpdated), so the resolve falls through to the
/// server cell (Resolve NO-LANDBLOCK verbatim) until the destination streams in.</item>
/// </list>
/// </summary>
public class TeleportArrivalRulesTests
{
[Fact]
public void Unhydratable_IsImpossible_Outdoor()
public void Unhydratable_IsImpossible()
{
Assert.Equal(ArrivalReadiness.Impossible,
TeleportArrivalRules.Decide(
claimUnhydratable: true, indoor: false,
indoorCellReady: false, outdoorReady: false));
}
[Fact]
public void Unhydratable_IsImpossible_Indoor()
{
TeleportArrivalRules.Decide(claimUnhydratable: true, indoor: false, indoorCellReady: false));
// …even for an indoor claim.
Assert.Equal(ArrivalReadiness.Impossible,
TeleportArrivalRules.Decide(
claimUnhydratable: true, indoor: true,
indoorCellReady: true, outdoorReady: false));
TeleportArrivalRules.Decide(claimUnhydratable: true, indoor: true, indoorCellReady: false));
}
[Fact]
public void Indoor_CellReady_IsReady()
{
Assert.Equal(ArrivalReadiness.Ready,
TeleportArrivalRules.Decide(
claimUnhydratable: false, indoor: true,
indoorCellReady: true, outdoorReady: false));
TeleportArrivalRules.Decide(claimUnhydratable: false, indoor: true, indoorCellReady: true));
}
[Fact]
public void Indoor_CellNotReady_IsNotReady()
public void Indoor_CellNotReady_HoldsNotReady()
{
Assert.Equal(ArrivalReadiness.NotReady,
TeleportArrivalRules.Decide(
claimUnhydratable: false, indoor: true,
indoorCellReady: false, outdoorReady: false));
TeleportArrivalRules.Decide(claimUnhydratable: false, indoor: true, indoorCellReady: false));
}
[Fact]
public void Outdoor_LandblockLoaded_IsReady()
public void Outdoor_PlacesImmediately()
{
// #145: never hold an outdoor arrival — place at once on the server position. The
// indoorCellReady flag is irrelevant for an outdoor destination.
Assert.Equal(ArrivalReadiness.Ready,
TeleportArrivalRules.Decide(
claimUnhydratable: false, indoor: false,
indoorCellReady: false, outdoorReady: true));
}
[Fact]
public void Outdoor_LandblockNotLoaded_IsNotReady()
{
// §3.4: the #145 residual — outdoor arrival on a not-yet-streamed landblock
// must hold. Previously returned Ready immediately.
Assert.Equal(ArrivalReadiness.NotReady,
TeleportArrivalRules.Decide(
claimUnhydratable: false, indoor: false,
indoorCellReady: false, outdoorReady: false));
TeleportArrivalRules.Decide(claimUnhydratable: false, indoor: false, indoorCellReady: false));
}
}