Categories
computer games dev-process devdiary entity systems games design

2014 Entity Systems: what are your Unity3D questions and problems?

In 2014, I’ll be making a new game in Unity that makes intensive use of an Entity System.

This will give me lots of ammo for a new post exploring the pros and cons of Unity’s “partial” Entity System architecture. I’ve been thinking about this a lot for the last couple of years, but I’ve been unhappy with the draft posts, and didn’t publish them.

Over the next couple of months, I’d love to hear from all of you the challenges, confusions, problems, and questions you have about this. I’m not promising quick answers – but it will help shape the blog posts I write, and as soon as I have a good enough set of answers, I’ll start posting them :).

Also: if you’ve used Unity on a significant live game I’d love to interview you (publically or privately, it’s up to you) about HOW you used the Entity System parts – what worked, what didn’t, what you customized (and why). From casual conversations, I know a few of you have done partial rip/replace jobs on the entity/component parts of Unity, mainly for performance reasons. This stuff is what I want to talk about!

…either email me (address in site navbar), or even better: comment on this post (so other people can read and reply too!)

26 replies on “2014 Entity Systems: what are your Unity3D questions and problems?”

I’ve got no specific questions, but I lately read your articles about entity systems and I was actually wondering how you’d apply any of that to Unity3D (and whether one should). Looking forward to your post!

I found the StrangeIOC documentation impenetrable and gave up on it.

IoC is tricky enough to grasp (every library in every language uses different terminology and different syntax :( ), but docs that say “this is IoC! But it’s not IoC! It’s a GUI library! It’s not a GUI Library! It’s a Binding framework! But it’s not a binding Framework!” … ad infinitum, until they have described everything *including* the kitchen sink … well, life’s too short :(.

So … I’d be very interested in any concrete / simple ideas you have on how it could be used – I’m happy to have a look at them. But I can’t cope with the crappy StrangeIOC docs on their own.

I’ve been working with Unity for a while now and tried various approaches to working with and around the Unity entity system. A few problems that I’ve encountered:

– Unity’s entity system is object oriented in the fashion that components should encapsulate data and behavior over that data. I’ve come to find that this is not a desirable property as it makes game behavior unnecessarily inflexible, e.g. it’s hard to turn off one set of subsystems, you can only turn off one instance of that subsystem (a MonoBehaviour object).
– Let’s say you want to update one component before the other in the update loop. The only way to do it is to give that component a priority number (e.g. -100). These numbers are fairly arbitrary, a cleaner solution would be to list the order of components or to make certain components depend explicity upon others so that Unity can determine the order of execution itself.
– Every Game Object in a scene has a position in the world. Sometimes you use a GameObject to store and serialize data, these components certainly do not need a position in the world, but you can’t remove that.
– Creating a Game Object in a scene will make sure it is a singleton and that it cannot be changed. Basically everything you wire up in the Unity scene will make sure that you have a scene full of singletons, effectively limiting your options for doing proper software design. Inversion of control (IoC) is one way to solve this problem. I’ve been using Zenject for doing IoC in Unity, it’s a fairly basic system but I hope it will do its job.
– Interfaces. Unity doesn’t use them, and it’s a shame. You cannot wire up components that implement an interface through the Unity scene, instead you have to extend MonoBehaviour. Also, many of Unity’s API components, for example Time, could do well with a nice interface so that: I could implement my own timer. Inheritance is not a good tool for composition and reducing duplication. First and foremost interfaces should be used for polymorphic behavior not abstract classes and you should always favor composition over inheritance.
– Unity’s Time module. It’s a good example of all the things that are wrong with Unity’s approach to API design. If I call Unity Time.scale = 0 then LateUpdate will magically not be called, and all components that use Time.deltaTime will get 0. Unity’s Time module is a good example of how global state, once again, ruins your ability to reason about your program and provides unnecessary inflexibility. Instead I might like to have several timers and be able to stop one and not the other.
– It seems that new features are first designed for the Unity Editor and that a limited set of the feature’s functionality can be accessed programatically. They should turn this around: design a feature with a good API, then build the editor functionality with the API. SQL is a good example of this exact same problem: designed for a UI: just type in the string and send off the query. Now most SQL API’s only provide you with a function query(string) and pretty soon you’re building dynamic query’s using string concatenation(!). String concatenation is not a very good/readable tool for composing queries. Datalog for example is much better: queries are data structures.

I’ve also been working on a more functional approach using Unity from F# and together with Ruben de Gooijer creating a proper entity system with Unity underneath, but the project is currently on hold. I’ll hopefully blog one day about how a more functional approach to game design works out.

I think Unity is an absolutely brilliant tool with a really crappy API.

wrt StrangeIOC – fair enough :) !

Reading F. Versnel’s post, he has echoed many of the issues i have with U3D but have been unable to concisely write down. Specifically the OOP nature of the component model U3D uses, and the mixture of data with processing.

I have struggled to find a clean way to “componentize” functionality but still feel that i’m lacking a fundamental understanding of how the authors of the tool want me to use it to implement complex game logic.

I’m interested in knowing why you call Unity’s model “partial” entity system? what differentiates it from the classic definition ?

Hi Adam,

I’m sorry you’ve found our documentation difficult. That’s odd to me, only insofar as the feedback I’ve received so far on our docs has been exceptionally positive (it’s one of the things we get consistent kudos for). I’d like to clarify a few points…and I’m happy to explain more if it’s helpful.

“this is IoC! But it’s not IoC! It’s a GUI library! It’s not a GUI Library! It’s a Binding framework! But it’s not a binding Framework!”

StrangeIoC is definitely IoC. The whole point is to use Inversion-of-Control to create clean refactorable code. The architecture is based on Robotlegs from AS3, a well-proven uber-design, and similar to IoC frameworks like Spring, Guice, Unity (the MS library), etc.

It is definitely not a GUI library. In fact, Strange does virtually nothing at the View layer other than encourage you to Mediate your Views. We do our best to stay out of the way of your Views so you can build/compose your Views in the way that suits you best.

It is absolutely, fundamentally a binding framework. At a deeper level than even IoC, Strange is built around a simple Binder class that allows you to easily connect anything to anything else. We use this Binder to enable injection/mediation/event binding across the whole of your app.

If the docs left you in any doubt on any of those points I apologize, since I wrote them and felt like I was being very clear. As I say, I’m happy to help clarify further.

All the best!

Thanks for the info.

I’m sure it all makes sense to you, but as an outsider who’s not used the library, it feels like a number of different concepts – each of which is a library in its own right – added together in a “strange” ;) way.

With a library, normally it does “one” thing, and I can start by simply “using it to do the one thing it’s for”. Your descriptions make it seem like Strange “does many things (that seem to me to be unrelated; how is a View anything to do with an IoC framework? I hate Views, I never use Views – I go out of my way to remove them. Does Strange require Views? What’s going on here?)”. Not only do I need to learn this thing to work out how to use it, I also have to learn how these (to me, seemingly: unrelated) concepts come together, since the docs imply it’s all of this at once.

Which in turn implies I’ll have to spend time disentangling them. If they’re in the library, I need them removed, which presumably means I’ll have to work out how to do that myself (libraries don’t usually support you ripping them apart!).

…by which time, my head hurts, and I give up, close the tab, and google “simple IoC C#”, because it feels like it would take me less time to *implement IoC myself, from scratch*, than it would simply to undertand WTF Strange is and how it works!

(just my personal experience)

Fair enough, and thanks for the feedback. Possibly those of us who came to Unity via Flash are more used to thinking through the particular architecture issues that Strange solves (certainly this is true for those used to Robotlegs). It actually is possible to use just the individual parts of Strange, but I totally get your point that you need to understand the big picture to see how/why you’d want any of its constituent parts. So there’s definitely a learning curve…that’s something we can work on addressing.

What StrangeIoC does in a nutshell is organize your entire app in a way that keeps the individual parts separate and (to the extent Unity allows this) testable. It’s a framework with a holistic approach to the problem of managing code dependency.

This includes IoC, since IoC helps maintain separation. It includes a structure for separating out Commands, Models and Services so that your code can efficiently maintain the single-responsibility principle. It includes separating View logic from business logic so everything just does its job. It includes an event bus so that any point in your code can receive the bits it cares about, while minimizing interdependency.

That’s the idea. I get that it may not be for you. But I believe in it (well, duh.), and with years now of using RL and Strange feel like it’s made me and the teams I’ve worked on a lot more flexible and efficient.

Ah, yes – I think the Flash/non-Flash background is the issue here.

e.g. “Commands, Models and Services” – outside of Flash, without further detail, we’d naturally assume those terms are so vague as to be meaningless – and/or come with baggage that most of us in game development were forced to stop doing a long time ago (usually because of performance issues).

I’ve no idea what any of this actually means w.r.t. Strange. I can only say “these are all concepts that I’ve only ever seen used in ways / use-cases that don’t make sense here” – i.e. I assume that Strange’s versions of them are something very different … but I have no reference point for that :(, and the docs don’t provide one.

Well, there you go. I guess I have some writing to do. :)

Anyway, I appreciate the viewpoint. Obviously I mostly speak with devs who start by expressing interest in the framework. I don’t often get to hear from one who’s looked at it and said “no thanks.” So this has been educational for me.

“Lior Tal

I’m interested in knowing why you call Unity’s model “partial” entity system? what differentiates it from the classic definition?”

Because it stuffs components inside of entities as far as I understand, instead of treating the whole scene’s component set as a “DB” that systems/whatever query. Also it makes assumptions that certain components should always be present (e.g. Position/transform).

PS: not that Artemis is perfect, don’t treat it as a holy grail, ES is an area of ongoing innovation.

@Lion
>I’m interested in knowing why you call Unity’s model “partial” entity system? what differentiates it from the classic definition?”

@SomeGuy
>Because it stuffs components inside of entities as far as I understand, instead of treating the whole scene’s component set as a “DB” that systems/whatever query.

What SomeGuy mentions above is a specific implementation of a type of more generic query interface. The component architecture aspects of Unity are definitely on the weaker side of things and traditional OOP still has quite a stranglehold on day to day development seemingly.

Regarding a “classic definition for an ES” or the entity system architecture if you will IMHO relies on completely on the implicit has-a relationship. This allows high level data oriented design by separating data from logic implicitly.

IMHO IoC (Inversion of Control) is traditional OOPs last dying breathe; in many ways a case of “the emperor has new clothes…”. An interesting recent article (also references RobotLegs):
http://www.davidarno.org/2013/11/13/are-ioc-containers-a-case-of-the-emperors-new-clothes/
So, indeed interesting to see the StrangeIoC dev come defend this angle; thanks, for dropping in… The interchange between Adam and StrangeIoC reminded me of this StackExchange answer discussing IoC from Joel Spolsky (boy did “they” gang up on him):
http://stackoverflow.com/questions/871405/why-do-i-need-an-ioc-container-as-opposed-to-straightforward-di-code/871420#871420

@StrangeIoC: In my component architecture / ES efforts I rely on a modification of the EventBus pattern (re I come from the Java angle; my effort is different than Guava’s or Otto’s implementation) for implicit messaging between components. Perhaps you can comment a bit on the EventBus associated with StrangeIoC (I’ve not read any docs). Given your effort is IoC I assume an EventBus is injected via DI into any interested object. Could you comment on the registration and event distribution aspects between producer / consumer? How dynamic is it?… I assume there is no direct link between producer / consumer as well, but interested parties must depend on the StrangeIoC container to get a reference to the event bus.

Anyway… This discussion is neat because I’ve skipped over Unity as a source of software architecture influence / ideas. No doubt it’s popular and useful and as a previous poster mentioned with a crappy API; re: Frank Versnel, nice descriptive post too.

I’ve been working with Unity for the past few years and have always been fairly unhappy with its object-model, strange reliance on “magic” methods and inability to properly differentiate between runtime/editing behaviour. What I found mostly that it’s far too easy for behaviours to become “rigid” and start represent actual object definitions (like having a “Player” behaviour). The other really annoying thing about Unity is the exponential explosion of its API with every update (adding layers on broken layers instead of actual fixes).

That said, I’ve recently been playing around with using a more “pure” ECS approach where none of my components have methods in them and instead have ‘system’ behaviours on a single root node in the scene. These systems are stepped by a “GameDriver” behaviour which is responsible for the calling order. And each system performs a specialized “GetCompononetsInChildren()” query to get and update the required components.

I mostly ignore the GameObject.transform and any other kind of method in the GameObject class (went so far as implementing my own Transform inspector which basically disables the usage of the transform during editing).

@Mike I love that SO.com post by Joel. As you say, very much “emperor’s new clothes”, especially reading the comments :).

Funny thing is … I remember being very interested in IoC back when it was new, and it wasn’t supposed to be this complex :(. But then again, it was also a bit like C++ template metaprogramming: very powerful, but very very easy to abuse. Looking around, I see more people seeming to abuse it than use it correctly. Perhaps it needs the kind of backlash that hit C++ templates (and has now settled down to – IME – a fairly good place where people use templates exactly when they’re right for the project, and don’t when they’re not)?

@AmirBarak

“That said, I’ve recently been playing around with using a more “pure” ECS approach where none of my components have methods in them and instead have ‘system’ behaviours on a single root node in the scene. ”

The area is very subjective, but would argue that types/objects that contain only data are not ‘components’.

@SomeGuy – you’re in the minority.

e.g. A few months back I canvassed game devs in 10+ different mid-large studios. The ones using logic-in-components consistently reported that the ECS didn’t work out, and most of them had stopped using it. The ones that perservered … had moved to “components are data-only”.

On logic in data components…. Depending on the data and access patterns it may be reasonable to include essential sanitizing / bounds checking methods in the data component if the data must be well formatted otherwise such code would need to be duplicated everywhere data is set / retrieved. A special case, but useful sometimes.

@adam My point is that a better name would be something like ‘record’ instead of ‘component’, but it’s just a rant. So most of game developers at least considered ECS? It’s strange there aren’t more open-source frameworks available. In enterprise you have like a dozen MVC frameworks per GUI technology.

@SomeGuy – ah, yes, I’m with you on that :).

Scott Bilas called them “Components” in 2002, speaking at the global Game-developers Conference … and that became the shared vocabulary everyone knew and recognized.

TBH, I think “Systems” are worse-named (and that’s my fault, although I can’t remember where I got the term from – might have been the team I was working with at Codemasters). I’ve been using “Processors” in my own code for a while as a more accurate name…

I have done something similar to you Amir

I have a central control object that has a ‘systemcontrol’ script attached. The update (Called by unity) on this script callse ‘SystemUpdate’ functions on a number of systems I have setup, in an order I have chosen.

Each system maintains a list of gameobjects that contains components relevant to itself. The components themselves are data only (excluding get/sets used for data formatting/validation).

It’s been fairly challenging, as one of the primary objects in my game is a very complex networked composite ship object, with multiple shield facings, turret banks and independently tracking turrets….all of which is driven through the system above. The game runs on an authoritative network architecture so I have faced some challenges setting up owner/proxy/server versions and dealing with interacting with a 3rd party networking solution(uLink).

The whole thing was originally inspired by this blog, so its quite interesting to see what the t-machine take on unity will be!

@Nicholas – how is the composite ship “challenging”? I’d have expected that to become easy once you had your ES set up?

‘Composite’ in isolation was not the issue. The issue was dealing with integration with a 3rd party networking system that, by design, wants to break the independence of components.

uLink does not allow you to set child objects as individual targets of network-synchronised data. You have to assign a network ID to the top level object and route communication through that top level object, then down to the children.

I was faced with either routing that data into an inefficient attempt to maintain the ES design, or to choose to break the ES design in a controlled way when interacting with networking code.

I opted for the latter. Efficiency trumps ideology.

@Nicholas
>I was faced with either routing that data into an inefficient attempt to maintain the ES design, or to choose to break the ES design in a controlled way when interacting with networking code.

While I’m not working in the sphere of Unity the problems you face in integrating 3rd party frameworks with an ES sounds like a good chance to consider the EventBus pattern. What this generally entails is that to hook up communication between the network framework and your ES you marshall data back and forth by events instead of direct communication. Ideally with an EventBus based on implicit syndication; not all EventBus implementations are implicit.

Integrating networking and marshaling benefits from a multithreaded approach as well. I’m not familiar again with the Unity threading model. I generally understand the Unity API is not thread safe per se, so I guess one would integrate things from the C# angle as far as threading models go and interaction with 3rd party frameworks.

In my world (Java / Android / desktop) the way I’m solving multithreading tasks such as integrating networking, journaling, and marshaling is through an application of the Disruptor. I’m extending the EventBus pattern to use a processing graph setup via one or more Disruptor based chains. I’m calling this the “DisruptorBus” since the result of events passed between threads will be delivered to / from a local EventBus. IE a network packet comes off the wire in a dedicated thread, marshaling / journaling can then occur on either the same thread or another one which results in an event that can then be fed to the control / logic thread of the game / app through the Disruptor chain hitting an EventBus in the logic thread and then syndicated implicitly to relevant components. Reverse this sequence to send data over the wire, etc.

I haven’t implemented any of the above yet, but that is the direction I’ll be attempting.

Regardless the EventBus pattern is likely relevant to explore to implement things in a clean way with Unity, 3rd party networking frameworks, and an ES.

Some links:
http://trading.aurorasolutions.org/over-6-million-transactions-per-second-in-a-real-time-system-an-out-of-the-box-approach/

C# implementation of the Disruptor pattern:
https://github.com/disruptor-net/Disruptor-net

While I have yet to see anyone write in depth on using the Disruptor pattern for games / near real time interactive & creative coding or interfacing with entity system architectures I do believe this direction is highly relevant to solving the type of problem you are facing.

Comments are closed.