Giter Site home page Giter Site logo

nano-ecs's Introduction

Build Status

nano-ecs

A nano-sized entity-component-system module.

nano-ecs is not a big bloated game engine framework, but rather a small focused module that does one thing well: creating and managing a set of entities and their components.

Background

If you aren't familiar with paradigm of entity-component-systems (or "ECS" as the cool kids call it), you may get some background mileage from this talk of mine, or this article here.

nano-ecs was created as fork of tiny-ecs, which provides similar functionality, but tries to do much more than basic ECS (timers, 2d transforms, object pools, etc). The goal of nano-ecs is to provide only a core lightweight ECS implementation.

Installation

Works on the server or the browser (via Browserify):

npm install nano-ecs

Usage

Manage your entities via a nano entity manager instance:

var nano = require('nano-ecs')

var world = nano()

Creating Entities

Create an entity, bereft of components:

var hero = world.createEntity();

Adding Components

A component is just a function that defines whatever properties on this that it'd like:

function PlayerControlled()
{
  this.gamepad = 1;
}
function Sprite()
{
  this.image = 'hero.png';
}

Components are added using addComponent and support chaining:

hero.addComponent(PlayerControlled).addComponent(Sprite);

All parameters after Sprite are sent to the constructor. E.g.

function Sprite (entity, imageName) {
  this.image = imageName
}

entity.addComponent(Sprite, 'hero.png')

Preferring convention over configuration, nano-ecs will add an instance member that is the name of the component constructor, camelCased:

hero.playerControlled.gamepad = 2;
hero.sprite.image === 'hero.png'; // true

Entities can be tagged with a string for fast retrieval:

hero.addTag('player');

...

var hero = world.queryTag('player')[0]

You can also remove components and tags in much the same way:

hero.removeComponent(Sprite);
hero.removeTag('player');

hasComponent will efficiently determine if an entity has a specific single component:

if (hero.hasComponent(Transform)) { ... }

A set of components can also be quickly checked:

if (hero.hasAllComponents([Transform, Sprite])) { ... }

Querying Entities

The entity manager indexes entities and their components, allowing extremely fast queries.

Entity queries return an array of entities.

Get all entities that have a specific set of components:

var toDraw = entities.queryComponents([Transform, Sprite]);

Get all entities with a certain tag:

var enemies = entities.queryTag('enemy');

Removing Entities

hero.remove();

Components

Any object constructor can be used as a component--nothing special required. Components should be lean data containers, leaving all the heavy lifting for the systems.

Creating Systems

In nano-ecs, there is no formal notion of a system. A system is considered any context in which entities and their components are updated. As to how this occurs will vary depending on your use.

In the example of a game, you could maintain a list of systems that are instantiated with a reference to the entity's world:

function PhysicsSystem (world)
{
  this.update = function (dt, time) {
    var candidates = world.queryComponents([Transform, RigidBody]);

    candidates.forEach(function(entity) {
      ...
    });
  }
}

Events

All entities can act as event emitters. One part of the game code can raise an event on an entity that a specific component or other system is free to handle:

function Health () {
  this.hp = 100
}

var entity = world.createEntity()

entity.addComponent(Health)

entity.on('damage', function (amount) {
  this.hp -= amount
  if (this.hp < 0) {
    entity.emit('death')
  }
})

Entity Manager API

var world = require('nano-ecs')()

world.createEntity()

Create a new, component-less entity.

world.removeAllEntities()

Remove all entities from the world.

world.removeEntity(entity)

Remove a specific entity by reference.

world.removeEntitiesByTag(tag)

Remove all entities with a given tag.

world.queryComponents(components=[])

Returns a list of all entities with the full list of components given.

world.queryTag(tag)

Returns a list of all entities with the given tag.

world.count()

Returns the total number of entities in the world.

Entity API

var entity = require('nano-ecs')().createEntity()

entity.remove()

Remove the entity from the world.

entity.addComponent(TComponent)

Add a component to an entity, by constructor function name.

entity.removeComponent(TComponent)

Remove a component from the entity, by constructor function name.

entity.hasComponent(TComponent)

Returns true if the entity has the component (by constructor function name), false otherwise.

entity.hasAllComponents(components=[])

Returns true if the entity has all of the components (by constructor function name), false otherwise.

entity.hasTag(tag)

Returns true if the entity has the given tag, false otherwise.

entity.addTag(tag)

Adds the given tag to the entity.

entity.removeTag(tag)

Remove the given tag from the entity.

Testing

Testing is done with Tape or any other software supporting the Test Anything Protocol and can be run with the command npm test. There is also a pre-commit hook that will ensure tests pass before any commit is permitted.

License

Copyright 2014 Brandon Valosek, forked and modified by Stephen Whitmore.

nano-ecs is released under the MIT license.

nano-ecs's People

Contributors

bvalosek avatar hackergrrl avatar noffle avatar parasti avatar jeremygiberson-at-privoro avatar jeremygiberson avatar

Stargazers

Jaron Wanderley avatar Jens Anders Bakke avatar  avatar J. G. Sebring avatar Martin Kinoo avatar Don Lour avatar Aaron Harvey avatar Julien Letellier avatar Chalee avatar V. Fabiano avatar Roman Hossain Shaon avatar Andrew Chou avatar Per Guth avatar James Fitzgerald avatar  avatar Mark Moissette avatar Fabio Dias Rollo avatar Stanislav Karkavin avatar  avatar Simon Oberhammer avatar Daniel Biegler avatar Lynn avatar  avatar Gordon Delfel avatar Yannis avatar Geoffroy Lafontaine avatar Anton Mata avatar AlienCoder avatar Jan Scheiper avatar  avatar Florian Morel avatar Tim van Scherpenzeel avatar Stanley Roache avatar Wouter Commandeur avatar Randy Tan avatar  avatar Paul Young avatar David Llanos avatar Joe Pea avatar Dmitrii Vasilev avatar Iain Kirkpatrick avatar Philip Edwards avatar Opher Vishnia avatar Ben Cooper avatar Leonardo Silveira avatar  avatar Normen Hansen avatar  avatar Natan avatar Gary Weiss avatar Derek Reynolds avatar Frederic Charette avatar Seth Vincent avatar rosancoderian avatar Xin Chen avatar Osman Zeki avatar Corban Brook avatar Joohun, Maeng avatar  avatar

Watchers

 avatar Gary Weiss avatar Aaron Harvey avatar V. Fabiano avatar  avatar

nano-ecs's Issues

events not work

first , thanks
this project helps me much.
but i have a problem when i use event ,it seems not work.
here is my code

var nano = require('nano-ecs')
var world = nano()

function Health () {
this.hp = 100
}

var entity = world.createEntity()
var b = world.createEntity()

entity.addComponent(Health)

entity.on('damage', function (amount) {
this.hp -= amount
if (this.hp < 0) {
entity.emit('death')
}
})
b.emit('damage')

the damage function not fired.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.