From b07ee4038264e5184e828ac5cfa4efeb30301f1c Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Tue, 14 May 2024 23:24:18 +0100 Subject: [PATCH 01/43] cinematic camera --- .../sdk/components/camera_mode_area.proto | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/proto/decentraland/sdk/components/camera_mode_area.proto b/proto/decentraland/sdk/components/camera_mode_area.proto index 6d754d43..df0d7f0e 100644 --- a/proto/decentraland/sdk/components/camera_mode_area.proto +++ b/proto/decentraland/sdk/components/camera_mode_area.proto @@ -9,7 +9,7 @@ import "decentraland/sdk/components/common/id.proto"; option (common.ecs_component_id) = 1071; // The CameraModeArea component can be attached to an Entity to define a region of space where -// the player's camera mode (1st-person or 3rd-person) is overridden. +// the player's camera mode (1st-person, 3rd-person or cinematic) is overridden. // // The Entity's Transform position determines the center-point of the region, while its size is // given as a vector in the `area` property below. The Transform rotation is applied, but the scale @@ -19,7 +19,20 @@ option (common.ecs_component_id) = 1071; // // Note that, while commonly used to delineate a 2D area in a scene (hence the name), the region // is actually a 3D volume. +// +// When mode is set to CtCinematic, the optional cinematic_entity must also be provided. The +// Position and Rotation components of the cinematic_entity's Transform then define the origin and +// direction of the cinematic camera. message PBCameraModeArea { - decentraland.common.Vector3 area = 1; // the 3D size of the region - common.CameraType mode = 2; // the camera mode to enforce + decentraland.common.Vector3 area = 1; // the 3D size of the region + common.CameraType mode = 2; // the camera mode to enforce + optional uint32 cimematic_entity = 3; // entity that defines the cinematic camera transform. required when mode = CtCinematic + optional CinematicControlType cinematic_avatar_control = 4; // allow avatars to move in cinematic mode. defaults to CCT_NONE + optional bool cinematic_camera_control = 5; // allow the camera to be rotated in cinematic mode. defaults to false +} + +enum CinematicControlType { + CCT_NONE = 0; // avatar cannot be moved while in cinematic mode + CCT_RELATIVE = 1; // avatar moves relative to the camera origin + CCT_TANK = 2; // avatar moves like a tank: left/right rotate the player, forward/backward advance/retreat the player } From 57932cf3dfa7afbb0d900e0034530132260e74e4 Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Wed, 15 May 2024 01:43:16 +0100 Subject: [PATCH 02/43] typo --- proto/decentraland/sdk/components/camera_mode_area.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/decentraland/sdk/components/camera_mode_area.proto b/proto/decentraland/sdk/components/camera_mode_area.proto index df0d7f0e..03a73151 100644 --- a/proto/decentraland/sdk/components/camera_mode_area.proto +++ b/proto/decentraland/sdk/components/camera_mode_area.proto @@ -26,7 +26,7 @@ option (common.ecs_component_id) = 1071; message PBCameraModeArea { decentraland.common.Vector3 area = 1; // the 3D size of the region common.CameraType mode = 2; // the camera mode to enforce - optional uint32 cimematic_entity = 3; // entity that defines the cinematic camera transform. required when mode = CtCinematic + optional uint32 cinematic_entity = 3; // entity that defines the cinematic camera transform. required when mode = CtCinematic optional CinematicControlType cinematic_avatar_control = 4; // allow avatars to move in cinematic mode. defaults to CCT_NONE optional bool cinematic_camera_control = 5; // allow the camera to be rotated in cinematic mode. defaults to false } From 59775b1e5c25125de2d7373db2fe9decf76d73ab Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Wed, 15 May 2024 16:28:18 +0100 Subject: [PATCH 03/43] separate avatar controls --- .../sdk/components/avatar_modifier_area.proto | 16 ++++++++++++ .../sdk/components/camera_mode_area.proto | 25 +++++++++++-------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/proto/decentraland/sdk/components/avatar_modifier_area.proto b/proto/decentraland/sdk/components/avatar_modifier_area.proto index aea88858..6a3fd017 100644 --- a/proto/decentraland/sdk/components/avatar_modifier_area.proto +++ b/proto/decentraland/sdk/components/avatar_modifier_area.proto @@ -23,6 +23,16 @@ message PBAvatarModifierArea { decentraland.common.Vector3 area = 1; // the 3D size of the region repeated string exclude_ids = 2; // user IDs that can enter and remain unaffected repeated AvatarModifierType modifiers = 3; // list of modifiers to apply + optional AvatarControlType control_mode = 4; + // if not explicitly set, the following properties default to user's preference settings + optional float run_speed = 5; // speed the player moves at, in m/s + optional float friction = 6; // how fast the player gets up to speed or comes to rest. higher = more responsive + optional float gravity = 7; // how fast the player accelerates vertically when not on a solid surface, in m/s. should normally be negative + optional float jump_height = 8; // how high the player can jump, in meters. should normally be positive. gravity must have the same sign for jumping to be possible + optional float max_fall_speed = 9; // max fall speed in m/s. should normally be negative + optional float turn_speed = 10; // speed the player turns in tank mode, in radians/s + optional float walk_speed = 11; // speed the player walks at, in m/s + optional bool allow_weighted_movement = 12;// wherther to allow player to move at a slower speed (e.g. with a walk-key or when using a gamepad/joystick). defaults to true } // AvatarModifierType is an effect that should be applied to avatars inside the region. @@ -30,3 +40,9 @@ enum AvatarModifierType { AMT_HIDE_AVATARS = 0; // avatars are invisible AMT_DISABLE_PASSPORTS = 1; // selecting (e.g. clicking) an avatar will not bring up their profile. } + +enum AvatarControlType { + CCT_NONE = 0; // avatar cannot move + CCT_RELATIVE = 1; // avatar moves relative to the camera origin + CCT_TANK = 2; // avatar moves like a tank: left/right rotate the player, forward/backward advance/retreat the player +} diff --git a/proto/decentraland/sdk/components/camera_mode_area.proto b/proto/decentraland/sdk/components/camera_mode_area.proto index 03a73151..daf6e26b 100644 --- a/proto/decentraland/sdk/components/camera_mode_area.proto +++ b/proto/decentraland/sdk/components/camera_mode_area.proto @@ -20,19 +20,24 @@ option (common.ecs_component_id) = 1071; // Note that, while commonly used to delineate a 2D area in a scene (hence the name), the region // is actually a 3D volume. // -// When mode is set to CtCinematic, the optional cinematic_entity must also be provided. The -// Position and Rotation components of the cinematic_entity's Transform then define the origin and -// direction of the cinematic camera. +// When mode is set to CtCinematic, the cinematic_settings field must also be provided. message PBCameraModeArea { decentraland.common.Vector3 area = 1; // the 3D size of the region common.CameraType mode = 2; // the camera mode to enforce - optional uint32 cinematic_entity = 3; // entity that defines the cinematic camera transform. required when mode = CtCinematic - optional CinematicControlType cinematic_avatar_control = 4; // allow avatars to move in cinematic mode. defaults to CCT_NONE - optional bool cinematic_camera_control = 5; // allow the camera to be rotated in cinematic mode. defaults to false + optional CinematicSettings cinematic_settings = 3; } -enum CinematicControlType { - CCT_NONE = 0; // avatar cannot be moved while in cinematic mode - CCT_RELATIVE = 1; // avatar moves relative to the camera origin - CCT_TANK = 2; // avatar moves like a tank: left/right rotate the player, forward/backward advance/retreat the player +message CinematicSettings { + uint32 camera_entity = 1; // Entity that defines the cinematic camera transform. + // Position -> camera's position + // Rotation -> camera's direction + // scale.z -> zoom level + // scale.x and scale.y -> unused + optional bool allow_manual_rotation = 2; // whether the user can move the camera's rotation. default false + optional float yaw_range = 3; // how far the camera can rotate around the y-axis / look left/right, in radians. default unrestricted + optional float pitch_range = 4; // how far the camera can rotate around the x-axis / look up-down, in radians. default unrestricted + // note: cameras can never look up/down further than Vec3::Y + optional float roll_range = 5; // how far the camera can rotate around the z-axis / tilt, in radians. default unrestricted + optional float zoom_min = 6; // minimum zoom level. must be greater than 0. defaults to the input zoom level + optional float zoom_max = 7; // maximum zoom level. must be greater than 0. defaults to the input zoom level } From 4b60facb1b9da54187b0e6c85ce781076308a703 Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Wed, 15 May 2024 16:34:48 +0100 Subject: [PATCH 04/43] separate message for movement settings --- .../sdk/components/avatar_modifier_area.proto | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/proto/decentraland/sdk/components/avatar_modifier_area.proto b/proto/decentraland/sdk/components/avatar_modifier_area.proto index 6a3fd017..bd639b16 100644 --- a/proto/decentraland/sdk/components/avatar_modifier_area.proto +++ b/proto/decentraland/sdk/components/avatar_modifier_area.proto @@ -23,16 +23,7 @@ message PBAvatarModifierArea { decentraland.common.Vector3 area = 1; // the 3D size of the region repeated string exclude_ids = 2; // user IDs that can enter and remain unaffected repeated AvatarModifierType modifiers = 3; // list of modifiers to apply - optional AvatarControlType control_mode = 4; - // if not explicitly set, the following properties default to user's preference settings - optional float run_speed = 5; // speed the player moves at, in m/s - optional float friction = 6; // how fast the player gets up to speed or comes to rest. higher = more responsive - optional float gravity = 7; // how fast the player accelerates vertically when not on a solid surface, in m/s. should normally be negative - optional float jump_height = 8; // how high the player can jump, in meters. should normally be positive. gravity must have the same sign for jumping to be possible - optional float max_fall_speed = 9; // max fall speed in m/s. should normally be negative - optional float turn_speed = 10; // speed the player turns in tank mode, in radians/s - optional float walk_speed = 11; // speed the player walks at, in m/s - optional bool allow_weighted_movement = 12;// wherther to allow player to move at a slower speed (e.g. with a walk-key or when using a gamepad/joystick). defaults to true + optional AvatarMovementSettings movement_settings = 4; } // AvatarModifierType is an effect that should be applied to avatars inside the region. @@ -41,6 +32,19 @@ enum AvatarModifierType { AMT_DISABLE_PASSPORTS = 1; // selecting (e.g. clicking) an avatar will not bring up their profile. } +message AvatarMovementSettings { + optional AvatarControlType control_mode = 1; + // if not explicitly set, the following properties default to user's preference settings + optional float run_speed = 2; // speed the player moves at, in m/s + optional float friction = 3; // how fast the player gets up to speed or comes to rest. higher = more responsive + optional float gravity = 4; // how fast the player accelerates vertically when not on a solid surface, in m/s. should normally be negative + optional float jump_height = 5; // how high the player can jump, in meters. should normally be positive. gravity must have the same sign for jumping to be possible + optional float max_fall_speed = 6; // max fall speed in m/s. should normally be negative + optional float turn_speed = 7; // speed the player turns in tank mode, in radians/s + optional float walk_speed = 8; // speed the player walks at, in m/s + optional bool allow_weighted_movement = 9; // wherther to allow player to move at a slower speed (e.g. with a walk-key or when using a gamepad/joystick). defaults to true +} + enum AvatarControlType { CCT_NONE = 0; // avatar cannot move CCT_RELATIVE = 1; // avatar moves relative to the camera origin From 724358e3c98c9c6023869e7ee624199f94cc5c6d Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Wed, 15 May 2024 16:37:31 +0100 Subject: [PATCH 05/43] add ui fields --- proto/decentraland/sdk/components/ui_text.proto | 2 ++ proto/decentraland/sdk/components/ui_transform.proto | 1 + 2 files changed, 3 insertions(+) diff --git a/proto/decentraland/sdk/components/ui_text.proto b/proto/decentraland/sdk/components/ui_text.proto index 389f608f..c914aa93 100644 --- a/proto/decentraland/sdk/components/ui_text.proto +++ b/proto/decentraland/sdk/components/ui_text.proto @@ -17,4 +17,6 @@ message PBUiText { optional common.TextAlignMode text_align = 3; // alignment within the bounds (default: center) optional common.Font font = 4; // font for the text (default: sans-serif) optional int32 font_size = 5; // size of the text (default: 10) + optional float outline_width = 6; // width of the outline (default: 0) + optional decentraland.common.Color4 outline_color = 7; // RGBA color of the outline (default: opaque black) } diff --git a/proto/decentraland/sdk/components/ui_transform.proto b/proto/decentraland/sdk/components/ui_transform.proto index d3e0783c..ac1c962b 100644 --- a/proto/decentraland/sdk/components/ui_transform.proto +++ b/proto/decentraland/sdk/components/ui_transform.proto @@ -145,4 +145,5 @@ message PBUiTransform { float padding_bottom = 51; optional PointerFilterMode pointer_filter = 52; // default: PointerFilterMode.PFM_NONE + optional float opacity = 53; // default: 1 } From 1e423c05c5d829ae90678c1645e40d142a3d3d98 Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Thu, 16 May 2024 11:41:22 +0100 Subject: [PATCH 06/43] add collider range --- proto/decentraland/sdk/components/avatar_modifier_area.proto | 3 ++- proto/decentraland/sdk/components/camera_mode_area.proto | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/proto/decentraland/sdk/components/avatar_modifier_area.proto b/proto/decentraland/sdk/components/avatar_modifier_area.proto index bd639b16..38be8e3d 100644 --- a/proto/decentraland/sdk/components/avatar_modifier_area.proto +++ b/proto/decentraland/sdk/components/avatar_modifier_area.proto @@ -24,6 +24,7 @@ message PBAvatarModifierArea { repeated string exclude_ids = 2; // user IDs that can enter and remain unaffected repeated AvatarModifierType modifiers = 3; // list of modifiers to apply optional AvatarMovementSettings movement_settings = 4; + optional bool use_collider_range = 5; // if true, the player will be considered inside the area when they are within 0.3m of the area. default true } // AvatarModifierType is an effect that should be applied to avatars inside the region. @@ -42,7 +43,7 @@ message AvatarMovementSettings { optional float max_fall_speed = 6; // max fall speed in m/s. should normally be negative optional float turn_speed = 7; // speed the player turns in tank mode, in radians/s optional float walk_speed = 8; // speed the player walks at, in m/s - optional bool allow_weighted_movement = 9; // wherther to allow player to move at a slower speed (e.g. with a walk-key or when using a gamepad/joystick). defaults to true + optional bool allow_weighted_movement = 9; // whether to allow player to move at a slower speed (e.g. with a walk-key or when using a gamepad/joystick). defaults to true } enum AvatarControlType { diff --git a/proto/decentraland/sdk/components/camera_mode_area.proto b/proto/decentraland/sdk/components/camera_mode_area.proto index daf6e26b..7a073bbf 100644 --- a/proto/decentraland/sdk/components/camera_mode_area.proto +++ b/proto/decentraland/sdk/components/camera_mode_area.proto @@ -25,6 +25,7 @@ message PBCameraModeArea { decentraland.common.Vector3 area = 1; // the 3D size of the region common.CameraType mode = 2; // the camera mode to enforce optional CinematicSettings cinematic_settings = 3; + optional bool use_collider_range = 4; // if true, the player will be considered inside the area when they are within 0.3m of the area. default true } message CinematicSettings { From 57842f76f6901dc1390c9e37fd6dfe2688fa13ba Mon Sep 17 00:00:00 2001 From: Lean Mendoza Date: Fri, 17 May 2024 07:46:53 -0300 Subject: [PATCH 07/43] publish a protocol-squad version --- .github/workflows/build-and-publish.yml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index ce889ff1..7b343723 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -6,6 +6,9 @@ on: release: types: - created +env: + IS_A_PR: ${{ github.event.pull_request.number != 'null' && github.head_ref != 'protocol-squad' }} + name: build-deploy jobs: @@ -17,6 +20,13 @@ jobs: outputs: dcl_protocol_s3_bucket_key: ${{ steps.publish_dcl_protocol.outputs.s3-bucket-key }} steps: + - name: (PR) Check if it's a PR + if: ${{ env.IS_A_PR == 'true' }} + run: | + echo "run from a PR" + echo "from env '${{env.IS_A_PR}}'" + echo "- '${{github.event.pull_request.number}}'" + echo "- env '${{github.head_ref}}'" - uses: actions/checkout@v2 - name: install run: make install @@ -28,6 +38,8 @@ jobs: uses: menduz/oddish-action@master id: publish_dcl_protocol with: + custom-tag: protocol-squad + branch-to-custom-tag: protocol-squad registry-url: 'https://registry.npmjs.org' access: public ## use action runId instead of current date to generate snapshot numbers @@ -44,14 +56,15 @@ jobs: gitlab-token: ${{ secrets.GITLAB_TOKEN }} gitlab-pipeline-url: ${{ secrets.GITLAB_URL }} env: + BRANCH_NAME: ${{ github.head_ref }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} AWS_DEFAULT_REGION: us-east-1 AWS_ACCESS_KEY_ID: ${{ secrets.SDK_TEAM_AWS_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.SDK_TEAM_AWS_SECRET }} notify_deployment: - needs: [check_and_build] - if: ${{ github.event.pull_request.number }} + needs: [check_and_build] + if: github.event.pull_request.number != 'null' && github.head_ref != 'protocol-squad' runs-on: ubuntu-latest name: Deployment Notification steps: From ae49e5ccef9728e1eeaf10f86f0cb686a8a755d5 Mon Sep 17 00:00:00 2001 From: Lean Mendoza Date: Mon, 27 May 2024 09:14:53 -0300 Subject: [PATCH 08/43] add text_wrapping --- proto/decentraland/sdk/components/ui_text.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/decentraland/sdk/components/ui_text.proto b/proto/decentraland/sdk/components/ui_text.proto index c914aa93..e2ce44c3 100644 --- a/proto/decentraland/sdk/components/ui_text.proto +++ b/proto/decentraland/sdk/components/ui_text.proto @@ -19,4 +19,5 @@ message PBUiText { optional int32 font_size = 5; // size of the text (default: 10) optional float outline_width = 6; // width of the outline (default: 0) optional decentraland.common.Color4 outline_color = 7; // RGBA color of the outline (default: opaque black) + optional bool text_wrapping = 8; // wrap text when the border is reached (default false) } From 5243189a109f870c620bbd710f5bb9ec6c18107d Mon Sep 17 00:00:00 2001 From: Lean Mendoza Date: Wed, 26 Jun 2024 12:22:35 -0300 Subject: [PATCH 09/43] feat: add scroll result component for scrolling ui transform --- .../sdk/components/ui_scroll_result.proto | 12 +++++++++++ .../sdk/components/ui_transform.proto | 20 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 proto/decentraland/sdk/components/ui_scroll_result.proto diff --git a/proto/decentraland/sdk/components/ui_scroll_result.proto b/proto/decentraland/sdk/components/ui_scroll_result.proto new file mode 100644 index 00000000..5e475560 --- /dev/null +++ b/proto/decentraland/sdk/components/ui_scroll_result.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; +import "decentraland/common/vectors.proto"; + +option (common.ecs_component_id) = 1097; + +message PBUiScrollResult { + decentraland.common.Vector2 value = 1; +} \ No newline at end of file diff --git a/proto/decentraland/sdk/components/ui_transform.proto b/proto/decentraland/sdk/components/ui_transform.proto index ac1c962b..8fb002e5 100644 --- a/proto/decentraland/sdk/components/ui_transform.proto +++ b/proto/decentraland/sdk/components/ui_transform.proto @@ -3,6 +3,7 @@ syntax = "proto3"; package decentraland.sdk.components; import "decentraland/sdk/components/common/id.proto"; +import "decentraland/common/vectors.proto"; option (common.ecs_component_id) = 1050; @@ -79,6 +80,20 @@ enum PointerFilterMode { PFM_BLOCK = 1; } +enum ShowScrollBar { + SSB_BOTH = 0; + SSB_ONLY_VERTICAL = 1; + SSB_ONLY_HORIZONTAL = 2; + SSB_HIDDEN = 3; +} + +message ScrollPositionValue { + oneof value { + decentraland.common.Vector2 position = 1; + string reference = 2; + } +} + message PBUiTransform { int32 parent = 1; int32 right_of = 2; @@ -146,4 +161,9 @@ message PBUiTransform { optional PointerFilterMode pointer_filter = 52; // default: PointerFilterMode.PFM_NONE optional float opacity = 53; // default: 1 + + optional string element_id = 54; // default empty + + optional ScrollPositionValue scroll_position = 55; // default position=(0,0) + optional ShowScrollBar scroll_visible = 56; // default ShowScrollBar.SSB_BOTH } From 9d2fa3cefd624513e86a842a1428e8581c44ed4a Mon Sep 17 00:00:00 2001 From: Lean Mendoza Date: Wed, 26 Jun 2024 19:13:33 -0300 Subject: [PATCH 10/43] remove boolean text wrapping --- proto/decentraland/sdk/components/ui_text.proto | 1 - 1 file changed, 1 deletion(-) diff --git a/proto/decentraland/sdk/components/ui_text.proto b/proto/decentraland/sdk/components/ui_text.proto index 543f01ca..6af0782d 100644 --- a/proto/decentraland/sdk/components/ui_text.proto +++ b/proto/decentraland/sdk/components/ui_text.proto @@ -26,5 +26,4 @@ message PBUiText { optional float outline_width = 7; // width of the outline (default: 0) optional decentraland.common.Color4 outline_color = 8; // RGBA color of the outline (default: opaque black) - optional bool text_wrapping = 9; // wrap text when the border is reached (default false) } From 61ce67823b2fac4c31223407401057fad9289363 Mon Sep 17 00:00:00 2001 From: Lean Mendoza Date: Tue, 30 Jul 2024 18:28:18 -0300 Subject: [PATCH 11/43] gltf node (#207) * gltf node * comment * split into two files * change enum name * fix prefix * add named_nodes * add opaque mesh and collider * replace opaque ids with gltf ids * paths, skins, extra state info * remove skin * comments --------- Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com> --- .../gltf_container_loading_state.proto | 13 ++++++ .../sdk/components/gltf_node.proto | 42 +++++++++++++++++++ .../sdk/components/gltf_node_state.proto | 20 +++++++++ .../sdk/components/material.proto | 11 +++++ .../sdk/components/mesh_collider.proto | 9 +++- .../sdk/components/mesh_renderer.proto | 11 +++-- public/sdk-components.proto | 2 + 7 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 proto/decentraland/sdk/components/gltf_node.proto create mode 100644 proto/decentraland/sdk/components/gltf_node_state.proto diff --git a/proto/decentraland/sdk/components/gltf_container_loading_state.proto b/proto/decentraland/sdk/components/gltf_container_loading_state.proto index 2bd38240..daa39933 100644 --- a/proto/decentraland/sdk/components/gltf_container_loading_state.proto +++ b/proto/decentraland/sdk/components/gltf_container_loading_state.proto @@ -10,4 +10,17 @@ import "decentraland/sdk/components/common/loading_state.proto"; // the current state of the GltfContainer of an entity. message PBGltfContainerLoadingState { common.LoadingState current_state = 1; + repeated string node_paths = 2; // all node paths in the gltf, which can be used with a GltfNode to inspect and modify the gltf contents + repeated string mesh_names = 3; // all meshes in the gltf. unnamed meshes will be auto-assigned a name of the form `MeshX` or `MeshX/PrimitiveY` + // where X is the mesh index and Y is the primitive index (and there is more than 1 primitive). note this may + // conflict with manually named meshes - to avoid any issues make sure all your meshes are explicitly named. + repeated string material_names = 4; // all materials in the gltf. unnamed materials will be auto-assigned a name of the form `MaterialX` where + // X is the material index. note this may conflict with manually named materials - to avoid any issues make + // sure all your materials are explicitly named. + repeated string skin_names = 5; // all mesh skins in the gltf. unnamed skins will be auto-assigned a name of the form `SkinX` where + // X is the skin index. note this may conflict with manually named skins - to avoid any issues make sure all + // your skins are explicitly named. + repeated string animation_names = 6; // all animations in the gltf. unnamed animations will be auto-assigned a name of the form `AnimationX` where + // X is the animation index. note this may conflict with manually named anims - to avoid any issues make sure all + // your animations are explicitly named. } diff --git a/proto/decentraland/sdk/components/gltf_node.proto b/proto/decentraland/sdk/components/gltf_node.proto new file mode 100644 index 00000000..430737be --- /dev/null +++ b/proto/decentraland/sdk/components/gltf_node.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; +option (common.ecs_component_id) = 1045; + +// a GltfNode links a scene entity with a node from within a gltf, allowing the scene to inspect it or modify it. +// This component must be added to a direct child of an entity with a PbGltfContainer component, or +// to a direct child of another entity with a GltfNode component, and the referenced gltf node must be a descendent of the gltf node +// in the parent. +// The name must match the path of one of the nodes within the Gltf. These are available on the GltfContainerLoadingState component. +// +// The renderer will attach a PbGltfNodeState to the entity describing the state. Once the state is `GNS_READY`, +// - the `Transform` will be updated to match the position of the node within the gltf (relative to the gltf root, or the parent node), +// - a `MeshRenderer` with a GltfMesh mesh type will be added (if the gltf node has a mesh). +// - a `MeshCollider` with a GltfMesh mesh type will be added (if the gltf node has a collider). +// - a `Material` component including a GltfMaterial reference will be added (if the gltf node has a material). +// +// After creation, if an animation moves the node, the `Transform` will be updated. +// +// From the scene, you can modify various components to alter the gltf node: +// - modifying the `Transform` position/rotation/scale will move the node. The position is interpreted relative to the gltf root (or parent node), +// regardless of any intermediate gltf node hierarchy. +// If an animation is playing, the animation takes priority and the scene entity's position will be updated to match the animation. +// - `Visibility` can be added to hide or show the node and it's children in the gltf hierarchy. +// - `MeshRenderer` can be added/modified/removed to create/modify/remove a mesh on the node. +// - `MeshCollider` can be added/modified/removed to create/modify/remove a collider on the node. +// - `Material` can be added or modified to change the material properties. If the gltf node has a material, the original material will be +// used as a base, and any gltf features (e.g. occlusion maps) from the gtlf spec that the renderer supports but that are not exposed in the +// PbMaterial will be maintained. +// +// The scene can add additional entities as children to the gltf node, but structural modifications of the gltf are not possible: +// - changing the scene hierarchy will not change the gltf node hierarchy. Moving the entity out of the gltf will sever the link and +// change the state to `GNS_FAILED`. +// - deleting the scene entity will not delete the gltf node. +// +// Removing the GltfNode will revert any changes to the original gltf. If the GltfNode component is removed and the mesh/collider/material +// are not removed, this will result in a duplication of these components as the previously-linked entity will retain it's components and +// the gltf node will also be displayed. +message PBGltfNode { + string path = 1; // the path of the target node in the Gltf. +} diff --git a/proto/decentraland/sdk/components/gltf_node_state.proto b/proto/decentraland/sdk/components/gltf_node_state.proto new file mode 100644 index 00000000..7b10b4f7 --- /dev/null +++ b/proto/decentraland/sdk/components/gltf_node_state.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; +option (common.ecs_component_id) = 1046; + +// See the details of the GltfNode component for more information. + +// The state of a linked gltf node. +// If the state is GNSV_FAILED, the renderer may describe the failure in the error string. +message PBGltfNodeState { + GltfNodeStateValue state = 1; + optional string error = 2; +} + +enum GltfNodeStateValue { + GNSV_PENDING = 0; + GNSV_FAILED = 1; + GNSV_READY = 2; +} diff --git a/proto/decentraland/sdk/components/material.proto b/proto/decentraland/sdk/components/material.proto index 65a98bc8..aa13131d 100644 --- a/proto/decentraland/sdk/components/material.proto +++ b/proto/decentraland/sdk/components/material.proto @@ -53,5 +53,16 @@ message PBMaterial { UnlitMaterial unlit = 1; PbrMaterial pbr = 2; } + + message GltfMaterial { + string gltf_src = 1; + string name = 2; + } + // A gltf material that may provide additional features not supported by the PbMaterial fields. + // If both gltf and material fields are provided, the gltf will be used only for extended features not + // supported by the PbMaterial. + // If this is provided and the `material` field is not provided, the renderer will update the material + // field with data that reflects the gltf material once it is loaded. + optional GltfMaterial gltf = 3; } diff --git a/proto/decentraland/sdk/components/mesh_collider.proto b/proto/decentraland/sdk/components/mesh_collider.proto index 3289566b..913225fb 100644 --- a/proto/decentraland/sdk/components/mesh_collider.proto +++ b/proto/decentraland/sdk/components/mesh_collider.proto @@ -30,6 +30,12 @@ message PBMeshCollider { // SphereMesh is a sphere shape that contains the Entity. message SphereMesh {} + // A collider constructed from a Gltf Mesh. + message GltfMesh { + string gltf_src = 1; // the GLTF file path as listed in the scene's manifest. + string name = 2; // the name of the mesh asset + } + optional uint32 collision_mask = 1; // enabled ColliderLayers (default CL_POINTER | CL_PHYSICS) oneof mesh { @@ -37,6 +43,7 @@ message PBMeshCollider { SphereMesh sphere = 3; CylinderMesh cylinder = 4; PlaneMesh plane = 5; + GltfMesh gltf = 6; } } @@ -59,4 +66,4 @@ enum ColliderLayer { CL_CUSTOM6 = 8192; CL_CUSTOM7 = 16384; CL_CUSTOM8 = 32768; -} \ No newline at end of file +} diff --git a/proto/decentraland/sdk/components/mesh_renderer.proto b/proto/decentraland/sdk/components/mesh_renderer.proto index eee8c134..a6095017 100644 --- a/proto/decentraland/sdk/components/mesh_renderer.proto +++ b/proto/decentraland/sdk/components/mesh_renderer.proto @@ -5,13 +5,11 @@ import "decentraland/sdk/components/common/id.proto"; option (common.ecs_component_id) = 1018; // The MeshRenderer component renders a basic geometric shape for an Entity. It can be a cube, a -// plane, a sphere or a cylinder. +// plane, a sphere, a cylinder, or a Gltf mesh. // // The cube and plane variants can include a UV texture mapping, so specific areas of a material // texture are rendered on different faces of the shape. They are serialized as a sequence of 2D // `float` coordinates, one for each corner of each side of each face. -// -// More complex shapes require the use of a `GltfContainer` component. message PBMeshRenderer { // BoxMesh renders a prism shape. @@ -34,10 +32,17 @@ message PBMeshRenderer { message SphereMesh { } + // A mesh from a Gltf. + message GltfMesh { + string gltf_src = 1; // the GLTF file path as listed in the scene's manifest. + string name = 2; // the name of the mesh asset + } + oneof mesh { BoxMesh box = 1; SphereMesh sphere = 2; CylinderMesh cylinder = 3; PlaneMesh plane = 4; + GltfMesh gltf = 5; } } diff --git a/public/sdk-components.proto b/public/sdk-components.proto index 64d7c6f2..527e6662 100644 --- a/public/sdk-components.proto +++ b/public/sdk-components.proto @@ -16,6 +16,8 @@ import public "decentraland/sdk/components/camera_mode.proto"; import public "decentraland/sdk/components/engine_info.proto"; import public "decentraland/sdk/components/gltf_container.proto"; import public "decentraland/sdk/components/gltf_container_loading_state.proto"; +import public "decentraland/sdk/components/gltf_node.proto"; +import public "decentraland/sdk/components/gltf_node_state.proto"; import public "decentraland/sdk/components/material.proto"; import public "decentraland/sdk/components/mesh_collider.proto"; import public "decentraland/sdk/components/mesh_renderer.proto"; From acd1db5432866eff0eff054accf077852b000f9a Mon Sep 17 00:00:00 2001 From: Lean Mendoza Date: Tue, 13 Aug 2024 07:03:16 -0300 Subject: [PATCH 12/43] use 1200 ids --- proto/decentraland/sdk/components/gltf_node.proto | 2 +- proto/decentraland/sdk/components/gltf_node_state.proto | 2 +- proto/decentraland/sdk/components/ui_scroll_result.proto | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proto/decentraland/sdk/components/gltf_node.proto b/proto/decentraland/sdk/components/gltf_node.proto index 430737be..9f2e3503 100644 --- a/proto/decentraland/sdk/components/gltf_node.proto +++ b/proto/decentraland/sdk/components/gltf_node.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package decentraland.sdk.components; import "decentraland/sdk/components/common/id.proto"; -option (common.ecs_component_id) = 1045; +option (common.ecs_component_id) = 1200; // a GltfNode links a scene entity with a node from within a gltf, allowing the scene to inspect it or modify it. // This component must be added to a direct child of an entity with a PbGltfContainer component, or diff --git a/proto/decentraland/sdk/components/gltf_node_state.proto b/proto/decentraland/sdk/components/gltf_node_state.proto index 7b10b4f7..1ce9512e 100644 --- a/proto/decentraland/sdk/components/gltf_node_state.proto +++ b/proto/decentraland/sdk/components/gltf_node_state.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package decentraland.sdk.components; import "decentraland/sdk/components/common/id.proto"; -option (common.ecs_component_id) = 1046; +option (common.ecs_component_id) = 1201; // See the details of the GltfNode component for more information. diff --git a/proto/decentraland/sdk/components/ui_scroll_result.proto b/proto/decentraland/sdk/components/ui_scroll_result.proto index 5e475560..7875f886 100644 --- a/proto/decentraland/sdk/components/ui_scroll_result.proto +++ b/proto/decentraland/sdk/components/ui_scroll_result.proto @@ -5,7 +5,7 @@ package decentraland.sdk.components; import "decentraland/sdk/components/common/id.proto"; import "decentraland/common/vectors.proto"; -option (common.ecs_component_id) = 1097; +option (common.ecs_component_id) = 1202; message PBUiScrollResult { decentraland.common.Vector2 value = 1; From 02076764ddb107b44860529e7195450183f4b9cc Mon Sep 17 00:00:00 2001 From: Lean Mendoza Date: Wed, 18 Sep 2024 06:54:52 -0300 Subject: [PATCH 13/43] in-world UI (#212) * inworld ui * add import * change name * update ui canvas component id --------- Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com> --- proto/decentraland/common/texture.proto | 9 ++++++++- .../decentraland/sdk/components/ui_canvas.proto | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 proto/decentraland/sdk/components/ui_canvas.proto diff --git a/proto/decentraland/common/texture.proto b/proto/decentraland/common/texture.proto index 5cd109b3..bb5767aa 100644 --- a/proto/decentraland/common/texture.proto +++ b/proto/decentraland/common/texture.proto @@ -31,10 +31,17 @@ message VideoTexture { optional TextureFilterMode filter_mode = 3; // default = FilterMode.Bilinear } +message UiCanvasTexture { + uint32 ui_canvas_entity = 1; + optional TextureWrapMode wrap_mode = 2; // default = TextureWrapMode.Clamp + optional TextureFilterMode filter_mode = 3; // default = FilterMode.Bilinear +} + message TextureUnion { oneof tex { Texture texture = 1; // default = null AvatarTexture avatar_texture = 2; // default = null VideoTexture video_texture = 3; // default = null + UiCanvasTexture ui_texture = 4; } -} \ No newline at end of file +} diff --git a/proto/decentraland/sdk/components/ui_canvas.proto b/proto/decentraland/sdk/components/ui_canvas.proto new file mode 100644 index 00000000..3790d96c --- /dev/null +++ b/proto/decentraland/sdk/components/ui_canvas.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +import "decentraland/sdk/components/common/id.proto"; +package decentraland.sdk.components; + +option (common.ecs_component_id) = 1203; + +import "decentraland/common/colors.proto"; + +// The UiCanvas component can be attached to a ui root entity to specify properties of the ui texture. +message PBUiCanvas { + uint32 width = 1; + uint32 height = 2; + + optional decentraland.common.Color4 color = 3; // default = (0.0, 0.0, 0.0, 0.0) / transparent +} From f199bbdc3741a3e75605f2fedbafe351d079b544 Mon Sep 17 00:00:00 2001 From: Lean Mendoza Date: Wed, 18 Sep 2024 06:57:08 -0300 Subject: [PATCH 14/43] lights initial (#217) * lights initial * Pb -> PB --------- Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com> --- .../sdk/components/global_light.proto | 22 ++++++++++ .../sdk/components/gltf_node.proto | 6 +-- proto/decentraland/sdk/components/light.proto | 42 +++++++++++++++++++ .../sdk/components/spotlight.proto | 21 ++++++++++ 4 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 proto/decentraland/sdk/components/global_light.proto create mode 100644 proto/decentraland/sdk/components/light.proto create mode 100644 proto/decentraland/sdk/components/spotlight.proto diff --git a/proto/decentraland/sdk/components/global_light.proto b/proto/decentraland/sdk/components/global_light.proto new file mode 100644 index 00000000..ea76ccb6 --- /dev/null +++ b/proto/decentraland/sdk/components/global_light.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package decentraland.sdk.components; + +import "decentraland/common/colors.proto"; +import "decentraland/common/vectors.proto"; + +import "decentraland/sdk/components/common/id.proto"; +option (common.ecs_component_id) = 1206; + +// defines the global scene light settings. must be added to the scene root. +// to control sunlight color, intensity, shadows etc, you can also add a PBLight to the scene root. +message PBGlobalLight { + // the direction the directional light shines in. + // default depends on time of day and explorer implementation + optional decentraland.common.Vector3 direction = 1; + // ambient light color + // default: White + optional decentraland.common.Color3 ambient_color = 2; + // ambient light intensity. the explorer default ambient brightness is multiplied by this non-physical quantity. + // default 1 + optional float ambient_brightness = 3; +} diff --git a/proto/decentraland/sdk/components/gltf_node.proto b/proto/decentraland/sdk/components/gltf_node.proto index 9f2e3503..86d1e26a 100644 --- a/proto/decentraland/sdk/components/gltf_node.proto +++ b/proto/decentraland/sdk/components/gltf_node.proto @@ -5,12 +5,12 @@ import "decentraland/sdk/components/common/id.proto"; option (common.ecs_component_id) = 1200; // a GltfNode links a scene entity with a node from within a gltf, allowing the scene to inspect it or modify it. -// This component must be added to a direct child of an entity with a PbGltfContainer component, or +// This component must be added to a direct child of an entity with a PBGltfContainer component, or // to a direct child of another entity with a GltfNode component, and the referenced gltf node must be a descendent of the gltf node // in the parent. // The name must match the path of one of the nodes within the Gltf. These are available on the GltfContainerLoadingState component. // -// The renderer will attach a PbGltfNodeState to the entity describing the state. Once the state is `GNS_READY`, +// The renderer will attach a PBGltfNodeState to the entity describing the state. Once the state is `GNS_READY`, // - the `Transform` will be updated to match the position of the node within the gltf (relative to the gltf root, or the parent node), // - a `MeshRenderer` with a GltfMesh mesh type will be added (if the gltf node has a mesh). // - a `MeshCollider` with a GltfMesh mesh type will be added (if the gltf node has a collider). @@ -27,7 +27,7 @@ option (common.ecs_component_id) = 1200; // - `MeshCollider` can be added/modified/removed to create/modify/remove a collider on the node. // - `Material` can be added or modified to change the material properties. If the gltf node has a material, the original material will be // used as a base, and any gltf features (e.g. occlusion maps) from the gtlf spec that the renderer supports but that are not exposed in the -// PbMaterial will be maintained. +// PBMaterial will be maintained. // // The scene can add additional entities as children to the gltf node, but structural modifications of the gltf are not possible: // - changing the scene hierarchy will not change the gltf node hierarchy. Moving the entity out of the gltf will sever the link and diff --git a/proto/decentraland/sdk/components/light.proto b/proto/decentraland/sdk/components/light.proto new file mode 100644 index 00000000..167560e5 --- /dev/null +++ b/proto/decentraland/sdk/components/light.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; +package decentraland.sdk.components; + +import "decentraland/common/colors.proto"; + +import "decentraland/sdk/components/common/id.proto"; +option (common.ecs_component_id) = 1204; + +// defines a light source. +// the world has a default directional light (like sunlight) which can be overridden by adding the light component to the scene root. +// a PBGlobalLight component can also be added to the root to control the directional light direction. +// point lights (lightbulbs) or spotlights can be created by attaching the light component to non-root entities. +message PBLight { + // whether the light is on + // default true + optional bool enabled = 1; + // light brightness in lux (lumens/m^2). + // + // for global directional light, this applies as a constant value at all surfaces and distances (though the effect on the surface still depends on incidence angle). + // the default global light illuminance varies from 400 (sunrise/sunset) to 10,000 (midday). + // for typical values, see https://en.wikipedia.org/wiki/Lux#Illuminance + // + // for point and spot lights, this is the lumens/m^2 at 1m distance from the light. to transform from raw lumens, + // divide lumens by ~12 (4*pi). + // e.g. a 100w household bulb with 1200 lumens would have an illuminance of ~100. + // a lighthouse bulb with 200,000 lumens would have an illuminance of ~15,000 (ignoring beam reflections) + // + // default + // for point/spotlights: 10,000 + // for global directional light: depends on explorer implementation. may vary on light direction, time of day, etc + optional float illuminance = 2; + // whether the light should cast shadows. + // note: even when set to true the engine may not display shadows, or may only show shadows for a limited number + // of lights depending on the implementation, platform, and user settings. + // default + // for point/spotlights: false / off + // for global directional light: true / on + optional bool shadows = 3; + // light color + // default White + optional decentraland.common.Color3 color = 4; +} diff --git a/proto/decentraland/sdk/components/spotlight.proto b/proto/decentraland/sdk/components/spotlight.proto new file mode 100644 index 00000000..40f46add --- /dev/null +++ b/proto/decentraland/sdk/components/spotlight.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; +option (common.ecs_component_id) = 1205; + +// defines a spotlight. +// spotlights are point lights that emit light only in a cone around the transform's forward direction. +// add this component together with the PBLight component to transform a point light into a spotlight. +// note that spotlights do not model any internal reflections / focus, they only restrict the area of effect. +// so for e.g. a torch beam, the bulb illuminance should be multiplied by the solid angle. +// a typical torch with a beam width of 15 degrees would use outer angle of 0.15 (7.5 degrees in radians), +// and an illuminance approximately equal to the bulb's lumens, e.g. 1200. +message PBSpotlight { + // the cone radius in radians. distance away from forward in which the light is visible. + // for a torch a value around 0.15 is appropriate. + float angle = 1; + // optional angle at which the light is brightest. should be <= outer angle. + // if specified, the light will fall off smoothly between `inner_angle` and `angle`. + optional float inner_angle = 2; +} From 27241f42da0d8860067fc83ad96c5549fd2f3d94 Mon Sep 17 00:00:00 2001 From: Lean Mendoza <8042536+leanmendoza@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:01:08 -0300 Subject: [PATCH 15/43] feat: ui transform - add z index (#232) add z index --- proto/decentraland/sdk/components/ui_transform.proto | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proto/decentraland/sdk/components/ui_transform.proto b/proto/decentraland/sdk/components/ui_transform.proto index 8fb002e5..a892d522 100644 --- a/proto/decentraland/sdk/components/ui_transform.proto +++ b/proto/decentraland/sdk/components/ui_transform.proto @@ -166,4 +166,6 @@ message PBUiTransform { optional ScrollPositionValue scroll_position = 55; // default position=(0,0) optional ShowScrollBar scroll_visible = 56; // default ShowScrollBar.SSB_BOTH + + optional int32 z_index = 57; // default 0 } From fdbbfb3223faa9c70f26eda53c9d5f2277a81e40 Mon Sep 17 00:00:00 2001 From: Lean Mendoza <8042536+leanmendoza@users.noreply.github.com> Date: Mon, 27 Jan 2025 08:42:14 -0300 Subject: [PATCH 16/43] feat: render to texture (#236) * add textureCamera and cameralayers component * update * add camera_layer --------- Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com> --- .../sdk/components/camera_layer.proto | 30 ++++++++++++++ .../sdk/components/camera_layers.proto | 11 +++++ .../sdk/components/global_light.proto | 2 +- .../sdk/components/texture_camera.proto | 41 +++++++++++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 proto/decentraland/sdk/components/camera_layer.proto create mode 100644 proto/decentraland/sdk/components/camera_layers.proto create mode 100644 proto/decentraland/sdk/components/texture_camera.proto diff --git a/proto/decentraland/sdk/components/camera_layer.proto b/proto/decentraland/sdk/components/camera_layer.proto new file mode 100644 index 00000000..56daf1cb --- /dev/null +++ b/proto/decentraland/sdk/components/camera_layer.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; +import "decentraland/common/colors.proto"; + +option (common.ecs_component_id) = 1210; + +message PBCameraLayer { + // layer to which these settings apply. must be > 0 + // Layer 0 is the default "real world" layer viewed by the player and cannot be modified. + uint32 layer = 1; + + // should the sun light affect this layer? default false + optional bool directional_light = 2; + + // should this layer show player avatars? default false + optional bool show_avatars = 3; + + // should this layer show the sky? default false + optional bool show_skybox = 4; + + // should this layer show distance fog? default false + optional bool show_fog = 5; + + // ambient light overrides for this layer. default -> use same as main camera + optional decentraland.common.Color3 ambient_color_override = 6; + optional float ambient_brightness_override = 7; +} diff --git a/proto/decentraland/sdk/components/camera_layers.proto b/proto/decentraland/sdk/components/camera_layers.proto new file mode 100644 index 00000000..9fcac006 --- /dev/null +++ b/proto/decentraland/sdk/components/camera_layers.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; + +option (common.ecs_component_id) = 1208; + +message PBCameraLayers { + repeated uint32 layers = 1; +} \ No newline at end of file diff --git a/proto/decentraland/sdk/components/global_light.proto b/proto/decentraland/sdk/components/global_light.proto index ea76ccb6..0fa10ba8 100644 --- a/proto/decentraland/sdk/components/global_light.proto +++ b/proto/decentraland/sdk/components/global_light.proto @@ -18,5 +18,5 @@ message PBGlobalLight { optional decentraland.common.Color3 ambient_color = 2; // ambient light intensity. the explorer default ambient brightness is multiplied by this non-physical quantity. // default 1 - optional float ambient_brightness = 3; + optional float ambient_brightness = 3; } diff --git a/proto/decentraland/sdk/components/texture_camera.proto b/proto/decentraland/sdk/components/texture_camera.proto new file mode 100644 index 00000000..d3c01a86 --- /dev/null +++ b/proto/decentraland/sdk/components/texture_camera.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; +import "decentraland/common/colors.proto"; + +option (common.ecs_component_id) = 1207; + +message PBTextureCamera { + // rendered texture width + optional uint32 width = 1; + // rendered texture height + optional uint32 height = 2; + // which layer of entities to render. entity layers can be specified by adding PBCameraLayers to target entities. + // defaults to 0 + optional uint32 layer = 3; + + // default black + optional decentraland.common.Color4 clear_color = 6; + // default infinity + optional float far_plane = 7; + + oneof mode { + Perspective perspective = 8; + Orthographic orthographic = 9; + /* Portal portal = 10; */ + }; +} + +message Perspective { + // vertical field of view in radians + // defaults to pi/4 = 45 degrees + optional float field_of_view = 1; +} + +message Orthographic { + // vertical extent of the visible range in meters + // defaults to 4m + optional float vertical_range = 1; +} From a7ca443281037de101f52c3c3885262e7c60298d Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:42:33 +0000 Subject: [PATCH 17/43] feat: pointer position and drag (#237) * 'initial' * 'initial' * rename * wip --------- Co-authored-by: Mateo "Kuruk" Miccino --- .../sdk/components/common/input_action.proto | 3 +++ .../sdk/components/primary_pointer_info.proto | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 proto/decentraland/sdk/components/primary_pointer_info.proto diff --git a/proto/decentraland/sdk/components/common/input_action.proto b/proto/decentraland/sdk/components/common/input_action.proto index 824d9cf0..661dd58e 100644 --- a/proto/decentraland/sdk/components/common/input_action.proto +++ b/proto/decentraland/sdk/components/common/input_action.proto @@ -25,4 +25,7 @@ enum PointerEventType { PET_DOWN = 1; PET_HOVER_ENTER = 2; PET_HOVER_LEAVE = 3; + PET_DRAG_LOCKED = 4; + PET_DRAG = 5; + PET_DRAG_END = 6; } \ No newline at end of file diff --git a/proto/decentraland/sdk/components/primary_pointer_info.proto b/proto/decentraland/sdk/components/primary_pointer_info.proto new file mode 100644 index 00000000..a3dad570 --- /dev/null +++ b/proto/decentraland/sdk/components/primary_pointer_info.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; +package decentraland.sdk.components; + +import "decentraland/common/vectors.proto"; +import "decentraland/sdk/components/common/id.proto"; +option (common.ecs_component_id) = 1209; + +message PBPrimaryPointerInfo { + optional PointerType pointer_type = 1; + // in pixels + optional decentraland.common.Vector2 screen_coordinates = 2; + // in pixels + optional decentraland.common.Vector2 screen_delta = 3; + // ray direction that can be used with the primary camera origin for + // raycasting from the cursor into the world + optional decentraland.common.Vector3 world_ray_direction = 4; +} + +enum PointerType { + POT_NONE = 0; + POT_MOUSE = 1; + POT_PAD = 2; + POT_TOUCH = 3; + POT_WAND = 4; +} From ea9043ba50a0591bd82be7703947a998e7c08bd2 Mon Sep 17 00:00:00 2001 From: "Mateo \"Kuruk\" Miccino" Date: Mon, 27 Jan 2025 08:49:56 -0300 Subject: [PATCH 18/43] build and publish --- .github/workflows/build-and-publish.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index 7b343723..a0c49421 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -2,6 +2,7 @@ on: push: branches: - main + - protocol-squad pull_request: release: types: From 5dc030d38c444755c93bf4988c85ae3c02b20782 Mon Sep 17 00:00:00 2001 From: Lean Mendoza <8042536+leanmendoza@users.noreply.github.com> Date: Sat, 1 Feb 2025 13:46:11 -0300 Subject: [PATCH 19/43] test --- .github/workflows/build-and-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index b42d3a82..dfb6387a 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -13,7 +13,7 @@ env: env: - BRANCH_TAG: ${{ github.ref_name == 'experimental' && 'experimental' || '' }} + BRANCH_TAG: ${{ github.ref_name == 'experimental' && 'experimental' || (github.ref_name == 'protocol-squad' && 'protocol-squad' || '') }} name: build-deploy jobs: From 72646626023f95c4404eef33d114ba3007b28b4c Mon Sep 17 00:00:00 2001 From: Lean Mendoza <8042536+leanmendoza@users.noreply.github.com> Date: Sat, 1 Feb 2025 13:47:19 -0300 Subject: [PATCH 20/43] test --- .github/workflows/build-and-publish.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index dfb6387a..a94511ab 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -10,9 +10,6 @@ on: - created env: IS_A_PR: ${{ github.event.pull_request.number != 'null' && github.head_ref != 'protocol-squad' }} - - -env: BRANCH_TAG: ${{ github.ref_name == 'experimental' && 'experimental' || (github.ref_name == 'protocol-squad' && 'protocol-squad' || '') }} name: build-deploy From b71756becd310ec09bde91fefad6dd6c032ac920 Mon Sep 17 00:00:00 2001 From: Lean Mendoza <8042536+leanmendoza@users.noreply.github.com> Date: Sat, 1 Feb 2025 13:49:02 -0300 Subject: [PATCH 21/43] test --- .github/workflows/build-and-publish.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index a94511ab..89573ad4 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -40,8 +40,6 @@ jobs: uses: menduz/oddish-action@master id: publish_dcl_protocol with: - custom-tag: protocol-squad - branch-to-custom-tag: protocol-squad registry-url: 'https://registry.npmjs.org' access: public ## use action runId instead of current date to generate snapshot numbers From a1309786db8a738fdf2946f1d5cf45de6e15c3e8 Mon Sep 17 00:00:00 2001 From: Lean Mendoza <8042536+leanmendoza@users.noreply.github.com> Date: Sat, 1 Feb 2025 13:57:51 -0300 Subject: [PATCH 22/43] test --- .github/workflows/build-and-publish.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index 89573ad4..4f8fe603 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -10,7 +10,6 @@ on: - created env: IS_A_PR: ${{ github.event.pull_request.number != 'null' && github.head_ref != 'protocol-squad' }} - BRANCH_TAG: ${{ github.ref_name == 'experimental' && 'experimental' || (github.ref_name == 'protocol-squad' && 'protocol-squad' || '') }} name: build-deploy jobs: @@ -40,6 +39,8 @@ jobs: uses: menduz/oddish-action@master id: publish_dcl_protocol with: + custom-tag: protocol-squad + branch-to-custom-tag: protocol-squad registry-url: 'https://registry.npmjs.org' access: public ## use action runId instead of current date to generate snapshot numbers @@ -55,10 +56,8 @@ jobs: ## inform gitlab after publishing to proceed with CDN propagation gitlab-token: ${{ secrets.GITLAB_TOKEN }} gitlab-pipeline-url: ${{ secrets.GITLAB_URL }} - custom-tag: ${{ env.BRANCH_TAG }} - branch-to-custom-tag: ${{ env.BRANCH_TAG }} env: - BRANCH_NAME: ${{ github.ref_name }} + BRANCH_NAME: ${{ github.head_ref }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} AWS_DEFAULT_REGION: us-east-1 AWS_ACCESS_KEY_ID: ${{ secrets.SDK_TEAM_AWS_ID }} From 1ef7f1a5698d77ca0716f8e3cc3af0df190871b4 Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:44:44 +0000 Subject: [PATCH 23/43] add force render on avatar components (#251) --- proto/decentraland/sdk/components/avatar_equipped_data.proto | 3 ++- proto/decentraland/sdk/components/avatar_shape.proto | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/proto/decentraland/sdk/components/avatar_equipped_data.proto b/proto/decentraland/sdk/components/avatar_equipped_data.proto index 1890fbd5..84cc3631 100644 --- a/proto/decentraland/sdk/components/avatar_equipped_data.proto +++ b/proto/decentraland/sdk/components/avatar_equipped_data.proto @@ -10,4 +10,5 @@ option (common.ecs_component_id) = 1091; message PBAvatarEquippedData { repeated string wearable_urns = 1; repeated string emote_urns = 2; -} \ No newline at end of file + repeated string force_render = 3; // slots that will render even if hidden +} diff --git a/proto/decentraland/sdk/components/avatar_shape.proto b/proto/decentraland/sdk/components/avatar_shape.proto index 9e1e3884..c856bf3d 100644 --- a/proto/decentraland/sdk/components/avatar_shape.proto +++ b/proto/decentraland/sdk/components/avatar_shape.proto @@ -38,5 +38,6 @@ message PBAvatarShape { // Shoes : "urn:decentraland:off-chain:base-avatars:bun_shoes"] repeated string wearables = 10; repeated string emotes = 11; // available emotes (default empty) + repeated string force_render = 12; // slots that will render even if hidden } From 5eec1a49bdc3ec87a4f6cc60a45d15a045dea3e2 Mon Sep 17 00:00:00 2001 From: "Mateo \"Kuruk\" Miccino" Date: Wed, 12 Mar 2025 18:30:46 -0300 Subject: [PATCH 24/43] fix ci --- .github/workflows/validate.yml | 5 ++++- scripts/check-proto-compabitility.sh | 21 ++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 264fbd47..09affc82 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -3,6 +3,9 @@ on: branches-ignore: - "main" +env: + BASE_BRANCH: protocol-squad # TODO: change to main for merging into main + name: validate-compatibility jobs: compat: @@ -19,4 +22,4 @@ jobs: - name: build and compile test run: make test - name: run the check script - run: ./scripts/check-proto-compabitility.sh + run: ./scripts/check-proto-compabitility.sh ${{ env.BASE_BRANCH }} diff --git a/scripts/check-proto-compabitility.sh b/scripts/check-proto-compabitility.sh index c7f7120a..7a9289df 100755 --- a/scripts/check-proto-compabitility.sh +++ b/scripts/check-proto-compabitility.sh @@ -1,15 +1,26 @@ #!/bin/bash set -e -x +# Check if the first argument (branch_name) is provided +if [ -z "$1" ]; then + echo "Error: Missing branch name parameter." + echo "Usage: $0 " + exit 1 +fi + +# Continue with the rest of the script +branch_name="$1" +echo "Branch name provided: $branch_name" + # Download the main branch ref zip -protocol_main_zip_url="https://github.com/decentraland/protocol/archive/refs/heads/main.zip" -protocol_main_zip_local="./protocol-main.zip" +protocol_zip_url="https://github.com/decentraland/protocol/archive/refs/heads/${branch_name}.zip" +protocol_zip_local="./protocol-main.zip" TMP_ZIP_DIR=$(mktemp -d) -curl -L "$protocol_main_zip_url" -o "$protocol_main_zip_local" -unzip "$protocol_main_zip_local" -d "$TMP_ZIP_DIR" -rm "$protocol_main_zip_local" || true +curl -L "$protocol_zip_url" -o "$protocol_zip_local" +unzip "$protocol_zip_local" -d "$TMP_ZIP_DIR" +rm "$protocol_zip_local" || true ln -s "$(pwd)/node_modules" "$TMP_ZIP_DIR/protocol-main/node_modules" From f22e88af6817b3691be634a73c4f3d49e6a91539 Mon Sep 17 00:00:00 2001 From: "Mateo \"Kuruk\" Miccino" Date: Wed, 12 Mar 2025 18:32:18 -0300 Subject: [PATCH 25/43] fix package.json --- .github/workflows/validate.yml | 2 +- package.json | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 09affc82..d659402a 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -1,7 +1,7 @@ on: push: branches-ignore: - - "main" + - "protocol-squad" env: BASE_BRANCH: protocol-squad # TODO: change to main for merging into main diff --git a/package.json b/package.json index 4c00b271..919dc8a8 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,10 @@ "name": "@dcl/protocol", "version": "1.0.0", "description": "", - "repository": "decentraland/protocol.git", + "repository": { + "type": "git", + "url": "git+https://github.com/decentraland/protocol.git" + }, "homepage": "https://github.com/decentraland/protocol#readme", "bugs": "https://github.com/decentraland/protocol/issues", "keywords": [], From 832f02f1198c63e8e894aacf85206b4778adcfe5 Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Thu, 3 Apr 2025 00:06:58 +0100 Subject: [PATCH 26/43] Border radius and texture cam volume (#257) * add border radius, move existing fields * add texture cam volume * add comment --- .../sdk/components/texture_camera.proto | 5 +++ .../sdk/components/ui_transform.proto | 41 +++++++++++++++---- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/proto/decentraland/sdk/components/texture_camera.proto b/proto/decentraland/sdk/components/texture_camera.proto index d3c01a86..1cf167cb 100644 --- a/proto/decentraland/sdk/components/texture_camera.proto +++ b/proto/decentraland/sdk/components/texture_camera.proto @@ -26,6 +26,11 @@ message PBTextureCamera { Orthographic orthographic = 9; /* Portal portal = 10; */ }; + + // controls whether this camera acts as a receiver for audio on sources with matching `PBCameraLayers`. + // range: 0 (off) - 1 (full volume) + // default: 0 + optional float volume = 10; } message Perspective { diff --git a/proto/decentraland/sdk/components/ui_transform.proto b/proto/decentraland/sdk/components/ui_transform.proto index a892d522..746fc0c7 100644 --- a/proto/decentraland/sdk/components/ui_transform.proto +++ b/proto/decentraland/sdk/components/ui_transform.proto @@ -3,6 +3,7 @@ syntax = "proto3"; package decentraland.sdk.components; import "decentraland/sdk/components/common/id.proto"; +import "decentraland/common/colors.proto"; import "decentraland/common/vectors.proto"; option (common.ecs_component_id) = 1050; @@ -160,12 +161,38 @@ message PBUiTransform { float padding_bottom = 51; optional PointerFilterMode pointer_filter = 52; // default: PointerFilterMode.PFM_NONE - optional float opacity = 53; // default: 1 - optional string element_id = 54; // default empty - - optional ScrollPositionValue scroll_position = 55; // default position=(0,0) - optional ShowScrollBar scroll_visible = 56; // default ShowScrollBar.SSB_BOTH - - optional int32 z_index = 57; // default 0 + // Border Width + optional YGUnit border_left_width_unit = 53; // YGUnit.YGU_UNDEFINED + optional float border_left_width = 54; + optional YGUnit border_top_width_unit = 55; // YGUnit.YGU_UNDEFINED + optional float border_top_width = 56; + optional YGUnit border_right_width_unit = 57; // YGUnit.YGU_UNDEFINED + optional float border_right_width = 58; + optional YGUnit border_bottom_width_unit = 59; // YGUnit.YGU_UNDEFINED + optional float border_bottom_width = 60; + + // Border Radius + optional YGUnit border_top_left_radius_unit = 61; // YGUnit.YGU_UNDEFINED + optional float border_top_left_radius = 62; + optional YGUnit border_top_right_radius_unit = 63; // YGUnit.YGU_UNDEFINED + optional float border_top_right_radius = 64; + optional YGUnit border_bottom_left_radius_unit = 65; // YGUnit.YGU_UNDEFINED + optional float border_bottom_left_radius = 66; + optional YGUnit border_bottom_right_radius_unit = 67; // YGUnit.YGU_UNDEFINED + optional float border_bottom_right_radius = 68; + + // Border Color + optional decentraland.common.Color4 border_top_color = 69; + optional decentraland.common.Color4 border_bottom_color = 70; + optional decentraland.common.Color4 border_left_color = 71; + optional decentraland.common.Color4 border_right_color = 72; + + optional float opacity = 73; // default: 1 + + optional string element_id = 74; // reference for scroll_position. default empty + optional ScrollPositionValue scroll_position = 75; // default position=(0,0) + optional ShowScrollBar scroll_visible = 76; // default ShowScrollBar.SSB_BOTH + + optional int32 z_index = 77; // default 0 } From 446cf4ad870ae911f80ba4f7ecc76d8026df1b59 Mon Sep 17 00:00:00 2001 From: Lean Mendoza <8042536+leanmendoza@users.noreply.github.com> Date: Wed, 18 Jun 2025 10:55:10 -0300 Subject: [PATCH 27/43] feat: add clipboard (#275) feat: add clipboard to restricted actions --- proto/decentraland/kernel/apis/restricted_actions.proto | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index b2dcc7b8..0a1df0fb 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -51,6 +51,12 @@ message MovePlayerToResponse { } message TeleportToResponse { } +message CopyToClipboardRequest { + string text = 1; +} + +message EmptyResponse { } + service RestrictedActionsService { // MovePlayerTo will move the player in a position relative to the current scene rpc MovePlayerTo(MovePlayerToRequest) returns (MovePlayerToResponse) {} @@ -76,4 +82,6 @@ service RestrictedActionsService { // TriggerSceneEmote will trigger an scene emote file in this current user rpc TriggerSceneEmote(TriggerSceneEmoteRequest) returns (SuccessResponse) {} + + rpc CopyToClipboard(CopyToClipboardRequest) returns (EmptyResponse) {} } From f2e135e3b5baf11cbe25821fc7c94e01f9cfed89 Mon Sep 17 00:00:00 2001 From: "Mateo \"Kuruk\" Miccino" Date: Wed, 18 Jun 2025 11:48:37 -0300 Subject: [PATCH 28/43] feat: add set ui focus on restricted actions --- proto/decentraland/kernel/apis/restricted_actions.proto | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index 0a1df0fb..78324922 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -51,6 +51,10 @@ message MovePlayerToResponse { } message TeleportToResponse { } +message SetUiFocusRequest { + string element_id = 1; +} + message CopyToClipboardRequest { string text = 1; } @@ -83,5 +87,9 @@ service RestrictedActionsService { // TriggerSceneEmote will trigger an scene emote file in this current user rpc TriggerSceneEmote(TriggerSceneEmoteRequest) returns (SuccessResponse) {} + // Sets the focus to a specific UI element + rpc SetUiFocus(SetUiFocusRequest) returns (SuccessResponse) {} + + // Copies the specified text to the user's clipboard rpc CopyToClipboard(CopyToClipboardRequest) returns (EmptyResponse) {} } From d35499ac93ab011744388b1da3edae9b8245bbda Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Fri, 8 Aug 2025 12:14:34 +0100 Subject: [PATCH 29/43] psquad lights reconciliation (#301) * feat: dynamic lights (#296) * added light source proto * tweaked docs * changed default intensity value in the docs * fixed range comment * remove previous light and spot_light messagetypes --------- Co-authored-by: daniele-dcl --- proto/decentraland/sdk/components/light.proto | 42 ------------------- .../sdk/components/light_source.proto | 28 +++++++++++++ .../sdk/components/spotlight.proto | 21 ---------- 3 files changed, 28 insertions(+), 63 deletions(-) delete mode 100644 proto/decentraland/sdk/components/light.proto create mode 100644 proto/decentraland/sdk/components/light_source.proto delete mode 100644 proto/decentraland/sdk/components/spotlight.proto diff --git a/proto/decentraland/sdk/components/light.proto b/proto/decentraland/sdk/components/light.proto deleted file mode 100644 index 167560e5..00000000 --- a/proto/decentraland/sdk/components/light.proto +++ /dev/null @@ -1,42 +0,0 @@ -syntax = "proto3"; -package decentraland.sdk.components; - -import "decentraland/common/colors.proto"; - -import "decentraland/sdk/components/common/id.proto"; -option (common.ecs_component_id) = 1204; - -// defines a light source. -// the world has a default directional light (like sunlight) which can be overridden by adding the light component to the scene root. -// a PBGlobalLight component can also be added to the root to control the directional light direction. -// point lights (lightbulbs) or spotlights can be created by attaching the light component to non-root entities. -message PBLight { - // whether the light is on - // default true - optional bool enabled = 1; - // light brightness in lux (lumens/m^2). - // - // for global directional light, this applies as a constant value at all surfaces and distances (though the effect on the surface still depends on incidence angle). - // the default global light illuminance varies from 400 (sunrise/sunset) to 10,000 (midday). - // for typical values, see https://en.wikipedia.org/wiki/Lux#Illuminance - // - // for point and spot lights, this is the lumens/m^2 at 1m distance from the light. to transform from raw lumens, - // divide lumens by ~12 (4*pi). - // e.g. a 100w household bulb with 1200 lumens would have an illuminance of ~100. - // a lighthouse bulb with 200,000 lumens would have an illuminance of ~15,000 (ignoring beam reflections) - // - // default - // for point/spotlights: 10,000 - // for global directional light: depends on explorer implementation. may vary on light direction, time of day, etc - optional float illuminance = 2; - // whether the light should cast shadows. - // note: even when set to true the engine may not display shadows, or may only show shadows for a limited number - // of lights depending on the implementation, platform, and user settings. - // default - // for point/spotlights: false / off - // for global directional light: true / on - optional bool shadows = 3; - // light color - // default White - optional decentraland.common.Color3 color = 4; -} diff --git a/proto/decentraland/sdk/components/light_source.proto b/proto/decentraland/sdk/components/light_source.proto new file mode 100644 index 00000000..025e48a2 --- /dev/null +++ b/proto/decentraland/sdk/components/light_source.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; +package decentraland.sdk.components; +import "decentraland/sdk/components/common/id.proto"; +import "decentraland/common/colors.proto"; +import "decentraland/common/texture.proto"; +option (common.ecs_component_id) = 1079; + +message PBLightSource { + optional bool active = 1; // default = true, whether the lightSource is active or not. + optional decentraland.common.Color3 color = 2; // default = white, the tint of the light, in RGB format where each component is a floating point value with a range from 0 to 1. + optional float intensity = 3; // default = 16000, light intensity expressed in candels (lumens/m^2 at 1 m distance, or lumens divided by 4*pi) + optional float range = 4; // default = -1, how far the light travels, expressed in meters. If negative will be computed automatically as pow(intensity, 0.25) + optional bool shadow = 5; // default = false, whether the light casts shadows or not. + optional decentraland.common.TextureUnion shadow_mask_texture = 6; // Texture mask through which shadows are cast to simulate caustics, soft shadows, and light shapes such as light entering from a window. + + oneof type { + Point point = 7; + Spot spot = 8; + } + + message Point { + } + + message Spot { + optional float inner_angle = 9; // default = 21.8. Inner angle can't be higher than outer angle, otherwise will default to same value. Min value is 0. Max value is 179. + optional float outer_angle = 10; // default = 30. Outer angle can't be lower than inner angle, otherwise will inner angle will be set to same value. Max value is 179. + } +} diff --git a/proto/decentraland/sdk/components/spotlight.proto b/proto/decentraland/sdk/components/spotlight.proto deleted file mode 100644 index 40f46add..00000000 --- a/proto/decentraland/sdk/components/spotlight.proto +++ /dev/null @@ -1,21 +0,0 @@ -syntax = "proto3"; -package decentraland.sdk.components; - -import "decentraland/sdk/components/common/id.proto"; -option (common.ecs_component_id) = 1205; - -// defines a spotlight. -// spotlights are point lights that emit light only in a cone around the transform's forward direction. -// add this component together with the PBLight component to transform a point light into a spotlight. -// note that spotlights do not model any internal reflections / focus, they only restrict the area of effect. -// so for e.g. a torch beam, the bulb illuminance should be multiplied by the solid angle. -// a typical torch with a beam width of 15 degrees would use outer angle of 0.15 (7.5 degrees in radians), -// and an illuminance approximately equal to the bulb's lumens, e.g. 1200. -message PBSpotlight { - // the cone radius in radians. distance away from forward in which the light is visible. - // for a torch a value around 0.15 is appropriate. - float angle = 1; - // optional angle at which the light is brightest. should be <= outer angle. - // if specified, the light will fall off smoothly between `inner_angle` and `angle`. - optional float inner_angle = 2; -} From d5049fe0c113558054edb6aa0c538e5ec6253daa Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Fri, 7 Nov 2025 11:13:37 +0000 Subject: [PATCH 30/43] clear/get focus --- .../kernel/apis/restricted_actions.proto | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index 78324922..b83476f9 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -55,6 +55,15 @@ message SetUiFocusRequest { string element_id = 1; } +message ClearUiFocusRequest { } + +message GetUiFocusRequest { } + +message UiFocusResponse { + // the element that is/was focussed + optional string element_id = 1; +} + message CopyToClipboardRequest { string text = 1; } @@ -88,7 +97,13 @@ service RestrictedActionsService { rpc TriggerSceneEmote(TriggerSceneEmoteRequest) returns (SuccessResponse) {} // Sets the focus to a specific UI element - rpc SetUiFocus(SetUiFocusRequest) returns (SuccessResponse) {} + rpc SetUiFocus(SetUiFocusRequest) returns (UiFocusResponse) {} + + // Clears the focus from any currently focused textentry or dropdown + rpc ClearUiFocus(SetUiFocusRequest) returns (UiFocusResponse) {} + + // Returns the element_id of any currently focused textentry or dropdown + rpc GetUiFocus(GetUiFocusRequest) returns (UiFocusResponse) {} // Copies the specified text to the user's clipboard rpc CopyToClipboard(CopyToClipboardRequest) returns (EmptyResponse) {} From 593cbae46f5fa0e6683ad5fee267f3f5e4ff56d4 Mon Sep 17 00:00:00 2001 From: "Mateo \"Kuruk\" Miccino" Date: Tue, 11 Nov 2025 11:53:52 -0300 Subject: [PATCH 31/43] fix component_id conflict --- proto/decentraland/sdk/components/camera_layer.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/decentraland/sdk/components/camera_layer.proto b/proto/decentraland/sdk/components/camera_layer.proto index 56daf1cb..6c648801 100644 --- a/proto/decentraland/sdk/components/camera_layer.proto +++ b/proto/decentraland/sdk/components/camera_layer.proto @@ -5,7 +5,7 @@ package decentraland.sdk.components; import "decentraland/sdk/components/common/id.proto"; import "decentraland/common/colors.proto"; -option (common.ecs_component_id) = 1210; +option (common.ecs_component_id) = 1211; message PBCameraLayer { // layer to which these settings apply. must be > 0 From e203261a012baa08ff3081ac32053587f2ec337e Mon Sep 17 00:00:00 2001 From: Lean Mendoza <8042536+leanmendoza@users.noreply.github.com> Date: Mon, 17 Nov 2025 13:26:51 -0300 Subject: [PATCH 32/43] add social v2 features (#324) * add social v2 features * add errors --- .../decentraland/social_service/errors.proto | 30 + .../social_service/v2/social_service_v2.proto | 574 +++++++++++++++++- 2 files changed, 593 insertions(+), 11 deletions(-) create mode 100644 proto/decentraland/social_service/errors.proto diff --git a/proto/decentraland/social_service/errors.proto b/proto/decentraland/social_service/errors.proto new file mode 100644 index 00000000..cd978fc8 --- /dev/null +++ b/proto/decentraland/social_service/errors.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; +package decentraland.social_service; + +message InvalidFriendshipAction { + optional string message = 1; +} + +message InternalServerError { + optional string message = 1; +} + +message InvalidRequest { + optional string message = 1; +} + +message ProfileNotFound { + optional string message = 1; +} + +message ConflictingError { + optional string message = 1; +} + +message ForbiddenError { + optional string message = 1; +} + +message NotFoundError { + optional string message = 1; +} diff --git a/proto/decentraland/social_service/v2/social_service_v2.proto b/proto/decentraland/social_service/v2/social_service_v2.proto index 363ed330..5608eab2 100644 --- a/proto/decentraland/social_service/v2/social_service_v2.proto +++ b/proto/decentraland/social_service/v2/social_service_v2.proto @@ -2,23 +2,36 @@ syntax = "proto3"; package decentraland.social_service.v2; import "google/protobuf/empty.proto"; - -// Errors -message InvalidFriendshipAction {} -message InternalServerError {} +import "decentraland/social_service/errors.proto"; // Types message User { string address = 1; } +message FriendProfile { + string address = 1; + string name = 2; + bool has_claimed_name = 3; + string profile_picture_url = 4; +} + +message BlockedUserProfile { + string address = 1; + string name = 2; + bool has_claimed_name = 3; + string profile_picture_url = 4; + optional int64 blocked_at = 5; +} + message Pagination { int32 limit = 1; int32 offset = 2; } message FriendshipRequestResponse { - User user = 1; + FriendProfile friend = 1; int64 created_at = 2; optional string message = 3; + string id = 4; } message FriendshipRequests { @@ -33,7 +46,6 @@ enum ConnectivityStatus { message GetFriendsPayload { optional Pagination pagination = 1; - optional ConnectivityStatus status = 2; } message GetFriendshipRequestsPayload { @@ -69,8 +81,8 @@ message PaginatedResponse { int32 page = 2; } -message PaginatedUsersResponse { - repeated User users = 1; +message PaginatedFriendsProfilesResponse { + repeated FriendProfile friends = 1; PaginatedResponse pagination_data = 2; } @@ -86,29 +98,45 @@ message UpsertFriendshipResponse { message Accepted { string id = 1; int64 created_at = 2; + FriendProfile friend = 3; + optional string message = 4; } oneof response { Accepted accepted = 1; InvalidFriendshipAction invalid_friendship_action = 2; InternalServerError internal_server_error = 3; + InvalidRequest invalid_request = 4; } } message FriendshipUpdate { + message RequestResponse { + FriendProfile friend = 1; + int64 created_at = 2; + optional string message = 3; + string id = 4; + } message AcceptResponse { User user = 1; } message RejectResponse { User user = 1; } message DeleteResponse { User user = 1; } message CancelResponse { User user = 1; } + message BlockResponse { User user = 1; } oneof update { - FriendshipRequestResponse request = 1; + RequestResponse request = 1; AcceptResponse accept = 2; RejectResponse reject = 3; DeleteResponse delete = 4; CancelResponse cancel = 5; + BlockResponse block = 6; } } +message FriendConnectivityUpdate { + FriendProfile friend = 1; + ConnectivityStatus status = 2; +} + message GetFriendshipStatusPayload { User user = 1; } @@ -121,6 +149,8 @@ enum FriendshipStatus { REJECTED = 4; DELETED = 5; BLOCKED = 6; + NONE = 7; + BLOCKED_BY = 8; } message GetFriendshipStatusResponse { @@ -131,15 +161,461 @@ message GetFriendshipStatusResponse { oneof response { Ok accepted = 1; InternalServerError internal_server_error = 2; + InvalidRequest invalid_request = 3; + } +} + +message BlockUserPayload { + User user = 1; +} + +message BlockUserResponse { + message Ok { + BlockedUserProfile profile = 1; + } + + oneof response { + Ok ok = 1; + InternalServerError internal_server_error = 2; + InvalidRequest invalid_request = 3; + ProfileNotFound profile_not_found = 4; } } +message UnblockUserPayload { + User user = 1; +} + +message UnblockUserResponse { + message Ok { + BlockedUserProfile profile = 1; + } + + oneof response { + Ok ok = 1; + InternalServerError internal_server_error = 2; + InvalidRequest invalid_request = 3; + ProfileNotFound profile_not_found = 4; + } +} + +enum PrivateMessagePrivacySetting { + ALL = 0; + ONLY_FRIENDS = 1; +} + +enum BlockedUsersMessagesVisibilitySetting { + SHOW_MESSAGES = 0; + DO_NOT_SHOW_MESSAGES = 1; +} + +message SocialSettings { + PrivateMessagePrivacySetting private_messages_privacy = 1; + BlockedUsersMessagesVisibilitySetting blocked_users_messages_visibility = 2; +} + +message GetSocialSettingsResponse { + message Ok { + SocialSettings settings = 1; + } + + oneof response { + Ok ok = 1; + InternalServerError internal_server_error = 2; + } +} + +message UpsertSocialSettingsPayload { + optional PrivateMessagePrivacySetting private_messages_privacy = 1; + optional BlockedUsersMessagesVisibilitySetting blocked_users_messages_visibility = 2; +} + +message UpsertSocialSettingsResponse { + oneof response { + SocialSettings ok = 1; + InternalServerError internal_server_error = 2; + InvalidRequest invalid_request = 3; + } +} + +message GetPrivateMessagesSettingsPayload { + repeated User user = 1; +} + +message GetPrivateMessagesSettingsResponse { + message PrivateMessagesSettings { + User user = 1; + PrivateMessagePrivacySetting private_messages_privacy = 2; + bool is_friend = 3; + } + + message Ok { + repeated PrivateMessagesSettings settings = 1; + } + + oneof response { + Ok ok = 1; + InternalServerError internal_server_error = 2; + InvalidRequest invalid_request = 3; + ProfileNotFound profile_not_found = 4; + } +} + +message GetBlockedUsersPayload { + optional Pagination pagination = 1; +} + +message GetBlockedUsersResponse { + repeated BlockedUserProfile profiles = 1; + PaginatedResponse pagination_data = 2; +} + +message GetBlockingStatusResponse { + repeated string blocked_users = 1; + repeated string blocked_by_users = 2; +} + +message BlockUpdate { + string address = 1; + bool is_blocked = 2; +} + +message CommunityMemberConnectivityUpdate { + string community_id = 1; + User member = 2; + ConnectivityStatus status = 3; +} + +// Private voice chats + +// Starting a private voice chat + +message StartPrivateVoiceChatPayload { + User callee = 1; +} + +message StartPrivateVoiceChatResponse { + message Ok { + string call_id = 1; + } + + oneof response { + Ok ok = 1; + InternalServerError internal_server_error = 2; + InvalidRequest invalid_request = 3; + ConflictingError conflicting_error = 4; + ForbiddenError forbidden_error = 5; + } +} + +// Accepting a private voice chat + +message AcceptPrivateVoiceChatPayload { + string call_id = 1; +} + +message AcceptPrivateVoiceChatResponse { + message Ok { + string call_id = 1; + PrivateVoiceChatCredentials credentials = 2; + } + + oneof response { + Ok ok = 1; + InternalServerError internal_server_error = 2; + InvalidRequest invalid_request = 3; + NotFoundError not_found = 4; + ForbiddenError forbidden_error = 5; + } +} + +// Rejecting a private voice chat + +message RejectPrivateVoiceChatPayload { + string call_id = 1; +} + +message RejectPrivateVoiceChatResponse { + message Ok { + string call_id = 1; + } + + oneof response { + Ok ok = 1; + InternalServerError internal_server_error = 2; + InvalidRequest invalid_request = 3; + NotFoundError not_found = 4; + } +} + +// Private voice chat updates + +enum PrivateVoiceChatStatus { + VOICE_CHAT_REQUESTED = 0; + VOICE_CHAT_ACCEPTED = 1; + VOICE_CHAT_REJECTED = 2; + VOICE_CHAT_ENDED = 3; + VOICE_CHAT_EXPIRED = 4; +} + +message PrivateVoiceChatCredentials { + string connection_url = 1; +} + +message PrivateVoiceChatUpdate { + string call_id = 1; + PrivateVoiceChatStatus status = 2; + optional User caller = 3; + optional User callee = 4; + optional PrivateVoiceChatCredentials credentials = 5; +} + +// Ending a private voice chat +// This is sent from the client to the server whenever the user wants to end the voice chat +// This could occur before the voice chat is accepted or after it is accepted + +message EndPrivateVoiceChatPayload { + string call_id = 1; +} + +message EndPrivateVoiceChatResponse { + message Ok { + string call_id = 1; + } + + oneof response { + Ok ok = 1; + InternalServerError internal_server_error = 2; + NotFoundError not_found = 3; + } +} + +// Get incoming private voice chat request + +message GetIncomingPrivateVoiceChatRequestResponse { + message Ok { + User caller = 1; + string call_id = 2; + } + + oneof response { + Ok ok = 1; + NotFoundError not_found = 2; + InternalServerError internal_server_error = 3; + } +} + +// Community Voice Chat messages + +// Community voice chat credentials - specific type for community chats +message CommunityVoiceChatCredentials { + string connection_url = 1; +} + +// Starting a community voice chat +message StartCommunityVoiceChatPayload { + string community_id = 1; +} + +message StartCommunityVoiceChatResponse { + message Ok { + CommunityVoiceChatCredentials credentials = 1; // Moderator gets credentials immediately + } + + oneof response { + Ok ok = 1; + InvalidRequest invalid_request = 2; + ForbiddenError forbidden_error = 3; + ConflictingError conflicting_error = 4; + InternalServerError internal_server_error = 5; + } +} + +// Joining a community voice chat +message JoinCommunityVoiceChatPayload { + string community_id = 1; +} + +message JoinCommunityVoiceChatResponse { + message Ok { + string voice_chat_id = 1; + CommunityVoiceChatCredentials credentials = 2; + } + + oneof response { + Ok ok = 1; + InvalidRequest invalid_request = 2; + ForbiddenError forbidden_error = 3; + NotFoundError not_found_error = 4; + ConflictingError conflicting_error = 5; + InternalServerError internal_server_error = 6; + } +} + +// Request to speak in community voice chat +message RequestToSpeakInCommunityVoiceChatPayload { + string community_id = 1; + bool is_raising_hand = 2; // true to raise hand (request to speak), false to lower hand (withdraw request) +} + +message RequestToSpeakInCommunityVoiceChatResponse { + message Ok { + string message = 1; + } + + oneof response { + Ok ok = 1; + InvalidRequest invalid_request = 2; + ForbiddenError forbidden_error = 3; + NotFoundError not_found_error = 4; + InternalServerError internal_server_error = 5; + } +} + +// Promote speaker in community voice chat +message PromoteSpeakerInCommunityVoiceChatPayload { + string community_id = 1; + string user_address = 2; +} + +message PromoteSpeakerInCommunityVoiceChatResponse { + message Ok { + string message = 1; + } + + oneof response { + Ok ok = 1; + InvalidRequest invalid_request = 2; + ForbiddenError forbidden_error = 3; + NotFoundError not_found_error = 4; + InternalServerError internal_server_error = 5; + } +} + +// Demote speaker in community voice chat +message DemoteSpeakerInCommunityVoiceChatPayload { + string community_id = 1; + string user_address = 2; +} + +message DemoteSpeakerInCommunityVoiceChatResponse { + message Ok { + string message = 1; + } + + oneof response { + Ok ok = 1; + InvalidRequest invalid_request = 2; + ForbiddenError forbidden_error = 3; + NotFoundError not_found_error = 4; + InternalServerError internal_server_error = 5; + } +} + +// Kick player from community voice chat +message KickPlayerFromCommunityVoiceChatPayload { + string community_id = 1; + string user_address = 2; +} + +message KickPlayerFromCommunityVoiceChatResponse { + message Ok { + string message = 1; + } + + oneof response { + Ok ok = 1; + InvalidRequest invalid_request = 2; + ForbiddenError forbidden_error = 3; + NotFoundError not_found_error = 4; + InternalServerError internal_server_error = 5; + } +} + +// Reject speak request in community voice chat +message RejectSpeakRequestInCommunityVoiceChatPayload { + string community_id = 1; + string user_address = 2; +} + +message RejectSpeakRequestInCommunityVoiceChatResponse { + message Ok { + string message = 1; + } + + oneof response { + Ok ok = 1; + InvalidRequest invalid_request = 2; + ForbiddenError forbidden_error = 3; + NotFoundError not_found_error = 4; + InternalServerError internal_server_error = 5; + } +} + +// Community Voice Chat Messages +message MuteSpeakerFromCommunityVoiceChatPayload { + string community_id = 1; + string user_address = 2; + bool muted = 3; +} + +message MuteSpeakerFromCommunityVoiceChatResponse { + message Ok { + bool muted = 1; // The resulting mute state + } + + oneof response { + Ok ok = 1; + ForbiddenError forbidden_error = 2; + NotFoundError not_found_error = 3; + InvalidRequest invalid_request = 4; + InternalServerError internal_server_error = 5; + } +} + +// End community voice chat (moderator/owner only) +message EndCommunityVoiceChatPayload { + string community_id = 1; +} + +message EndCommunityVoiceChatResponse { + message Ok { + string message = 1; + } + + oneof response { + Ok ok = 1; + InvalidRequest invalid_request = 2; + ForbiddenError forbidden_error = 3; + NotFoundError not_found_error = 4; + InternalServerError internal_server_error = 5; + } +} + +enum CommunityVoiceChatStatus { + COMMUNITY_VOICE_CHAT_STARTED = 0; + COMMUNITY_VOICE_CHAT_ENDED = 1; +} + +// Community voice chat updates/events - 'started' and 'ended' status +message CommunityVoiceChatUpdate { + string community_id = 1; + int64 created_at = 2; + CommunityVoiceChatStatus status = 3; // 'started' or 'ended' + optional int64 ended_at = 4; // Only present when status is 'ended' + repeated string positions = 5; // Positions/coordinates associated with the community (world: false) + bool is_member = 6; // Whether the receiving user is a member of the community + string community_name = 7; // Name of the community + optional string community_image = 8; // Image/picture of the community + repeated string worlds = 9; // World names associated with the community (world: true) +} + service SocialService { // Get the list of friends for the authenticated user - rpc GetFriends(GetFriendsPayload) returns (PaginatedUsersResponse) {} + rpc GetFriends(GetFriendsPayload) returns (PaginatedFriendsProfilesResponse) {} // Get the list of mutual friends between the authenticated user and the one in the parameter - rpc GetMutualFriends(GetMutualFriendsPayload) returns (PaginatedUsersResponse) {} + rpc GetMutualFriends(GetMutualFriendsPayload) returns (PaginatedFriendsProfilesResponse) {} // Get the pending friendship requests for the authenticated user rpc GetPendingFriendshipRequests(GetFriendshipRequestsPayload) returns (PaginatedFriendshipRequestsResponse) {} @@ -155,5 +631,81 @@ service SocialService { rpc SubscribeToFriendshipUpdates(google.protobuf.Empty) returns (stream FriendshipUpdate) {} + // Get the friendship status between the authenticated user and the one in the parameter rpc GetFriendshipStatus(GetFriendshipStatusPayload) returns (GetFriendshipStatusResponse) {} + + // Subscribe to connectivity updates of friends: ONLINE, OFFLINE, AWAY + rpc SubscribeToFriendConnectivityUpdates(google.protobuf.Empty) + returns (stream FriendConnectivityUpdate) {} + + rpc BlockUser(BlockUserPayload) returns (BlockUserResponse) {} + + rpc UnblockUser(UnblockUserPayload) returns (UnblockUserResponse) {} + + rpc GetBlockedUsers(GetBlockedUsersPayload) returns (GetBlockedUsersResponse) {} + + rpc GetBlockingStatus(google.protobuf.Empty) returns (GetBlockingStatusResponse) {} + + rpc SubscribeToBlockUpdates(google.protobuf.Empty) returns (stream BlockUpdate) {} + + // Get all the social settings for the authenticated user + rpc GetSocialSettings(google.protobuf.Empty) returns (GetSocialSettingsResponse) {} + + // Insert or update the social settings for the authenticated user + rpc UpsertSocialSettings(UpsertSocialSettingsPayload) returns (UpsertSocialSettingsResponse) {} + + // Get the private messages privacy settings for the requested users + rpc GetPrivateMessagesSettings(GetPrivateMessagesSettingsPayload) returns (GetPrivateMessagesSettingsResponse) {} + + // Subscribe to community member connectivity updates: ONLINE, OFFLINE + rpc SubscribeToCommunityMemberConnectivityUpdates(google.protobuf.Empty) + returns (stream CommunityMemberConnectivityUpdate) {} + + // Start a private voice chat + rpc StartPrivateVoiceChat(StartPrivateVoiceChatPayload) returns (StartPrivateVoiceChatResponse) {} + + // Accept a private voice chat + rpc AcceptPrivateVoiceChat(AcceptPrivateVoiceChatPayload) returns (AcceptPrivateVoiceChatResponse) {} + + // Reject a private voice chat + rpc RejectPrivateVoiceChat(RejectPrivateVoiceChatPayload) returns (RejectPrivateVoiceChatResponse) {} + + // End a private voice chat + rpc EndPrivateVoiceChat(EndPrivateVoiceChatPayload) returns (EndPrivateVoiceChatResponse) {} + + // Get the incoming private voice chat request + rpc GetIncomingPrivateVoiceChatRequest(google.protobuf.Empty) returns (GetIncomingPrivateVoiceChatRequestResponse) {} + + // Subscribe to private voice chat updates + rpc SubscribeToPrivateVoiceChatUpdates(google.protobuf.Empty) returns (stream PrivateVoiceChatUpdate) {} + + // Start a community voice chat (moderator/owner only) + rpc StartCommunityVoiceChat(StartCommunityVoiceChatPayload) returns (StartCommunityVoiceChatResponse) {} + + // Join a community voice chat + rpc JoinCommunityVoiceChat(JoinCommunityVoiceChatPayload) returns (JoinCommunityVoiceChatResponse) {} + + // Request to speak in community voice chat + rpc RequestToSpeakInCommunityVoiceChat(RequestToSpeakInCommunityVoiceChatPayload) returns (RequestToSpeakInCommunityVoiceChatResponse) {} + + // Promote speaker in community voice chat (moderator only) + rpc PromoteSpeakerInCommunityVoiceChat(PromoteSpeakerInCommunityVoiceChatPayload) returns (PromoteSpeakerInCommunityVoiceChatResponse) {} + + // Demote speaker in community voice chat (moderator only) + rpc DemoteSpeakerInCommunityVoiceChat(DemoteSpeakerInCommunityVoiceChatPayload) returns (DemoteSpeakerInCommunityVoiceChatResponse) {} + + // Kick player from community voice chat (moderator only) + rpc KickPlayerFromCommunityVoiceChat(KickPlayerFromCommunityVoiceChatPayload) returns (KickPlayerFromCommunityVoiceChatResponse) {} + + // Reject speak request in community voice chat (moderator only) + rpc RejectSpeakRequestInCommunityVoiceChat(RejectSpeakRequestInCommunityVoiceChatPayload) returns (RejectSpeakRequestInCommunityVoiceChatResponse) {} + + // End community voice chat (moderator/owner only) + rpc EndCommunityVoiceChat(EndCommunityVoiceChatPayload) returns (EndCommunityVoiceChatResponse) {} + + // Subscribe to community voice chat updates (only 'started' events) + rpc SubscribeToCommunityVoiceChatUpdates(google.protobuf.Empty) returns (stream CommunityVoiceChatUpdate) {} + + // Mute or unmute a speaker in a community voice chat + rpc MuteSpeakerFromCommunityVoiceChat(MuteSpeakerFromCommunityVoiceChatPayload) returns (MuteSpeakerFromCommunityVoiceChatResponse) {} } From 9179af1751d3b3fd2b76161aab6da603a945e03f Mon Sep 17 00:00:00 2001 From: "Mateo \"Kuruk\" Miccino" Date: Thu, 29 Jan 2026 10:58:20 -0300 Subject: [PATCH 33/43] Add timestamp field to PlayerEmote message --- proto/decentraland/kernel/comms/rfc4/comms.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/decentraland/kernel/comms/rfc4/comms.proto b/proto/decentraland/kernel/comms/rfc4/comms.proto index 83f098d3..3487e56c 100644 --- a/proto/decentraland/kernel/comms/rfc4/comms.proto +++ b/proto/decentraland/kernel/comms/rfc4/comms.proto @@ -69,6 +69,7 @@ message MovementCompressed { message PlayerEmote { uint32 incremental_id = 1; string urn = 2; + float timestamp = 3; } message SceneEmote { From de6a708785a88d7c761b4b452f17601a16fb1745 Mon Sep 17 00:00:00 2001 From: "Mateo \"Kuruk\" Miccino" Date: Thu, 29 Jan 2026 11:15:29 -0300 Subject: [PATCH 34/43] Add is_instant and is_emoting fields to Movement message Cherry-picked from experimental PR #279 (fix: emotes interpolation) --- proto/decentraland/kernel/comms/rfc4/comms.proto | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/proto/decentraland/kernel/comms/rfc4/comms.proto b/proto/decentraland/kernel/comms/rfc4/comms.proto index 3487e56c..88e44cfd 100644 --- a/proto/decentraland/kernel/comms/rfc4/comms.proto +++ b/proto/decentraland/kernel/comms/rfc4/comms.proto @@ -55,10 +55,11 @@ message Movement { bool is_long_jump = 12; bool is_long_fall = 13; bool is_falling = 14; - bool is_stunned = 15; - float rotation_y = 16; + // interpolation + bool is_instant = 17; + bool is_emoting = 18; } message MovementCompressed { From b658867b7ec6a89d2b10904dce3627ddfb3777b8 Mon Sep 17 00:00:00 2001 From: Lean Mendoza <8042536+leanmendoza@users.noreply.github.com> Date: Tue, 3 Feb 2026 19:35:57 -0300 Subject: [PATCH 35/43] add experimental avatar locomotion settings --- .../avatar_locomotion_settings.proto | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 proto/decentraland/sdk/components/avatar_locomotion_settings.proto diff --git a/proto/decentraland/sdk/components/avatar_locomotion_settings.proto b/proto/decentraland/sdk/components/avatar_locomotion_settings.proto new file mode 100644 index 00000000..a16f2169 --- /dev/null +++ b/proto/decentraland/sdk/components/avatar_locomotion_settings.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; + +option (common.ecs_component_id) = 1211; + +// The PBAvatarLocomotionSettings component allows scenes to modify locomotion settings defining things such +// as the avatar movement speed, jump height etc. +message PBAvatarLocomotionSettings { + optional float walk_speed = 1; // Maximum speed when walking (in meters per second) + optional float jog_speed = 2; // Maximum speed when jogging (in meters per second) + optional float run_speed = 3; // Maximum speed when running (in meters per second) + optional float jump_height = 4; // Height of a regular jump (in meters) + optional float run_jump_height = 5; // Height of a jump while running (in meters) + optional float hard_landing_cooldown = 6; // Cooldown time after a hard landing before the avatar can move again (in seconds) +} From a48721efb9b676efd0c27f6e06db6d699f5c9f10 Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Mon, 23 Feb 2026 14:03:52 +0000 Subject: [PATCH 36/43] Script based movement (#356) * add shapecast method * add avatar movement / info * bump ids * numbers are hard * ci * fix names, add to sdk-components * update ids < 2048 * add IA_MODIFIER * update comments --- .../sdk/components/avatar_movement.proto | 45 +++++++++++++++++++ .../sdk/components/avatar_movement_info.proto | 16 +++++++ .../sdk/components/common/input_action.proto | 1 + .../decentraland/sdk/components/raycast.proto | 13 ++++++ public/sdk-components.proto | 2 + 5 files changed, 77 insertions(+) create mode 100644 proto/decentraland/sdk/components/avatar_movement.proto create mode 100644 proto/decentraland/sdk/components/avatar_movement_info.proto diff --git a/proto/decentraland/sdk/components/avatar_movement.proto b/proto/decentraland/sdk/components/avatar_movement.proto new file mode 100644 index 00000000..27a3a7c6 --- /dev/null +++ b/proto/decentraland/sdk/components/avatar_movement.proto @@ -0,0 +1,45 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; +import "decentraland/common/vectors.proto"; + +option (common.ecs_component_id) = 1501; + +message PBAvatarMovement { + decentraland.common.Vector3 velocity = 1; + float orientation = 2; // 0-360, we don't allow pitch/roll + optional decentraland.common.Vector3 ground_direction = 3; +} + +// engine behaviour (uses only capsule shapecasts and GJK closest point for portability): +// 1: set avatar orientation from movement info -> P1 +// 2: record "ground collider" - nearest collider within threshold distance in ground_direction using avatar collider shapecast +// 3: update all colliders, record previous transform and new transform. +// 4: apply ground collider movement: take collider closest point, modify P1 translation and rotation by closest point translation and rotation change -> P2 +// 5: resolve collisions using position-based constraints +// initialize constraints to -inf, +inf +// repeat +// for each collider[i] that collides with the P3+N player: +// if closest point = capsule middle (i.e. collider collides with P3 collider but with radius 0), +// ignore / continue +// else +// update constraints based on minimum movement to escape collision +// e.g. if avatar is 1cm into the floor, constraint_min = max(constraint_min, vec3(0, 0.01, 0)) +// reposition player to satisfy constraints for each axis: +// y: satsify floor before ceiling: new position = max(constraint_min, min(constraint_max, current position)) +// x and z: if squashed, take average, else satisfy the required constraint +// if constraint_min > constraint_max then new position = average(constraint_min, constraint_max) +// else new position = clamp(current position, constraint_min, constraint_max) +// while position !~= previous position +// 6: apply velocity (collide and slide) +// disable anything we are initially colliding with +// shapecast avatar from position to position + velocity * timestep +// on impact: +// project velocity onto slide plane (standard "Collide & Slide") +// velocity = old velocity - (normal * dot(velocity, normal)) +// repeat continue with residual velocity and residual time +// 7: provide AvatarMovementInfo values +// actual velocity = (final - P3+N) / timestep +// external_velocity = (P3+N - P1) / timestep \ No newline at end of file diff --git a/proto/decentraland/sdk/components/avatar_movement_info.proto b/proto/decentraland/sdk/components/avatar_movement_info.proto new file mode 100644 index 00000000..e67a634d --- /dev/null +++ b/proto/decentraland/sdk/components/avatar_movement_info.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package decentraland.sdk.components; + +import "decentraland/sdk/components/common/id.proto"; +import "decentraland/common/vectors.proto"; + +option (common.ecs_component_id) = 1500; + +message PBAvatarMovementInfo { + float step_time = 1; // the length of time the current step velocity will apply for + float previous_step_time = 2; // the length of time the previous step velocity applied for + decentraland.common.Vector3 requested_velocity = 3; // the velocity requested for the previous frame + decentraland.common.Vector3 actual_velocity = 4; // the resulting velocity taking collisions into account + decentraland.common.Vector3 external_velocity = 5; // the velocity imparted by movement of the "ground" platform or pushing from other moving colliders +} diff --git a/proto/decentraland/sdk/components/common/input_action.proto b/proto/decentraland/sdk/components/common/input_action.proto index 661dd58e..283f2d7c 100644 --- a/proto/decentraland/sdk/components/common/input_action.proto +++ b/proto/decentraland/sdk/components/common/input_action.proto @@ -17,6 +17,7 @@ enum InputAction { IA_ACTION_4 = 11; IA_ACTION_5 = 12; IA_ACTION_6 = 13; + IA_MODIFIER = 14; } // PointerEventType is a kind of interaction that can be detected. diff --git a/proto/decentraland/sdk/components/raycast.proto b/proto/decentraland/sdk/components/raycast.proto index 5514bfb7..2896c041 100644 --- a/proto/decentraland/sdk/components/raycast.proto +++ b/proto/decentraland/sdk/components/raycast.proto @@ -45,6 +45,12 @@ message PBRaycast { // Collision mask, by default CL_POINTER | CL_PHYSICS optional uint32 collision_mask = 9; + + // shape to cast, default ray + optional RaycastShape shape = 11; + + // include hits with entities from other scenes + optional bool include_world = 12; } // RaycastQueryType indicates whether the ray should stop on the first collition, or continue. @@ -56,3 +62,10 @@ enum RaycastQueryType { // Do not perform the raycast, only set the raycast result with empty hits RQT_NONE = 2; } + +enum RaycastShape { + // cast a point, get collisions along a ray + RS_RAY = 0; + // cast the avatar collider shape, get collisions from sweeping the shape + RS_AVATAR = 1; +} \ No newline at end of file diff --git a/public/sdk-components.proto b/public/sdk-components.proto index 5169aed0..466b46a1 100644 --- a/public/sdk-components.proto +++ b/public/sdk-components.proto @@ -9,6 +9,8 @@ import public "decentraland/sdk/components/avatar_base.proto"; import public "decentraland/sdk/components/avatar_emote_command.proto"; import public "decentraland/sdk/components/avatar_equipped_data.proto"; import public "decentraland/sdk/components/avatar_modifier_area.proto"; +import public "decentraland/sdk/components/avatar_movement.proto"; +import public "decentraland/sdk/components/avatar_movement_info.proto"; import public "decentraland/sdk/components/avatar_shape.proto"; import public "decentraland/sdk/components/billboard.proto"; import public "decentraland/sdk/components/camera_mode_area.proto"; From 8e3097024cd83ae7dfb871b588f765e2c470798d Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Mon, 2 Mar 2026 12:35:18 +0000 Subject: [PATCH 37/43] add active modifiers and locomotion settings (#361) --- proto/decentraland/sdk/components/avatar_movement_info.proto | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proto/decentraland/sdk/components/avatar_movement_info.proto b/proto/decentraland/sdk/components/avatar_movement_info.proto index e67a634d..1e9f7f77 100644 --- a/proto/decentraland/sdk/components/avatar_movement_info.proto +++ b/proto/decentraland/sdk/components/avatar_movement_info.proto @@ -4,6 +4,8 @@ package decentraland.sdk.components; import "decentraland/sdk/components/common/id.proto"; import "decentraland/common/vectors.proto"; +import "decentraland/sdk/components/avatar_locomotion_settings.proto"; +import "decentraland/sdk/components/input_modifier.proto"; option (common.ecs_component_id) = 1500; @@ -13,4 +15,6 @@ message PBAvatarMovementInfo { decentraland.common.Vector3 requested_velocity = 3; // the velocity requested for the previous frame decentraland.common.Vector3 actual_velocity = 4; // the resulting velocity taking collisions into account decentraland.common.Vector3 external_velocity = 5; // the velocity imparted by movement of the "ground" platform or pushing from other moving colliders + decentraland.sdk.components.PBAvatarLocomotionSettings active_avatar_locomotion_settings = 6; + decentraland.sdk.components.PBInputModifier active_input_modifier = 7; } From b829b38e1b41f5db266d9b8a922977f7484d2ea2 Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Mon, 2 Mar 2026 13:31:45 +0000 Subject: [PATCH 38/43] update camera layer component id (#364) --- proto/decentraland/sdk/components/camera_layer.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/decentraland/sdk/components/camera_layer.proto b/proto/decentraland/sdk/components/camera_layer.proto index 6c648801..e6efc0c3 100644 --- a/proto/decentraland/sdk/components/camera_layer.proto +++ b/proto/decentraland/sdk/components/camera_layer.proto @@ -5,7 +5,7 @@ package decentraland.sdk.components; import "decentraland/sdk/components/common/id.proto"; import "decentraland/common/colors.proto"; -option (common.ecs_component_id) = 1211; +option (common.ecs_component_id) = 1503; message PBCameraLayer { // layer to which these settings apply. must be > 0 From 14f756d2b9a3db444cddd2b29118956368906b75 Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Tue, 10 Mar 2026 18:19:46 +0000 Subject: [PATCH 39/43] add WalkPlayerTo RPC and walk fields to movement components (#374) - Add WalkPlayerTo RPC to RestrictedActionsService with position, stop_threshold and optional timeout - Add walk_target and walk_threshold fields to PBAvatarMovementInfo (engine -> scene) - Add walk_success optional bool to PBAvatarMovement (scene -> engine, set for one frame on completion) --- .../kernel/apis/restricted_actions.proto | 18 +++++++++++++++++- .../sdk/components/avatar_movement.proto | 3 ++- .../sdk/components/avatar_movement_info.proto | 2 ++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/proto/decentraland/kernel/apis/restricted_actions.proto b/proto/decentraland/kernel/apis/restricted_actions.proto index 5fe63d9f..fb8bc648 100644 --- a/proto/decentraland/kernel/apis/restricted_actions.proto +++ b/proto/decentraland/kernel/apis/restricted_actions.proto @@ -48,7 +48,17 @@ message SuccessResponse { message TriggerEmoteResponse { } -message MovePlayerToResponse { +message MovePlayerToResponse { + bool success = 1; +} + +message WalkPlayerToRequest { + decentraland.common.Vector3 new_relative_position = 1; + float stop_threshold = 2; + optional float timeout = 3; // max seconds before the request is failed; not passed to the movement scene +} + +message WalkPlayerToResponse { bool success = 1; } @@ -79,6 +89,12 @@ service RestrictedActionsService { // whole interpolation being completed or interrupted (e.g: by input movement) rpc MovePlayerTo(MovePlayerToRequest) returns (MovePlayerToResponse) {} + // WalkPlayerTo will walk the player to a position relative to the current scene, + // managed by the movement controller scene. Returns success when the player reaches + // within stop_threshold distance, or false if the path is blocked, the player gets + // stuck, the player interrupts the walk with manual input, or the optional timeout expires. + rpc WalkPlayerTo(WalkPlayerToRequest) returns (WalkPlayerToResponse) {} + // TeleportTo will move the user to the specified world LAND parcel coordinates rpc TeleportTo(TeleportToRequest) returns (TeleportToResponse) {} diff --git a/proto/decentraland/sdk/components/avatar_movement.proto b/proto/decentraland/sdk/components/avatar_movement.proto index 27a3a7c6..74851531 100644 --- a/proto/decentraland/sdk/components/avatar_movement.proto +++ b/proto/decentraland/sdk/components/avatar_movement.proto @@ -9,8 +9,9 @@ option (common.ecs_component_id) = 1501; message PBAvatarMovement { decentraland.common.Vector3 velocity = 1; - float orientation = 2; // 0-360, we don't allow pitch/roll + float orientation = 2; // 0-360, we don't allow pitch/roll optional decentraland.common.Vector3 ground_direction = 3; + optional bool walk_success = 4; // set for one frame when a walk_target ends: true = reached target, false = failed; absent = in progress or no walk } // engine behaviour (uses only capsule shapecasts and GJK closest point for portability): diff --git a/proto/decentraland/sdk/components/avatar_movement_info.proto b/proto/decentraland/sdk/components/avatar_movement_info.proto index 1e9f7f77..bb9e006a 100644 --- a/proto/decentraland/sdk/components/avatar_movement_info.proto +++ b/proto/decentraland/sdk/components/avatar_movement_info.proto @@ -17,4 +17,6 @@ message PBAvatarMovementInfo { decentraland.common.Vector3 external_velocity = 5; // the velocity imparted by movement of the "ground" platform or pushing from other moving colliders decentraland.sdk.components.PBAvatarLocomotionSettings active_avatar_locomotion_settings = 6; decentraland.sdk.components.PBInputModifier active_input_modifier = 7; + optional decentraland.common.Vector3 walk_target = 8; // if set, the movement scene should walk the player to this scene-relative position + optional float walk_threshold = 9; // stop distance for walk_target; considered reached when within this distance } From ba53eb07fb2f7f1b4e4b978fffedd98a9abda3da Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Mon, 27 Apr 2026 17:47:43 +0100 Subject: [PATCH 40/43] feat(ui_input): add multi_line flag to PBUiInput (#394) --- proto/decentraland/sdk/components/ui_input.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/decentraland/sdk/components/ui_input.proto b/proto/decentraland/sdk/components/ui_input.proto index 33dac448..5ef2960f 100644 --- a/proto/decentraland/sdk/components/ui_input.proto +++ b/proto/decentraland/sdk/components/ui_input.proto @@ -17,4 +17,5 @@ message PBUiInput { optional common.Font font = 11; // default=0 optional int32 font_size = 12; // default=10 optional string value = 13; + optional bool multi_line = 14; // default=false; when true, the input accepts newlines and behaves as a textarea } \ No newline at end of file From 767845ec17fea55379461c48fc6f4a6cdb7b219e Mon Sep 17 00:00:00 2001 From: Mateo Miccino Date: Tue, 12 May 2026 13:49:52 -0300 Subject: [PATCH 41/43] feat: add screen_inset_area to PBUiCanvasInformation (cherry-pick of #399) (#400) * feat: add screen_inset_area to PBUiCanvasInformation Exposes the device safe-area insets (notch, status bar, home indicator, rounded corners, etc.) to scenes so that mobile UIs can be laid out without being occluded. On desktop this is typically (0, 0, 0, 0). * feat: mark screen_inset_area as optional makes the field's optionality explicit at the proto level so consumers read it as a presence-tracked, opt-in value (renderers may not always report it). --- .../decentraland/sdk/components/ui_canvas_information.proto | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proto/decentraland/sdk/components/ui_canvas_information.proto b/proto/decentraland/sdk/components/ui_canvas_information.proto index f2e84e97..5dd10cf6 100644 --- a/proto/decentraland/sdk/components/ui_canvas_information.proto +++ b/proto/decentraland/sdk/components/ui_canvas_information.proto @@ -21,4 +21,10 @@ message PBUiCanvasInformation { // chat UI hidden and with no minimap could have a rect that covers the whole screen. // on the contrary, if the chat UI is shown, the rect would be smaller. decentraland.common.BorderRect interactable_area = 4; + // informs the sdk about the screen inset area (safe margins). these are the + // insets from each edge of the screen that are reserved by the device or + // platform UI (for example: the notch, status bar, home indicator, or rounded + // corners on mobile). scenes should avoid placing critical UI within these + // insets to ensure it is not occluded. on desktop this is typically (0, 0, 0, 0). + optional decentraland.common.BorderRect screen_inset_area = 5; } From a9f7d8143229cc72ea3fe87bb0b12e0833e22384 Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Tue, 12 May 2026 18:35:55 +0100 Subject: [PATCH 42/43] feat(ui_input): add clear_on_submit flag to PBUiInput (#404) --- proto/decentraland/sdk/components/ui_input.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/decentraland/sdk/components/ui_input.proto b/proto/decentraland/sdk/components/ui_input.proto index 5ef2960f..d32dfdd2 100644 --- a/proto/decentraland/sdk/components/ui_input.proto +++ b/proto/decentraland/sdk/components/ui_input.proto @@ -18,4 +18,5 @@ message PBUiInput { optional int32 font_size = 12; // default=10 optional string value = 13; optional bool multi_line = 14; // default=false; when true, the input accepts newlines and behaves as a textarea + optional bool clear_on_submit = 15; // default=true; when false, the input value is preserved after pressing Enter } \ No newline at end of file From 72201f0b99443bdf4f087c146e719d8bd65169a0 Mon Sep 17 00:00:00 2001 From: Gon Pombo Date: Wed, 20 May 2026 11:44:43 -0300 Subject: [PATCH 43/43] feat: add AMT_HIDE_NAMETAGS to AvatarModifierType (#406) --- proto/decentraland/sdk/components/avatar_modifier_area.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/proto/decentraland/sdk/components/avatar_modifier_area.proto b/proto/decentraland/sdk/components/avatar_modifier_area.proto index 38be8e3d..81cdbf6a 100644 --- a/proto/decentraland/sdk/components/avatar_modifier_area.proto +++ b/proto/decentraland/sdk/components/avatar_modifier_area.proto @@ -31,6 +31,7 @@ message PBAvatarModifierArea { enum AvatarModifierType { AMT_HIDE_AVATARS = 0; // avatars are invisible AMT_DISABLE_PASSPORTS = 1; // selecting (e.g. clicking) an avatar will not bring up their profile. + AMT_HIDE_NAMETAGS = 2; // the name tag displayed above an avatar is hidden. } message AvatarMovementSettings {