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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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/39] 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 }