This ADR describes the ECS-based plugin architecture used in the Decentraland Explorer
(decentraland/unity-explorer), which replaces the DataStore/Bridge/HUD plugin pattern
described in ADR-56 (now deprecated). The new system uses
IDCLPlugin with Global and World scopes, dependency injection via containers, and
an Entity Component System architecture built on top of the Arch ECS framework.
The old plugin system (ADR-56) was designed around the unity-renderer architecture which relied on DataStore, Bridges, HUDs, and subsystems. With the migration to unity-explorer, the entire runtime architecture was rebuilt around ECS principles, making the old plugin pattern obsolete.
The new architecture needs to support:
Plugins are defined with two scopes:
All plugins implement IDCLPlugin which provides:
Components are registered at the plugin level via ComponentsContainer using
RegisterComponent. Each component has a unique ID (12xx for main, 14xx for
experimental, 16xx for Regenesis Labs).
Containers manage dependencies between plugins. Plugins declare their dependencies, and the container resolves them at initialization time.
The FeaturesRegistry singleton determines if a feature is enabled based on
Feature Flags, App Arguments, or other conditions. Plugins can check
FeaturesRegistry.Instance.IsEnabled(FeatureId) to conditionally enable
functionality.
| Aspect | ADR-56 (Old) | This ADR (New) |
|---|---|---|
| Data storage | DataStore (ScriptableObjects) | ECS components, single-instance entities |
| Communication | Bridges + events | ECS systems reading/writing components |
| UI | HUDController | MVC pattern (ControllerBase/ViewBase/MVCManager) |
| Lifecycle | Plugin class with Initialize/Dispose | IDCLPlugin with container-managed lifecycle |
| Threading | Main thread only | MultiThreadSync queue-based mutex + SyncedGroup guards |
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.