npm package: @mildx/ecs
Description: A minimalistic Entity Component System (ECS) library for TypeScript. This library is designed to provide the core building blocks for an ECS architecture while giving you, the developer, full control over your game's structure and dependencies.
Latest version: 0.2.0

# ECS Library

A minimalistic Entity Component System (ECS) library for TypeScript.
This library is designed to provide the core building blocks for an ECS architecture while giving you, the developer, full control over your game's structure and dependencies.

It includes an optional game loop management class, object pooling, and some basic components and systems.

## Core Concepts

- Registry: The main orchestrator. It creates entities, stores components and resources, and runs systems.
- Entity: A simple number that acts as a unique ID. It holds no data or logic.
- Component: A class that extends Component and contains only data. It represents a single aspect of an entity (e.g., its position or health).
- System: A class that extends System and contains only logic. Systems operate on entities that have a specific set of components.
- Resource: A global data container class similar to components but they are not attached to any specific entity.

## Installation

`npm install @mildx/ecs`

## Basic Usage

This example shows how to set up a simple world where entities move based on their velocity.

### 1. Define Your Components

Components are simple classes that hold data. They are internally managed with a pool.

```typescript
import { Component } from '@mildx/ecs';

class PositionComponent extends Component {
  public x: number = 0;
  public y: number = 0;

  // Optional, called before the component is released back in the pool.
  public release(): void {
    this.x = 0;
    this.y = 0;
  }
}

class VelocityComponent extends Component {
  public vx: number = 0;
  public vy: number = 0;

  public release(): void {
    this.vx = 0;
    this.vy = 0;
    super();
  }
}
```

### 2. Define A Time Resource

A simple Time object to be managed by the game loop.

```typescript
class TimeResource {
  public deltaTime: number = 0;
}
```

### 3. Define Your Systems

Systems contain your game logic.

```typescript
import { System, Registry, Component } from '@mildx/ecs';

// Create a query only once.
const movingEntitiesQuery = registry.createQuery({
  all: [PositionComponent, VelocityComponent],
});

class MovementSystem extends System {
  public update(): void {
    // Systems automatically recieve a reference to the registry.
    const time = this.registry.getResource(TimeResource);
    const entities = this.registry.query(movingEntitiesQuery);

    for (const entity of entities) {
      const position = this.registry.getComponent(entity, PositionComponent)!;
      const velocity = this.registry.getComponent(entity, VelocityComponent)!;

      position.x += velocity.vx * time.deltaTime;
      position.y += velocity.vy * time.deltaTime;
    }
  }
}
```

### 4. Set Up Your Game Loop

Tie everything together in your main game file.

```typescript
import { Registry } from '@mildx/ecs';

const time = new TimeResource();

const registry = new Registry();

// 2. Add systems to the registry
registry.addSystem(new MovementSystem());

// 3. Add the resource to the registry
registry.addResource(time);

// 4. Create an entity
const myEntity = registry.acquireEntity();
registry.addComponent(myEntity, new PositionComponent(100, 50));
registry.addComponent(myEntity, new VelocityComponent(10, 5));

// Simplified example of game loop
let lastTime = Date.now();
setInterval(() => {
  time.deltaTime = Date.now() - lastTime;
  lastTime = Date.now();
  registry.update();
}, 1000 / 60);
```