{"id":31473398,"url":"https://github.com/elnudev/konoyo","last_synced_at":"2025-10-01T21:54:44.111Z","repository":{"id":312493707,"uuid":"1047676959","full_name":"ElnuDev/konoyo","owner":"ElnuDev","description":"A very simple ECS implemented in Zig with heavy use of comptime.","archived":false,"fork":false,"pushed_at":"2025-08-31T03:19:14.000Z","size":34,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-31T03:32:44.988Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ElnuDev.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-31T00:49:45.000Z","updated_at":"2025-08-31T03:19:18.000Z","dependencies_parsed_at":"2025-08-31T03:42:54.412Z","dependency_job_id":null,"html_url":"https://github.com/ElnuDev/konoyo","commit_stats":null,"previous_names":["elnudev/konoyo"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ElnuDev/konoyo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElnuDev%2Fkonoyo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElnuDev%2Fkonoyo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElnuDev%2Fkonoyo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElnuDev%2Fkonoyo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ElnuDev","download_url":"https://codeload.github.com/ElnuDev/konoyo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ElnuDev%2Fkonoyo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277919964,"owners_count":25899460,"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","status":"online","status_checked_at":"2025-10-01T02:00:09.286Z","response_time":88,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":"2025-10-01T21:54:42.378Z","updated_at":"2025-10-01T21:54:44.107Z","avatar_url":"https://github.com/ElnuDev.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# konoyo\n\nA very simple ECS implemented in Zig with heavy use of comptime. Doesn't do anything fancy like archetypes.\n\nTo run the raylib exmaple, run `zig build -Dexample run`.\n\n## Getting started\n\nTo get started, import konoyo and initialize an ECS world type definition with a component list.\n\nComponent types must meet the following requirements:\n\n- name must end in \"Component\". This convention is enforced so it's clear what types in your project are queryable.\n- cannot be named \"EntityComponent\"\n- cannot be zero-sized (e.g. empty structs)\n\nOnce you have declared your world type, you can initialize it with an allocator. For each of the provided components, konoyo internally stores a hash table mapping from a `u32` entity ID to component instances.\n\nSupposing you have already defined a `TransformComponent` and `SpriteComponent` (the ones used here are the same in the [example](example)), you can set up konoyo as follows.\n\n```ZIG\nconst std = @import(\"std\");\nconst ecs = @import(\"konoyo\");\n\nconst World = ecs.World(\u0026[_]type{\n    TransformComponent,\n    SpriteComponent,\n});\n\nvar gpa = std.heap.GeneralPurposeAllocator(.{}){};\nconst allocator = gpa.allocator();\n\nvar world = World.init(allocator);\ndefer world.deinit();\n```\n\n### Spawning entities\n\nTo create an entity, call `world.createEntity`. This will return a unique ID for the created entity.\n\n```ZIG\nconst entity = world.createEntity();\n```\n\nYou can then add any component that was defined in the world definition.\n\n```ZIG\nworld.insert(entity, TransformComponent {\n    ...\n});\nworld.insert(entity, SpriteComponent {\n    ...\n});\n```\n\n### Querying entities\n\nTo query the world, call `world.query`, passing in a query slice of types you want your query to return. The query will return an array list of `QueryResult(Query)`. Each query result will contain an `entity` field with the entity ID and one field for each type in your query, e.g. querying for a `TransformComponent` will give you a `transform` field in every query result.\n\n```ZIG\nconst Query = \u0026[_]type{ *TransformComponent, *const SpriteComponent };\nconst results = world.query(query);\ndefer world.allocator.free(results);\nfor (results) |e| {\n    std.debug.print(\"Entity ID: {}\\n\", .{ e.entity });\n    e.transform.position.x += 42;\n    e.sprite.draw(e.transform.position);\n}\n```\n\nOptional components are also supported.\n\n```ZIG\nconst Query = \u0026[_]type{ *TransformComponent, ?*const SpriteComponent };\n```\n\nQueried types are immutable by default: `Component` is a valid shorthand for `*const Component`.\n\n```ZIG\nconst Query = \u0026[_]type{ *TransformComponent, ?SpriteComponent };\n```\n\n### More utils\n\n```ZIG\n// get total number of components with given component\n_ = world.count(SpriteComponent);\n\nconst entity = 0;\n// deleteEntity returns whether or not the entity existed to begin with\n_ = world.deleteEntity(entity);\n// delete returns whether or not the component existed to begin with\n_ = world.delete(entity, TransformComponent);\n// check if entity exists\n_ = world.entityExists(entity);\n```\n\n## Acknowledgements\n\nReimu fumo sprite by Jaysa under CC0 via [OpenGameArt.org](https://opengameart.org/content/touhou-fumo-factory)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felnudev%2Fkonoyo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felnudev%2Fkonoyo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felnudev%2Fkonoyo/lists"}