Skip to content

fix: use the launched realm for local scene development scene room metadata - #9503

Open
gonpombo8 wants to merge 4 commits into
devfrom
fix/local-scene-development-realm-port
Open

fix: use the launched realm for local scene development scene room metadata#9503
gonpombo8 wants to merge 4 commits into
devfrom
fix/local-scene-development-realm-port

Conversation

@gonpombo8

@gonpombo8 gonpombo8 commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

LocalSceneDevelopmentSceneRoomMetaDataSource built its base URL from the hardcoded IRealmNavigator.LOCALHOST constant (http://127.0.0.1:8000) rather than the realm the client was actually launched with:

URLDomain baseUrl = URLDomain.FromString(IRealmNavigator.LOCALHOST);

sdk-commands start only defaults to port 8000 — it takes --port, and tools that embed it pick their own port (the Creator Hub uses a random ephemeral one). Whenever the scene server is not on 8000, this source can never reach it, so MetaDataAsync fails every cycle and the GateKeeper scene room never connects for local scene development.

The realm is already parsed from the deep link and carried as DynamicWorldParams.LocalSceneDevelopmentRealm (it's what LocalSceneDevelopmentPlugin uses via RealmUrls.LocalSceneDevelopmentRealmAsync), so this threads that value through CommsContainer.Create into the metadata source. The parameter is optional and falls back to IRealmNavigator.LOCALHOST when empty, so existing behaviour is unchanged when no realm is supplied.

Repro

npm start -- --port 8003   # any port other than 8000

then launch the desktop client from the printed deep link. Before this change the client logs, on repeat:

[ERROR] [15:24:40] [Error] MetaDataSource: MetaDataAsync error Local scene server unreachable at http://127.0.0.1:8000: Cannot connect to destination host

Note it reports :8000 even though the deep link's realm says :8003. With the fix it targets http://127.0.0.1:8003 and the scene room connects.

What could break

  • Only the local scene development path is touched; SceneRoomMetaDataSource (play mode) is untouched.
  • The new constructor parameter is optional, so other call sites keep compiling — LocalSceneDevelopmentPlayground (editor-only demo) still uses the loopback default deliberately.
  • The realm string arrives already normalised by ApplicationParametersParser (trailing / stripped, macOS http// protocol patched), so it has the same shape as the constant it replaces and URLDomain.Append behaves identically.
  • If the realm were ever empty in local scene development mode, behaviour falls back to exactly what it does today.

How to test

  1. Clone the sdk7-test-scenes repo and enter this scene locally
  2. In the scene root folder open a terminal and run npm i and then npm run start -- --port 8003
  3. Close the Explorer that auto-opened. Leave the scene running in the console/terminal.
  4. Download the build from this PR and open it connected to the local scene (keep in mind its position is 73,-8): https://github.com/decentraland/unity-explorer/blob/dev/docs/how-to-connect-to-a-local-scene.md
  5. Once you enter the scene, open the scene console and confirm you DON'T see the MetadataAsync error Local scene server unreachable at http://127.0.0.1:8000
  6. Close everything and start again from step (2) but with normal port: ``npm run start` and confirm the scene still behaves as expected

…tadata

The scene room metadata source read a hardcoded http://127.0.0.1:8000
instead of the realm the client was launched with, so it never reached
a scene server started on any other port.
@gonpombo8
gonpombo8 requested review from a team as code owners July 28, 2026 18:28
@github-actions
github-actions Bot requested a review from DafGreco July 28, 2026 18:29
@decentraland-bot decentraland-bot added the ext-contribution Identifies a contribution which was not initiated by a Unity Developer label Jul 28, 2026
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

badge

Warnings count reduced: 14054 => 14047

@github-actions

Copy link
Copy Markdown
Contributor

Slack notification sent to #explorer-ext-contributions for external review.
To re-send, delete this comment and re-add the ext-contribution label.

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

badge

All Unity tests passed ✅

TESTS SUITE Result Passed Failed Skipped
EditMode ✅ Passed 24264 0 13
PlayMode ✅ Passed 236 0 5

@decentraland-bot decentraland-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review: fix: use the launched realm for local scene development scene room metadata

Step 2 — Root-cause check

PASS. LocalSceneDevelopmentSceneRoomMetaDataSource.MetaDataAsync hardcoded IRealmNavigator.LOCALHOST (http://127.0.0.1:8000) as the base URL, ignoring the actual realm from the deep link. When sdk-commands start --port 8003 (or any non-default port) is used, every metadata fetch cycle fails with Local scene server unreachable at http://127.0.0.1:8000. The fix threads the already-parsed realm from DynamicWorldParams.LocalSceneDevelopmentRealm through to the metadata source constructor, addressing the cause directly.

Step 3 — Design & integration

PASS. No new types or lifecycle management introduced. The change threads an existing, already-populated value through the established container pipeline:

Bootstraper.csDynamicWorldParams.LocalSceneDevelopmentRealmDynamicWorldContainerCommsContainer.CreateLocalSceneDevelopmentSceneRoomMetaDataSource

The data originates from RealmUrls.LocalSceneDevelopmentRealmAsync(), which reads the deep-link realm parameter already normalized by ApplicationParametersParser.

Other consumers checked:

  • LocalSceneDevelopmentPlayground.cs:49 (editor-only demo) — correctly continues to use the no-arg constructor, falling back to the default localhost. This is deliberate for the editor playground.
  • No other call sites exist for LocalSceneDevelopmentSceneRoomMetaDataSource.

The optional parameter (string? realm = null) with string.IsNullOrWhiteSpace fallback preserves full backward compatibility.

Teardown trace: No new subscriptions, events, connections, or disposables introduced. The realm field is a plain readonly string — no teardown needed.

Step 4 — Member audit

  • realm field (private readonly string): consumed once in MetaDataAsync:34 to construct URLDomain baseUrl. Single-use within the class is appropriate — it replaces a hardcoded constant. Not a derived predicate or single-use intermediate; it's a configuration value stored at construction time.
  • No new public properties or accessors added.

Step 5 — Line-level review

No blocking issues found across both passes.

Pass A (blocking categories):

  1. Code quality: naming follows conventions (realm camelCase private field, localSceneDevelopmentRealm camelCase parameter). readonly applied correctly.
  2. Bugs: the ! null-forgiving operator at line 27 is correct — string.IsNullOrWhiteSpace returning false guarantees realm is non-null.
  3. Security: no new attack surface. The realm URL was already accepted from deep-link params and used elsewhere (LocalSceneDevelopmentPlugin.cs:46). This PR threads it to one additional consumer. Local development path only, client-side, no credentials attached.
  4. Performance: no allocations in hot paths. The realm field is set once in the constructor.
  5. Error handling: fallback to IRealmNavigator.LOCALHOST when realm is null/empty matches pre-existing behavior.
  6. Resource leaks: no new subscriptions, connections, or disposables.
  7. Nullability: string? realm = null parameter correctly annotated as nullable; stored field is non-nullable string after the guard — contract is sound.

Pass B (design/encapsulation smells): None. No magic values introduced, no naming issues, no encapsulation leaks, no construction smells.

Security review: No secrets, injection risks, auth/authz issues, or sensitive data exposure. The realm URL is validated for null/whitespace and used only to construct local HTTP requests to the scene server.

Step 6 — Complexity

SIMPLE. Three files, 15 additions / 6 deletions. Straightforward parameter threading with no ECS, async, plugin, or architectural changes.

Step 7 — QA assessment

YES. The change modifies runtime code in the comms/multiplayer path that affects local scene development connectivity.

Step 8 — Non-blocking warnings

None. Main scene not modified.

Step 9 — Verdict

REVIEW_RESULT: PASS ✅
COMPLEXITY: SIMPLE
COMPLEXITY_REASON: Threads an existing parameter through the container pipeline to the local scene development metadata source — no ECS, async, or architectural changes.
QA_REQUIRED: YES


Reviewed by Jarvis 🤖 · Requested by gonpombo8 via Slack

The warning ratchet requires strictly fewer warnings than the S3
baseline (14087 vs branch 14089). Suppress InconsistentNaming for the
wire-format DTO fields and fix four APIClient local names to shed 7.

@pravusjif pravusjif left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch!

@balducciv

Copy link
Copy Markdown

✅ PR reviewed and approved by QA on both platforms following the PR test instructions.
✅ Smoke test performed on Windows and Mac to verify the normal flow is working as expected.

Build: v0.161.0-alpha-fix/local-scene-development-realm-port-93b994d
OS: macOS (Apple M3 Pro) and Windows 11

Test results:

  • Scene server on non-default port (--port 8003) — client correctly targets http://127.0.0.1:8003, no MetaDataAsync/Local scene server unreachable errors (Mac + Windows)
  • Scene server on default port (npm run start, port 8000) — regression check passed, scene still loads and behaves as expected (Mac + Windows)
  • In-game console shows 0 errors on both port configurations (screenshots attached)
  • Player.log build version matches PR HEAD commit 93b994d on all 4 logs collected

Unrelated errors noted (do not affect verdict):

None

Verdict: PASS ✅

Windows:

Player port 8003 windows (1).log

Player port 8000 windows.log

30 07 2026_17 49 55_REC port 8003 30 07 2026_17 51 31_REC port 8000

Mac:

Player-prev port 8000.log

Player port 8003.log

Screenshot 2026-07-30 at 5 14 38 PM - port 8000 Screenshot 2026-07-30 at 5 11 31 PM - port 8003

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

Labels

ext-contribution Identifies a contribution which was not initiated by a Unity Developer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants