Skip to content

Latest commit

 

History

History
118 lines (85 loc) · 2.9 KB

README.md

File metadata and controls

118 lines (85 loc) · 2.9 KB

@dcl/ecs

Core Entity Component System (ECS) package for Decentraland scenes. Implements a CRDT-based ECS architecture for networked scene state.

Installation

npm install @dcl/ecs

Usage

import { engine } from '@dcl/ecs'

// Create entity
const entity = engine.addEntity()

// Define and add component
const Health = engine.defineComponent(1, {
  current: Number,
  max: Number,
  regeneration: Number
})

Health.create(entity, {
  current: 100,
  max: 100,
  regeneration: 1
})

// Create system
engine.addSystem((dt: number) => {
  for (const [entity, health] of engine.mutableGroupOf(Health)) {
    if (health.current < health.max) {
      health.current = Math.min(health.max, health.current + health.regeneration * dt)
    }
  }
})

Technical Overview

Component Definition

Components are defined with a unique ID and a schema. The schema is used to:

  • Generate TypeScript types
  • Create binary serializers/deserializers
  • Set up CRDT operations

CRDT Implementation

The ECS uses CRDTs (Conflict-free Replicated Data Types) to enable deterministic state updates across multiple engine instances:

  • Component updates are CRDT operations with logical timestamps
  • Multiple engine instances can be synced by exchanging CRDT operations
  • Conflict resolution uses timestamps and entity IDs to ensure consistency
  • Binary transport format minimizes network overhead

Network Entities

For multiplayer scenes, the syncEntity method marks entities that should be synchronized across peers. In the background it creates a NetworkEntity and a SyncComponents components with all the info necessary to synchronise the entity through the network.

import { engine, NetworkEntity } from '@dcl/ecs'

// Create a networked entity
const foe = engine.addEntity()
NetworkEntity.create(foe)

// Components on this entity will be synced across peers
Health.create(foe, { current: 100, max: 100, regeneration: 1 })

Each peer maintains its own engine instance. When using NetworkEntity:

  • The owner peer can modify the entity's components
  • Other peers receive read-only replicas
  • Updates are propagated through the network transport layer using CRDT operations

Example transport message:

{
  entityId: number
  componentId: number
  timestamp: number
  data: Uint8Array // Serialized component data
}

Performance Features

  • Zero-allocation component iteration
  • Dirty state tracking for efficient updates
  • Binary serialization for network transport
  • Batched component operations

Development

# Build
make build

# Test
make test

# Clean and reinstall
make clean && make install

Documentation