ADR-128: Realms modifiers for Worlds in Renderer

More details about this document
Latest published version:
https://adr.decentraland.org/adr/ADR-128
Authors:
dalkia
Feedback:
GitHub decentraland/adr (pull requests, new issue, open issues)
Edit this documentation:
GitHub View commits View commits on githistory.xyz

Abstract

This document describes the approach used for implementing realms modifiers. These modifiers allow to modify the state and behavior of the renderer depending on the realm that has been accessed. The approach allows to easily add or remove functionalities as they are required by the Worlds features.

Context, Reach & Prioritization

A new Worlds feature is being actively developed. A World is a developer-generated realm, in which he/she will be able to take control of different features that had not been possible until now. Also, it allows a sandbox mode which will only run their own scene, giving a boost in performance.

In the first phase of this project, and as the main scope of the MVP, users who got, or just acquire a NAME, will have access to the public beta of Worlds. This will allow them to create a self-contained scene, with limited space and specifications, which can be deployed on catalyst's network content servers, free of charge for the duration of the beta period, not to exceed 12 months.

Discoverability of content will be outside-in, as content creators will be able to share easy to remember URLs to enter the World directly, or inside-out using a join command. Anybody will be able to join a World.

Solution Space Exploration

To be able to modify the features necessary in each world, we are developing a Realms Plugin which contains Realms Modifiers. Each of these modifiers will have the responsibility to alter DCL functionality by checking if we are entering a developer-generated realm or a DAO realm.

Specification

Realms Plugin

The realms plugin is the entry point for the realms modifier. It is created under the explorer-realms_modifier_plugin flag and acts as a bridge which receives the 'AboutResponse' sent by kernel and distributes it among all implemented modifiers. By comparing the just accessed realms with the list of available catalysts, it determines if a realm is part of the DAO or a user created world. This variable is necessary for modifiers to execute certain functionality. In the near future, we could add this bool to the 'AboutResponse' section, so this responsibility relies completely on the data and not on a comparison.

Realm Modifiers Interface

Describes the behavior necessary for realm modifiers. Current implementation requires to specify if we are on a DAO realm; since some behavior still relies on this property.

namespace DCLPlugins.RealmsPlugin
{
    public interface IRealmsModifier : IDisposable
    {
        void OnEnteredRealm(bool isCatalyst, AboutResponse realmConfiguration);
    }
}

Modifiers currently implemented are:

Controls how the green blockers should be shown on each realm. If a realm is a Catalyst or it has a value on Configurations.CityLoaderContentServer then the green blockers will be shown.

Controls the functionality associated to the minimap when entering a Realm. It determines if the minimap should be visible using the realmConfiguration.Configurations.Minimap.Enabled value. Also, it determines if the Jump To Home Button should be present. This button will appear on any given user world, and it will take the user back to the home location in the most populated DAO Catalyst. When needed, this modifier will implement the change of the minimap image; as a user generated world will have the possibility to show its own minimap png.

Data Structure

AboutResponse contains the info of the realm which has just been accessed. This class is autogenerated from protobuff specifications and adheres to ADR-110: Realm description. Each modifier gets access to the AboutResponse, and gets the info necessary to execute its behavior. It has the following structure:

type About = {
  healthy: boolean
  configurations: {
    networkId: number
    realmName?: string
    scenesUrn: string[]
    globalScenesUrn: string[]
  }
  content: {
    healthy: boolean
    version?: string
    commitHash?: string
    publicUrl: string
  }
  comms: {
    healthy: boolean
    protocol: string
    fixedAdapter?: string
    usersCount?: number
  }
  lambdas: {
    healthy: boolean
    version?: string
    commitHash?: string
    publicUrl: string
  }
  bff?: {
    healthy: boolean
    userCount: number
    commitHash?: string
    publicUrl: string
  }
}

Example:

{
  "healthy": true,
  "content": {
    "healthy": true,
    "version": "5.1.2",
    "commitHash": "dce61c002c89db4966c0cdd008d3d654f297050b",
    "publicUrl": "https://peer.decentraland.org/content"
  },
  "configurations": {
    "realmName": "catalyst-4",
    "networkId": 1,
    "minimap": {
      "enabled": false
    },
    "skybox": {
      "fixedHour": 36000
    }
  },
  "comms": {
    "healthy": true,
    "protocol": "v3",
    "fixedAdapter": "ws-room:mini-comms.decentraland.org/rooms/test-room"
  },
  "lambdas": {
    "healthy": true,
    "version": "5.1.2",
    "commitHash": "dce61c002c89db4966c0cdd008d3d654f297050b",
    "publicUrl": "https://peer.decentraland.org/lambdas"
  },
  "bff": {
    "healthy": true,
    "commitHash": "369c5dafeda62a1b16f5232cd477565cc3f3d513",
    "userCount": 0,
    "publicUrl": "/"
  }
}

As an example of usage, MinimapModifier.cs looks for Configurations.Minimap.Enabled to determine if the minimap should be shown on that configuration.

Current Implementation

classDiagram
   RealmPlugin <-- IRealmModifier
   IRealmModifier <|-- RealmBlockerModifier
   IRealmModifier <|-- RealmMinimapModifier
   class RealmPlugin {
      +List <IRealmModifier> realmModifiers
      +void SetRealmModifiers()
      +void RealmChanged(AboutResponse current, AboutResponse _)
    }
   class IRealmModifier {
        <<interface>>
    +void OnEnteredRealm(bool isCatalyst, AboutResponse realmConfiguration)
   }

RFC 2119 and RFC 8174

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.

License

Copyright and related rights waived via CC0-1.0. Living