Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 22KB

2 years ago
6 years ago
2 years ago
5 years ago
2 years ago
2 years ago
2 years ago
4 months ago
2 years ago
4 months ago
2 years ago
4 months ago
2 years ago
4 months ago
2 years ago
4 months ago
2 years ago
4 months ago
2 years ago
2 years ago
4 months ago
2 years ago
4 months ago
2 years ago
4 months ago
2 years ago
4 months ago
2 years ago
4 months ago
2 years ago
4 months ago
2 years ago
4 months ago
2 years ago
2 years ago
4 months ago
2 years ago
2 years ago
5 years ago
2 years ago
2 years ago
4 months ago
5 years ago
2 years ago
7 months ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
2 years ago
6 years ago
6 years ago
3 years ago
3 years ago
4 years ago
5 years ago
2 years ago
3 years ago
2 years ago
3 years ago
2 years ago
6 years ago
3 years ago
3 years ago
2 years ago
3 years ago
3 years ago
3 years ago
6 years ago
6 years ago
3 years ago
3 years ago
5 years ago
2 years ago
2 years ago
2 years ago
6 years ago
3 years ago
6 years ago
10 months ago
5 years ago
3 years ago
8 months ago
2 years ago
6 years ago
3 years ago
6 years ago
6 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. # Svelto.ECS C# Entity Component System framework
  2. Real ECS framework for c\#. Enables to write encapsulated, decoupled, maintainable, highly efficient, data oriented, cache friendly, code without pain. Although the framework is platform agnostic \(compatible with c\# 7 and above and .net standard 2.0 and above\), it comes with several Unity extensions.
  3. ## Svelto.ECS in pills
  4. Svelto.ECS is easy to start with, but full of tricks for expert users. The hardest problem to overcome is usually to shift mentality from OOP programming to ECS programming rather than using the framework itself. If you would like to read an ECS faq, you can check this article: https://github.com/SanderMertens/ecs-faq
  5. ### Svelto.ECS at glance
  6. simplest setup:
  7. ```csharp
  8. using System;
  9. using Svelto.ECS;
  10. using Svelto.ECS.Schedulers;
  11. using Svelto.ECS.Vanilla.Example.SimpleEntityEngine;
  12. /// <summary>
  13. /// This is the common pattern to declare Svelto Exclusive Groups (usually split by composition root)
  14. /// </summary>
  15. public static class ExclusiveGroups
  16. {
  17. public static ExclusiveGroup group0 = new ExclusiveGroup();
  18. public static ExclusiveGroup group1 = new ExclusiveGroup();
  19. }
  20. namespace Svelto.ECS.Vanilla.Example
  21. {
  22. /// <summary>
  23. /// The Context is the application starting point.
  24. /// As a Composition root, it gives to the coder the responsibility to create, initialize and
  25. /// inject dependencies.
  26. /// Every application can have more than one context and every context can have one
  27. /// or more composition roots (a facade, but even a factory, can be a composition root)
  28. /// </summary>
  29. public class SimpleContext
  30. {
  31. public SimpleContext()
  32. {
  33. //an entity submission scheduler is needed to submit entities to the Svelto database, Svelto is not
  34. //responsible to decide when to submit entities, it's the user's responsibility to do so.
  35. var entitySubmissionScheduler = new SimpleEntitiesSubmissionScheduler();
  36. //An EnginesRoot holds all the engines and entities created. it needs a EntitySubmissionScheduler to know when to
  37. //add previously built entities to the Svelto database. Using the SimpleEntitiesSubmissionScheduler
  38. //is expected as it gives complete control to the user about when the submission happens
  39. _enginesRoot = new EnginesRoot(entitySubmissionScheduler);
  40. //an entity factory allows to build entities inside engines
  41. var entityFactory = _enginesRoot.GenerateEntityFactory();
  42. //the entity functions allows other operations on entities, like remove and swap
  43. var entityFunctions = _enginesRoot.GenerateEntityFunctions();
  44. //Add the Engine to manage the SimpleEntities
  45. var behaviourForEntityClassEngine = new BehaviourForEntityClassEngine(entityFunctions);
  46. _enginesRoot.AddEngine(behaviourForEntityClassEngine);
  47. //build Entity with ID 0 in group0
  48. entityFactory.BuildEntity<SimpleEntityDescriptor>(new EGID(0, ExclusiveGroups.group0));
  49. //submit the previously built entities to the Svelto database
  50. entitySubmissionScheduler.SubmitEntities();
  51. //as Svelto doesn't provide an engine/system ticking system, it's the user's responsibility to
  52. //update engines
  53. behaviourForEntityClassEngine.Update();
  54. Console.Log("Done - click any button to quit");
  55. System.Console.ReadKey();
  56. Environment.Exit(0);
  57. }
  58. readonly EnginesRoot _enginesRoot;
  59. }
  60. //An EntityComponent must always implement the IEntityComponent interface
  61. //don't worry, boxing/unboxing will never happen.
  62. public struct EntityComponent : IEntityComponent
  63. {
  64. public int counter;
  65. }
  66. /// <summary>
  67. /// The EntityDescriptor identifies your Entity. It's essential to identify
  68. /// your entities with a name that comes from the Game Design domain.
  69. /// </summary>
  70. class SimpleEntityDescriptor : GenericEntityDescriptor<EntityComponent> { }
  71. namespace SimpleEntityEngine
  72. {
  73. public class BehaviourForEntityClassEngine :
  74. //this interface makes the engine reactive, it's absolutely optional, you need to read my articles
  75. //and wiki about it.
  76. IReactOnAddEx<EntityComponent>, IReactOnSwapEx<EntityComponent>, IReactOnRemoveEx<EntityComponent>,
  77. //while this interface is optional too, it's almost always used as it gives access to the entitiesDB
  78. IQueryingEntitiesEngine
  79. {
  80. //extra entity functions
  81. readonly IEntityFunctions _entityFunctions;
  82. public BehaviourForEntityClassEngine(IEntityFunctions entityFunctions)
  83. {
  84. _entityFunctions = entityFunctions;
  85. }
  86. public EntitiesDB entitiesDB { get; set; }
  87. public void Ready() { }
  88. public void Update()
  89. {
  90. //Simple query to get all the entities with EntityComponent in group1
  91. var (components, entityIDs, count) = entitiesDB.QueryEntities<EntityComponent>(ExclusiveGroups.group1);
  92. uint entityID;
  93. for (var i = 0; i < count; i++)
  94. {
  95. components[i].counter++;
  96. entityID = entityIDs[i];
  97. }
  98. Console.Log("Entity Struct engine executed");
  99. }
  100. //the following methods are called by Svelto.ECS when an entity is added to a group
  101. public void Add((uint start, uint end) rangeOfEntities, in EntityCollection<EntityComponent> entities
  102. , ExclusiveGroupStruct groupID)
  103. {
  104. var (_, entityIDs, _) = entities;
  105. for (uint index = rangeOfEntities.start; index < rangeOfEntities.end; index++)
  106. //Swap entities between groups is a very common operation and it's necessary to
  107. //move entities between groups/sets. A Group represent a state/adjective of an entity, so changing
  108. //group means change state/behaviour as different engines will process different groups.
  109. //it's the Svelto equivalent of adding/remove components to an entity at run time
  110. _entityFunctions.SwapEntityGroup<SimpleEntityDescriptor>(new EGID(entityIDs[index], groupID), ExclusiveGroups.group1);
  111. }
  112. //the following methods are called by Svelto.ECS when an entity is swapped from a group to another
  113. public void MovedTo((uint start, uint end) rangeOfEntities, in EntityCollection<EntityComponent> entities
  114. , ExclusiveGroupStruct fromGroup, ExclusiveGroupStruct toGroup)
  115. {
  116. var (_, entityIDs, _) = entities;
  117. for (var index = rangeOfEntities.start; index < rangeOfEntities.end; index++)
  118. {
  119. Console.Log($"entity {entityIDs[index]} moved from {fromGroup} to {toGroup}");
  120. //like for the swap operation, removing entities from the Svelto database is a very common operation.
  121. //For both operations is necessary to specify the EntityDescriptor to use. This has also a philosophical
  122. //reason to happen, it's to always remind which entity type we are operating with.
  123. _entityFunctions.RemoveEntity<SimpleEntityDescriptor>(new EGID(entityIDs[index], toGroup));
  124. }
  125. }
  126. //the following methods are called by Svelto.ECS when an entity is removed from a group
  127. public void Remove((uint start, uint end) rangeOfEntities, in EntityCollection<EntityComponent> entities, ExclusiveGroupStruct groupID)
  128. {
  129. var (_, entityIDs, _) = entities;
  130. for (uint index = rangeOfEntities.start; index < rangeOfEntities.end; index++)
  131. Console.Log($"entity {entityIDs[index]} removed from {groupID.ToString()}");
  132. }
  133. }
  134. }
  135. }
  136. ```
  137. learn more about svelto on the Wiki page: https://github.com/sebas77/Svelto.ECS/wiki
  138. ## Svelto.ECS philosophy
  139. Svelto.ECS wasn't born just from the needs of a large team, but also as a result of years of reasoning behind software engineering applied to game development. Svelto.ECS hasn't been created just to write faster code, it has been designed to help developing better code. Performance gains is just one of the benefits in using Svelto.ECS, as ECS is a great way to write cache-friendly code. Svelto.ECS has been developed with the idea of ECS being a paradigm and not just a pattern, helping the user to shift away from Object Oriented Programming with consequent improvements on the code design and code maintainability. Svelto.ECS is the result of years of iteration of the ECS paradigm applied to real game development with the intent to be as foolproof as possible. Svelto.ECS has been designed to be used by a medium-size/large team working on long term projects where the cost of maintainability is relevant.
  140. ## Is it Archetype? Is it Sparse set? No it's something else :O
  141. **Svelto.ECS** is loosely based on the **Archetype** idea. The main difference compared to any other Archetype-based model is that Svelto Archetypes are static, meaning that users cannot add or remove components at runtime. There are many design reasons behind this decision, including the fact that users are often not aware of the costs of structural changes.
  142. While other frameworks typically limit user freedom to avoid exposing flaws in the archetype-based concept, Svelto.ECS introduces the concept of **groups**. This is simply an explicit way for the user to define sets of entities and iterate through them as quickly as possible.
  143. **GroupCompounds** build on this idea by allowing users to change the "state"/"set"/"group" according to tags that serve effectively as adjective or state identifiers.
  144. Entities can change state moving between sets swapping them in groups explcitly, rather than changing archetype.
  145. ## Why using Svelto.ECS with Unity?
  146. Svelto.ECS doens't use a traditional archetype model like DOTS ECS does. The novel hybrid approach based on groups instead than archetypes has been designed to allow the user to take the right decision when it comes to states management. Svelto.ECS doesn't allow archetypes to change dynamically, the user cannot add or remove components after the entity is created. Handling entities states with components can quickly lead to very intensive structural changes operations, so groups have been introduced to avoid the wild explosion of states permutations and let the user see explicitly the cost of their decisions.
  147. Filters have been added to make the handling of multiple states even more flexible by adding a new dimension to subset creation. Using filters it's possible to subset groups while avoiding structural changes (that happens when changing groups in Svelto.ECS too). DOTS engineers also realised this and consequentially introduced the new *Enableable components* which are less flexible than the Svelto.ECS filters as they implicitly tie the subsets to enabled/disabled components, while Filters in Svelto.ECS don't.
  148. Thanks to the explicit use of Groups and Filters, the Svelto user is able to find the right trade off to handle entities states.
  149. _Svelto.ECS is lean. It hasn't been designed to move a whole engine such as Unity from OOP to ECS, therefore it doesn't suffer from unjustifiable complexity overhead to try to solve problems that often are not linked to gameplay development. Svelto.ECS is fundamentally feature complete at this point of writing and new features in new versions are more nice to have than fundamental._
  150. ### Unity Compatibility
  151. Svelto.ECS is partially compatible with Unity 2019.3.x cycle as long as it's not used with any DOTS package (including collections). It is compatible with all the versions of Unity from 2020 and above.
  152. ### Svelto.ECS is fully compatible with DOTS Burst and Jobs.
  153. Svelto.ECS is designed to take full advantange of the DOTS modules and to use specifically DOTS ECS as an engine library, through the (optional) SveltoOnDOTS wrapper. Svelto.ECS native components and interfaces are fully compatible with Burst.
  154. ## Why using Svelto.ECS without Unity?
  155. There are so many c# game engines out there (Stride, Flax, Monogame, FlatRedBall, Evergine, Godot, UniEngine just to mention some) and Svelto.ECS is compatible with all of them!
  156. ## Performance considerations
  157. Aside from resizing the database absolutely when necessary, all the Svelto operations are memory allocation free. Some containers may need to be preallocated (and then disposed) but those are already advanced scenarios. When using pure ECS (no EntityViewComponents) components are stored in native collections across all the platforms, which means gaining some performance from losing the managed memory checks. With pure ECS, iterating components is automatically cache-friendly.
  158. _Note: Svelto.ECS has a ton of allocating run-time checks in debug, so if you want to profile you need to profile a release version or use PROFILE_SVELTO define_
  159. ## If you decide to use Svelto.ECS
  160. Svelto.ECS is an Open Source Project provided as it is, no support is guaranteed other than the help given on the Svelto Discord channel. Issues will be fixed when possible. If you decide to adopt Svelto.ECS, it's assumed you are willing to partecipate to the development of the product if necessary.
  161. ## Official Examples (A.K.A. where is the documentation?)
  162. Documentation is costly to mantain so check the highly documented and simple mini-examples. Please study them all regardless the platform you intend to use Svelto with.
  163. First of all please check the wiki page:
  164. https://github.com/sebas77/Svelto.ECS/wiki
  165. After that, you can get all the help you need from the official chat:
  166. **Official Discord Server \(join to get help from me for free!\)**
  167. * [https://discord.gg/3qAdjDb](https://discord.gg/3qAdjDb)
  168. but don't forget to check the FAQ AKA Discussions first (all the FAQ like questions will be redirected to Discussions)
  169. https://github.com/sebas77/Svelto.ECS/discussions
  170. ## Official Articles
  171. **Theory related articles (from the most recent to the oldest, read from the oldest if you are new to it):**
  172. * [OOP abstraction layer in an ECS-centric application](https://www.sebaslab.com/oop-abstraction-layer-in-a-ecs-centric-application/) \(this article is important for starters!\)
  173. * [ECS abstraction layers and module encapsulation](https://www.sebaslab.com/ecs-abstraction-layers-and-modules-encapsulation/)
  174. * [The Quest for Maintainable Code and The Path to ECS](http://www.sebaslab.com/the-quest-for-maintainable-code-and-the-path-to-ecs/)
  175. * [The truth behind Inversion of Control – Part V – Entity Component System design to achieve true Inversion of Flow Control](http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-v-drifting-away-from-ioc-containers/)
  176. * [The truth behind Inversion of Control – Part IV – Dependency Inversion Principle](http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-iv-dependency-inversion-principle/)
  177. * [The truth behind Inversion of Control – Part III – Entity Component System Design](http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-iii-entity-component-systems/)
  178. * [The truth behind Inversion of Control – Part II – Inversion of Control](http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-ii-inversion-of-control/)
  179. * [The truth behind Inversion of Control – Part I – Dependency Injection](http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-i-dependency-injection/)
  180. * [Inversion of Control with Unity – part 2](http://www.sebaslab.com/ioc-container-for-unity3d-part-2/)
  181. * [Inversion of Control with Unity – part 1](http://www.sebaslab.com/ioc-container-for-unity3d-part-1/)
  182. **Practical articles**
  183. * [Svelto ECS 3.4 internals: How to integrate ComputeSharp](https://www.sebaslab.com/svelto-ecs-3-4-internals-how-to-integrate-computesharp/)
  184. * [Svelto.ECS 3.4 – Svelto On DOTS ECS update](https://www.sebaslab.com/svelto-ecs-3-4-svelto-on-dots-ecs-update/)
  185. * [Svelto.ECS 3.3 and the new Filters API](https://www.sebaslab.com/svelto-ecs-3-3-and-the-new-filters-api/)
  186. * [What’s new in Svelto.ECS 3.0](https://www.sebaslab.com/whats-new-in-svelto-ecs-3-0/)
  187. * [Svelto MiniExample 7: Stride Engine demo](https://www.sebaslab.com/svelto-miniexample-7-stride-engine-demo/)
  188. * [Svelto Mini Examples: The Unity Survival Example](https://www.sebaslab.com/the-new-svelto-ecs-survival-mini-example/)
  189. * [Svelto Mini (Unity) Examples: Doofuses Must Eat](https://www.sebaslab.com/svelto-mini-examples-doofuses-must-eat/)
  190. * [Learning Svelto.ECS by example – The Vanilla Example](http://www.sebaslab.com/learning-svelto-ecs-by-example-the-vanilla-example/)
  191. * [Porting a boid simulation from UnityECS/Jobs to Svelto.ECS/Tasks](https://www.sebaslab.com/porting-a-boid-simulation-from-unityecs-to-svelto-ecs/)
  192. * [Svelto.ECS+Tasks to write Data Oriented, Cache Friendly, Multi-Threaded code](http://www.sebaslab.com/svelto-ecs-svelto-tasks-to-write-data-oriented-cache-friendly-multi-threaded-code-in-unity/)
  193. Note: I included the IoC articles just to show how I shifted over the years from using an IoC container to use an ECS framework and the rationale behind its adoption.
  194. ## Users Generated Content \(I removed all the outdated articles, so this is a call for new ones!\)
  195. * [A Beginner’s Guide to Svelto.ECS (3.0) with Unity by Jiheh Ritterling](https://jiheh.medium.com/a-beginners-guide-to-svelto-ecs-3-0-with-unity-e9dbc88a2145)
  196. **Svelto Community Extensions**
  197. * [***Svelto.ECS inspector***](https://github.com/akrogame/svelto-ecs-inspector)
  198. * [***Svelto.ECS.Schema - Schema and State Machine extensions for Svelto.ECS***](https://github.com/cathei/Svelto.ECS.Schema)
  199. * [***Being able to swap entities between a subset of compound tags to another subset of compound tags***](https://gist.github.com/jlreymendez/c2f441aaf6ac7b5f233ecd990314e9cc)
  200. * [***Automatic way to control svelto engines order without having to pass in a string using attributes***](https://gist.github.com/dragonslaya84/88e6bb998eda8fe4ee912f01d67feec9)
  201. ## How to clone the repository:
  202. The folders Svelto.ECS and Svelto.Common, where present, are submodules pointing to the relative repositories. If you find them empty, you need to update them through the submodule command. Check some instructions here: https://github.com/sebas77/Svelto.ECS.Vanilla.Example/wiki
  203. ## Svelto distributed as Unity Package through OpenUPM [![openupm](https://img.shields.io/npm/v/com.sebaslab.svelto.ecs?label=openupm&registry_uri=https://package.openupm.com)](https://openupm.com/packages/com.sebaslab.svelto.ecs/)
  204. or just install the package that comes from the link https://package-installer.glitch.me/v1/installer/OpenUPM/com.sebaslab.svelto.ecs?registry=https%3A%2F%2Fpackage.openupm.com
  205. this is shown in this example too: https://github.com/sebas77/Svelto.MiniExamples/tree/master/UPM-Integration/UPM
  206. ## Svelto distributed as Nuget
  207. I am not a Nuget expert, but thanks to our contributors, Svelto.ECS can be found at https://www.nuget.org/packages/Svelto.ECS/
  208. the Hello World example uses the nuget package directly: https://github.com/sebas77/Svelto.MiniExamples/tree/master/Example5-Net-HelloWorld
  209. ## In case of bugs
  210. Best option is to fork and clone [https://github.com/sebas77/Svelto.ECS.Tests](https://github.com/sebas77/Svelto.ECS.Tests), add new tests to reproduce the problem and request a pull. I will then fix the issue. Also feel free to contact me on Discord.
  211. ## Unity Installation Note:
  212. if you are installing Svelto.ECS manually and not through OUPM, you need to copy the projecs folders under the Package folder like:
  213. <img width="512" alt="image" src="https://github.com/sebas77/Svelto.ECS/assets/945379/73d02526-f8f6-4aff-88d8-4bd3cdd9deeb">
  214. and add this into your manifest:
  215. ```
  216. ,
  217. "scopedRegistries": [
  218. {
  219. "name": "OpenUPM",
  220. "url": "https://package.openupm.com",
  221. "scopes": [
  222. "org.nuget.system.runtime.compilerservices.unsafe"
  223. ]
  224. }
  225. ]
  226. ```
  227. looking like:
  228. ```
  229. {
  230. "dependencies": {
  231. ...
  232. },
  233. "scopedRegistries": [
  234. {
  235. "name": "OpenUPM",
  236. "url": "https://package.openupm.com",
  237. "scopes": [
  238. "org.nuget.system.runtime.compilerservices.unsafe"
  239. ]
  240. }
  241. ]
  242. }
  243. ```
  244. ## I like the project, how can I help?
  245. Hey, thanks a lot for considering this. You can help in several ways. The simplest is to talk about Svelto.ECS and spread the word, the more we are, the better it is for the community. Then you can help with the documentation, updating the wiki or writing your own articles. Svelto.ECS has all the features needed to make a game with the ECS pattern, but some areas are lacking: *A visual debugger and more unit tests are needed*. Other platforms other than Unity could get some love too: Stride Game, Godot, monogame, FNA or whatever supports c#. Porting to other languages, especially c++, would be awesome but probably pointless. Please check the lane dedicated to the community tasks list here: https://github.com/users/sebas77/projects/3 and let me know if you want to take something on!
  246. ## Svelto Framework is used to develop the following products\(\*\):
  247. ![Toy Trains](https://github.com/sebas77/Svelto.ECS/assets/945379/282494a8-1c0a-43be-8fb7-b2edddcf5938)
  248. ![Beyond These Stars](https://user-images.githubusercontent.com/945379/235711883-eff208d3-9e1f-45b7-90e5-83c2d7a0a805.png)
  249. ![Robocraft](https://user-images.githubusercontent.com/945379/225630614-20dbdf8e-2d7f-48d5-8e04-39e6d43a43ab.png)
  250. ![Techblox](https://user-images.githubusercontent.com/945379/123062411-65ee3600-d404-11eb-8dca-d30c28ed909d.png)
  251. ![Gamecraft](https://user-images.githubusercontent.com/945379/163145452-3e8d959a-1453-4373-8010-38bb7717f79e.png)
  252. ![Robocraft Infinity](https://user-images.githubusercontent.com/945379/163145385-7635f193-b69b-4508-a391-f41a3331122c.png)
  253. ![Cardlife](https://user-images.githubusercontent.com/945379/163145315-9ea85b13-48e1-42f3-b97b-3d2c7564a0ea.png)
  254. ![HoleIo](https://user-images.githubusercontent.com/945379/163145100-31039e0c-9604-4298-8ace-89f92b294e06.png)
  255. \*If you want your products made with Svelto here, just send me an email or whatever, I'll be super happy to add them.
  256. _**Note: Dear Svelto Users : Although I am committed to help you and write articles as much as I can, I will never be able to keep all the documentation up to date. If you are a happy svelto user and you want to contribute, please feel free to update the github wiki! 🙏👊**_