From e58c4b058b62c88b7552715f729e7a417e8c1119 Mon Sep 17 00:00:00 2001 From: Vitaly Popuzin Date: Wed, 15 Jul 2026 13:14:15 +0200 Subject: [PATCH 1/9] feat: add OpenExplorerUi restricted action (ExplorerUi, OpenResult) Adds an OpenExplorerUi RPC to the existing RestrictedActionsService so SDK7 scenes can open native explorer UI panels. Introduces the ExplorerUi enum (7 fullscreen sections) and a dedicated OpenExplorerUiResponse carrying an OpenResult verdict (opened / rejected reasons). Additive, non-breaking. Part of the Scene-triggered Explorer UI feature (iteration 1). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../kernel/apis/restricted_actions.proto | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index 3bddab3c..a7c17db3 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -64,6 +64,33 @@ message EmptyResponse { } message StopEmoteRequest { } +enum ExplorerUi { + EU_UNSPECIFIED = 0; + EU_MAP = 1; + EU_SETTINGS = 2; + EU_BACKPACK = 3; + EU_CAMERA_REEL = 4; + EU_COMMUNITIES = 5; + EU_PLACES = 6; + EU_EVENTS = 7; +} + +enum OpenResult { + OR_UNSPECIFIED = 0; + OR_OPENED = 1; + OR_REJECTED_NOT_CURRENT_SCENE = 2; + OR_REJECTED_ALREADY_OPEN = 3; + OR_REJECTED_FEATURE_DISABLED = 4; +} + +message OpenExplorerUiRequest { + ExplorerUi ui = 1; +} + +message OpenExplorerUiResponse { + OpenResult open_result = 1; +} + service RestrictedActionsService { // MovePlayerTo will move the player to a position relative to the current scene. // If 'duration' field is used in the request, the success response depends on the @@ -97,4 +124,7 @@ service RestrictedActionsService { // StopEmote will stop the current emote rpc StopEmote(StopEmoteRequest) returns (SuccessResponse) {} + + // OpenExplorerUi opens a specific explorer UI panel + rpc OpenExplorerUi(OpenExplorerUiRequest) returns (OpenExplorerUiResponse) {} } From d10116a0fc8ba9c8b138f95c49f088d6ce6295e4 Mon Sep 17 00:00:00 2001 From: Vitaly Popuzin Date: Wed, 15 Jul 2026 23:08:04 +0200 Subject: [PATCH 2/9] refactor: rename OpenResult enum to OpenExplorerUiResult (OEUR_ value prefix) Naming-only change for the openExplorerUi restricted action. Renames the verdict enum OpenResult -> OpenExplorerUiResult, prefixes its values OR_ -> OEUR_, and updates the OpenExplorerUiResponse field to open_result. ExplorerUi/EU_* unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../kernel/apis/restricted_actions.proto | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index 1a6ebdd1..2594ef44 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -76,12 +76,12 @@ enum ExplorerUi { EU_EVENTS = 7; } -enum OpenResult { - OR_UNSPECIFIED = 0; - OR_OPENED = 1; - OR_REJECTED_NOT_CURRENT_SCENE = 2; - OR_REJECTED_ALREADY_OPEN = 3; - OR_REJECTED_FEATURE_DISABLED = 4; +enum OpenExplorerUiResult { + OEUR_UNSPECIFIED = 0; + OEUR_OPENED = 1; + OEUR_REJECTED_NOT_CURRENT_SCENE = 2; + OEUR_REJECTED_ALREADY_OPEN = 3; + OEUR_REJECTED_FEATURE_DISABLED = 4; } message OpenExplorerUiRequest { @@ -89,7 +89,7 @@ message OpenExplorerUiRequest { } message OpenExplorerUiResponse { - OpenResult open_result = 1; + OpenExplorerUiResult open_result = 1; } service RestrictedActionsService { From fbeea498e1592ad2caa391f593e92cce202e44e8 Mon Sep 17 00:00:00 2001 From: Vitaly Popuzin Date: Mon, 20 Jul 2026 12:23:04 +0200 Subject: [PATCH 3/9] refactor: drop enum-value prefix on OpenExplorerUiResult Enum values are now bare names (UNSPECIFIED/OPENED/REJECTED_*) instead of the OEUR_ prefix. Enum type OpenExplorerUiResult and ExplorerUi/EU_* unchanged. Co-Authored-By: Claude Opus 4.8 --- .../decentraland/kernel/apis/restricted_actions.proto | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index 2594ef44..0f3bef66 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -77,11 +77,11 @@ enum ExplorerUi { } enum OpenExplorerUiResult { - OEUR_UNSPECIFIED = 0; - OEUR_OPENED = 1; - OEUR_REJECTED_NOT_CURRENT_SCENE = 2; - OEUR_REJECTED_ALREADY_OPEN = 3; - OEUR_REJECTED_FEATURE_DISABLED = 4; + UNSPECIFIED = 0; + OPENED = 1; + REJECTED_NOT_CURRENT_SCENE = 2; + REJECTED_ALREADY_OPEN = 3; + REJECTED_FEATURE_DISABLED = 4; } message OpenExplorerUiRequest { From 82dee8f621142f09f14054f9ca3a43cac311cc7d Mon Sep 17 00:00:00 2001 From: Vitaly Popuzin Date: Mon, 20 Jul 2026 13:15:13 +0200 Subject: [PATCH 4/9] docs: document OpenExplorerUi extension points and verdict-only contract Comment-only. Records the additive-evolution intent for ExplorerUi and OpenExplorerUiResult, the oneof extension point for future per-panel params on OpenExplorerUiRequest, and that OpenExplorerUiResponse carries only the open verdict (post-open events belong to a separate future event channel). No wire/semantic change. Co-Authored-By: Claude Opus 4.8 --- .../kernel/apis/restricted_actions.proto | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index 0f3bef66..4feb079a 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -65,6 +65,8 @@ message EmptyResponse { } message StopEmoteRequest { } +// Identifies which fullscreen explorer panel OpenExplorerUi targets. +// Additive: new panels are appended with the next number; existing values never change. enum ExplorerUi { EU_UNSPECIFIED = 0; EU_MAP = 1; @@ -76,19 +78,30 @@ enum ExplorerUi { EU_EVENTS = 7; } +// Verdict of an OpenExplorerUi request (enum rather than a bool so new outcomes stay expressible). +// Additive: new rejection reasons may be appended; existing values never change. enum OpenExplorerUiResult { UNSPECIFIED = 0; OPENED = 1; - REJECTED_NOT_CURRENT_SCENE = 2; - REJECTED_ALREADY_OPEN = 3; - REJECTED_FEATURE_DISABLED = 4; + REJECTED_NOT_CURRENT_SCENE = 2; // the standard restricted-actions current-scene gate rejected the call + REJECTED_ALREADY_OPEN = 3; // a fullscreen panel is already open + REJECTED_FEATURE_DISABLED = 4; // the requested section is hidden by feature flags } message OpenExplorerUiRequest { ExplorerUi ui = 1; + + // Extension point for future per-panel parameters, as a oneof so each panel gets its + // own optional param message without touching existing fields. Field numbers 10+ are + // for these params, e.g.: + // message MapParams { int32 focus_x = 1; int32 focus_y = 2; } + // oneof params { MapParams map = 10; } } message OpenExplorerUiResponse { + // Carries only the verdict of the open action. Post-open signals (panel closed, flow + // outcomes, milestones) are deliberately out of scope here and are delivered through a + // separate additive event channel (a grow-only scene component), keeping this contract stable. OpenExplorerUiResult open_result = 1; } @@ -126,6 +139,7 @@ service RestrictedActionsService { // StopEmote will stop the current emote rpc StopEmote(StopEmoteRequest) returns (SuccessResponse) {} - // OpenExplorerUi opens a specific explorer UI panel + // OpenExplorerUi opens a specific fullscreen explorer panel and returns the open verdict. + // Follows the same scene->explorer pathway as OpenNftDialog / OpenExternalUrl. rpc OpenExplorerUi(OpenExplorerUiRequest) returns (OpenExplorerUiResponse) {} } From 0e8b20c81d187e2bc29fcfe6219cedb1ccd878e8 Mon Sep 17 00:00:00 2001 From: Vitaly Popuzin Date: Mon, 20 Jul 2026 14:56:19 +0200 Subject: [PATCH 5/9] feat: add REJECTED_NO_USER_GESTURE to OpenExplorerUiResult Additive enum value (=5) for the gesture-gate on openExplorerUi. Existing values unchanged. Rejected when the call did not originate from a user gesture. Co-Authored-By: Claude Opus 4.8 --- proto/decentraland/kernel/apis/restricted_actions.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index 4feb079a..f7890bb9 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -86,6 +86,7 @@ enum OpenExplorerUiResult { REJECTED_NOT_CURRENT_SCENE = 2; // the standard restricted-actions current-scene gate rejected the call REJECTED_ALREADY_OPEN = 3; // a fullscreen panel is already open REJECTED_FEATURE_DISABLED = 4; // the requested section is hidden by feature flags + REJECTED_NO_USER_GESTURE = 5; // rejected: the call did not originate from a user gesture } message OpenExplorerUiRequest { From e3987e9544055530484373e1dac3f41040aebebd Mon Sep 17 00:00:00 2001 From: Vitaly Popuzin <35366872+popuz@users.noreply.github.com> Date: Wed, 22 Jul 2026 18:00:53 +0200 Subject: [PATCH 6/9] Update proto/decentraland/kernel/apis/restricted_actions.proto Co-authored-by: Mateo Miccino Signed-off-by: Vitaly Popuzin <35366872+popuz@users.noreply.github.com> --- proto/decentraland/kernel/apis/restricted_actions.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index f7890bb9..2d510105 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -85,7 +85,7 @@ enum OpenExplorerUiResult { OPENED = 1; REJECTED_NOT_CURRENT_SCENE = 2; // the standard restricted-actions current-scene gate rejected the call REJECTED_ALREADY_OPEN = 3; // a fullscreen panel is already open - REJECTED_FEATURE_DISABLED = 4; // the requested section is hidden by feature flags + REJECTED_FEATURE_DISABLED = 4; // the requested section is hidden by feature flags or client doesn't have that feature REJECTED_NO_USER_GESTURE = 5; // rejected: the call did not originate from a user gesture } From 9fd50adf7d7d50766702e72206efbf797bfc7fe7 Mon Sep 17 00:00:00 2001 From: Vitaly Popuzin Date: Thu, 23 Jul 2026 21:01:45 +0200 Subject: [PATCH 7/9] refactor: make EU_SETTINGS the ExplorerUi zero value, drop EU_UNSPECIFIED Remove EU_UNSPECIFIED and renumber ExplorerUi contiguously so EU_SETTINGS holds 0, making the least-intrusive panel the default for an unset ui field. Trim standalone doc-comment lines on ExplorerUi, OpenExplorerUiResult and the OpenExplorerUi rpc. Co-Authored-By: Claude Opus 4.8 --- .../kernel/apis/restricted_actions.proto | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index f7890bb9..b3b23d3e 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -66,20 +66,18 @@ message EmptyResponse { } message StopEmoteRequest { } // Identifies which fullscreen explorer panel OpenExplorerUi targets. -// Additive: new panels are appended with the next number; existing values never change. +// EU_SETTINGS holds 0 so an unset `ui` field defaults to the least-intrusive panel. enum ExplorerUi { - EU_UNSPECIFIED = 0; + EU_SETTINGS = 0; EU_MAP = 1; - EU_SETTINGS = 2; - EU_BACKPACK = 3; - EU_CAMERA_REEL = 4; - EU_COMMUNITIES = 5; - EU_PLACES = 6; - EU_EVENTS = 7; + EU_BACKPACK = 2; + EU_CAMERA_REEL = 3; + EU_COMMUNITIES = 4; + EU_PLACES = 5; + EU_EVENTS = 6; } // Verdict of an OpenExplorerUi request (enum rather than a bool so new outcomes stay expressible). -// Additive: new rejection reasons may be appended; existing values never change. enum OpenExplorerUiResult { UNSPECIFIED = 0; OPENED = 1; @@ -141,6 +139,5 @@ service RestrictedActionsService { rpc StopEmote(StopEmoteRequest) returns (SuccessResponse) {} // OpenExplorerUi opens a specific fullscreen explorer panel and returns the open verdict. - // Follows the same scene->explorer pathway as OpenNftDialog / OpenExternalUrl. rpc OpenExplorerUi(OpenExplorerUiRequest) returns (OpenExplorerUiResponse) {} } From 73554cbb2c0b44882adc17862101f26713f03031 Mon Sep 17 00:00:00 2001 From: Vitaly Popuzin Date: Thu, 23 Jul 2026 21:15:31 +0200 Subject: [PATCH 8/9] made already open to not be "rejected" state --- proto/decentraland/kernel/apis/restricted_actions.proto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index f1eae6e2..a8c571fa 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -81,8 +81,8 @@ enum ExplorerUi { enum OpenExplorerUiResult { UNSPECIFIED = 0; OPENED = 1; - REJECTED_NOT_CURRENT_SCENE = 2; // the standard restricted-actions current-scene gate rejected the call - REJECTED_ALREADY_OPEN = 3; // a fullscreen panel is already open + WAS_ALREADY_OPEN = 2; // a fullscreen panel is already open + REJECTED_NOT_CURRENT_SCENE = 3; // the standard restricted-actions current-scene gate rejected the call REJECTED_FEATURE_DISABLED = 4; // the requested section is hidden by feature flags or client doesn't have that feature REJECTED_NO_USER_GESTURE = 5; // rejected: the call did not originate from a user gesture } From 0e7de00f34d8153382007463e57a635a05ecccf8 Mon Sep 17 00:00:00 2001 From: Vitaly Popuzin Date: Thu, 23 Jul 2026 21:17:21 +0200 Subject: [PATCH 9/9] comments clean-up --- proto/decentraland/kernel/apis/restricted_actions.proto | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index a8c571fa..9ebfad06 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -81,7 +81,7 @@ enum ExplorerUi { enum OpenExplorerUiResult { UNSPECIFIED = 0; OPENED = 1; - WAS_ALREADY_OPEN = 2; // a fullscreen panel is already open + WAS_ALREADY_OPEN = 2; // a fullscreen panel is already open REJECTED_NOT_CURRENT_SCENE = 3; // the standard restricted-actions current-scene gate rejected the call REJECTED_FEATURE_DISABLED = 4; // the requested section is hidden by feature flags or client doesn't have that feature REJECTED_NO_USER_GESTURE = 5; // rejected: the call did not originate from a user gesture @@ -91,16 +91,13 @@ message OpenExplorerUiRequest { ExplorerUi ui = 1; // Extension point for future per-panel parameters, as a oneof so each panel gets its - // own optional param message without touching existing fields. Field numbers 10+ are - // for these params, e.g.: + // own optional param message without touching existing fields. // message MapParams { int32 focus_x = 1; int32 focus_y = 2; } // oneof params { MapParams map = 10; } } message OpenExplorerUiResponse { - // Carries only the verdict of the open action. Post-open signals (panel closed, flow - // outcomes, milestones) are deliberately out of scope here and are delivered through a - // separate additive event channel (a grow-only scene component), keeping this contract stable. + // Carries only the verdict of the open action. OpenExplorerUiResult open_result = 1; }