{"id":15483402,"url":"https://github.com/hackergrrl/nano-ecs","last_synced_at":"2025-09-13T17:32:47.942Z","repository":{"id":35771104,"uuid":"40050738","full_name":"hackergrrl/nano-ecs","owner":"hackergrrl","description":":small_blue_diamond: A nano-sized Entity-Component-System library.","archived":false,"fork":false,"pushed_at":"2020-05-27T21:02:46.000Z","size":86,"stargazers_count":59,"open_issues_count":0,"forks_count":5,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-12-28T17:44:39.642Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hackergrrl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-01T15:25:17.000Z","updated_at":"2023-10-12T02:28:19.000Z","dependencies_parsed_at":"2022-09-06T14:51:39.296Z","dependency_job_id":null,"html_url":"https://github.com/hackergrrl/nano-ecs","commit_stats":null,"previous_names":["noffle/nano-ecs"],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackergrrl%2Fnano-ecs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackergrrl%2Fnano-ecs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackergrrl%2Fnano-ecs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackergrrl%2Fnano-ecs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hackergrrl","download_url":"https://codeload.github.com/hackergrrl/nano-ecs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232896583,"owners_count":18593521,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-02T05:15:01.463Z","updated_at":"2025-01-07T14:46:03.855Z","avatar_url":"https://github.com/hackergrrl.png","language":"JavaScript","readme":"[![Build Status](https://travis-ci.org/noffle/nano-ecs.svg?branch=master)](https://travis-ci.org/noffle/nano-ecs)\n\n# nano-ecs\n\n\u003e A nano-sized entity-component-system module.\n\n`nano-ecs` is not a big bloated game engine framework, but rather a small\nfocused module that [does one thing\nwell](https://en.wikipedia.org/wiki/Unix_philosophy#Do_One_Thing_and_Do_It_Well):\ncreating and managing a set of entities and their components.\n\n\n## Background\n\nIf you aren't familiar with paradigm of entity-component-systems (or \"ECS\" as\nthe cool kids call it), you may get some background mileage from [this talk of\nmine](https://github.com/noffle/ECSTalk/blob/master/ECS%20Presentation.pdf), or\n[this article\nhere](http://www.gamedev.net/page/resources/_/technical/game-programming/understanding-component-entity-systems-r3013).\n\n`nano-ecs` was created as fork of\n[`tiny-ecs`](https://github.com/bvalosek/tiny-ecs), which provides similar\nfunctionality, but tries to do much more than basic ECS (timers, 2d transforms,\nobject pools, etc). The goal of `nano-ecs` is to provide only a core lightweight\nECS implementation.\n\n\n## Installation\n\nWorks on the server or the browser (via [Browserify](http://browserify.org)):\n\n```\nnpm install nano-ecs\n```\n\n\n## Usage\n\nManage your entities via a `nano` entity manager instance:\n\n```javascript\nvar nano = require('nano-ecs')\n\nvar world = nano()\n```\n\n\n### Creating Entities\n\nCreate an entity, bereft of components:\n\n```javascript\nvar hero = world.createEntity();\n```\n\n\n### Adding Components\n\nA component is just a function that defines whatever properties on `this` that\nit'd like:\n\n```javascript\nfunction PlayerControlled()\n{\n  this.gamepad = 1;\n}\n```\n\n```javascript\nfunction Sprite()\n{\n  this.image = 'hero.png';\n}\n```\n\nComponents are added using `addComponent` and support chaining:\n\n```javascript\nhero.addComponent(PlayerControlled).addComponent(Sprite);\n```\n\nAll parameters after `Sprite` are sent to the constructor. E.g.\n\n```js\nfunction Sprite (entity, imageName) {\n  this.image = imageName\n}\n\nentity.addComponent(Sprite, 'hero.png')\n```\n\nPreferring convention over configuration, `nano-ecs` will add an instance member\nthat is the name of the component constructor, camelCased:\n\n```javascript\nhero.playerControlled.gamepad = 2;\nhero.sprite.image === 'hero.png'; // true\n```\n\nEntities can be tagged with a string for fast retrieval:\n\n```javascript\nhero.addTag('player');\n\n...\n\nvar hero = world.queryTag('player')[0]\n```\n\nYou can also remove components and tags in much the same way:\n\n```javascript\nhero.removeComponent(Sprite);\nhero.removeTag('player');\n```\n\n`hasComponent` will efficiently determine if an entity has a specific single\ncomponent:\n\n```javascript\nif (hero.hasComponent(Transform)) { ... }\n```\n\nA set of components can also be quickly checked:\n\n```javascript\nif (hero.hasAllComponents([Transform, Sprite])) { ... }\n```\n\n\n### Querying Entities\n\nThe entity manager indexes entities and their components, allowing extremely\nfast queries.\n\nEntity queries return an array of entities.\n\nGet all entities that have a specific set of components:\n\n```javascript\nvar toDraw = entities.queryComponents([Transform, Sprite]);\n```\n\nGet all entities with a certain tag:\n\n```javascript\nvar enemies = entities.queryTag('enemy');\n```\n\n\n### Removing Entities\n\n```javascript\nhero.remove();\n```\n\n\n### Components\n\nAny object constructor can be used as a component--nothing special required.\nComponents should be lean data containers, leaving all the heavy lifting for the\nsystems.\n\n\n### Creating Systems\n\nIn `nano-ecs`, there is no formal notion of a system. A system is considered any\ncontext in which entities and their components are updated. As to how this\noccurs will vary depending on your use.\n\nIn the example of a game, you could maintain a list of systems that are\ninstantiated with a reference to the entity's world:\n\n```\nfunction PhysicsSystem (world)\n{\n  this.update = function (dt, time) {\n    var candidates = world.queryComponents([Transform, RigidBody]);\n\n    candidates.forEach(function(entity) {\n      ...\n    });\n  }\n}\n```\n\n\n### Events\n\nAll entities can act as event emitters. One part of the game code can raise an\nevent on an entity that a specific component or other system is free to handle:\n\n```javascript\nfunction Health () {\n  this.hp = 100\n}\n\nvar entity = world.createEntity()\n\nentity.addComponent(Health)\n\nentity.on('damage', function (amount) {\n  this.hp -= amount\n  if (this.hp \u003c 0) {\n    entity.emit('death')\n  }\n})\n```\n\n\n## Entity Manager API\n\n```javascript\nvar world = require('nano-ecs')()\n```\n\n### world.createEntity()\n\nCreate a new, component-less entity.\n\n### world.removeAllEntities()\n\nRemove all entities from the world.\n\n### world.removeEntity(entity)\n\nRemove a specific entity by reference.\n\n### world.removeEntitiesByTag(tag)\n\nRemove all entities with a given tag.\n\n### world.queryComponents(components=[])\n\nReturns a list of all entities with the full list of components given.\n\n### world.queryTag(tag)\n\nReturns a list of all entities with the given tag.\n\n### world.count()\n\nReturns the total number of entities in the world.\n\n\n## Entity API\n\n```javascript\nvar entity = require('nano-ecs')().createEntity()\n```\n\n### entity.remove()\n\nRemove the entity from the world.\n\n### entity.addComponent(TComponent)\n\nAdd a component to an entity, by constructor function name.\n\n### entity.removeComponent(TComponent)\n\nRemove a component from the entity, by constructor function name.\n\n### entity.hasComponent(TComponent)\n\nReturns true if the entity has the component (by constructor function name),\nfalse otherwise.\n\n### entity.hasAllComponents(components=[])\n\nReturns true if the entity has all of the components (by constructor function\nname), false otherwise.\n\n### entity.hasTag(tag)\n\nReturns true if the entity has the given tag, false otherwise.\n\n### entity.addTag(tag)\n\nAdds the given tag to the entity.\n\n### entity.removeTag(tag)\n\nRemove the given tag from the entity.\n\n\n## Testing\n\nTesting is done with [Tape](http://github.com/substack/tape) or any other\nsoftware supporting the [Test Anything Protocol](https://testanything.org) and\ncan be run with the command `npm test`. There is also a pre-commit hook that\nwill ensure tests pass before any commit is permitted.\n\n\n## License\nCopyright 2014 Brandon Valosek, forked and modified by Stephen Whitmore.\n\n**nano-ecs** is released under the MIT license.\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhackergrrl%2Fnano-ecs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhackergrrl%2Fnano-ecs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhackergrrl%2Fnano-ecs/lists"}