All Projects → outerminds → Entia

outerminds / Entia

Licence: MIT license
Entia is a free, open-source, data-oriented, highly performant, parallelizable and extensible Entity-Component-System (ECS) framework written in C# especially for game development.

Programming Languages

C#
18002 projects
powershell
5483 projects

Projects that are alternatives of or similar to Entia

URSA
[DEPRECATED] integrated ECS framework for Unity
Stars: ✭ 30 (+7.14%)
Mutual labels:  system, ecs, entity
entitas-python
Entitas ECS implementation in Python.
Stars: ✭ 41 (+46.43%)
Mutual labels:  system, ecs, entity
Entitycomponentsystemsamples
No description or website provided.
Stars: ✭ 4,218 (+14964.29%)
Mutual labels:  system, ecs, entity
uecs
Micro ECS
Stars: ✭ 30 (+7.14%)
Mutual labels:  system, ecs, entity
Geotic
Entity Component System library for javascript
Stars: ✭ 97 (+246.43%)
Mutual labels:  system, ecs, entity
Ecs Snake
Simple snake game powered by ecs framework.
Stars: ✭ 41 (+46.43%)
Mutual labels:  system, ecs, entity
Entitas Csharp
Entitas is a super fast Entity Component System (ECS) Framework specifically made for C# and Unity
Stars: ✭ 5,393 (+19160.71%)
Mutual labels:  ecs, entity
Kengine
Entity-Component-System (ECS) with a focus on ease-of-use, runtime extensibility and compile-time type safety and clarity.
Stars: ✭ 417 (+1389.29%)
Mutual labels:  ecs, entity
Entt
Gaming meets modern C++ - a fast and reliable entity component system (ECS) and much more
Stars: ✭ 6,017 (+21389.29%)
Mutual labels:  ecs, no-dependencies
ecs
A dependency free, lightweight, fast Entity-Component System (ECS) implementation in Swift
Stars: ✭ 79 (+182.14%)
Mutual labels:  ecs, entity
Htframework
Unity HTFramework, a rapid development framework of client to the unity.
Stars: ✭ 179 (+539.29%)
Mutual labels:  ecs, entity
Entitas Cpp
Entitas++ is a fast Entity Component System (ECS) C++11 port of Entitas C#
Stars: ✭ 229 (+717.86%)
Mutual labels:  ecs, entity
Rockgo
A developing game server framework,based on Entity Component System(ECS).
Stars: ✭ 532 (+1800%)
Mutual labels:  ecs, extensible
Actors.unity
🚀Actors is a framework empowering developers to make better games faster on Unity.
Stars: ✭ 437 (+1460.71%)
Mutual labels:  ecs, entity
dwarlixir
A dwarf-fortress clone / MUD / side project in Elixir
Stars: ✭ 46 (+64.29%)
Mutual labels:  mit, mit-license
magento-grid-colors
Magento 2 Grid Colors module for colorizing admin grids. Supports saving of states with the help of grid's bookmarks.
Stars: ✭ 54 (+92.86%)
Mutual labels:  mit, mit-license
entity-system-js
ensy - A very simple Entity System for JavaScript
Stars: ✭ 90 (+221.43%)
Mutual labels:  ecs, entity
Entitas-Redux
An entity-component framework for Unity with code generation and visual debugging
Stars: ✭ 84 (+200%)
Mutual labels:  ecs, entity
SpaceWar-ECS
A space war game made with ECS and JobSystem in Unity.
Stars: ✭ 26 (-7.14%)
Mutual labels:  ecs, entity
magento-ngrok
Magento 2 module for ngrok.io service support
Stars: ✭ 45 (+60.71%)
Mutual labels:  mit, mit-license

Entia

Entia is a free, open-source, data-oriented, highly performant, parallelizable and extensible Entity-Component-System (ECS) framework written in C# especially for game development. It takes advantage of the latest C#7+ features to represent state exclusively with contiguous structs. No indirection, no boxing, no garbage collection and no cache misses.

Since Entia is built using .Net Standard 2.0, it is compatible with .Net Core 2.0+, .Net Framework 4.6+, Mono 5.4+, Xamarin and any other implementation of .Net that follows the standard (see this page for more details). Therefore it is compatible with any game engine that has proper C# support.

📥 Download

For the full Unity game engine integration of the framework, see Entia.Unity.


Content


Installation

  • Download the most recent stable version of Entia.
  • Extract the 'Entia.zip' package in a relevant directory.
  • Add 'Entia.dll' and 'Entia.Core.dll' as dependencies in your project.
  • Optionally install the packaged Visual Studio 2017 extension 'Entia.Analyze.vsix' to get Entia specific code analysis.

Tutorial

  • Here is a snippet of code to get you up and running:
using Entia;
using Entia.Core;
using Entia.Modules;
using Entia.Phases;
using Entia.Systems;
using static Entia.Nodes.Node;

public static class Game
{
    public static void Run()
    {
        var world = new World();
        var controllers = world.Controllers();
        var resources = world.Resources();

        // As the name suggest, this execution node will execute its children 
        // in sequential order.
        var node = Sequence(
            // Insert systems here using 'System<T>()' where 'T' is your system type.
            System<Systems.Motion>(),
            System<Systems.ControllerInput>(),
            System<Systems.Health>());

        // A controller is built from the node to allow the execution of your systems.
        if (controllers.Control(node).TryValue(out var controller))
        {
            // This resource will allow the application to close.
            ref var game = ref resources.Get<Resources.Game>();
            // Executes a typical execution routine.
            controller.Run(in game.Quit);
        }
    }
}

namespace Resources
{
    public struct Game : IResource { public bool Quit; }
}

namespace Systems
{
    public struct Motion : IRun
    {
        public void Run() { /* TODO */ }
    }

    public struct ControllerInput : IRun
    {
        public void Run() { /* TODO */ }
    }

    public struct Health : IRun
    {
        public void Run() { /* TODO */ }
    }
}
  • For more details, please consult the wiki.

The Basics

ECS stands for Entity, Component, System. I will go into details about what each of those are, but they are going to be the elements that allow you to program efficiently and pleasantly in a data-oriented style. But what does 'data-oriented' mean, you ask? Well, data-oriented design (DOD) is a way of solving programming problems just like object-oriented programming (OOP). It differs mainly by its focus on memory layout which has some important ramifications such as separating data from logic. This separation makes programs more performant and more composable. Without going into details about DOD since many more knowledgeable articles already exist on the subject, it is to be known that Entia puts DOD at its core and that will translate in certain practices that require a certain amount of getting used to.

Ok, back to ECS. Most programmers have heard at some point that it is better to use composition over inheritance. That is because inheritance, even when well designed, is more rigid and harder to change after the fact compared to its composed equivalent and in game development, things tend to change all the time in unexpected ways. ECS takes the idea of composition to the extreme by removing inheritance and, as mentioned above, by separating data and logic. This effectively flattens the structure of programs and makes them much more granular and easier to assemble. So here's a brief definition of the essential elements of ECS:

  • Entity: an unique identifier (often implemented as a simple integer).
  • Component: a chunk of data associated with an Entity.
  • System: a piece of logic that processes a subset of all Entities and their associated Components.

So an Entity can be conceptually thought of as a container for Components, but this could be misleading since an Entity does not contain anything as it is only an identifier. All it does is group Components together such that they can be queried by Systems and as such it relates more to a key in a database table where the columns would be the Components than it does to a bag of Components.

As for Components, they must remain plain and inert data, meaning that they do not hold any logic whatsoever. No methods, no constructors, no destructors, no properties, no events, no nothing except public fields. This ensures that Components are easy to understand, predictable, easy to serialize and have a good memory layout. This might be surprising and/or worrying for a mind that is used to control the access to their object's data with properties and/or methods but I'm telling you that as soon as you let go of the idea of protecting/hiding data you eventually realize that it was not strictly necessary and that everything is actually alright.

Since Entities are just identifiers and Components are just inert chunks of data, we need something to actually does something in this program. Systems are the last missing piece. They are conceptually the equivalent to a function that take all the existing Entities and Components, filters the ones it is interested in and processes them in some way. This means that ideally, Systems do not hold any state since all the game state exists exclusively within Components. I say ideally because for optimization purposes, some System local state may be needed.


More Concepts

Entities, Components and Systems are the minimal set of concepts that the framework needs to be useful, but additional ones have been added for convenience and performance. I will very briefly expose them here, but each of these will be described in much more details in the wiki.

  • World: the collection of all existing Entities and Components. It is the giant block of data that manages all the other blocks of data. The World is also the basis for extensibility because it holds the framework's modules and allows anyone to add one. This makes the framework extremely adaptable to any game development setup.
  • Message: a temporary Component that is not attached to an Entity and that simplifies System communication.
  • Resource: a World-wide Component that is not attached to an Entity that holds global data.
  • Group: a list of all the Entities in a given World that conform to a query.
  • Node: a data wrapper around Systems that allow to define execution behavior and order.
  • Controller: a wrapper around Systems that executes them based on the behavior defined in nodes and that controls their state.
  • Phase: a data type that is associated with a phase of execution. It allows to run systems at different times such as initialization time, run time, dispose time or any other time that you care to define.

Recurrent Usage Patterns

I will specify here recurrent usage patterns that are used in the framework.

When in doubt, use a struct.

  • Almost everything you will implement when using the framework will be a struct. Entities are structs, Components are structs, Systems are structs and other concepts such as Messages, Resources, Queryables and Injectables are all structs.
  • The framework will enforce the usage of structs.
  • This (almost abusive) usage of structs is deliberate.
    • Structs are great for cache locality and as such will allow the CPU to access them much more quickly than reference types.
    • ECS is all about favoring composition and structs enforce this idea since they prevent any kind of OOP inheritance impulses that one could have.
    • Structs correspond much more appropriately to plain and inert data.
    • Structs don't require useless indirection and null checking when accessing members.
    • The cost of passing (copying) large structs around is nullified by C#7's ref returns.

Most concepts have an empty associated interface.

  • Components must implement IComponent, Systems must implement ISystem, Messages must implement IMessage and so on.
  • These interfaces are all empty but they enforce users to be explicit about their intent since all data would otherwise look alike.
  • The framework will enforce that you use the correct interface with the appropriate functionality.

Most things are extensible.

  • Whether you want to add a new way to query Entities or add you custom serialization module, there is a way to extend the framework to accommodate you.
  • The whole framework is implemented as extensions to the World which means that it is so extensible that you could, in principle, implement another ECS within Entia.
  • Most extensions use interfaces and/or attributes to allow efficient, flexible and AOT (ahead of time compilation) friendly extensions.
    • For example, to implement a new kind of query, you would have to define a struct that implements the IQueryable<T> (an empty interface) where T is an IQuerier and define a type that implements IQuerier (a non-empty interface that builds queries).
    • This interface-linking pattern (an interface that has for main purpose to link a type T) is used a lot in the framework. It makes it explicit what the default implementation for concepts is and ensures that those linked types are properly AOT compiled even when using generic types.
    • AOT support is essential since some target platforms (such as iOS) require it.
  • Most existing implementations can be replaced with your own.
    • If you don't like how the framework parallelizes your Systems, you can replace the threading model by your own.
    • Most modules are implemented as a map between a specification type and an implementation interface and expose a Set method such that implementations can be replaced.
  • It is to be noted that extensions may require a fair amount of knowledge about how the framework works to make them work properly. I have tried to make relatively small modules such that extending one doesn't require too much knowledge, but still consider this as an advanced feature.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].