0.0.28 • Published 3 years ago

aecs v0.0.28

Weekly downloads
4
License
ISC
Repository
gitlab
Last release
3 years ago

Awesome Entity Component System

An entity component system made with typescript.

Install

npm i --save aecs

Getting Started

To use the entity component system, you first must create an instance of Engine.

import { Engine } from "aecs";
const engine = new Engine();

Define your Components:

import { Component } from "aecs";

// Components can have custom constructors, but they must be able to be initialized
// with no arguments, because the engine creates the instances for you.
// Try not to save complex data types in your components
// due to the handling of references inside javascript

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

Create an Entity type:

import { Entity } from "aecs";

//can have a constructor but is not needed
//the type is basically only used for queries from your systems

export class PlayerEntity extends Entity {}

For the creation of your entities it makes sense to define a Prefab.

import { Prefab } from "aecs";

export class PlayerPrefab extends Prefab<PlayerEntity> { // <-- entityType needed
    private spawnX: number = 0;
    private spawnY: number = 0;

    protected init(): void {
        //code here runs only once for the creation of the prefab instance
    }

    public someSetterDefinedByYou(x: number, y: number): void {
        this.spawnX = x;
        this.spawnY = y;
    }

    public instantiate(): PlayerEntity {
        const positionComponent = new PositionComponent();
        positionComponent.x = this.spawnX;
        positionComponent.y = this.spawnY;

        return new PlayerEntity(<<<SOME_ID>>>, [positionComponent]);
    }
}

Finally a System is created to work with the entities and components

import { System } from "aecs";

//in this system we will instantiate a player and listen for keyboard inputs to move the player around

export class PlayerSystem extends System {
    private playerPrefab: PlayerPrefab;

    init(): void {
        this.playerPrefab = this.prefabManager.getPrefab<PlayerPrefab>(PlayerPrefab);
        this.playerPrefab.someSetterDefinedByYou(10, 10);
        this.ecm.instantiatePrefab(this.playerPrefab);
    }

    // we have multiple ways to query for components/entities
    run(delta: number): void {
        //query by id
        let playerEntityItem = this.ecm.getEntity<PlayerEntity>(<<<SOME_ID>>>)

        //query by entity type -> returns array
        let playerEntities = this.ecm.getEntites<PlayerEntity>(PlayerEntity);

        //query by a specific component + id
        let positionComponent = this.ecm.getComponent<PositionComponent>(PositionComponent, <<<SOME_ID>>>);

        //query all by component type -> returns array
        let positionComponents = this.ecm.getComponents<PositionComponent>(PositionComponent);

        if(some key pressed) {
            //do things with entities & components here
        }
    }
}

AECS is defined by multiple Worlds. Think of a world like a container which hold multiple prefabs & systems. So you could have for example a GameWorld and a MenuWorld etc. To get the engine running we need to define a world for our systems and prefabs to run.

import { World } from "aecs";

export interface WorldProperties {
    someValue: string;
}

export class SomeWorld extends World<WorldProperties> {
    init(): void {
        this.initPrefabs([
            new PlayerPrefab(PlayerEntity)  // needs the entity type
        ]);

        this.initSystems([
            new PlayerSystem(true)  // bool if active or not
        ]);
    }

    update(delta: number): void {
        this.callSystems(delta);    //in our loop we call all systems
    }
}

In the last step we add our created GameWorld to the engine and start it all up

engine.addWorlds([
    new SomeWorld({someValue: "someValue"})
]);
engine.setActiveWorld(SomeWorld);
engine.start(60);   // number of ticks we want to have per second

//alternative you can manually call the update loop with
//engine.update(deltaTime?: number);

Important!

When you build your project with webpack it is needed to the following option to your webpack.config.js, otherwise aecs will throw all sorts of errors during runtime!

optimization: {
    minimizer: [
        new ESBuildMinifyPlugin({
            keepNames: true
        })
    ]
},
0.0.20

3 years ago

0.0.21

3 years ago

0.0.22

3 years ago

0.0.23

3 years ago

0.0.24

3 years ago

0.0.25

3 years ago

0.0.15

3 years ago

0.0.16

3 years ago

0.0.17

3 years ago

0.0.18

3 years ago

0.0.19

3 years ago

0.0.10

3 years ago

0.0.11

3 years ago

0.0.12

3 years ago

0.0.13

3 years ago

0.0.14

3 years ago

0.0.26

3 years ago

0.0.9

3 years ago

0.0.27

3 years ago

0.0.8

3 years ago

0.0.28

3 years ago

0.0.5

3 years ago

0.0.4

3 years ago

0.0.7

3 years ago

0.0.6

3 years ago

0.0.3

6 years ago

0.0.2

6 years ago

0.0.1

6 years ago