clean, fast and simple with entitas and unity - unite melbourne 2016
TRANSCRIPT
![Page 1: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/1.jpg)
ENTITY COMPONENT SYSTEM
ARCHITECTUREClean, fast and simple with Entitas and Unity
![Page 2: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/2.jpg)
ARCHITECTUREwhy it matters
![Page 3: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/3.jpg)
Simon SchmidEngineer
![Page 4: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/4.jpg)
![Page 5: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/5.jpg)
![Page 6: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/6.jpg)
![Page 7: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/7.jpg)
![Page 8: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/8.jpg)
![Page 9: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/9.jpg)
GAME DEVELOPMENTis hard
![Page 10: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/10.jpg)
GAME ENGINE
![Page 11: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/11.jpg)
ARCHITECTUREstill?
![Page 12: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/12.jpg)
DESIGN PATTERNS
![Page 13: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/13.jpg)
WHY SHOULD Icare
![Page 14: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/14.jpg)
![Page 15: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/15.jpg)
![Page 16: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/16.jpg)
![Page 17: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/17.jpg)
WHY SHOULD Icare
![Page 18: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/18.jpg)
![Page 19: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/19.jpg)
ENTITY COMPONENT SYSTEMARCHITECTURE
![Page 20: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/20.jpg)
ENTITAS#1 ECS ON GITHUB
![Page 21: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/21.jpg)
ENTITAS
cleanfast
simple
![Page 22: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/22.jpg)
ENTITASINTRODUCTION
![Page 23: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/23.jpg)
![Page 24: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/24.jpg)
![Page 25: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/25.jpg)
![Page 26: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/26.jpg)
![Page 27: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/27.jpg)
![Page 28: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/28.jpg)
UNITY COMPONENTS:Data + Behaviour
ENTITAS COMPONENTSData only
![Page 29: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/29.jpg)
public class Archer : Troop {
public int health; public float speed; // ...
void Awake() { // ... }
void Start() { // ... }
void Update() { // ... }}
![Page 30: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/30.jpg)
public class Archer : Troop { // Inheritance
public int health; public float speed; // Data // ...
void Awake() { // ... } // Initialization
void Start() { // ... }
void Update() { // ... // Update }}
![Page 31: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/31.jpg)
// Data only - no behaviour
public class PositionComponent : IComponent { public Vector3 value;}
public class MovableComponent : IComponent {}
![Page 32: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/32.jpg)
+------------------+ | Pool | |------------------| | e e | +-----------+ | e e---|----> | Entity | | e e | |-----------| | e e e | | Component | | e e | | | +-----------+ | e e | | Component-|----> | Component | | e e e | | | |-----------| | e e e | | Component | | Data | +------------------+ +-----------+ +-----------+ | | | +-------------+ | | e | Groups | | e e | +---> | +------------+ | e | | | | e | e | e | +--------|----+ e | | e | | e e | +------------+
![Page 33: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/33.jpg)
![Page 34: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/34.jpg)
LOGIC?
![Page 35: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/35.jpg)
Games are interactive simulations— Maxim Zaks
![Page 36: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/36.jpg)
public class MovementSystem : IExecuteSystem {
public void Execute() {
var movables = Pools.pool.GetGroup( Matcher.AllOf( Matcher.Velocity, Matcher.Position ));
foreach (var e in movables.GetEntities()) { var pos = e.position.value; e.ReplacePosition(pos + e.velocity.value); } }}
![Page 37: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/37.jpg)
SINGLE RESPONSIBILITYprinciple
![Page 38: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/38.jpg)
SYSTEMSChain of Responsibility
+------------+ +------------+ +------------+ +------------+| | | | | | | || System | +---> | System | +---> | System | +---> | System || | | | | | | |+------------+ +------------+ +------------+ +------------+
![Page 39: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/39.jpg)
SYSTEMSChain of Responsibility
|-------------------------------- Game Loop --------------------------------|
+------------+ +------------+ +------------+ +------------+| | | | | | | || System | +---> | System | +---> | System | +---> | System || | | | | | | |+------------+ +------------+ +------------+ +------------+
![Page 40: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/40.jpg)
SYSTEMS IN ENTITAS- Initialize System- Execute System- Reactive System
![Page 41: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/41.jpg)
DEMOMatch One
![Page 42: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/42.jpg)
![Page 43: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/43.jpg)
ENTITAS
▸ cleanfast
simple
![Page 44: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/44.jpg)
CLEANSeparation of concerns
Composition over InheritanceSingle responsibility principle
Consistency
![Page 45: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/45.jpg)
SEPARATION OFCONCERNS
![Page 46: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/46.jpg)
![Page 47: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/47.jpg)
Composition overINHERITANCE
![Page 48: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/48.jpg)
![Page 49: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/49.jpg)
![Page 50: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/50.jpg)
![Page 51: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/51.jpg)
![Page 52: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/52.jpg)
![Page 53: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/53.jpg)
![Page 54: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/54.jpg)
![Page 55: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/55.jpg)
![Page 56: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/56.jpg)
![Page 57: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/57.jpg)
![Page 58: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/58.jpg)
![Page 59: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/59.jpg)
![Page 60: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/60.jpg)
![Page 61: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/61.jpg)
![Page 62: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/62.jpg)
![Page 63: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/63.jpg)
![Page 64: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/64.jpg)
![Page 65: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/65.jpg)
![Page 66: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/66.jpg)
![Page 67: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/67.jpg)
![Page 68: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/68.jpg)
SINGLE RESPONSIBILITYprinciple
![Page 69: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/69.jpg)
public class MovementSystem : IExecuteSystem {
public void Execute() {
var movables = Pools.pool.GetGroup( Matcher.AllOf( Matcher.Velocity, Matcher.Position ));
foreach (var e in movables.GetEntities()) { var pos = e.position.value; e.ReplacePosition(pos + e.velocity.value); } }}
![Page 70: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/70.jpg)
it["adds velocity to position"] = () => {
// given var pool = Pools.sharedInstance.core; var entity = pool.CreateEntity() .AddPosition(Vector3.one) .AddVelocity(Vector3.one);
var system = pool.CreateSystem(new MovementSystem());
// when system.Execute();
// then entity.position.value.should_be(new Vector3(2, 2, 2));};
![Page 71: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/71.jpg)
CONSISTENCY
![Page 72: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/72.jpg)
CLEANSeparation of concerns
Composition over InheritanceSingle responsibility principle
Consistency
![Page 73: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/73.jpg)
ENTITAS
clean▸ fastsimple
![Page 74: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/74.jpg)
![Page 75: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/75.jpg)
UNITY VS ENTITAS: Objects1000 objects with 2 components
Memory: 9x (2.9 MB vs 0.32 MB)CPU: 17x (105 ms vs 6 ms)
![Page 76: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/76.jpg)
![Page 77: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/77.jpg)
ENTITAS VS UNITY: Logicupdate 25000 objects
Memory: 5x (36.4 MB vs 7.6 MB)CPU: 2x (20.5 ms vs 9.6 ms)
![Page 78: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/78.jpg)
UNITY BLOG10000 Update() calls by Valentin Simonov
![Page 79: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/79.jpg)
ENTITAS
cleanfast
▸ simple
![Page 80: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/80.jpg)
SIMPLEsimilar to Unity
simple conventionseasy to add features
Visual DebuggingReusing code
![Page 81: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/81.jpg)
SYSTEMSChain of Responsibility
+------------+ +------------+ +------------+ +------------+| | | | | | | || System | +---> | System | +---> | System | +---> | System || | | | | | | |+------------+ +------------+ +------------+ +------------+
![Page 82: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/82.jpg)
SYSTEMSChain of Responsibility
+------------+ +------------+ +------------+| | | | | || System | +---> | System | +------------------------> | System || | | | | |+------------+ +------------+ +------------+
![Page 83: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/83.jpg)
SYSTEMSChain of Responsibility
+------------+ +------------+ +------------+ +------------+| | | | | | | || System | +---> | System | +---> | System | +---> | System || | | | | | | |+------------+ +------------+ +------------+ +------------+
![Page 84: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/84.jpg)
SIMPLEsimilar to Unity
simple conventionseasy to add features
Visual DebuggingReusing code
![Page 85: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/85.jpg)
ENTITAS ISopen source
GITHUB.COM/SSCHMID/ENTITAS-CSHARP
![Page 86: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/86.jpg)
WOOGA.COM/JOBS
![Page 87: Clean, fast and simple with Entitas and Unity - Unite Melbourne 2016](https://reader036.vdocument.in/reader036/viewer/2022062503/58f014061a28ab2f388b4667/html5/thumbnails/87.jpg)
QUESTIONS?#ENTITAS
GITHUB.COM/SSCHMID/ENTITAS-CSHARP