decentraland / adr Goto Github PK
View Code? Open in Web Editor NEWArchitecture Decisions Records
Home Page: https://adr.decentraland.org/
License: Other
Architecture Decisions Records
Home Page: https://adr.decentraland.org/
License: Other
layout: adr
adr: 231
title: Voting Power Tracking for Marketplace Saved Items
date: 2023-05-09
status: Idea
type: Standards Track
spdx-license: CC0-1.0
authors:
This document outlines the guidelines for counting the number of users who have saved an item in the Marketplace. The approach adopted is similar to the one used in Places for determining the highest-rated percentage of upvotes and downvotes from users with specific Voting Power. However, it has been adapted to meet the needs of the recently launched Marketplace Lists feature.
Previously, users of the Decentraland Marketplace needed an option to save items for future reference, leading to missed opportunities for creators and potential customers. The Marketplace Lists feature was introduced to tackle this problem, enabling users to easily create and manage lists of items they plan to save for later and offering a gamified experience.
To improve accuracy and empower community members, a Voting Power criterion has been introduced for calculating the number of users who have saved an item in a list, ensuring a more precise count of saved items.
The strategy employed in Places has been adapted to the new feature requirements. When a new item is added to the list, the user's Voting Power (VP) is retrieved from the Snapshot platform and stored for future use. Then, the number of times an item has been added to a list only considers users with a specific VP.
One potential drawback of this method is that users may transfer their assets to a new account and re-add an item to the list with the same Voting Power, as it is only recorded once an item is added. As a result, this could cause the count for that item to be artificially inflated, as the same assets would be counted twice when retrieving the VP, resulting in an inaccurate count.
The guidelines mentioned above were introduced on May 4, 2023.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
This is a follow up issue to discuss and continue adding comments to the RFC-14.
It describes:
Although the first may be sound in the void, RFC-4 describes that all communications inside a room/island/adapter are designed to be broadcasted. Rendering the routing logic pointless. And adding a fallback to begin with seems like starting with the wrong foot.
This issue is to challenge to get to a problem to fix, before proposing a solution.
A proposal to frame the problem would be:
Decentraland communication adapters are varied in capabilities and costs (from WebSockets, to Livekit to name a few.) but a low-cost solution that works everywhere is still needed. The current version of "comms" uses an P2P incomplete mesh with gossip replication of messages to achieve pseudo full-mesh capabilities. One of the identified problems with this incomplete mesh is that the organization of the connections may lead to local clusters which play against the intended design. That is so, because connections are created at random and refreshed at high intervals (within the 10s seconds).
Statement of the problem:
Find a P2P adapter that enables lightweight (cheap) communications in incomplete meshes, to work as fallback when all other adapters are not available.
- It must require no extra fallback services (besides STUN, TURN and signaling, which are needed to fully support WebRTC)
- It must ensure that the connections don't form local clusters
- It must ensure that there are bi-directional communication paths between any A and B peers in the mesh
- It should prioritize to always have short paths (fewer than X hops) between any A and B peers in meshes of 100 peers
- The overhead traffic of the protocols (signaling, message metadata, synchronization messages) should be minimum
Metrics for success:
- Ping responses. In any given mesh of N known peers, a Ping message should receive N responses before the 10second mark (this interval should lower with the evolution of the protocol). Store this number in a histogram to track progress.
layout: adr
adr: 144
title: Realm resolution from connection string
date: 2022-12-13
status: Review
type: Standards Track
spdx-license: CC0-1.0
authors:
This document describes the Realm resolution algorithms to consistently resolve servers based on a realm connection string. It resembles DNS, and uses the DAO catalysts, ENS and URLs to resolve the realms as described in ADR-110.
Realms (ADR-110) are the configurations that define what and how is executed and rendered in a Decentraland Explorer ADR-102. If we reason by analogy and consider an Explorer like a Web Browser, and the Scenes like WebSites. Then the Realm is the URL of that site.
Realm are represented as strings. Those strings need to be resolved to a /about
endpoint to fetch the configuration.
The mechanism to resolve that endpoint is:
https://peer.decentraland.org/about
dcl.realm
TXT values
.dcl.eth
subdomain, then it falls back to the Worlds resolverNAME and ENS holders can decide where their worlds are hosted. For that purpose, a special record dcl.realm
can be added both to ENS and NAME tokens and it should resolve to a base URL that is compliant with the Realm specification (ADR-110)
Worlds is a configuration of services that enable deploying Decentraland scenes using NAME, as described in ADR-111. To resolve Worlds, an URL in the shape of https://worlds-content-server.decentraland.org/world/<NAME>.dcl.eth
is used, the /about
response is compliant with the Realm specification (ADR-110)
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Document the decision behind adopting React for UIs
In order to facilitate communication between the renderer and the scenes, a special number of reserved entities are needed. These entities hold no special logic compared to other entities, but they have static IDs that systems can use to share information about the renderer, player, camera, etc.
Decision
We will reserve 512 static entities numbers, starting at 0. The "0" entity will be the root entity of the scenes, and all other entities will be parented to it by default.
List of static entities per scene
RootEntity = 0
: It is the root of the scene.
SceneInformation
component (READ ONLY) of the root entity has the scene metadata (scene.json), the content mappings, and the scene id.ForeignEntitiesFrom { names: string[] }
component is set from the scene itself and is used to signal the renderer about Foreign entity replication policies.ForeignEntitiesReservation { name: string, from: Entity, to: Entity }
component is used to signal the renderer (or other actors) that this scene CAN share its entities as ForeignEntities.LoadingState { status = LOADING/RUNNING/PAUSED }
component is set by the renderer.CommsState
component is set by the kernel and used to query information about the current Comms connection (including realm).PlayerEntity = 1
: Represents the current player avatar.
Transform
component is READ/WRITE from the scene.PlayerPortableExperiences
component (READ ONLY) contains information about the current portable experiences run by the user.PlayerIdentity
component (READ ONLY) contains information about the Ethereum address, guest mode, and names of the player.AvatarShape
component (READ ONLY) contains information about the wearables, hair, eyes and skin colors, and the equipped wearables.CameraEntity = 2
:
Transform
component is READ ONLY from the scene.PointerLocked
component (READ ONLY) presence signals the status of the pointer-locking of the renderer.CameraMode { mode = ThirdPerson/FirstPerson }
component is used to get the current camera mode; it is only set from the Renderer.By reserving a fixed number of static entities and assigning specific roles to them, we simplify the renderer-scene communication. This decision will make it easier for systems to share information about the renderer, player, camera, etc.
However, it is important to note that some of the components mentioned above are still TBD and may be subject to future revisions.
adr: 130
title: Scene Compiler & Global variables SDK7
date: 2022-11-15
status: Idea
type: Standards Track
spdx-license: CC0-1.0
authors:
This document describes the approach used to define which global variables are exposed in the SDK7, and how the scenes should be compiled in order to optimize the bundle of the scene.
In the previous SDK, we had exposed a lot of global variables and they were bundled inside the ECS.
This is a problem for the final bundle size because even if you don't use any of that vars, they will be compiled inside the scene.
An example of this is the ecs-math library. We should import the vars that we want to use, and compile them only if we are using it (Tree Shaking).
Also we need to remove the AMD loader when we compile the scene, and use esbuild so we can enable tree shaking.
Tree shaking is a term to describe the removal of dead code.
Right now if you import a library inside your scene but you don't use a single line of that library, your scene will be bundled with the entire library code. Meaning a lot of extra kb that are not necessary.
Our current build tools for the web are 10-100x slower than they could be. The main goal of the esbuild bundler project is to bring about a new era of build tool performance, and create an easy-to-use modern bundler along the way.
Use esbuild to compile the scenes in order to optimize the final bundle size with tree shaking, and deprecate the current amd loader we have.
This was really useful but we reach a point were we need to improve the way the scenes are bundled. We are going to deliver a lot of new features, and systems inside our sdk-library and we need that the bundle size of the scenes contains only the code that is being used, instead of the entire library.
Remove unnecessary global vars that are exposed and bundled inside the SDK7.
We should export only the engine and the baseComponents as global variables of the scene.
Currently in the SDK7 we are importing the @dcl/ecs-math
library and exporting all the vars as global variables.
This means that your scene will have all the @dcl/ecs-math code even if you don't use a single line of code.
We should remove all the ecs-math library and expose it as an external library, just like we do with @dcl/react-ecs
// game.ts
import { Vector3, Color3 } from '@dcl/ecs-math'
Transform.create(someEntity, { position: Vector3.create(0, 0, 0) } )
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Document the technical changes in the avatar assembly system and overrides.
layout: adr
adr: 153
title: Semantics of entity parenting with ECS-compatible semantics
date: 2022-12-14
status: Living
type: Standards Track
spdx-license: CC0-1.0
authors:
This document describes the semantics of changing parenting of entities and what happens when an entity in the middle of a branch of the tree is removed. The problem is complex because in an ECS approach, entities are stored in a flat structure, and trees are a synthetic construct for positioning purposes only. The decision is that when an entity in the middle of a branch is removed, all its children will be re-parented to the root entity.
Transform
component doesn't exist in an entity, it is assumed that the entity has a scale={1,1,1}
Transform
component has the same rendering semantics than an entity with a Transform.Identity
Transform.Identity
by default.Transform.Identity
componentAfter creating and emparenting entities with explicit transform in the form:
ROOT_ENTITY
└── A
└── B
└── C
└── D
└── E
└── F
Transform
component from entity D, the engine should assume entity D has a Transform.Identity
component.Transform.Identity
component has parent=ROOT_ENTITY
, the rendering tree now looks like:ROOT_ENTITY
├── A
│ └── B
│ └── C
└── D
└── E
└── F
Appendix
Transform.Identity = {
scale = {1,1,1}
position = {0,0,0}
rotation = {0,0,0,1}
parent = ROOT_ENTITY
}
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
adr: 125
title: User interface components for SDK 7
date: 2022-11-14
status: Idea
type: Standards Track
spdx-license: CC0-1.0
authors:
This specification covers an initial set of components of the SDK to create flexbox-based user interfaces. The components only describe behavior and configuration skipping position and sizing, that is considered layouting and is given by the UiTransform component from ADR-124.
... initial elements required for feature parity ...
PointerEvents
componentWe are going to reuse the existing PointerHoverFeedback component, but with another name (HoverFeedback is not the most accurate name IMO).
We are going to use this component to tell the renderer which entities are going to be clickable/hover, etc.
enum PointerEventType {
PET_UP = 0;
PET_DOWN = 1;
PET_HOVER_ENTER = 2;
PET_HOVER_LEAVE = 3;
}
// We can talk about this name
message PBPointerEvents {
message Info {
optional common.InputAction button = 1; // default=InputAction.ANY
optional string hover_text = 2; // default='Interact'
optional float max_distance = 3; // default=10
optional bool show_feedback = 4; // default=true
}
message Entry {
PointerEventType event_type = 1;
Info event_info = 2;
}
repeated Entry pointer_events = 1;
}
PointerEventsResult
componentWe are going to use the same component that we are currently using for 3D objects, so we can reuse the same logic and we dont to manage multiple messages that does the same.
This pointerEventResult message has a lot of props that we are not going to use inside the Hit prop, but since they can all be undefined, we can only send the entity and it'll be ok.
message PBPointerEventsResult {
// a list of the last N pointer commands (from the engine)
repeated PointerCommand commands = 1;
// this message represents a pointer event, used both for UP and DOWN actions
message PointerCommand {
common.InputAction button = 1; // identifier of the input
RaycastHit hit = 2;
PointerEventType state = 4;
int32 timestamp = 5; // could be a Lamport timestamp
optional float analog = 6; // if the input is analog then we store it here
}
}
UiText
componentTo all extents, it is a reusable label for the UI.
message PBUiText {
string value = 1;
optional decentraland.common.Color4 color = 2; // default=(1.0,1.0,1.0,1.0)
TextAlignMode text_align = 3;
Font font = 4; // default=0 - SansSerif
optional int32 font_size = 5; // default=10
}
UiBackground
componentSets the background of a UI element. By default it has a transparent color. It can specify a 9-slices texture. When a texture and a color are specified, the color multiplies the texture to enable easy customization of UI elements in different states i.e. active, focused, highlighted.
message PBUiBackground {
// default=(0.0, 0.0, 0.0, 0.0)
optional decentraland.common.Color4 color = 1;
// texture for the background
optional Texture texture = 2;
// texture mode
BackgroundTextureMode texture_mode = 3;
// texture_slices, represents the top | right | bottom | left sizes of the
// slices for the borders. values are percentages of the texture.
// default=(1/3,1/3,1/3,1/3)
optional Rect texture_slices = 4;
// when STRETCH is selected, the uvs are configurable
// default=default plane uvs
optional repeated float uvs = 5;
}
enum BackgroundTextureMode {
// https://docs.unity3d.com/Manual/9SliceSprites.html
// https://developer.mozilla.org/en-US/docs/Web/CSS/border-image-slice
// https://forum.unity.com/threads/how-does-slicing-in-ui-tookkit-works.1235863/
NINE_SLICES = 0; (default)
// CENTER enables the texture to be rendered centered in relation to the
// element. If the element is smaller than the texture then the background
// should use the element as stencil to cut off the out-of-bounds area
CENTER = 1;
// STRETCH enables the texture to cover all the area of the container,
// adopting its aspect ratio. It takes the UVs from the uvs field
STRETCH = 2;
}
UiButton
componentUiButton can be implemented with a UiText+UiTransform+UiBackground
to start.
UiInput
UiInput adds an editable behavior to the UiEntity. By default it can render a placeholder label.
message UiInput {
// placeholder text
optional string placeholder = 1;
// color of the text
// default=(0.0,0.0,0.0,1.0)
optional decentraland.common.Color4 color = 2;
// color of the placeholder text
// default=(0.3,0.3,0.3,1.0)
optional decentraland.common.Color4 placeholder_color = 3;
// makes it non-interactable
bool disabled = 4;
// text align
TextAlignMode text_align = 10;
// font family default=0 - SansSerif
Font font = 11;
// font size default=10
optional int32 font_size = 12;
}
message UiInputResult {
string value = 1
// Maybe we can add some state info of the input here such as Focused/Selected etc ?
}
message UiDropdown {
// does this accept an empty selection?
// a.k.a "null" state
bool accept_empty = 1;
// placeholder for "null" state
optional string empty_label = 2;
// list of strings
repeated string options = 3;
// default=-1 when accept_empty==true
// default=0 when accept_empty==false
int32 selected_index = 4;
// makes it non-interactable
bool disabled = 4;
// text align
TextAlignMode text_align = 10;
// font family default=0 - SansSerif
Font font = 11;
// font size default=10
optional int32 font_size = 12;
}
message UiDropdownResult {
int32 value = 1
}
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
layout: adr
adr: 175
title: Remove assets from Renderer's build
date: 2023-01-16
status: Idea
type: ADR
spdx-license: CC0-1.0
authors:
This document describes an approach on how to make the reference's client lightweight by streaming the currently embedded assets.
Every nice UI, sound effect, particle or material we add to the renderer increases its size. This directly impact loading times or caching since the client's size will go above the max allowed for it. The idea is to pack textures and audio files and stream them in runtime.
Similar to what we are doing with scene assets, we can pack everything into one or multiple (to always be under the cache size limit) asset packs to be consumed by the client. This solution should be part of a different system than the one used for scene assets; therefore we can evaluate using an alternative like Addressables for consuming the assets.
Regardless of the bundling approach, a CI job (within the same pipeline) can be developed as a part of the building process. It would take the assets, pack them and upload them to the server.
Currently the renderer is a self-contained experience; to run any renderer you just need a compatible kernel and catalyst; it should be the same for the assets packs.
A handful of solutions can be implemented to ensure that a version of the Renderer consumes its asset packs counterpart. All of them would require versioning the packs so the client can distinguish them by name/endpoint/path. At building time a manifest with this information can be placed in StreamingAssets to be consulted in runtime.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
layout: adr
adr:
title: Add favorite places
date: 2023-01-31
status: Idea
type: ADR
spdx-license: CC0-1.0
authors:
This document describes an approach on how to integrate the new Favorite Places functionality in Decentraland.
To enhance the discoverability of the different Decentraland places, there is the need of adding a favorite mechanism. This will allow user to store and retrieve easily a set of their best loved places.
To integrate this changes at multiple levels are required, from the visual representation in the explorer, to the backend structure that will allow the saving and retrieving of a user favorites.
Following a list of the expected functionalities:
In a future iteration it will be possible to favorite places from the minimap HUD and also from the map parcel info pop-up, currently not possible due to technical limitations of the renderer map handling and Places API restriction to curated places.
More in the limitations section.
After an initial discussion about whether to store favorites in the user profile or in Places, we are more incline to store everything in Places, more informations about the decision journey at the end.
The Places API will need to add three new endpoints:
In additon a change will be required in the current place data structure in order to show the favorite information in the explore places list with a boolean.
To facilitate the addition of the feature when handling favorites we should use the same data structure currently used for Places, with the boolean addition previously mentioned:
public class Realm
{
public string serverName;
public string layer;
public int usersCount;
public int maxUsers;
public Vector2Int[] userParcels;
}
public string id;
public string name;
public string creator;
public string description;
public string thumbnail;
public Vector2Int baseCoords;
public Vector2Int[] parcels;
public int usersTotalCount;
public bool isPOI;
public Realm[] realms;
With the current functionalities provided by the Places website it is not possible to favorite all the Decentraland areas due to a restriction that allows only curated Places to be displayed. This together with a legacy code integration of the map in the unity renderer will allow the favorite functionality to be applied only in the places section in the explore menu.
In the initial iteration it has been discussed where to store the favorite list, the two options were storing them in the user profile or storing them in Places, the following PROs and CONs made us lean towards the Places option:
In addition, because currently unity-renderer doesn't communicate directly with the Places API, it has been thought that the missing endpoints will be contacted with the old kernel request system, in order to avoid blocking the development of this new functionality until the authentication system and request handling is transferred to the unity renderer.
This ADR describes the mechanisms used to authenticate and validate HTTP requests. It presents different alternatives and decides to use the AuthChain mechanism since it is compatible with with digital signature algorithm used in EVM compatible schemas and it inherits the same capabilities as other mechanisms with the addition of signed headers and payloads.
Write a Standard Track ADR documenting the architecture deccisions implemented in the reference client to check entities and meshes against their scene bounds and how the client reacts to that (preview and production).
Tackled at #193
layout: adr
adr: 239
title: Avatar Assembly Changes
date: 2023-05-23
status: Draft
type: Standards Track
spdx-license: CC0-1.0
authors:
@davidejensen @olavra
Previously, the avatar system has been unreliable and limited over different aspects.
To increase users freedom, create a reliable, flexible and scalable system the following changes will be applied:
The different decisions will become the standard base for Decentraland Avatar Assembly System, initially applied in the unity reference client, but then proposed to any external platform that uses the Decentraland avatars.
Previously the hiding and replacing functionality was following a rule of "Last equipped", meaning that replaces and hides were applied based on the last wearable equipped, creating discrepancy and an inconsistent behaviour. Additionally it was not solving situations of mutual hiding (wearable A hiding B and B hiding A)
To standardize this an ordered list of categories will be followed to calculate which wearables are hiding which.
The proposed priority list is (from most important to least):
All elements associated with the face, such as the mouth, eyes, and eyebrows, directly depend on the visualization of the head. The head is not a wearable itself, so it cannot create circular references, and it is hidden as soon as one or more wearables determine it.
The following example illustrates the expected behavior: If a wearable of type "Mask" hides another wearable of type "Hat", and this in turn hides wearables of type "Mask", the wearable of type "Mask" will have visualization priority, hiding the Mask.
The current result of equipping an item that replaces or hides other wearables is unexpected and inconsistent. When a player navigates through their inventory items, as they equip, unequip, or hide other wearables from other categories without notice, they cannot reverse this behavior when equipping a different wearable.
When a wearable unequips another wearable, the latter could be running a portable experience. By deactivating it, any progress or data in memory could be lost, ruining its expected behavior.
The decision-making capacity of creators is overlapping with the freedom of choice of players. When a player purchases a wearable, thinking it will combine well with what they already have in their inventory, they may be unpleasantly surprised that these are not compatible. Information about which other wearables are replaced or hidden is not clearly indicated in the marketplace or backpack.
There is no real weighty reason for a wearable to unequip another wearable, instead of hiding it to prevent clipping problems.
On the base of that the replacing functionality for new wearables will be removed, pre-existing wearables will see the replacing list being merged with the hiding list.
Previously, by unequipping the upper_body, the lower_body, the feet or the eyebrows, caused the system to fallback to default wearables (t-shirt, pants and shoes).
This prevents, for example, players from going barefoot or without t-shirt.
The system will extent the concept of Body by removing the default fallback wearables.
These pieces, which can be called "Bare feet", "Naked Top" and "Naked Bottom", are not considered wearables, but rather parts of the base body geometry that are exclusively displayed when no wearables are equipped and there are no other wearables hiding the relevant category.
The base body geometry and textures will change to make them more suitable for an environment for all audiences.
To extend further players ability to use the wearables they have in all their glory. If an equipped wearable is hidden by the effect of another wearable, players can unhide them and override this instruction.
This forced render effect is removed as soon as another wearable that re-hides that category is equipped, forcing the user to show it again.
In order to store the force render categories, it is proposed to add a new field to the player profile holding a list of overridden hide categories.
This list of string will hold the current overridden categories so that each player can render other players (and itself) according to the new rules.
As an example:
"forceRender": ["mask","top_head","feet"]
This example means that when the avatar is going to be assembled the "mask", "top_head" and "feet" categories will be shown even if other wearables are hiding them.
Here's the avatar definition with the additional forceRender field that will be provided:
{
"timestamp":1684839566179,
"avatars":[
{
"hasClaimedName":true,
"description":"",
"tutorialStep":256,
"name":"Username",
"avatar":{
"bodyShape":"urn:decentraland:off-chain:base-avatars:BaseMale",
"wearables":[
"urn:decentraland:off-chain:base-avatars:eyebrows_00",
"urn:decentraland:off-chain:base-avatars:mouth_00",
"urn:decentraland:off-chain:base-avatars:casual_hair_01",
"urn:decentraland:off-chain:base-avatars:beard",
"urn:decentraland:matic:collections-v2:0xc11b9d892e12cfaca551551345266d60e9abff6e:1",
"urn:decentraland:matic:collections-v2:0x84a1d84f183fa0fd9b6b9cb1ed0ff1b7f5409ebb:5",
"urn:decentraland:ethereum:collections-v1:halloween_2020:hwn_2020_ghostblaster_tiara",
"urn:decentraland:ethereum:collections-v1:halloween_2020:hwn_2020_cat_eyes",
"urn:decentraland:off-chain:base-avatars:piratepatch",
"urn:decentraland:matic:collections-v2:0xca7c347ffdeee480092f3b1268550b60ea031077:4",
"urn:decentraland:matic:collections-v2:0x2a3a6d0c92b18102ed189233976c974473a59c87:0"
],
"forceRender":["mask","top_head","feet"]
"emotes":[
{
"slot":0,
"urn":"raiseHand"
},
{
"slot":1,
"urn":"urn:decentraland:matic:collections-v2:0x167d6b63511a7b5062d1f7b07722fccbbffb5105:0"
},
{
"slot":2,
"urn":"urn:decentraland:matic:collections-v2:0x875146d1d26e91c80f25f5966a84b098d3db1fc8:1"
},
{
"slot":3,
"urn":"urn:decentraland:matic:collections-v2:0x875146d1d26e91c80f25f5966a84b098d3db1fc8:2"
},
{
"slot":4,
"urn":"urn:decentraland:matic:collections-v2:0x875146d1d26e91c80f25f5966a84b098d3db1fc8:0"
},
{
"slot":5,
"urn":"headexplode"
},
{
"slot":6,
"urn":"tektonik"
},
{
"slot":7,
"urn":"clap"
},
{
"slot":8,
"urn":"handsair"
},
{
"slot":9,
"urn":"dance"
}
],
"snapshots":{
"body":"https://interconnected.online/content/contents/bafkreihhwboio77zsl6evt6i3f5iun5ek65w7dyuvl44xwk33zts4qx2v4",
"face256":"https://interconnected.online/content/contents/bafkreiddnf2ixknlhio4hk7ao47agiwkqs43cg3nkoyibckgmhz5iqn3he"
},
"eyes":{
"color":{
"r":0.529411792755127,
"g":0.501960813999176,
"b":0.47058823704719543,
"a":1
}
},
"hair":{
"color":{
"r":0.10980392247438431,
"g":0.10980392247438431,
"b":0.10980392247438431,
"a":1
}
},
"skin":{
"color":{
"r":0.800000011920929,
"g":0.6078431606292725,
"b":0.46666666865348816,
"a":1
}
}
},
"ethAddress":"0x1hd7fl09yivcn7z6asc0a8af9c3b1ba28hdy65sd",
"userId":"0x1hd7fl09yivcn7z6asc0a8af9c3b1ba28hdy65sd",
"version":12,
"hasConnectedWeb3":true
}
]
}
With the points previously discovered, the suggested procedure to visualize an avatar is the following:
https://catalyst/lambdas/profile/address
)https://catalyst/lambdas/collections/wearables?wearableId=urnId
)data.hides
in each wearable definition )forceRender
)This document intention is to describe the current problem with the synchronization of state of scenes and renderer and therefore, the evaluated alternatives and options to deal with these specific issues through different CRDT algorithms in order to optimize performance by preserving and reproducing 'user intention' in a more consistent and reasonable way.
layout: adr
adr: 151
title: Rendering order for UI entities
date: 2022-12-14
status: Review
type: Standards Track
spdx-license: CC0-1.0
authors:
This document describes the requirements to render the UI entities for the Decentraland Protocol. TL;DR; Pre-order using the entity tree defined by the UiTransform (ADR-124).
The UI entities are derived from a synthetic tree of entities defined by the UiTransformComponent (ADR-124). That entity should be rendered from the root to the leafs recursively using a pre-order sequencing.
That means the children will overwrite the pixels of the parent. This is a common practice, HTML, ReactNative and Unity's UiToolkit behave this way OOTB.
It MUST be possible to configure entities to act as stencil to only render what it is between the borders of the parent entity. The default behavior SHALL always be that children will be rendered in full even though are bigger than the borders of the parent.
TODO: create ADR for UiOverflowMode component
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
layout: adr
adr: 206
title: Back-end dependencies for the new Backpack V2
date: 2023-04-04
status: Review
type: ADR
spdx-license: CC0-1.0
authors:
This is a technical proposal for the needs described here: PRD: Backpack V2
The intention of this document is:
This initiative will require a cross team effort that will include the following teams:
We currently have several lambdas endpoints (some of them compatible with pagination) that are already being used by the current version of the Backpack to retrieve the information about the wearables. These endpoints are:
/lambdas/collections/wearables?collectionId=urn:decentraland:off-chain:base-avatars
/lambdas/users/:userId/wearables?includeDefinitions=true
/lambdas/users/:userId/emotes?includeDefinitions=true
/lambdas/users/:userId/third-party-wearables/:collectionId&includeDefinitions=true
We need to support the features in the lambdas. It is recommended to create new ones, to keep retro-compatibility, but we leave the decision to the @platform team.
In order to give the user the possibility of seeing and managing any type of wearables (BASE, OWNED and THIRD PARTY) together in the backpack, we would need to receive all the information from a single endpoint instead of having to request them separately.
These will be the filters available in the UI to filter the wearables:
In order to be able to manage these filters, we will need an endpoint where we can specify a list of collection ids (either "Decentraland", "urn:decentraland:off-chain:base-avatars" or any third party collection) and return the list of wearables that match with those collections.
/lambdas/users/:userId/wearables?includeDefinitions=true&collectionIds=decentraland
/lambdas/users/:userId/wearables?includeDefinitions=true&collectionIds=urn:decentraland:off-chain:base-avatars
/lambdas/users/:userId/wearables?includeDefinitions=true&collectionIds=urn:decentraland:matic:collections-thirdparty:cryptoavatars,urn:decentraland:matic:collections-thirdparty:kollectiff,...
/lambdas/users/:userId/wearables?includeDefinitions=true&collectionIds=decentraland,urn:decentraland:off-chain:base-avatars,urn:decentraland:matic:collections-thirdparty:cryptoavatars,urn:decentraland:matic:collections-thirdparty:kollectiff,...
In order to give the user the possibility of seeing and managing any type of emotes (BASE or OWNED) together in the backpack, we would need to receive all the information from a single endpoint instead of having to request them separately.
This will be the filter available in the UI to filter the emotes:
In order to be able to manage these filters, we will need an endpoint where we can specify a list of collection ids (either "decentraland" or "base") and return the list of emotes that match with those collections.
/lambdas/users/:userId/emotes?includeDefinitions=true&collectionIds=decentraland
/lambdas/users/:userId/emotes?includeDefinitions=true&collectionIds=base
/lambdas/users/:userId/emotes?includeDefinitions=true&collectionIds=decentraland,base
The user will be able to filter the wearables/emotes by text.
In order to be able to do it, we will need to add a new parameter to the existing endpoints that will be used to specify a text and return the list of wearables that match with that text. The new parameter will be called textFilter
and will be a string that will accept any value.
In order to be able to manage this filter, we will need an endpoint (the same described in the previous sections) where we can specify a text and return the list of wearables that match with that text.
/lambdas/users/:userId/wearables?includeDefinitions=true&collectionIds=decentraland,urn:decentraland:off-chain:base-avatars,urn:decentraland:matic:collections-thirdparty:cryptoavatars,urn:decentraland:matic:collections-thirdparty:kollectiff&textFilter=aviator
/lambdas/users/:userId/wearables?includeDefinitions=true&collectionIds=decentraland,base&textFilter=chic
The user will be able to filter the wearables by category.
In order to be able to manage this filter, we will need an endpoint (the same described in the previous sections) where we can specify the category and return the list of wearables that match with that category.
/lambdas/users/:userId/wearables?includeDefinitions=true&collectionIds=decentraland,urn:decentraland:off-chain:base-avatars,urn:decentraland:matic:collections-thirdparty:cryptoavatars,urn:decentraland:matic:collections-thirdparty:kollectiff&category=hat
The user will be able to sort the wearables/emotes by different criteria: newest/oldest, rarest/less rare or name A-Z/name Z-A.
In order to be able to manage this sorting, we will need an endpoint (the same described in the previous sections) where we can specify the sorting criteria and return the list of wearables sorted by that criteria. The sorting parameter will be a string that will accept the following values:
newest
oldest
rarest
less_rare
name_a_z
name_z_a
In cases where wearables or emotes dont have minted timestamps, they should be added at the bottom of the list.
/lambdas/users/:userId/wearables?includeDefinitions=true&collectionIds=decentraland,urn:decentraland:off-chain:base-avatars,urn:decentraland:matic:collections-thirdparty:cryptoavatars,urn:decentraland:matic:collections-thirdparty:kollectiff&sort=rarest
/lambdas/users/:userId/wearables?includeDefinitions=true&collectionIds=decentraland,base&sort=name_a_z
The user will be able to click on a wearable and open a modal with some details as:
To be able to request this information, the client will have to use the minted id instead of the generic id. This information is available when querying the wearables.
In order to be able to get this info, we will need to create a new endpoint that will return the details of a specific wearable:
/lambdas/wearables/:wearableId/market-details
The user will be able to click on a [RANDOMIZE] button and equip a random list of wearables on his avatar.
In order to be able to do it, we will need to create a new endpoint that will return a random list of wearable ids from the owned wearables of the user.
The wearables must be from each category, avoiding conflicts with hides and replaces whenever possible.
/lambdas/users/:userId/random-wearables
The outfit information should be stored in the catalyst because we need to support multi-platform.
On the other hand, we should avoid storing it in profiles since it is information that only each individual user needs and does not need to be shared with other users.
Adding it to the profiles would add an additional data transfer for each request unnecessarily.
Update: The outfit information will be stored in the user profile.
Regarding to the outfit image previews, they can be generated in the client when saving the outfit.
There is no need to store the images in the catalysts.
We may encounter the need of checking that the wearables in the outfit are valid for the current user. (What happens if the user does not have the wearable anymore?)
We though about several alternatives to avoid performance issues by saving the profile every time you equip an item:
Saving the profile would mean that the nearby users will be able to see the changes as soon as possible.
Update: we will go for option 1, taking in consideration that we cant save the profile during the quitting of the application. It will only be saved when closing the backpack, just like the "save" button worked before.
We will need to refactor the current emotes catalog, the same way on how we did on wearables catalog, so its supports pagination.
We will also reduce kernel responsibilities, moving all (or most) of the emote handling in the renderer.
No need backend support.
Open ticket: #4429
In Unity we are going to implement a new UI for the backpack v2 requirements, including all the components needed.
We will keep retro-compatibility with the old one, including the UI, service calls and dependencies.
layout: adr
adr: 0 # replace this number for the PR or ISSUE number
title: Title of the ADR
date: 2020-02-20
status: Idea, Draft # pick one of these
type: Standards Track | Meta | RFC # pick one of these
spdx-license: CC0-1.0
authors:
This document presents the problem of cyclic entities in an entity tree. Cycles are not compatible with how the rendering engines work since it is an unrepresentable and invalid state.
Assuming the following valid messages:
Timestamp:0 EntityC.parent = EntityA
Timestamp:1 EntityA.parent = EntityB
Timestamp:2 EntityB.parent = EntityC
Timestamp:4 EntityC.parent = ROOT
The rules of CRDT allow us to derive a final state
0 ROOT
└──C
└──B
└──A
Assuming these messages will arrive in any order (thanks to the commutative property of CRDT), every implementation of Decentraland should reach the same final state without conflict. But partially or sequentially processing the shuffled messages, may render invalid intermediate states with cycles.
Most engines will fail and crash with such situation. And adding safeguards to the PUT messages will add way more complexity than anticipated to the renderer.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.