Skip to content

fix: banned users cannot teleport after second attempt#8868

Open
sandrade-dcl wants to merge 2 commits into
devfrom
fix/banned-users-cannot-teleport-after-second-attempt
Open

fix: banned users cannot teleport after second attempt#8868
sandrade-dcl wants to merge 2 commits into
devfrom
fix/banned-users-cannot-teleport-after-second-attempt

Conversation

@sandrade-dcl
Copy link
Copy Markdown
Contributor

Pull Request Description

Fix #7505

What does this PR change?

  • Banned users could not teleport after the second attempt to the banned scene; the chat showed An item with the same key has already been added. Key: SceneCommunicationPipe+SubscriberKey in builds, or Cannot add the same SystemGroupWorld twice in editor, and all further teleports stopped working.
  • Root cause: after ECSBannedScene.TrySetCurrentSceneAsBannedAsync disposed the banned scene it reset SceneLoadingState to UNINITIALIZED/PromiseCreated=false so the scene could load again once the ban was lifted, but left BannedSceneComponent on the entity. On the next frame ResolveSceneStateByIncreasingRadiusSystem.UpdateLoadingState did not filter by BannedSceneComponent and issued a fresh AssetPromise<ISceneFacade>. LoadSceneSystem resolved it into a new SceneFacade (registering it in SystemGroupSnapshot), but ControlSceneUpdateLoopSystem.HandleNotCreatedScenes does filter by BannedSceneComponent so the promise was never consumed and the SceneFacade leaked along with its SystemGroupWorld registration. Re-entering the scene later created a second SceneFacade with the same registration key and collided with the orphan.
  • Fix: short-circuit UpdateLoadingState for entities that carry BannedSceneComponent, matching the semantics already used by HandleNotCreatedScenes. The orphan promise (and therefore the orphan SceneFacade) is never created, and the unban path is unaffected — once BannedSceneComponent is removed the entity flows through UpdateLoadingState as before.

Test Steps

  • As an admin, ban a user from a scene (e.g. Genesis Plaza).
  • As the banned user, enter the banned scene → scene unloads and ban notification shows (unchanged behavior).
  • Teleport to a non-banned parcel.
  • Teleport back to the banned scene → no chat error, no SystemGroupWorld twice exception in editor.
  • Continue teleporting freely between scenes; behavior matches a non-banned user.
  • Unban the user, return to the previously banned scene → scene loads normally.

Code Review Reference

Please review our Branch & PR Standards before submitting. It explains the automated review flow, QA/DEV approval requirements, and what each label does — especially useful for first-time contributors.

- Added a check in `UpdateLoadingState` to return early for entities with `BannedSceneComponent`.
@sandrade-dcl sandrade-dcl requested review from a team as code owners May 26, 2026 13:37
@sandrade-dcl sandrade-dcl self-assigned this May 26, 2026
@claude

This comment has been minimized.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 26, 2026

Claude finished @sandrade-dcl's task in 1m 19s —— View job


Review

  • Gather context
  • Read changed file and surrounding code
  • Analyze root cause vs fix
  • Post review feedback

Root-cause check

Problem: After ECSBannedScene.TrySetCurrentSceneAsBannedAsync disposed the banned scene, it reset SceneLoadingState to UNINITIALIZED/PromiseCreated=false but left BannedSceneComponent on the entity. On the next frame UpdateLoadingState (which had no banned-entity guard) issued a fresh AssetPromise<ISceneFacade>. HandleNotCreatedScenes already filters banned entities ([None(typeof(BannedSceneComponent))]), so that promise was never consumed — the SceneFacade and its SystemGroupWorld registration leaked. Re-entering the scene created a second registration under the same key, producing the Cannot add the same SystemGroupWorld twice / duplicate-key collision.

Assessment: ✅ Fixes the actual cause. The guard is placed at exactly the right point — where the orphan promise originates — and is symmetric with the consumer's existing exclusion. The unban path is unaffected: once BannedSceneComponent is removed, the entity flows through UpdateLoadingState as before.


Previous blocking issue — resolved

The first commit referenced HandleNotCreatedScenes by name in the comment (CLAUDE.md violation). The follow-up commit f9b6ef4d replaced it with:

// Promises for banned-scene entities are not consumed downstream; issuing one here would leak its SceneFacade.

This satisfies the CLAUDE.md rule: the comment now states the non-obvious invariant (why the guard exists) without naming any specific caller.

No remaining blocking issues.


REVIEW_RESULT: PASS ✅
COMPLEXITY: COMPLEX
COMPLEXITY_REASON: Modifies ResolveSceneStateByIncreasingRadiusSystem, a core ECS scene-lifecycle system that controls asset-promise creation and scene loading order.
QA_REQUIRED: YES

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Claude reviewed this PR and found no blocking issues, but assessed it as complex — human DEV review is still required before merging.

@m3taphysics
Copy link
Copy Markdown
Collaborator

PR #8868, run #26454320267

Builds: Windows change, Windows baseline, macOS change, macOS baseline

Framework 13 i7

Metric Change Baseline Delta Improvement
Samples 2701 2700
CPU average 33.3 ms 33.3 ms -0.0 ms 0.0%
CPU 1% worst 33.4 ms 33.8 ms -0.4 ms 1.3%
CPU 0.1% worst 33.5 ms 36.8 ms -3.3 ms 8.9% 🟢
GPU average 8.5 ms 8.5 ms 0.0 ms -0.3%
GPU 1% worst 17.1 ms 17.0 ms 0.1 ms -0.5%
GPU 0.1% worst 23.0 ms 23.4 ms -0.4 ms 1.9%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[QA] Explorer | Banned users cannot teleport after second attempt

2 participants