Skip to content

feat: add PBExplorerUiEventsResult and relocate ExplorerUi enum - #455

Open
popuz wants to merge 2 commits into
mainfrom
feat/explorer-ui-events-result
Open

feat: add PBExplorerUiEventsResult and relocate ExplorerUi enum#455
popuz wants to merge 2 commits into
mainfrom
feat/explorer-ui-events-result

Conversation

@popuz

@popuz popuz commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

What

Adds the PBExplorerUiEventsResult grow-only SDK component (id 1220) so scenes can observe when a fullscreen explorer panel they opened is opened/closed, and relocates the ExplorerUi enum from decentraland/kernel/apis/restricted_actions.proto to a new decentraland/sdk/components/common/explorer_ui.proto.

Round 2 of openExplorerUi (round 1: #451).

Files

  • new proto/decentraland/sdk/components/common/explorer_ui.protoExplorerUi enum, moved verbatim.
  • edit proto/decentraland/kernel/apis/restricted_actions.proto — imports the new file; OpenExplorerUiRequest.ui now refers to decentraland.sdk.components.common.ExplorerUi. OpenExplorerUiResult is unchanged and stays put.
  • new proto/decentraland/sdk/components/explorer_ui_events_result.protoPBExplorerUiEventsResult, id 1220.
  • edit public/sdk-components.proto — one import public line.

The component carries ui, a uint32 timestamp (scene tick, matching PBPointerEventsResult / PBTriggerAreaResult), and a oneof event with nested empty UiOpened / UiClosed. Field numbers 10-19 are reserved for generic window events; future per-panel feature events start at 20.

Why move the enum

js-sdk-toolchain's scripts/rpc-api-generation/index.ts:203 hardcodes decentraland/sdk/components/common/ as the only path that collapses a proto type to a single nominal TypeScript identity. With the enum left in kernel/apis, a scene would hold two incomparable ExplorerUi types — one from ~system/RestrictedActions, one from @dcl/ecs. TypeScript enums are nominal, so e.ui === ExplorerUi.EU_MAP would not typecheck and scene authors would need a cast on every comparison.

After the move, both generated modules import the same declaration — confirmed empirically against a local codegen run:

out-ts/decentraland/kernel/apis/restricted_actions.gen.ts:5
  import { ExplorerUi, ... } from "../../sdk/components/common/explorer_ui.gen";
out-ts/decentraland/sdk/components/explorer_ui_events_result.gen.ts:3
  import { ExplorerUi, ... } from "./common/explorer_ui.gen";

There is existing precedent for restricted_actions.proto importing from sdk/components/common/ — it already imports avatar_mask.proto.

The move and the new component must ship together. A relocation with no component proto importing the enum leaves it ungenerated in @dcl/ecs and re-declared in apis.d.ts — that would be a regression, not a no-op. Splitting this PR in two is therefore not an option.

Compatibility

The relocation is source-breaking but wire-compatible:

  • field number 1 on OpenExplorerUiRequest.ui — unchanged
  • enum values EU_SETTINGS = 0EU_EVENTS = 6 — unchanged
  • wire types — unchanged (enums are varints either way)

Only the generated type's namespace/location changes. buf breaking under this repo's configured WIRE_JSON policy (proto/buf.yaml) passes on this diff; CI runs it as its own step ahead of the check script.

unity-explorer needs regeneration only. Both hand-written consumers already import both namespaces and reference the type by its bare name, so the C# namespace change requires no source edits there.

The validate-compatibility check will be red — expected, and an override is requested

./scripts/check-proto-compabitility.sh reports exactly one error:

- Type of field ui was changed ExplorerUi -> decentraland.sdk.components.common.ExplorerUi
  from the type .decentraland.kernel.apis.OpenExplorerUiRequest

The tool is not wrong — it is stricter than the repo's configured buf policy. It compares fully-qualified type names textually and correctly reports a source-level break for consumers of generated code. It is proto-compatibility-tool, pinned at ^1.1.2-20220925163655.commit-25bd040, and takes positional arguments only — there is no allowlist or exception flag, so the check cannot be scoped without editing the script. Nothing under .github/ or in the script has been touched: the red check is disclosed, not hidden.

Override rationale: the break is real but has zero consumers. openExplorerUi merged 2026-07-28. The latest stable @dcl/sdk is 7.25.0, published 2026-07-27, so it does not contain the API — only next/experimental tarballs do. No creator on the stable channel is affected. That window closes with the next release, which is precisely why the relocation happens now rather than later.

Requesting a maintainer override on this single check.

Merge order

protocol (this PR) → publish → repin @dcl/protocol in js-sdk-toolchain + unity-explorer → test scene.

Adds the PBExplorerUiEventsResult component (ecs_component_id 1220) so
scenes can observe when fullscreen explorer panels open and close, and
relocates the ExplorerUi enum out of the restricted-actions API into
decentraland/sdk/components/common/explorer_ui.proto.

The relocation is required, not cosmetic. js-sdk-toolchain's RPC API
generator (scripts/rpc-api-generation/index.ts:203) hardcodes
decentraland/sdk/components/common/ as the only path whose proto types
collapse to a single nominal TypeScript identity. With the enum left in
restricted_actions.proto a scene would hold two incomparable ExplorerUi
types -- one from ~system/RestrictedActions, one from @dcl/ecs. After the
move, restricted_actions.gen.ts and explorer_ui_events_result.gen.ts both
import ExplorerUi from the same generated module.

The move and the new component must ship together: relocating the enum
without a component proto importing it leaves it ungenerated in @dcl/ecs
and re-declared in apis.d.ts, which is a regression.

Wire compatibility is untouched -- field number 1, values 0-6, and wire
types are all unchanged. buf breaking with WIRE_JSON (the policy
configured in proto/buf.yaml) passes.

Expected red check: validate-compatibility runs
scripts/check-proto-compabitility.sh, which compares fully-qualified type
names textually and is stricter than the repo's configured buf policy. It
reports a source-level break for the `ui` field. The break is real but
has zero consumers -- openExplorerUi merged 2026-07-28 and the latest
stable @dcl/sdk (7.25.0, published 2026-07-27) does not contain the API,
so only next/experimental tarballs are affected. A team override is
requested rather than suppressing the check.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown

Test this pull request

  • The @dcl/protocol package can be tested in scenes by running
    npm install "https://sdk-team-cdn.decentraland.org/@dcl/protocol/branch//dcl-protocol-1.0.0-30567850943.commit-063282b.tgz"

`ui` and `event` are independent axes, so every pair of the two is
representable. The previous comment invited per-panel feature events into
the same oneof at field 20+, which would have made pairs such as
`ui = EU_MAP` carrying a backpack event perfectly legal, and pushed the
burden of recognising and ignoring them onto every consumer.

State the rule instead: a variant belongs in this oneof only if it is
meaningful for every value of `ui`. Panel-specific events get their own
result component, where the component identity carries the panel and the
contradiction cannot be expressed. That also matches how the rest of the
protocol scales -- PBUiDropdownResult, PBUiInputResult, PBTriggerAreaResult,
PBVideoEvent and PBAudioEvent are separate components rather than variants
of one shared event bus.

Comment-only change; the wire format is untouched.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant