{"id":15896093,"url":"https://github.com/blackglory/extra-ecs","last_synced_at":"2026-01-03T11:43:52.044Z","repository":{"id":57289273,"uuid":"525021522","full_name":"BlackGlory/extra-ecs","owner":"BlackGlory","description":"🌲 A maintainable and readable entity component system implementation","archived":false,"fork":false,"pushed_at":"2024-09-04T13:46:47.000Z","size":2563,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-27T19:47:44.004Z","etag":null,"topics":["browser","esm","library","nodejs","npm-package","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/extra-ecs","language":"TypeScript","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/BlackGlory.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-15T14:36:20.000Z","updated_at":"2024-09-04T13:46:50.000Z","dependencies_parsed_at":"2024-09-05T17:08:16.993Z","dependency_job_id":null,"html_url":"https://github.com/BlackGlory/extra-ecs","commit_stats":{"total_commits":110,"total_committers":1,"mean_commits":110.0,"dds":0.0,"last_synced_commit":"8a45017fcee83c3c68b7087620cd96cbb212c161"},"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlackGlory%2Fextra-ecs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlackGlory%2Fextra-ecs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlackGlory%2Fextra-ecs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlackGlory%2Fextra-ecs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BlackGlory","download_url":"https://codeload.github.com/BlackGlory/extra-ecs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232320250,"owners_count":18504974,"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":["browser","esm","library","nodejs","npm-package","typescript"],"created_at":"2024-10-06T09:05:58.584Z","updated_at":"2026-01-03T11:43:51.998Z","avatar_url":"https://github.com/BlackGlory.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# extra-ecs\n## Install\n```sh\nnpm install --save extra-ecs\n# or\nyarn add extra-ecs\n```\n\n## Usage\n```ts\nimport { StructureOfArrays, float64 } from 'structure-of-arrays'\nimport { World, Query, allOf } from 'extra-ecs'\n\nconst Enabled = Symbol()\nconst Position = new StructureOfArrays({\n  x: float64\n, y: float64\n})\nconst Velocity = new StructureOfArrays({\n  x: float64\n, y: float64\n})\n\nconst world = new World()\nconst player = world.createEntityId()\nconst enemy = world.createEntityId()\nworld.addComponents(\n  player\n, [Position] // equivalent to [Position, { x: 0, y: 0 }]\n, [Velocity, { x: 10, y: 0 }]\n, [Enabled]\n)\nworld.addComponents(\n  enemy\n, [Position, { x: 100, y: 0 }]\n, [Velocitiy, { x: -10, y: 0 }]\n, [Enabled]\n)\n\nconst movableQuery = new Query(world, allOf(Position, Velocity, Enabled))\n\nfunction movementSystem(deltaTime: number): void {\n  for (const entityId of movableQuery.findAllEntityId()) {\n    Position.arrays.x[entityId] += Velocity.arrays.x[entityId] * deltaTime\n    Position.arrays.y[entityId] += Velocity.arrays.y[entityId] * deltaTime\n  }\n}\n\nmovementSystem(deltaTime)\n```\n\n## API\n```ts\ntype Component\u003cT extends Structure = any\u003e =\n| StructureOfArrays\u003cT\u003e\n| StructureOfSparseMaps\u003cT\u003e\n| symbol\n```\n\n### World\n```ts\ntype MapComponentsToComponentValuePairs\u003cT extends Array\u003cStructure | Falsy\u003e\u003e = {\n  [Index in keyof T]:\n    [Exclude\u003cT[Index], | Falsy\u003e] extends [infer U]\n    ? (\n        U extends Structure\n        ? (\n            Equals\u003cU, {}\u003e extends true\n            ? Falsy | [component: Component\u003cU\u003e]\n            : Falsy | [component: Component\u003cU\u003e, value?: MapTypesOfStructureToPrimitives\u003cU\u003e]\n          )\n        : never\n      )\n    : never\n}\n\nclass World {\n  getAllEntityIds(): Iterable\u003cnumber\u003e\n  createEntityId(): number\n  hasEntityId(entityId: number): boolean\n  removeEntityId(entityId: number): void\n\n  componentsExist\u003cT extends NonEmptyArray\u003cComponent\u003e\u003e(\n    entityId: number\n  , ...components: T\n  ): MapProps\u003cT, boolean\u003e\n  getComponents(entityId: number): Iterable\u003cComponent\u003e\n  addComponents\u003cT extends NonEmptyArray\u003cStructure | Falsy\u003e\u003e(\n    entityId: number\n  , ...componentValuePairs: MapComponentsToComponentValuePairs\u003cT\u003e\n  ): void\n  removeComponents\u003cT extends Structure\u003e(\n    entityId: number\n  , ...components: NonEmptyArray\u003cComponent\u003cT\u003e | Falsy\u003e\n  ): void\n}\n```\n\n### Query\n```ts\nclass Query {\n  constructor(world: World, pattern: Pattern)\n\n  hasEntityId(entityId: number): boolean\n  findAllEntityIds(): Iterable\u003cnumber\u003e\n\n  destroy(): void\n}\n```\n\n#### Patterns\n```ts\ntype Pattern =\n| Component\n| Expression\n\ntype Expression =\n| Not\n| AllOf\n| AnyOf\n| OneOf\n```\n\n##### and\n```ts\nfunction and(left: Pattern, right: Pattern): AllOf\n```\n\n##### or\n```ts\nfunction or(left: Pattern, right: Pattern): AnyOf\n```\n\n##### xor\n```ts\nfunction xor(left: Pattern, right: Pattern): OneOf\n```\n\n##### not\n```ts\nfunction not(...patterns: NonEmptyArray\u003cPattern\u003e): Not\n```\n\n`not(pattern1, pattern2) = not(anyOf(pattern1, pattern2))`\n\n##### allOf\n```ts\nfunction allOf(...patterns: NonEmptyArray\u003cPattern\u003e): AllOf\n```\n\n`allOf(pattern1, pattern2, pattern3) = and(and(pattern1, pattern2), pattern3)`\n\n##### anyOf\n```ts\nfunction anyOf(...patterns: NonEmptyArray\u003cPattern\u003e): AnyOf\n```\n\n`anyOf(pattern1, pattern2, pattern3) = or(or(pattern1, pattern2), pattern3)`\n\n##### oneOf\n```ts\nfunction oneOf(...patterns: NonEmptyArray\u003cPattern\u003e): OneOf\n```\n\n`oneOf(pattern1, pattern2, pattern3) = xor(xor(pattern1, pattern2), pattern3)`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblackglory%2Fextra-ecs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblackglory%2Fextra-ecs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblackglory%2Fextra-ecs/lists"}