This ADR describes the ECS runtime architecture used in the Decentraland Explorer (decentraland/unity-explorer), which replaces the runtime architecture described in ADR-67 (now deprecated). The new architecture is built on the Arch ECS framework with a dual-world system, automated system ordering, and a hybrid ECS approach that allows Unity MonoBehaviours as components.
The old runtime architecture (ADR-67) was designed for unity-renderer and focused on component registration patterns to avoid a god-object anti-pattern where the runtime knew about all components. It used UPM packages for segregation.
The new explorer client was built from scratch using a pure ECS approach with the Arch framework, introducing fundamentally different patterns for component registration, system lifecycle, and world management.
The runtime maintains two types of worlds:
Systems run on the main thread once per frame, organized into system groups. The Arch.SystemGroups library automates system creation and dependency resolution.
Key design rules:
ref pointers and must be
applied last
Components follow these guidelines:
ISceneFacade), and components referenced from other worlds
Two patterns for communication between Global and Scene worlds:
IECSToCRDTWriter bridges data from the global
world to scene-visible CRDT components. Used for data that scenes need to observe (e.g.,
player transforms)
Safety guards:
ISceneIsCurrentListener prevents background scenes from modifying global state
IFinalizeWorldSystem ensures cleanup on world disposalSyncedGroup system guards ensure operations only run when the scene is in
Running state
ECS and async/await are married through the Asset Promise pattern:
AssetPromise<TAsset, TLoadingIntention> represented as entities
Callbacks are explicitly forbidden in ECS. No delegates, events, or subscriptions. Systems
execute logic only in their Update function. Data propagation from Unity objects
to systems must go through components, not events.
| Aspect | ADR-67 (Old) | This ADR (New) |
|---|---|---|
| Framework | Custom component registration | Arch ECS framework |
| Worlds | Single world | Dual-world (Global + per-scene) |
| System ordering | Manual | Automated via Arch.SystemGroups |
| Component storage | Plugin-level registration | ComponentsContainer with unique IDs |
| Threading | Main thread only | Job System + MultiThreadSync mutex |
| Unity integration | Traditional MonoBehaviour | Hybrid ECS (MonoBehaviours as components) |
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.