Categories
entity systems games industry programming

Which languages need Entity Systems libraries right now?

A few months ago I ran a survey to find out which programming-languages people were using with Entity Systems:

https://docs.google.com/forms/d/18JF6uCHI0nZ1-Yel76uZzL1UfFMI21QvDlcnXSGXSHo/viewform

I’m about to publish a Patreon article on Entity Systems (here if you want to support me), but I wanted to put something up on my blog at the same time, so here’s a quick look at the stats.

Categories
entity systems

Survey: which language(s) do you use along with an #entitysystem in #gamedev?

A lot of us have been looking at alternative engines recently, and for me the biggest challenge is that the intersection between “game engine I can use easily” and “programming language I am willing to use” is quite small.

That got me thinking: if you started a new commercial ES today, what language does your audience want?

Short Google form

FYI: I picked the top 10 global languages by popularity, and then cherrypicked from the next 50 or so on http://sogrady-media.redmonk.com/sogrady/files/2015/07/lang-rank-615-wm.png – favouring ones where I have met people that I know are using them in gamedev today.

Categories
entity systems

Support me on Patreon for early access to new Entity Systems articles

I love researching and writing about Entity Systems, but it takes me days or weeks to make a single article. I’ve written almost nothing for the past 18 months because on my current salary I can’t afford the time off work.

So … now I’m crowdfunding the long, detailed, in-depth ES articles. This gives me a way to spend the time I need to write each one while still paying rent, food, etc.

You don’t have to sign-up – I know there’s lots of people like myself who are in bad financial situations, and I hope all the articles will be made free eventually. But if you’ve found my ES articles useful, and you want more of them, and you can spare $5 once every couple of months, please do.

You can sign up here: https://www.patreon.com/tmachine

Categories
entity systems Unity3D

Simple #unity3d bugs and flaws fixed by Entity Systems – number 1

I periodically write massive long documents detailing all the bugs in Unity that I know, have memorized, and have to workaround on a day-to-day / hour-to-hour basis. But it makes me so angry and frustrated – so much terrible coding, so little technology-leadership at the company – that I end up deleting it. Life is too short to be daily reminded how crappy (and yet easy to fix) our tools are.

Then, every 6 months or so, when people ask me for simple examples of how ECS’s fix Unity, I have to wrack my brains for something simple.

So I’m going to start blogging simple examples as I run into them, with only enough context for me to understand them. Here’s the first…

Categories
entity systems programming

Entity ID’s: how big, using UUIDs or not, why, etc?

This has come up a few times, and I ended up replying on Twitter:

But that’s a crappy way to find things later, so I made a quick-and-dirty infographic with a few key points:

Docs-entityID

Categories
dev-process devdiary entity systems games design programming Unity3D

2015 talk: Progress on An Entity System for #Unity3d

Slides from my talk last night at Unity Brighton.

Three parts:

  1. First: introduction / overview of Entity Systems, and why you care (as a “person who makes games”)
  2. Second: Progress so far: screenshots of the Unity Editor with explanation of the new features I’ve added
  3. Third: Challenges and solutions I’ve encountered so far

Aliqua-progress-2015-BUUG-v3

WordPress, HTML, the web etc – don’t support “presentations” yet. No, I’m not creating a fake Slideshare account just so you can wait ages for a non-bookmarkable slide viewer to (slowly) load. Until then … we have PDF. Enjoy!

Categories
entity systems programming Unity3D

Unity3D Entity Systems: Zero-copy data storage revisited

Recap: previous posts on Unity3D and designing an efficient Entity Systems add-on library, using structs to store data in C#.

But …

Categories
entity systems Unity3D

Data Structures for Entity Systems: Multi-threading and Networking

(One of a series of posts about converting Unity3D into a 1st-class Entity Component System. Read others here)

It’s a year and a half since I wrote about choosing Data Structures for high-performance Entity Systems in A-AAA games. I always had a followup post in mind, but never wrote it down (thanks largely to the demise of #AltDevBlog). These days I’m too busy to write such big articles, but it’s long overdue … This post is a shorter version of what I had planned, but should have enough to get you going in the right directions.

Categories
entity systems Unity3D

Replacing Unity3d’s core architecture: Structs

(One of a series of posts about converting Unity3D into a 1st-class Entity Component System. Read others here)

How to store game data: GameObject? MonoBehaviour? ScriptableObject?

Those three pillars of Unity’s architecture are the curse of game implementation and performance. Architecturally, they’re great: they’re a big part of what makes Unity easy for newcomers to pick up and understand within hours, instead of taking weeks.

On large Unity game projects, they’re hated for being slow and hard to work with when you get to hundreds of thousands (or millions, tens of millions, …) in a single scene. Unity provides zero tools and support for this situation – it just gets harder and harder to work with, and slower and slower to run.

In Entity Systems world, we hate them because they are inherently slow and buggy – no matter how great Unity’s coders, they’ll never make them work as well as our preferred approach (See below).

But … replacing them forces you to replace most of the Unity Editor!

Most of the features of our Entity System need new Editor GUI anyway. If we’re going to be adding big chunks to the editor, replacing GO/MB/SO is going to be much cheaper than normal. And it potentially has huge benefits that are independent of the Entity System.

If we’re going to replace them, what will we replace them with? Custom versions that have almost the same name and work the same way? Or something very different?

What is Unity’s ‘GameObject’ anyway?

As far as I can tell, the real meaning of GameObject is:

def. GameObject: Something that exists inside a Scene, and has a Position, Rotation, and Scale. It can be “embedded” inside any other GameObject, meaning that any change to the other object’s Position, Rotation, or Scale gets merged onto this one. It’s the ONLY thing that can have Unity “Components” (MonoBehaviours) attached to it. Anything that is not a GameObject, and is not attached to a GO, gets deleted every time you load/reload/play/resume a Scene.

From a code perspective, looking at the backend systems, there’s a lot more to it. The GameObject (GO) has a slightly weird name, when you think about it. You use it so much during Unity dev that you stop noticing it. “Game … Object” … wha?

Other purposes GameObject serves

Here’s a few obvious ones (I’ll edit later if I think of more):

  1. Guarantees everything has the GetInstanceID() method
    1. Needed for Unity’s Serialization system to work (because of how it’s been designed, not because serializing requires this – C# has built-ins that would have done the same job)
    2. Enables the Editor to “select” anything in any tab/window, and that thing is ALSO selected in all other tabs/windows (e.g. click in Scene, and the Inspector updates to show the components on that thing)
    3. …probably loads of other things. It’s so commonly used I hardly notice it
  2. When doing in-Editor things, Unity can often “ignore” classes that are “not part of the game, because they don’t extend GameObject”
    1. Reading between the lines of official docs, and simplifying vastly, this is what happens behind the scenes. Especially with Serialization, I suspect.
    2. This can be a huge pain. It’s hard to debug code when “GameObject subclasses” magically behave differently to “all other classes” with no indication of why
  3. Since every GO has a Transform … you can do automatic, general-purpose, high-quality, Occlusion Culling
    1. NB: for this to work perfectly, you’d also want every GameObject to have a .bounds variable. Why did Unity’s original architects leave that out? Dunno, sorry.

How to store game-data: the Entity Systems ideal way

We know this, it’s been discussed to death: if your programming language supports it, use structs.

By definition, structs are the most memory-efficient, CPU-efficient, multi-thread-safe, typesafe way of storing data, bar none. There is no better way to do this in mainstream languages. C# and C++ both support structs; I think we have a winner!

There are probably some awesomely clever advanced Math ways of doing things better, or by using raw assembler and code optimized for each individual CPU on the market. Or, or … but: in terms of what’s ‘normal’, and commonly used, this is the best you’re going to get

But how will this work in practice? What about all the “other” roles of GO etc in Unity?

Structs in … Identity (GetInstanceID)

Simple ECS implementations often hand-around raw pointers to their Components; that gets messy with Identity.

But most (all?) advanced implementations have some kind of indirection – a smart pointer, or an integer “index” that the Component Storage / Manager maps internally to the actual point in memory where that lives.

If we turn that “advanced” feature into a requirement, we should be fine.

Structs in … Serialization

  1. Start writing your own version of the Unity Serialization system that only uses structs
  2. Finish it the same day
  3. Discover it runs 10 times faster than Unity’s built-in one
  4. …with fewer bugs
  5. PROFIT!

Structs are the easiest thing you could possibly try to serialize and deserialize. Unity coders probably wish that they could restrict us all to structs – it would make their live much easier in some ways.

User-written structs: special rules?

Do we need to add special “rules” to user-written structs that appear in the game?

Nope! It turns out that C#’s built-in Reflection system is able to inspect every struct, shows us every field/property/etc, and lets us easily read and write to them. Both private and public.

CAVEAT: structs break C# .SetValue()

Yeah, this sucks – and it’s nothing to do with Unity, it’s core C#.

A little care is needed when we implement the Entity System internals. But it has no effect on user code / game code.

Structs in … SceneView (Transforms)

No! Just … NO!

This is one of the architectural mistakes of Unity we’re going to fix in passing: we won’t require everything to have a Transform.

However, it foreshadows a more subtle problem that we’ll eventually have to deal with:

Entity Systems are a table-based/Relational/RDBMS way to store and access data; such systems are very inefficient at storing and retrieving tree-structured data (e.g. OOP classes + objects)

The transform hierarchy in a Unity scene is a massive tree. As it turns out, it’s bigger than it needs to be (because of that law of Unity that everything must have a Transform) – but we uses trees all the damn time in game-development. So it’s a problem we’ll have to come back to.

Bigger storage: where do the structs live?

Fine; at the lowest level, the individual ECS Components, we’ll use structs.

But how do we store those?

Choosing the right aggregate data-structures for your ECS is a major topic in itself. C# gives us (almost) total control of how we’d like to do it – plenty of rope to hang ourselves with.

At this point: I’m not sure.

As a temporary solution, I’m going to focus on making the storage-system swappable, so that I can implement a crappy version quickly, and then easily swap-it-out with something much better – without having to rewrite anything else.

Does it work?

Yes. I tried it – I wrote a complete replacement for the Unity Inspector tab that only works on Entities-with-Components, where “Component” is any struct. Ugly, but it works:

Screen Shot 2015-04-29 at 14.41.23

Everything there is auto-generated (including the colour; every struct gets a globally unique background colour, which I find makes it much easier when you have hundreds or thousands of Component types).

The only tricky bit was the problem with C# FieldInfo.SetValue(…), as mentioned above.

Further Reading

…some things I might want to pick up on in future posts:

Categories
entity systems Unity3D

Kickstarting Entity Systems in Unity3d – What to include?

A first-class Entity System for Unity3D

Unity is a great 3D engine and a good editor – but the programming environment is 10-15 years behind the curve. Entity Systems are a much better way of writing games, but they are surprisingly difficult to add to Unity.

I’ll bring the latest in modern ES techniques to Unity, turning parts of it from a “weak” programming environment into “one of the best”. In game-engine terms, this will put it far ahead of the pack.

This blog post is testing the waters:

  1. You can give me direct feedback on the proposed contents/scope
  2. I can start to see how much interest there is in making this

First round of feedback

A lot of people read this and got the impression I was going to charge them extra for the final product, and provide a library with no tutorials. Big confusion and misunderstanding! So, I’ve reworded those bits to be clearer.

Kickstarter: planning the campaign

Target Audiences (Expected)

I think I have four target audiences:

  1. Newbie devs, and non-programmers (artists, designers), who find the “coding” parts of Unity overwhelmingly difficult today
  2. Unity devs who’ve never used an Entity System on a real game project, and don’t know what they’re missing. They may have a lot of experience (shipped multiple games), or none (University/College students).
  3. Small Indie teams / sole coders who’ve used Entity Systems elsewhere, and feel that coding in Unity is slow, error-prone, boring, frustrating, and time-wasting by comparison
  4. Large Indie teams whose games won’t work in Unity because Unity is so bad at scaling to large projects. They’ve already re-written or replaced substantial chunks of Unity’s core so that it’ll work fast enough / reliably enough.

Types of Reward

Reward type 1: Discounted License

Everyone who backs the KS gets a copy of the library / license to use it. By backing the KS (at any level) you’re getting a substantially cheaper purchase compared to the final launch pricing on the Asset Store.

There might be some options here for different team sizes, different levels of support, etc.

Reward type 2: Expert Knowledge

When you have non-trivial questions about ES design and usage, it’s hard to get the attention of experts. They’re usually experienced, older, programmers with young families, or working in senior jobs. They have little free time.

Big developers fix this by hiring experts for a few days at a time. But small teams/individuals can’t afford the “entry” cost – as a Consultant, you need to charge at least $5,000 per engagement to cover all the admin overhead and hidden costs.

So, we have some options here to give everyone this kind of access.

Reward type 3: Source Code

In mainstream IT, when you purchase a library you rarely (if ever) get the source code. If you find bugs, or missing features, the vendor works hard and fast to fix them for you.

In the games industry, it’s the other way around: vendors take no responsibility for the code they’ve sold you, and in return … they give you full source access. “Fix it yourself, dude!”

If I let everyone have source, it raises my support costs. With each change, it won’t work for some people – because they’ve modified their copy – and I’ll have to help them update it.

On the flip side: Source code is your “Plan B” in case I get sick, or sell-out, or lose interest in the project, etc. It also gives you an easy way to add features of your own and send them back to me (which I then take on responsibility for maintaining).

I’m offering this, but it’ll be a high-cost. The teams that really need it should have no problem justifying the cost.

Types of Stretch Goal

To clear up confusion: these are things that would be present in the core product (e.g. the GUI is going to be a major part of the library!), but stretch goals would allow me to add extras to each of them.

Goal type 1: Editor GUI

In my experience the biggest effect on programming speed – once you get past your innate ability + level of experience – is the quality and “friction” of your tools.

As soon as you go beyond the simple stuff it’s damn hard to extend the Unity editor. But I’ve been hacking the Editor for a few years now, and I’m willing to do pretty much anything. Especially if it makes it easier to make games with!

Goal type 2: Example Games

The core will have some form of tutorials, but it probably won’t have a complete demo game.

Writing a game just to demonstrate an API is extremely time-consuming, and it’s not what you’re paying for when you buy the library.

But … it’s also a great idea: it improves the quality of the API, by giving me a reference product to check everything is as easy-to-use as intended. So I’d like to write one (or several), but I can’t do that on the base funding.

(Aside: If I ran the technology division at Unity corp, they’d be writing and publishing games every quarter)

Goal type 3: Tutorials

There will be tutorials with the core library. They’ll cover the basics of how to use it.

But … I’d like to go further, and do tutorials for every aspect. I’d like to do a written tutorial for everything, and I’d like to ALSO do a video tutorial for everything (some people only use written tutorials, other people only use videos. I’d like to make it great for both groups).

With a new library, tutorials are extremely expensive to write. Minor changes to the API – bug fixes, refactorings, feature additions – invalidate whole pages of tutorial at one stroke.

Pricing and Funding levels

Tier costs

These are approximate based on extrapolations of cost and expected “version 1.0” feature-set.

  • License: $50-$150 (after launch, general public can buy at $200-$400 in Asset Store)
  • Source code: $300-$1000 (various amounts of support)
  • Access to experts: $150-$750 (various levels of privacy + interaction)

UPDATE: One person has stated they would “never pay these prices”. That’s fine – they’re way outside my target audience. I’m more likely to increase these prices than decrease them. If you know what an ECS is, and understand the value, this is probably too cheap already.

Funding targets

This is what it’s going to cost to build:

  1. Minimal version that’s usable in most game-dev: approx. $15,000
  2. My preferred v1.0: approx. $75,000
  3. High-quality version for large games: approx. $200,000

I can write-off about 50% of the cost as this is a project that I need and will use myself – and it’s a labour of love. I can also add a %age in expected additional sales that happen naturally after the campaign has ended (from the Asset Store, etc).

But Kickstarter takes a cut, and the government takes a cut, and Amazon takes a cut. In the end, I need a KS campaign to raise something like:

  1. Minimal funding: $5,000
  2. Preferred funding: $30,000
  3. High-quality funding: $75,000

My situation

Who are you, anyway?

In case you don’t know … I’ve run Technology/Development for a couple of game companies (e.g. Mindcandy, NCsoft Europe). My StackOverflow score is somewhere north of 20,000. I’ve contributed to a few open-source projects, but the one I’m most active on is the SVG rendering library for iOS and Mac, where I’m the project lead and one of the top 3 contributors.

I started writing about Entity Systems back in 2007, mostly because I was frustrated that so many game studios were “doing it wrong”.

What I’m doing now

I teach non-technical people how to program. I work with schools, teachers, and directly with children/adults. I invented a new system of programming using physical objects and toys.

Working with a local school, I’m making a new course where I’ll be teaching children “how to make games with Unity3D”. I’m particularly interested in what I can do to the Unity Editor to make it more user-friendly and better for use in the classroom.

Depending on how this goes, I have a few people in mind I’ll hire to share the burden of writing this library. It’s something I need both in my day-job and in all my personal game projects. Doing it as a Kickstarter gives me the excuse to spend 100x as much time and effort on it as I would otherwise, and gives me a much better library than I’d get on my own.

Why Kickstarter?

I suck at Marketing. The biggest risk factor to this project is that I fail to make enough noise, and hence there’s too little money coming in to pay for the ongoing development and support. As a result, dev gets sidelined while I pay the bills.

A Kickstarter is my way of testing “can I find a critical mass of people who need this project, and get them to put their money where their mouth is?”.

It’s going to be hard – I suck at marketing – but to be honest I’m leaning heavily on the idea that this is something people want badly enough they’ll help me market and promote it. With KS, there’s no risk to you for helping here … if the campaign fails, you pay nothing. If it succeeds, I get enough cash (and enough users!) to guarantee development through to a production-ready version.

Are you in?

Support me on Patreon, writing about Entity Systems and sharing tech demos and code examples

Categories
entity systems Unity3D

ECS for Unity: design notes + next prototype

Recently I’ve been thinking a lot about how a high-quality ECS would appear / present itself within Unity, how it would interact with standard Unity3d game-code at the API level, how it would appear in the Unity Editor, etc. This evening, I had a go at making some of that within Unity itself.

NB: a few weeks ago I made a small Editor Plugin that used Reflection to upgrade and fix some of the core Unity Editor code/GUI. That was practice for what I’m doing here. It’ll hopefully appear on the Asset Store at some point (pending review right now!) – it has the full source unobfuscated, so you can see for yourself both what and how I got it to do its clever bits.

Categories
dev-process entity systems Unity3D

Unity’s failure as an Entity System, example 1: Selecting things

Entity Systems in Unity… some examples of the problems

This is a new series of blog posts, where I’m going to document specific ways + concrete examples in which Unity fails (sometimes spectacularly) as an “ECS” game engine.

I like Unity; but the core architecture (which is very old) is a half-assed ECS, and if we’re to upgrade it into a really good, modern, architecture … we first need to understand exactly where it’s failing, and why.

So, let’s start with Selecting Things…

Background

Game

A 2-player card game where each player normally draws a card each turn, and then plays one or more cards. Sometimes (e.g. when discarding because “too many cards in hand”) they have to select more than one card at once.

Initial version of game will be 1-player versus computer. Very soon: want to upgrade to OPTIONAL 2-players on-screen, with one using the mouse, other using gamepad. Ultimately, want to also add over-the-internet multiplayer (which ends up interfacing with the codebase in a very similar way to the original 1-player-vs-computer, so we can ignore for now).

Code Situation

Player taps card. Now … we must inform many other scripts and independent systems, so they can choose to eg.

  • ignore (if invalid for current state of game)
  • react (e.g. zoom to display the card more clearly)
  • “select” internally (side-effects include: deselect other things)
  • advance the game (if it was waiting-for-input)
  • ..etc

Problem

What/where do you send the “player clicked on a card; can some piece(s) of code PLEASE deal with this??!!?” ?

Addendum

In Unity, only the low-level “card” object can sensibly detect it has been clicked on.

Both Unity’s Physics (old) and EventSystem (new) effectively force this via their core design. Both require you to attach scripts to the physical objects that will be clicked.

In practice, this is bad for OOP (and bad for ECS too). When there’s e.g. 100 cards all of which must be separately clickable, your code is really in the wrong place. You don’t want cards (which sometimes are in a deck, sometimes on the table, sometimes “virtual” (perhaps in a virtual, unopened booster pack etc)) … to be containing all the GAME logic required to know what to do when they’re touched!

Classic Entity System / ECS solution

  1. Create a SelectedByPlayer component
  2. Add it to the card
  3. Sit back, and relax. Code that cares about input will scan “get me all SelectedByPlayer components” on each frame, and react accordingly

Everything works automatically; any System/Processor that’s “waiting for a selection”, or “making render changes when selections add/remove”, etc … will pick up what it needs, with no work.

You can add new input-handling routines simply by adding them. That’s all. No other changes needed.

Attempting to solve this in Unity

UNITY 4.6/5.0

Maybe … NB: I’ve only just started using the new GUI/EventSystem in Unity 4.6+ .. create a custom Input event, and a custom InputModule that can understand that, and then put all the code for ALL affected systems/processors into one monolithic ugly, hard-to-maintain script from Hell.

I suspect that this code will be quite maintainable w.r.t. adding new Input hardware in future – e.g. allowing mouse vs gamepad. But it’s going to suck at the rest, all the business-logic and handling. Which is going to be > 95% of the maintenance cost.

You get one small benefit: you can separate-out different inputs (click versus drag). Sadly, in reality: 95% of game actions will be simple clicks. This is one of those “the code architecture sounded great in academic situation, but reality is so unbalanced, it works out less well in practice” situations.

This is a classic OOP solution, and has the downsides. The only significant benefit I can think of is that it’s a “known” Hell: if you’ve done a lot of OOP game coding, you’ll be familiar with the pain you’re going to run into.

UNITY CLASSIC

Make a new class “CardClickManager” whose sole purpose is to reference all the possible bits of OOP code that “might” need to react, and which has to be updated by hand EVERY TIME you modify, add, or remove some input-handling code ANYWHERE else in the codebase.

Pretty much the same as above, except it:

  • … is even more simplistic (no event-dispatch systems)
  • … making it even harder to maintain + debug
  • … is slightly more proprietary

Conclusions / Improving Unity

So far, I cannot think of any sane, maintainable solution here other than “suck it down and use OOP, and suffer forever”, or “throw away Unity GameObject/Component, and implement a proper ECS”.

That’s fine, though. That’s the point of these posts – to hilight situations where there’s no good middle-ground, where we must create the data-centric, cleanly-separated architecture of a modern ECS.

Counter-ideas very welcome! Comment away, guys…

Categories
computer games entity systems Unity3D

Towards a Unity3D ECS: what GUI? What features?

This year, one of my goals was to build a sane, powerful, viable Entity System / Entity-Component System within Unity3D. Something I could build current and future games on, and save a lot of dev-time (both in ease-of-use and in easily adding missing features that I wish Unity had).

So, progress?

Categories
entity systems

Unconference on Entity Systems – Pre-Signup

Entity Systems are widely used in gamedev and starting to appear in mainstream IT / software development. But we want MORE developers and designers to benefit from this…

So, Richard Lord and I are going to do a mini conference on ES ideas/designs/uses/implementation/etc.

I’ll arrange venue, agenda (e.g. a Keynote) – but this will be an Unconference, so most/all sessions will be interactive, freeform, with no fixed Speakers.

To book a venue, I need an idea of numbers. So, if you’d like to come, please fill out this google form. Note: I’m planning to do this in Brighton, (UK) – less than 30 minutes from an International Airport (Gatwick).

https://docs.google.com/forms/d/156Sb9Qhx4RIX1d0BZg_22MVlUSoUb-gRqwrOq0zeT-w/viewform

Key info:

  • Date: Summer/Autumn 2014
  • Location: Brighton, UK
  • Cost: minimal (depends on demand + venue)
Categories
entity systems

Your best links and articles on Entity Systems / Component Systems

The Entity Systems wiki is pretty good – simple source-code examples in 5 different languages, and links to 10 x richer, more complex “frameworks”.

But it’s got little (almost nothing) in links to articles, introductions, tutorials on the topic. I know there’s a lot that’s been written – just look at all the trackbacks on my old ES blog posts.

Let’s fill out a page on the wiki with tutorials, techniques, etc. What are your favourites (and can you give a 1-sentence summary of what each one does well?)

Categories
entity systems games design programming

Data Structures for Entity Systems: Contiguous memory

This year I’m working on two different projects that need an Entity System (ES). One of them is a non-game app written natively on iOS + Android. The other is an FPS in Unity3D.

There are good, basic Open-Source ES’s out there today (and c.f. the sidebar there). I tried porting a few, but none of them were optimized for performance, and most of them were too tightly coupled to a single programming language or platform. I’ve started a new ES of my own – Aliqua.org – to fix these problems, and I’m already using it in an app that’s in alpha-testing.

I’ll be blogging experiences, challenges, and ideas as I go.

2016 Update: Support me on Patreon, writing about Entity Systems and sharing tech demos and code examples

Background: focus on ES theory, or ES practice?

If you’re new to ES’s, you should read my old blog posts (2007 onwards), or some of the source code + articles from the ES wiki.

My posts focussed on theory: I wanted to inspire developers, and get people using an ES effectively. I was fighting institutionalised mistakes – e.g. the over-use of OOP in ES development – and I wrote provocatively to try and shock people out of their habits.

But I avoided telling people “how” to implement their ES. At the extreme, I feared it would end up specifying a complete Game Engine:

…OK. Fine. 7 years later, ES’s are widely understood and used well. It’s time to look at the practice: how do you make a “good” ES?

NB: I’ve always assumed that well-resourced teams – e.g. AAA studios – need no help writing a good ES. That’s why I focussed on theory: once you grok it, implementation concerns are no different from writing any game-engine code. These posts are aimed at non-AAA teams: those who lack the money (or expertise) to make an optimized ES first time around.

For my new ES library, I’m starting with the basics: Data Structures, and how you store your ES data in memory.

Where you see something that can be done better – please comment!

Aside on Terminology: “Processors, née Systems”

ES “Systems” should be batch-processing algorithms: you give them an array/stream of homogeneous data, and they repeat one algorithm on each row/item. Calling them “Processors” instead of “Systems” reduces confusion.

Why care about Data Structures?

There is a tension at the heart of Entity Systems:

  • In an ES game, we design our code to be Functional: independent, data-oriented, highly efficient for streaming, batching, and multi-threaded execution. Individual Processors should be largely independent, and easy to split out onto different CPU cores.
  • With the “Entity” (ID) itself, we tie those Functional chunks together into big, messy, inter-dependent, cross-functional … well, pretty much: BLOBs. And we expect everything to Just Work.

If our code/data were purely independent, we’d have many options for writing high-performance code in easy ways.

If our data were purely chunked, fixed at compile-time, we’d have tools that could auto-generate great code.

But combining the two, and muddling it around at runtime, poses tricky problems. For instance:

  1. Debugging: we’ve gone from clean, separable code you can hold in your head … to amorphous chunks that keep swelling and contracting from frame-to-frame. Ugh.
  2. Performance: we pretend that ES’s are fast, cache-efficient, streamable … but at runtime they’re the opposite: re-assembled every frame from their constituent parts, scattered all over memory
  3. Determinism: BLOBs are infamously difficult to reason about. How big? What’s in them? What’s the access cost? … we probably don’t know.

With a little care, ES’s handle these challenges well. Today I’m focussing on performance. Let’s look at the core need here:

  • Each frame, we must:
    1. Iterate over all the Processors
    2. For each Processor:
      1. Establish what subset of Entity/Component blobs it needs (e.g. “everything that has both a Position and a Velocity”)
      2. Select that from the global Entity/Component pool
      3. Send the data to the CPU, along with the code for the Processor itself

The easiest way to implement selection is to use Maps (aka Associative Arrays, aka Dictionaries). Each Processor asks for “all Components that meet [some criteria]”, and you jump around in memory, looking them up and putting them into a List, which you hand to the Processor.

But Maps scatter their data randomly across RAM, by design. And the words “jump around in memory” should have every game-developer whimpering: performance will be bad, very bad.

NB: my original ES articles not only use Maps, but give complete source implementations using them. To recap: even in 2011, Android phones could run realtime 30 FPS games using this. It’s slow – but fast enough for simple games

Volume of data in an ES game

We need some figures as a reference point. There’s not enough detailed analysis of ES’s in particular, so a while back I wrote an analysis of Components needed to make a Bomberman clone.

…that’s effectively a high-end mobile game / mid-tier desktop game.

Reaching back to 2003, we also have the slides from Scott’s GDC talk on Dungeon Siege.

…that’s effectively a (slightly old) AAA desktop game.

From that, we can predict:

  • Number of Component-types: 50 for AA, 150 for AAA
  • Number of unique assemblages (sets of Component-types on an Entity): 1k for AA, 10k for AAA
  • Number of Entities at runtime: 20k for AA, 100k for AAA
  • Size of each Component in bytes: 64bits * 10-50 primitives = 100-500 bytes

How do OS’s process data, fast?

In a modern game the sheer volume of data slows a modern computer to a crawl – unless you co-operate with the OS and Hardware. This is true of all games. CPU and RAM both run at a multiple of the bus-speed – the read/write part is massively slow compared to the CPU’s execution speed.

OS’s reduce this problem by pre-emptively reading chunks of memory and caching them on-board the CPU (or near enough). If the CPU is processing M1, it probably wants M2 next. You transfer M2 … Mn in parallel, and if the CPU asks for them next, it doesn’t have to wait.

Similarly, RAM hardware reads whole rows of data at once, and can transfer it faster than if you asked for each individual byte.

Net effect: Contiguous memory is King

If you store your data contiguously in RAM, it’ll be fast onto the Bus, the CPU will pre-fetch it, and it’ll remain in cache long enough for the CPU(s) to use it with no extra delays.

NB: this is independent of the programming-language you’re using. In C/C++ you can directly control the data flow, and manually optimize CPU-caching – but whatever language you use, it’ll be compiled down to something similar. Careful selection and use of data-structures will improve CPU/cache performance in almost all languages

But this requires that your CPU reads and writes that data in increasing order: M1, M2, M3, …, M(n).

With Data Structures, we’ll prioritize meeting these targets:

  1. All data will be as contiguous in RAM as possible; it might not be tightly-packed, but it will always be “in order”
  2. All EntitySystem Processors will process their data – every frame (tick) – in the order it sits in RAM
    • NOTE: a huge advantage of ES’s (when used correctly) is that they don’t care what order you process your gameobjects. This simplifies our performance problems
  3. Keep the structures simple and easy to use/debug
  4. Type-safety, compile-time checks, and auto-complete FTW.

The problem in detail: What goes wrong?

When talking about ES’s we often say that they allow or support contiguous data-access. What’s the problem? Isn’t that what we want?

NB: I’ll focus on C as the reference language because it’s the closest to raw hardware. This makes it easier to describe what’s happening, and to understand the nuances. However, these techniques should also be possible directly in your language of choice. e.g. Java’s ByteBuffer, Objective-C’s built-in C, etc.

Usually you see examples like a simple “Renderer” Processor:

  • Reads all Position components
    • (Position: { float: x, float y })
  • Each tick, draws a 10px x 10px black square at the Position of each Component

We can store all Position components in a tightly-packed Array:

compressed-simple-array

This is the most efficient way a computer can store / process them – everything contiguous, no wasted space. It also gives us the smallest possible memory footprint, and lets the RAM + Bus + CPU perform at top speed. It probably runs as fast or faster than any other engine architecture.

But … in reality, that’s uncommon or rare.

The hard case: One Processor reads/writes multiple Component-types

To see why, think about how we’d update the Positions. Perhaps a simple “Movement” Processor:

  • Reads all Position components and all Velocity components
    • (Position: { float: x, float y })
    • (Velocity: { float: dx, float dy })
  • Each tick, scales Velocity.dx by frame-time, and adds it to Position.x (and repeats for .dy / .y)
  • Writes the results directly to the Position components

“Houston, we have a problem”

This is no longer possible with a single, purely homogeneous array. There are many ways we can go from here, but none of them are as trivial or efficient as the tight-packed array we had before.

Depending on our Data Structure, we may be able to make a semi-homogeneous array: one that alternates “Position, Velocity, Position, Velocity, …” – or even an array-of-structs, with a struct that wraps: “{ Position, Velocity }”.

…or maybe not. This is where most of our effort will go.

The third scenario: Cross-referencing

There’s one more case we need to consider. Some games (for instance) let you pick up items and store them in an inventory. ARGH!

…this gives us an association not between Components (which we could handle by putting them on the same Entity), but between Entities.

To act on this, one of our Processors will be iterating across contiguous memory and will suddenly (unpredictably) need to read/write the data for a different Entity (and probably a different ComponentType) elsewhere.

This is slow and problematic, but it only happens thousands of times per second … while the other cases happen millions of times (they have to read EVERYTHING, multiple times – once per Processor). We’ll optimize the main cases first, and I’ll leave this one for a later post.

Iterating towards a solution…

So … our common-but-difficult case is: Processors reading multiple Components in parallel. We need a good DS to handle this.

Iteration 1: a BigArray per ComponentType

The most obvious way forwards is to store the EntityID of each row into our Arrays, so that you can match rows from different Arrays.

If we have a lot of spare memory, instead of “tightly-packing” our data into Arrays, we can use the array-index itself as the EntityID. This works because our EntityID’s are defined as integers – the same as an array-index.

rect3859

Usage algorithm:

  • For iterating, we send the whole Array at once
  • When a Processor needs to access N Components, we send it N * big-arrays
  • For random access, we can directly jump to the memory location
    • The Memory location is: (base address of Array) + (Component-size * EntityID)
    • The base-address can easily be kept/cached with the CPU while iterating
    • Bonus: Random access isn’t especially random; with some work, we could optimize it further

Problem 1: Blows the cache

This approach works for our “simple” scenario (1 Component / Processor). It seems to work for our “complex” case (multiple Components / Processor) – but in practice it fails.

We iterate through the Position array, and at each line we now have enough info to fetch the related row from the Velocity array. If both arrays are small enough to fit inside the CPU’s L1 cache (or at least the L2), then we’ll be OK.

Each instance is 500 bytes
Each BigArray has 20k entries

Total: 10 MegaBytes per BigArray

This quickly overwhelms the caches (even an L3 Cache would struggle to hold a single BigArray, let alone multiple). What happens net depends a lot on both the algorithm (does it read both arrays on every row? every 10th row?), and the platform (how does the OS handle RAM reads when the CPU cache is overloaded?).

We can optimize this per-platform, but I’d prefer to avoid the situation.

Problem 2: memory usage

Our typeArray’s will need to be approimately 10 megabytes each:

For 1 Component type: 20,000 Entities * 50 variables * 8 bytes each = 8 MB

…and that’s not so bad. Smaller components will give smaller typeArrays, helping a bit. And with a maximum of 50 unique ComponentTypes, we’ve got an upper bound of 500 MB for our entire ES. On a modern desktop, that’s bearable.

But if we’re doing mobile (Apple devices in 2014 still ship with 512 MB RAM), we’re way too big. Or if we’re doing dynamic textures and/or geometry, we’ll lose a lot of RAM to them, and be in trouble even on desktop.

Problem 3: streaming cost

This is tied to RAM usage, but sometimes it presents a bottleneck before you run out of memory.

The data has to be streamed from RAM to the CPU. If the data is purely contiguous (for each component-type, it is!), this will be “fast”, but … 500 MB data / frame? DDR3 peaks around 10 Gigabytes / second, i.e.:

Peak frame rate: 20 FPS … divided by the number of Processors

1 FPS sound good? No? Oh.

Summary: works for small games

If you can reduce your entity count by a factor of 10 (or even better: 100), this approach works fine.

  • Memory usage was only slightly too big; a factor of 10 reduction and we’re fine
  • CPU caching algorithms are often “good enough” to handle this for small datasets

The current build of Aliqua is using this approach. Not because I like it, but because it’s extremely quick and easy to implement. You can get surprisingly far with this approach – MyEarth runs at 60 FPS on an iPad, with almost no detectable overhead from the ES.

Iteration 2: the Mega-Array of Doom

Even on a small game, we often want to burst up to 100,000+ Entities. There are many things we could do to reduce RAM usage, but our biggest problem is the de-contiguous data (multiple independent Arrays). We shot ourselves in the foot. If we can fix that, our code will scale better.

es-datastructures-structured-bigarray

In an ideal world, the CPU wants us to interleave the components for each Entity. i.e. all the Components for a single Entity are adjacent in memory. When a Processor needs to “read from the Velocity and write to the Position”, it has both of them immediately to hand.

Problem 1: Interleaving only works for one set at a time

If we interleave “all Position’s with all Velocity’s”, we can’t interleave either of them with anything else. The Velocity’s are probably being generated by a different Processor – e.g. a Physics Engine – from yet another ComponentType.

mega-array

So, ultimately, the mega-array only lets us optimize one Processor – all the rest will find their data scattered semi-randomly across the mega-array.

NB: this may be acceptable for your game; I’ve seen cases where one or two Processors accounted for most of the CPU time. The authors optimized the DS for one Processor (and/or had a duplicate copy for the other Processor), and got enough speed boost not to worry about the rest

Summary: didn’t really help?

The Mega Array is too big, and it’s too interconnected. In a lot of ways, our “lots of smaller arrays – one per ComponentType” was a closer fit. Our Processors are mostly independent of one another, so our ideal Data Structure will probably consist of multiple independent structures.

Perhaps there’s a halfway-house?

Iteration 3: Add internal structure to our MegaArray

When you use an Entity System in a real game, and start debugging, you notice something interesting. Most people start with an EntityID counter that increases by 1 each time a new Entity is created. A side-effect is that the layout of components on entities becomes a “map” of your source code, showing how it executed, and in what order.

e.g. With the Iteration-1 BigArrays, my Position’s array might look like this:

rect3859

  1. First entity was an on-screen “loading” message, that needed a position
  2. BLANK (next entity holds info to say if loading is finished yet, which never renders, so has no position)
  3. BLANK (next entity is the metadata for the texture I’m loading in background; again: no position)
  4. Fourth entity is a 3d object which I’ll apply the texture to. I create this once the texture has finished loading, so that I can remove the “loading” message and display the object instead
  5. …etc

If the EntityID’s were generated randomly, I couldn’t say which Component was which simply by looking at the Array like this. Most ES’s generate ID’s sequentially because it’s fast, it’s easy to debug (and because “lastID++;” is quick to type ;)). But do they need to? Nope.

If we generate ID’s intelligently, we could impose some structure on our MegaArray, and simplify the problems…

  1. Whenever a new Entity is created, the caller gives a “hint” of the Component Types that entity is likely to acquire at some time during this run of the app
  2. Each time a new unique hint is presented, the EntitySystem pre-reserves a block of EntityID’s for “this and all future entities using the same hint”
  3. If a range runs out, no problem: we add a new range to the end of the MegaArray, with the same spec, and duplicate the range in the mini-table.
  4. Per frame, per Processor: we send a set of ranges within the MegaArray that are needed. The gaps will slow-down the RAM-to-CPU transfer a little – but not much

es-datastructures-structured-megaarray

Problem 1: Heterogeneity

Problem 1 from the MegaArray approach has been improved, but not completely solved.

When a new Entity is created that intends to have Position, Velocity, and Physics … do we include it as “Pos, Vel”, “Pos, Phys” … or create a new template, and append it at end of our MegaArray?

If we include it as a new template, and insist that templates are authoritative (i.e. the range for “Pos, Vel” templates only includes Entities with those Components, and no others) … we’ll rapidly fragment our mini-table. Every time an Entity gains or loses a Component, it will cause a split in the mini-table range.

Alternatively, if we define templates as indicative (i.e. the range for “Pos, Vel” contains things that are usually, but not always Pos + Vel combos), we’ll need some additional info to remember precisely which entities in that range really do have Pos + Vel.

Problem 2: Heterogeneity and Fragmentation from gaining/losing Components

When an Entity loses a Component, or gains one, it will mess-up our mini-table of ranges. The approach suggested above will work … the mini-table will tend to get more and more fragmented over time. Eventually every range is only one item long. At that point, we’ll be wasting a lot of bus-time and CPU-cache simply tracking which Entity is where.

NB: As far as I remember, it’s impossible to escape Fragmentation when working with dynamic data-structures – it’s a fundamental side effect of mutable data. So long as our fragmentating problems are “small” I’ll be happy.

Problem 3: Heterogeneity and Finding the Components within the Array

If we know that “Entity 4” starts at byte-offset “2048”, and might have a Position and Velocity, that’s great.

But where do we find the Position? And the Velocity?

They’re at “some” offset from 2048 … but unless we know all the Components stored for Entity 4 … and what order they were appended / replaced … we have no idea which. Raw array-data is typeless by nature…

Iteration 4: More explicit structure; more indexing tables

We add a table holding “where does each Entity start”, and tables for each Component stating “offset for that Component within each Entity”. Conveniently, this also gives us a small, efficient index of “which Entities have Component (whatever)”:

es-datastructures-structured-megaarray-by-component

Problem 1: non-contiguous data!

To iterate over our gameobjects, we now need:

  • One big mega-array (contiguous)
  • N x mini arrays (probably scattered around memory)

Back to square one? Not quite – the mini-arrays are tiny. If we assume a limit of 128,000 entities, and at most 8kb of data for all Components on an Entity, our tables will be:

[ID: 17bits][Offset: 13 bits] = 30 bits per Component

…so that each mini-array is 1-40 kB in size. That’s small enough that several could fit in the cache at once.

Good enough? Maybe…

At this point, our iterations are quite good, but we’re seeing some recurring problems:

  • Re-allocation of arrays when Components are added/removed (I’ve not covered this above – if you’re not familiar with the problem, google “C dynamic array”)
  • Fragmentation (affects every iteration after Iteration 1, which doesn’t get any worse simple because it’s already as bad as it could be)
  • Cross-referencing (which I skipped)

I’ve also omitted history-tracking – none of the DS’s above facilitate snapshots or deltas of game state. This doesn’t matter for e.g. rendering – but for e.g. network code it becomes extremely important.

There’s also an elephant in the room: multi-threaded access to the ES. Some ES’s, and ES-related engines (*cough*Unity*cough*), simply give-up on MT. But the basis of an ES – independent, stateless, batch-oriented programming – is perfect for multi threading. So there must be a good way of getting there…

…which gives me a whole bunch of things to look at in future posts :).

PS … thanks to:

Writing these things takes ages. So much to say, so hard to keep it concise. I inflicted early drafts of this on a lot of people, and I wanted to say “thanks, guys” :). In no particular order (and sorry in advance if final version cut bits you thought should be in there, or vice versa): TCE’ers (especially Dog, Simon Cooke, doihaveto, archangelmorph, Hypercube, et al), ADB’ers (Amir Ebrahimi, Yggy King, Joseph Simons, Alex Darby, Thomas Young, etc). Final edit – and any stupid mistakes – are mine, but those people helped a lot with improving, simplifying, and explaining what I was trying to say.

Categories
entity systems iphone programming

Cross-platform Entity System design

I’ve started a new open-source project to make an ES designed specifically to be ported to different platforms and work the same way, with the same class/method names, on every platform:

Aliqua.org

Here’s some thoughts on “why” I’m doing this, and “how” I’m making it work…

Categories
entity systems programming

Artemis Entity System in ObjectiveC

I wanted to try the latest version of Artemis, and I had an old game project that was quickly written in OOP style. So I went looking for an ObjC port…

Existing port: outdated

There was a port linked on the Artemis site that was OK – but had no documentation or updates, and Artemis has moved on since then.

There were also no unit tests etc – and the current Artemis getting-started wouldn’t work with this port (because so much has changed). So I started a new port…

New port: ObjC Artemis 100%

Primary aim:

  • make it identical to the core Artemis.
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 :).

Categories
entity systems

Entity System game on Steam Greenlight: The Few (WW2 planes RTS)

http://steamcommunity.com/sharedfiles/filedetails/?id=130180383