{"id":22666648,"url":"https://github.com/fireblade-engine/ecs","last_synced_at":"2025-04-05T19:11:39.872Z","repository":{"id":28131194,"uuid":"116304503","full_name":"fireblade-engine/ecs","owner":"fireblade-engine","description":"A dependency free, lightweight, fast Entity-Component System (ECS) implementation in Swift","archived":false,"fork":false,"pushed_at":"2024-10-01T16:12:28.000Z","size":811,"stargazers_count":109,"open_issues_count":10,"forks_count":10,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-06T18:02:30.143Z","etag":null,"topics":["ecs","entity","entity-component-system","entitycomponentsystem","fireblade-engine","game-development","game-engine","gamedev","ios","linux","macos","spm","swift","swift-package-manager","windows"],"latest_commit_sha":null,"homepage":"","language":"Swift","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/fireblade-engine.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["ctreffs"],"custom":["https://www.paypal.com/donate?hosted_button_id=GCG3K54SKRALQ"]}},"created_at":"2018-01-04T20:29:07.000Z","updated_at":"2024-09-10T08:49:44.000Z","dependencies_parsed_at":"2024-02-26T21:29:52.809Z","dependency_job_id":"1834f405-19e3-4da4-aeef-ff60b4f73cf6","html_url":"https://github.com/fireblade-engine/ecs","commit_stats":{"total_commits":492,"total_committers":6,"mean_commits":82.0,"dds":"0.21138211382113825","last_synced_commit":"6f1ddd2bc47f91dcc11e4dba7394c27efdefcd18"},"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fireblade-engine%2Fecs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fireblade-engine%2Fecs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fireblade-engine%2Fecs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fireblade-engine%2Fecs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fireblade-engine","download_url":"https://codeload.github.com/fireblade-engine/ecs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247386264,"owners_count":20930619,"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":["ecs","entity","entity-component-system","entitycomponentsystem","fireblade-engine","game-development","game-engine","gamedev","ios","linux","macos","spm","swift","swift-package-manager","windows"],"created_at":"2024-12-09T14:17:29.022Z","updated_at":"2025-04-05T19:11:39.840Z","avatar_url":"https://github.com/fireblade-engine.png","language":"Swift","readme":"# Fireblade ECS (Entity-Component System)\n[![license](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE)\n[![macOS](https://github.com/fireblade-engine/ecs/actions/workflows/ci-macos.yml/badge.svg)](https://github.com/fireblade-engine/ecs/actions/workflows/ci-macos.yml)\n[![Linux](https://github.com/fireblade-engine/ecs/actions/workflows/ci-linux.yml/badge.svg)](https://github.com/fireblade-engine/ecs/actions/workflows/ci-linux.yml)\n[![Windows](https://github.com/fireblade-engine/ecs/actions/workflows/ci-windows.yml/badge.svg)](https://github.com/fireblade-engine/ecs/actions/workflows/ci-windows.yml)\n[![WASM](https://github.com/fireblade-engine/ecs/actions/workflows/ci-wasm.yml/badge.svg)](https://github.com/fireblade-engine/ecs/actions/workflows/ci-wasm.yml)\n[![documentation](https://github.com/fireblade-engine/ecs/workflows/Documentation/badge.svg)](https://github.com/fireblade-engine/ecs/wiki)  \n[![codecov](https://codecov.io/gh/fireblade-engine/ecs/branch/master/graph/badge.svg)](https://codecov.io/gh/fireblade-engine/ecs)\n[![spi-swift-versions](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Ffireblade-engine%2Fecs%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/fireblade-engine/ecs)\n[![spi-swift-platforms](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Ffireblade-engine%2Fecs%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/fireblade-engine/ecs)\n\nThis is a **dependency free**, **lightweight**, **fast** and **easy to use** [Entity-Component System](https://en.wikipedia.org/wiki/Entity_component_system) implementation in Swift. It is developed and maintained as part of the [Fireblade Game Engine project](https://github.com/fireblade-engine).\n\nSee the [Fireblade ECS Demo App](https://github.com/fireblade-engine/ecs-demo) or have a look at [documentation in the wiki](https://github.com/fireblade-engine/ecs/wiki) to get started.\n\n## 🚀 Getting Started\n\nThese instructions will get you a copy of the project up and running on your local machine and provide a code example.\n\n### 📋 Prerequisites\n\n* [Swift Package Manager (SPM)](https://github.com/apple/swift-package-manager)\n* [Swiftlint](https://github.com/realm/SwiftLint) for linting - (optional)\n* [SwiftEnv](https://swiftenv.fuller.li/) for Swift version management - (optional)\n\n### 💻 Installing\n\nFireblade ECS is available for all platforms that support [Swift 5.8](https://swift.org/) and higher and the [Swift Package Manager (SPM)](https://github.com/apple/swift-package-manager).\n\nExtend the following lines in your `Package.swift` file or use it to create a new project.\n\n```swift\n// swift-tools-version:5.8\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"YourPackageName\",\n    dependencies: [\n        .package(url: \"https://github.com/fireblade-engine/ecs.git\", from: \"0.17.5\")\n    ],\n    targets: [\n        .target(\n            name: \"YourTargetName\",\n            dependencies: [\"FirebladeECS\"])\n    ]\n)\n\n```\n\n## 📝 Code Example\n\n### 🏛️ Nexus\n\nThe core element in the Fireblade-ECS is the [Nexus](https://en.wiktionary.org/wiki/nexus#Noun). \nIt acts as a centralized way to store, access and manage entities and their components. \nA single `Nexus` may (theoretically) hold up to 4294967295 `Entities` at a time.   \nYou may use more than one `Nexus` at a time.\n\nInitialize a `Nexus` with\n\n```swift\nlet nexus = Nexus()\n```\n\n### 👤 Entities\n\nthen create entities by letting the `Nexus` generate them.\n\n```swift\n// an entity without components\nlet newEntity = nexus.createEntity()\n```\n\nTo define components, conform your class to the `Component` protocol\n\n```swift\nfinal class Position: Component {\n\tvar x: Int = 0\n\tvar y: Int = 0\n}\n```\nand assign instances of it to an `Entity` with\n\n```swift\nlet position = Position(x: 1, y: 2)\nentity.assign(position)\n```\n\nYou can be more efficient by assigning components while creating an entity.\n\n```swift\n// an entity with two components assigned.\nnexus.createEntity {\n\tPosition(x: 1, y: 2)\n\tColor(.red)\n}\n\n// bulk create entities with multiple components assigned.\nnexus.createEntities(count: 100) { _ in\n\tPosition()\n\tColor()\n}\n\n```\n### 👪 Families\n\nThis ECS uses a grouping approach for entities with the same component types to optimize cache locality and ease up access to them.   \nEntities with the __same component types__ may belong to one `Family`. \nA `Family` has entities as members and component types as family traits.\n\nCreate a family by calling `.family` with a set of traits on the nexus.\nA family that contains only entities with a `Movement` and `PlayerInput` component, but no `Texture` component is created by\n\n```swift\nlet family = nexus.family(requiresAll: Movement.self, PlayerInput.self,\n                          excludesAll: Texture.self)\n```\n\nThese entities are cached in the nexus for efficient access and iteration.\nFamilies conform to the [Sequence](https://developer.apple.com/documentation/swift/sequence) protocol so that members (components) \nmay be iterated and accessed like any other sequence in Swift.   \nAccess a family's components directly on the family instance. To get family entities and access components at the same time call `family.entityAndComponents`.\nIf you are only interested in a family's entities call `family.entities`.\n\n```swift\nclass PlayerMovementSystem {\n\tlet family = nexus.family(requiresAll: Movement.self, PlayerInput.self,\n                              excludesAll: Texture.self)\n\n\tfunc update() {\n\t\tfamily\n\t\t\t.forEach { (mov: Movement, input: PlayerInput) in\n\t\t\t\n\t\t\t// position \u0026 velocity component for the current entity\n\t\t\t\n\t\t\t// get properties\n\t\t\t_ = mov.position\n\t\t\t_ = mov.velocity\n\t\t\t\n\t\t\t// set properties\n\t\t\tmov.position.x = mov.position.x + 3.0\n\t\t\t...\n\t\t\t\n\t\t\t// current input command for the given entity\n\t\t\t_ = input.command\n\t\t\t...\n\t\t\t\n\t\t}\n\t}\n\n\tfunc update2() {\n\t\tfamily\n\t\t\t.entityAndComponents\n\t\t\t.forEach { (entity: Entity, mov: Movement, input: PlayerInput) in\n\t\t\t\n\t\t\t// the current entity instance\n\t\t\t_ = entity\n\n\t\t\t// position \u0026 velocity component for the current entity\n\t\t\t\n\t\t\t// get properties\n\t\t\t_ = mov.position\n\t\t\t_ = mov.velocity\n\t\t\t\n\t\t\t\n\t\t}\n\t}\n\n\tfunc update3() {\n\t\tfamily\n\t\t\t.entities\n\t\t\t.forEach { (entity: Entity) in\n\t\t\t\n\t\t\t// the current entity instance\n\t\t\t_ = entity\n\t\t}\n\t}\n}\n```\n\n### 🧑 Singles\n\nA `Single` on the other hand is a special kind of family that holds exactly **one** entity with exactly **one** component for the entire lifetime of the Nexus. This may come in handy if you have components that have a [Singleton](https://en.wikipedia.org/wiki/Singleton_(mathematics)) character. Single components must conform to the `SingleComponent` protocol and will not be available through regular family iteration.\n\n```swift\nfinal class GameState: SingleComponent {\n    var quitGame: Bool = false\n}\nclass GameLogicSystem {\n    let gameState: Single\u003cGameState\u003e\n    \n    init(nexus: Nexus) {\n        gameState = nexus.single(GameState.self)\n    }\n    \n    func update() {\n        // update your game sate here\n        gameState.component.quitGame = true\n        \n        // entity access is provided as well\n        _ = gameState.entity\n    }\n}\n\n```\n\n### 🔗 Serialization\n\n\nTo serialize/deserialize entities you must conform their assigned components to the `Codable` protocol.  \nConforming components can then be serialized per family like this:\n\n```swift\n// MyComponent and YourComponent both conform to Component and Codable protocols.\nlet nexus = Nexus()\nlet family = nexus.family(requiresAll: MyComponent.self, YourComponent.self)\n\n// JSON encode entities from given family.\nvar jsonEncoder = JSONEncoder()\nlet encodedData = try family.encodeMembers(using: \u0026jsonEncoder)\n\n// Decode entities into given family from JSON. \n// The decoded entities will be added to the nexus.\nvar jsonDecoder = JSONDecoder()\nlet newEntities = try family.decodeMembers(from: jsonData, using: \u0026jsonDecoder)\n\n```\n\n## 🧪 Demo\n\nSee the [Fireblade ECS Demo App](https://github.com/fireblade-engine/ecs-demo) to get started.\n\n## 📖 Documentation\n\nConsult the [online documentation](https://swiftpackageindex.com/fireblade-engine/ecs/documentation/FirebladeECS), or preview it locally:\n\n- `make preview-docs`\n\n## 💁 How to contribute\n\nIf you want to contribute please see the [CONTRIBUTION GUIDE](CONTRIBUTING.md) first. \n\nTo start your project contribution run these in your command line:\n\n1. `git clone git@github.com:fireblade-engine/ecs.git fireblade-ecs`\n2. `cd fireblade-ecs`\n3. `make setupEnvironment`\n\nBefore commiting code please ensure to run:\n\n- `make precommit`\n\nThis project is currently maintained by [Christian Treffs](https://github.com/ctreffs).   \nSee also the list of [contributors](https://github.com/fireblade-engine/ecs/contributors) who participated in this project.\n\n## 🔏 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details\n\n## 🙏 Acknowledgments\n\nInspired by  \n\n- [Ashley](https://github.com/libgdx/ashley)\n- [Entitas](https://github.com/sschmid/Entitas-CSharp)\n- [EntitasKit](https://github.com/mzaks/EntitasKit)\n","funding_links":["https://github.com/sponsors/ctreffs","https://www.paypal.com/donate?hosted_button_id=GCG3K54SKRALQ"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffireblade-engine%2Fecs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffireblade-engine%2Fecs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffireblade-engine%2Fecs/lists"}