js-ecs

Entity Component System for Javascript

Usage no npm install needed!

<script type="module">
  import jsEcs from 'https://cdn.skypack.dev/js-ecs';
</script>

README

npm i --save js-ecs

Usage

const ecs = require('js-ecs')

Can be webpacked to browser

Sample

const {Engine, Entity, System} = require('js-ecs')

class Position{
    constructor(x, y){
        this.x = x
        this.y = y
    }
}
class Velocity{
    constructor(x, y){
        this.x = x
        this.y = y
    }
}

class MoveSys extends System{
    constructor(){
        super()
    }
    update(dt){
        //this.getC('Position', 'Velocity').forEach(({Position: p, Velocity: v})=>{
        const es = this.get('Position', 'Velocity')
        es.forEach(e=>{
            const p = e.get('Position')
            const v = e.get('Velocity')
            p.x += v.x*dt
            p.y += v.y*dt
        })
    }
}

const engine = new Engine()
engine.addSystem(new MoveSys())
engine.addEntity(new Entity(new Position(0, 0), new Velocity(1, 1)))

let lastTime
requestAnimationFrame(time=>{
    if(!lastTime){
        //do first init or something
    }else{
        engine.update((time - lastTime)/1000)
    }
    lastTime = time
})

Docs

Entity

A bag of components.

constructor(...components)

  • Expects instances of components

add(...components)

  • Expects instances of components

remove(...componentsOrComponentNames)

  • Expects component instances or string names of components (their constructor names)

get(componentName)

  • Given a component name, returns its instance

getAll(...componentName)

  • Expects string names of components (their constructor names), if omitted returns a copy of all components
  • Returns instances of the component names given

destroy()

  • removes components from linked ECS engine

engine

  • Currently attached ECS engine (could be undefined)

Component

Any class object. Will be named/referenced as its constructor name.

System

Logic. Gathers components it wants to govern and furthers them.

update()

  • Should be overriden
  • Will forward anything in engine's update call
    • Common standard is to send dt which is delta time/time elapsed since last update
  • Put your system logic in here to run every tick/frame

get(...componentNames)

  • Expects string names of components (their constructor names)
  • Returns entities that have all the requested components

getC(...componentNames)

  • Expects string names of components (their constructor names)
  • Returns entities (entity) and their matching components

attached(engine)

  • Use by overriding. Is called when attached to an ECS engine.
  • Put logic here to be run when system is attached to a ECS engine

dettached(engine)

  • Use by overriding. Is called when attached to an ECS engine.
  • Put logic here to be run when system is dettached from a ECS engine

engine

  • Currently attached ECS engine (could be undefined)

Engine

Executes ECS architecture.

update()

  • Calls all attached systems
  • Should be called on every tick/frame
  • Will forward any arguments sent to systems update call
    • Common standard is to send dt which is delta time/time elapsed since last update

addSystem(...systems)

  • will remove from old engine if exists

removeSystem(...systems)

addEntity(...entities)

  • will remove from old engine if exists

removeEntity(...entities)

find(...componentNames)

  • Expects string names of components (their constructor names)
  • Returns entities that have all the requested components

on(event, cb, ...componentNames)

  • events: add or remove
  • cb: function that will be called on the event. Will receive the matching entity (entity) and its matching components
  • componentNames: expects string names of components (their constructor names), will only trigger event if all components are changed

off(event, cb)

  • events: add or remove
  • cb: function that was assigned to the event
  • Returns cb