An introduction to Entity Systems

Home Forum Development User Code & Projects An introduction to Entity Systems

This topic contains 179 replies, has 20 voices, and was last updated by  Bonechilla 1 year, 6 months ago.

Viewing 15 posts - 1 through 15 (of 180 total)
  • Author
    Posts
  • #27768
    +10

    Brent Owens
    461p
    Keymaster

    Hey all,
    I posted up a little article about Entity Systems on the Attack of the Gelatinous Blob indieDB page.
    If you have been wondering what they are all about, or have never heard of them before and are now curious, then it would be worth a read. If you are a seasoned ES veteran then you might be a little bored :)
    enjoy

    #196571

    Wesley Shillingford
    834p
    Participant

    Awesome, will have to check it out later

    #196572
    +1

    zzuegg
    210p
    Participant

    As always, i always like reading about how others solve certain situations. I can’t wait to read something about AI ;)

    On more detailed questions:

    I have seen you use

    in your EntitySystems.. i am curious about this function, since my first implementations was similar. I did a full iteration over all entitys for each each entity system. The result was that this caused a big bottleneck and the result for these queries are likely the same on every frame.. What i did to solve this was to introduce a EntitySystemToEntityMapper (ESTEM) . Basically when a Entity gets a new Component then the ESTEM needs only the recheck every EntitySystem (which are more likely less then entity’s) and refresh the mapping.. The refresh happens as first thing on every frame if a component was added or removed. I additionally have ‘swiched’ also the execution: Instead of doing i do:

    The performance win was really big.. The ESTEM boosted performance incredibly, while the second part was mainly for multithreading optimisation..

    #196573

    Normen Hansen
    2792p
    Keymaster

    Theres no need to extend the simple system to add perfromance improvements. Rather apply.. performance improvements ^^ Caching comes to mind, afaik @pspeed caches even changes to the entries, so he basically never needs to scan the whole dataset.

    #196574

    Brent Owens
    461p
    Keymaster

    I have two Maps of Maps, each used for a different kind of lookup, sort of like an index on a database table.
    The main map for looking up all entities with a certain component looks like this:
    Map, Map>

    So there I look up the component type of HealthComponent.class and that gives me a map of entityId:actualComponentObject (every entity with a component of that type). For multiple component types I perform the lookup for each type, and then get all entities that are in each one. It turns out to be incredibly fast.

    I also have another map for getting all components for a specific entity:
    Map, Component>>
    There I can look up the entity using its ID, then I can pick what component I want using the Component.class

    #196575

    Shirkit
    74p
    Participant

    Using Artemis (http://gamadu.com/artemis/) those things get solved for you @zzuegg

    #196576

    pspeed
    3053p
    Keymaster

    @zzuegg said:
    As always, i always like reading about how others solve certain situations. I can’t wait to read something about AI ;)

    On more detailed questions:

    I have seen you use

    in your EntitySystems.. i am curious about this function, since my first implementations was similar. I did a full iteration over all entitys for each each entity system. The result was that this caused a big bottleneck and the result for these queries are likely the same on every frame.. What i did to solve this was to introduce a EntitySystemToEntityMapper (ESTEM) . Basically when a Entity gets a new Component then the ESTEM needs only the recheck every EntitySystem (which are more likely less then entity’s) and refresh the mapping.. The refresh happens as first thing on every frame if a component was added or removed. I additionally have ‘swiched’ also the execution: Instead of doing i do: The performance win was really big.. The ESTEM boosted performance incredibly, while the second part was mainly for multithreading optimisation..

    Formalizing the “systems” in an entity system is generally the wrong approach in my opinion. It forces you to do everything single threaded and the greatest feature of a properly implemented entity system is that you are free to use the entity system from any thread at any time. “Systems” are just the “code that isn’t an entity system”. They can be JME controls, they can be separate executor services, etc.. Like any data base system (and an entity system is essentially a fancy database, in memory or not), the query is main point of optimization. There are numerous ways to optimize this without throwing away the scalability benefits of an entity system’s thread-flexibility architecture. For example, in Mythruna I can grab EntitySets. These are essentially Set except they have a few extra methods on them. An EntitySet is similar a database ResultSet except that it acts just like a Set and the query can be reissued. But in a sense, it is a handle on a changing set of results… when they actually change is totally under the caller’s control. For example, a visual “system” (a JME control in this case), might then just grab one for Position and ModelInfo components:

    Mythruna takes advantage of the fact that its Entity System is all used by one JVM process and then just propagates changes under the covers. EntitySet.applyChanges() is essentially a free call if none of the entities has changed. And it’s a minimal call if they have since the changes were already accumulated and ready to go.

    The concept could be extended to multi-process systems, too. The idea of cached queries like this is not a particularly new one, I guess and there are various ways to approach the problem depending on requirements.

    To me, though, the query is the single biggest point to optimize and worth a little time to do right.

    #196577

    Empire Phoenix
    615p
    Participant

    Hehe its somewhat similar to the entity system i use, main difference is, I do stuff fully eventbased, so I rarly need querys at all. Also in my entity system, each component has all clientdside proxy data everytime, so there is more than just the id. (Eg position rotation), since this simiplifies networking due to me never having to know anything on that layer about the entity at all.

    #196578
    +2

    pspeed
    3053p
    Keymaster

    @EmpirePhoenix said:
    Hehe its somewhat similar to the entity system i use, main difference is, I do stuff fully eventbased, so I rarly need querys at all. Also in my entity system, each component has all clientdside proxy data everytime, so there is more than just the id. (Eg position rotation), since this simiplifies networking due to me never having to know anything on that layer about the entity at all.

    In my entity system an “entity” (little E) is just an ID. You can do all interactions with the entity system, an EntityID, and the components you want to mess with.

    EntitySets provide Entity objects (big E). These are locally cached “entities” (little E) representing a snapshot of when the query was last run.

    The problem that I had with typical event systems in a general architecture better suited to update loops was the potential for out of band messages. Now, all of the events are collected inside the current EntitySets and only applied to the local copies with applyChanges() is called… then those Entity objects in that set are frozen in time until the next update is called.

    Multithreading in this architecture is essentially free. I pretty much never have to think about it. The network layer iterates over the entities that it is interested in and blasts them out.

    I will say that my current network architecture that I’m developing for physics state is _much_ more complicated than that. It’s essentially bypassing the entity system on the server. The physics thread uses the entity system to track the mobile objects and blasts state updates to a ZoneManager. State is collected per zone and a separate state collector thread packages the relevant state out for each player. These objects are very specific to the networking layer and there are no entities at that point.

    The client then unpacks these messages and modifies local state in the client-side entity system. To the client, it looks just like it’s running a local physics instance directly updating the entities… all through the entity system.

    I should write an article sometime.

    #196579

    Normen Hansen
    2792p
    Keymaster

    Please, do not confuse some system that calls some objects “entities” with an entity system as described here. This is a very specific implementation that doesn’t allow much “idea adding” or hampering with the general structure. Its very specific and should be done exactly as described to actually be useful.

    #196580

    kazeshiro
    10p
    Participant

    Nice reading!
    Concise and easy to understand.
    Thanks a lot

    #196581

    Shirkit
    74p
    Participant

    @normen said:
    Please, do not confuse some system that calls some objects “entities” with an entity system as described here. This is a very specific implementation that doesn’t allow much “idea adding” or hampering with the general structure. Its very specific and should be done exactly as described to actually be useful.

    You mean what was describred by @pspeed ?

    #196582

    pspeed
    3053p
    Keymaster

    @shirkit said:
    You mean what was describred by @pspeed ?

    I don’t think so. Normen and I generally agree on Entity System design. Pretty sure it was directed at the other posts talking about taking it in odd directions.

    #196583

    Shirkit
    74p
    Participant

    @pspeed said:
    I don’t think so. Normen and I generally agree on Entity System design. Pretty sure it was directed at the other posts talking about taking it in odd directions.

    That’s why I asked, suddenly I thought that my whole implementation of Entity Systems wasn’t an ES!

    #199923

    stephanator
    5p
    Participant

    Hey guys, I have a question(Ok maybe 3) for you.

    The overall concepts of the ES aren’t a problem for me, I’m used to using Hibernate at work and breaking things down to data sets is fairly commonplace in my head. Its rather easy for me to view ES as a relational database in memory.

    The confusion starts to come in:
    How the loops generally look in an example system?
    How do systems trade data?

    You also mention this function:

    could you pseudocode if for me? Im pretty sure i could run from there after seeing what this does behind the hood.

    And Sploreg, the article you wrote is probably the best crash course on ES that I’ve seen so far. Too many “tutorials” on ES assume a rather large amount of previous knowledge from the reader. Good job. Wish it came front page on google three weeks ago when i started reading on the subject lol

Viewing 15 posts - 1 through 15 (of 180 total)

You must be logged in to reply to this topic.