{"id":20932322,"url":"https://github.com/excessive/pecs","last_synced_at":"2026-04-02T01:16:23.828Z","repository":{"id":149595708,"uuid":"68143715","full_name":"excessive/pecs","owner":"excessive","description":"Practical Entity Component System","archived":false,"fork":false,"pushed_at":"2019-01-12T05:02:12.000Z","size":13,"stargazers_count":18,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-06T15:07:21.142Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/excessive.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2016-09-13T20:12:24.000Z","updated_at":"2024-12-22T14:52:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"b1f1aca0-84fa-483d-abc4-a06bfd38b09a","html_url":"https://github.com/excessive/pecs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/excessive/pecs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excessive%2Fpecs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excessive%2Fpecs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excessive%2Fpecs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excessive%2Fpecs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/excessive","download_url":"https://codeload.github.com/excessive/pecs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excessive%2Fpecs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31293748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T01:05:07.454Z","status":"ssl_error","status_checked_at":"2026-04-02T00:56:46.496Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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-11-18T21:48:00.208Z","updated_at":"2026-04-02T01:16:23.811Z","avatar_url":"https://github.com/excessive.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Practical Entity Component System\n\nPECS is a practical, powerful, and provocative ECS designed to be easy to use,\neasy to understand, and **FAST**! Build PECS into your game and let it do all\nthe heavy lifting for you!\n\n## Building\nTo use PECS in your own project, just update your include paths and `#include \u003cpecs.hpp\u003e`.\n\nTo compile the example, make sure [GENie](https://github.com/bkaradzic/GENie) is in your path and then simply run `make`.\n\n## Requirements\nAny more-or-less C++11-compatible compiler. May support older compilers in the future, but we like Lambdas and range-based for.\n\nKnown good:\n- VS 2013\n- GCC 6.1 (older should be fine)\n- Clang 3.8 (older should be fine)\n\n## Example\n\n```cpp\n#include \"pecs.hpp\"\n\nusing namespace pecs;\n\n// Define a bunch of component groups\nenum {\n\tCOMPONENT_ANY       = 0,\n\tCOMPONENT_INFO      = 1 \u003c\u003c 0,\n\tCOMPONENT_TRANSFORM = 1 \u003c\u003c 1\n};\n\nstruct component_info_t {\n\tstd::string name;\n};\n\nstruct component_transform_t {\n\tfloat position[3];\n\tfloat scale[3];\n\tfloat orientation[4];\n\tfloat direction[3];\n};\n\n// Resize components as more entities flood in\ntemplate \u003ctypename T\u003e\nvoid resize(std::vector\u003cT\u003e \u0026components, uint32_t id) {\n\tsize_t c = components.capacity();\n\n\twhile (c \u003c= id) {\n\t\tc = std::max\u003csize_t\u003e(c, 1);\n\t\tc = c \u003c\u003c 1;\n\t}\n\n\tif (components.size() \u003c= id) {\n\t\tcomponents.reserve(c);\n\t\tcomponents.resize(id+1);\n\t}\n}\n\nstruct test_world_t : world_t {\n\tstd::vector\u003ccomponent_info_t\u003e      infos;\n\tstd::vector\u003ccomponent_transform_t\u003e transforms;\n\n\tvoid set_component(entity_t *entity, component_info_t component) {\n\t\tentity-\u003emask |= COMPONENT_INFO;\n\t\tresize(this-\u003einfos, entity-\u003eid);\n\t\tthis-\u003einfos[entity-\u003eid] = component;\n\t}\n\n\tvoid set_component(entity_t *entity, component_transform_t component) {\n\t\tentity-\u003emask |= COMPONENT_TRANSFORM;\n\t\tresize(this-\u003etransforms, entity-\u003eid);\n\t\tthis-\u003etransforms[entity-\u003eid] = component;\n\t}\n};\n\nstruct test_system_t : system_t {\n\tstd::string name;\n\n\ttest_system_t(std::string name) {\n\t\tthis-\u003ename     = name;\n\t\tthis-\u003epriority = 0;\n\t\tthis-\u003emask     = COMPONENT_INFO | COMPONENT_TRANSFORM;\n\t}\n\n\tvoid on_add(world_t *world) {\n\t\tprintf(\"Added system to world!\\n\");\n\t}\n\n\tvoid on_remove(world_t *world) {\n\t\tprintf(\"Removed system from world!\\n\");\n\t}\n\n\tvoid on_add(entity_t *entity) {\n\t\tprintf(\"Added entity to system!\\n\");\n\t}\n\n\tvoid on_remove(entity_t *entity) {\n\t\tprintf(\"Removed entity form system!\\n\");\n\t}\n\n\tvoid update(double dt) {\n\t\ttest_world_t *world = (test_world_t*)this-\u003eworld;\n\n\t\tfor (auto \u0026entity : world-\u003eentities) {\n\t\t\tPECS_SKIP_INVALID_ENTITY;\n\n\t\t\tauto \u0026info = world-\u003einfos[entity.id];\n\t\t\tprintf(\"%s\\n\", info.name.c_str());\n\n\t\t\tauto \u0026transform = world-\u003etransforms[entity.id];\n\t\t\ttransform.position[0] += transform.position[1];\n\n\t\t\t(void)info;\n\t\t\t(void)transform;\n\t\t}\n\t}\n};\n\nint main(int argc, char* argv[]) {\n\t// Create new world\n\ttest_world_t world;\n\n\t// Create new system\n\ttest_system_t a = test_system_t(\"Test System\");\n\tworld.add(\u0026a);\n\n\t// Create new entities\n\tconst size_t num_entities = 5;\n\tprintf(\"Adding %ld entities...\\n\", num_entities);\n\n\tfor (size_t i = 0; i \u003c num_entities; i++) {\n\t\tentity_t entity = world.get_entity();\n\t\tworld.set_component(\u0026entity,\n\t\t\tcomponent_info_t { \"I am an entity!\" }\n\t\t);\n\t\tworld.set_component(\u0026entity,\n\t\t\tcomponent_transform_t {\n\t\t\t\t{ 5.0, 6.0, 7.0 },\n\t\t\t\t{ 1.0, 1.0, 1.0 },\n\t\t\t\t{ 0.0, 0.0, 0.0, 1.0 },\n\t\t\t\t{ 0.0, 0.0, 1.0 }\n\t\t\t}\n\t\t);\n\t\tworld.add(entity);\n\t}\n\n\t// Run a few update cycles\n\tfor (int i = 0; i \u003c 10; i++) {\n\t\tworld.update(1.0);\n\t}\n\n\treturn 0;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexcessive%2Fpecs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexcessive%2Fpecs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexcessive%2Fpecs/lists"}