Swiftpack.co - Package - fireblade-engine/ecs

Fireblade ECS (Entity-Component-System)

Build Status version 0.6.0 license swift version platforms

This is a dependency free, lightweight, fast and easy to use Entity-Component-System implementation in Swift. It is developed and maintained as part of the Fireblade Game Engine project.

See the Fireblade ECS Demo App to get started.

Getting Started

These instructions will get you a copy of the project up and running on your local machine and provide a code example.



Fireblade ECS is available for all platforms that support Swift 4.2 and higher and the Swift Package Manager (SPM).

Extend the following lines in your Package.swift file or use it to create a new project.

// swift-tools-version:4.2

import PackageDescription

let package = Package(
    name: "YourPackageName",
    dependencies: [
        .package(url: "https://github.com/fireblade-engine/ecs.git", from: "0.6.0")
    targets: [
            name: "YourTargetName",
            dependencies: ["FirebladeECS"])

Code Example

The core element in the Fireblade-ECS is the Nexus. It acts as a centralized way to store, access and manage entities and their components. A single Nexus may (theoretically) hold up to 4294967295 Entities at a time.
You may use more than one Nexus at a time.

Initialize a Nexus with

let nexus = Nexus()

then create entities by letting the Nexus generate them.

let myEntity = nexus.create(entity: "myEntity")

You can define Components like this

class Movement: Component {
	var position: (x: Double, y: Double) = (0.0, 1.0)
	var velocity: Double = 0.1

and assign instances of them to an Entity with

let movement = Movement()


This ECS uses a grouping approach for entities with the same component types to optimize cache locality and ease up access to them.
Entities with the same component types may belong to one Family. A Family has entities as members and component types as family traits.

Create a family by calling .family with a set of traits on the nexus. A family that containts only entities with a Movement and PlayerInput component, but no Texture component is created by

let family = nexus.family(requiresAll: Movement.self, PlayerInput.self,
                          excludesAll: Texture.self)

These entities are cached in the nexus for efficient access and iteration. Families conform to the Sequence protocol so that members (components) may be iterated and accessed like any other sequence in Swift.
Access a familiy's components directly on the family instance. To get family entities and access components at the same time call family.entityAndComponents. If you are only interested in a family's entities call family.entities.

class PlayerMovementSystem {
	let family = nexus.family(requiresAll: Movement.self, PlayerInput.self,
                              excludesAll: Texture.self)

	func update() {
			.forEach { (mov: Movement, input: PlayerInput) in
			// position & velocity component for the current entity
			// get properties
			_ = mov.position
			_ = mov.velocity
			// set properties
			mov.position.x = mov.position.x + 3.0
			// current input command for the given entity
			_ = input.command

	func update2() {
			.forEach { (entity: Entity, mov: Movement, input: PlayerInput) in
			// the currenty entity instance
			_ = entity

			// position & velocity component for the current entity
			// get properties
			_ = mov.position
			_ = mov.velocity

	func update3() {
			.forEach { (entity: Entity) in
			// the currenty entity instance
			_ = entity


A 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 character. Single components must conform to the SingleComponent protocol and will not be available through regular family iteration.

final class GameState: SingleComponent {
    var quitGame: Bool = false
class GameLogicSystem {
    let gameState: Single<GameState>
    init(nexus: Nexus) {
        gameState = nexus.single(GameState.self)
    func update() {
        // update your game sate here
        gameState.component.quitGame = true
        // entity access is provided as well
        _ = gameState.entity


See the Fireblade ECS Demo App to get started.


We use SemVer for versioning. For the versions available, see the tags on this repository.


See also the list of contributors who participated in this project.


This project is licensed under the MIT License - see the LICENSE file for details


Inspired by


Stars: 8
Help us keep the lights on


Used By

Total: 1


0.6.3 - Mar 8, 2019

  • Fixes a bug in the sparse set implementation
  • Add Swift 5 compatibility
  • Improvements
  • Cleanups

0.6.0 - Feb 14, 2019

  • Adds concept of a Single
  • Families are now structs
  • Bugfixes
  • Improve code coverage
  • Divide tests into unit tests and performance tests
  • Cleanups

0.5.1 - Dec 4, 2018

  • Conform TypedFamily to Sequence
  • Cleanups
  • Account for number of components in nexus for equatable comparison

0.5.0 - Sep 29, 2018

  • rework of the family access to support LazySequenceProtocol
  • renamed Family to TypedFamily[1-5]
  • family members (aka components) may be accessed directly on the family instance (sequence)
  • family's entities may be accessed via family.entities (sequence)
  • family's entities + components may be accessed via family.entityAndComponents (sequence)
  • extended tests
  • added more performance measures

0.4.3 - Sep 27, 2018

  • Cleanups
  • ACL
  • Travis CI integration