Benefits of implementing systems like classes instead of just functions

In an Entity System I am making, there is a central class called World, which stores all component instances. It's a dictionary-of-arrays, and entity ids are indexes for the arrays.

To access a component of an entity with id = 3 you would do this: world.storage["ComponentType"][3].

So, each loop of the game, these arrays would be fed to their respected systems ( movement(world.storage["Position"], world.storage["Velocity"]) ).

Now, I don't see why systems couldn't be implemented just as functions, as I showed. What optimizations can be made by using classes with data and methods (caching)?

Also, these systems would need to iterate over all the entities that exist, doesn't this make entity frameworks much slower than regular inheritance based engines? Why do some people "register" systems to the World class?

• I think the end of your question got cut off? – MichaelHouse Jul 26 '12 at 1:01
• Only two letters and a question mark. – jcora Jul 26 '12 at 5:03

What optimizations can be made by using classes with data and methods (caching)?

On a logical level, x.y() is completely equivalent to y(x), and in most languages is pretty much implemented exactly that way. The only benefit you get is that your language might treat member variables as locals within methods, so that you save some typing. eg. Java and C++ do this, Python does not.

On a practical level, where the data is located makes a difference to the speed of access. Unfortunately how much difference and how to influence this is 100% dependent on the language you are using. But in general, if you can ensure that data that is used together or used sequentially is stored closely together, and if your language is low level enough, you can see some significant performance increases.

Also, these systems would need to iterate over all the entities that exist, doesn't this make entity frameworks much slower than regular inheritance based engines?

No, because again the systems are logically equivalent. The traditional system would iterate over all entities, and for each entity, would iterate over each element of functionality that needs processing. (The iteration may be implicit in that there would be a sequence of function calls.) The component system starts with the element of functionality and iterates over each entity that uses it. Exactly the same code gets called, just in a different order.

There's no free lunch - to get the same results you do the same work in all systems. The only difference is how you want to organise it all.

• What do you mean by "logically equivalent"? – jcora Jul 26 '12 at 14:05
• I mean there's no practical difference except in how you type them. – Kylotan Jul 26 '12 at 15:53

I am using a component/subsystem architecture in my current system for multiple reasons.

1. I want to operate on batches of like data in order to optimize cache hits. If I store my components in the subsystems I can do this but I have to have logic somewhere to create the correct components and attach them to the entity messaging system. In some systems this is done in the world model, so the subsystems need to be registered. In my system I have a separate engine class handling it. There is a BehaviorTypes enum to determine what kind of behavior is being requested or provided.

2. I want to avoid data sharing problems without violating encapsulation by passing needed data in message parameters. I do this by making my entities an ID, a messaging system and a collection of behavior data components. These components are processed by the subsystems and the entity is notified of changes to it's member components through OnChanged type events. The components are physically located within the subsystems. Additional subsystems can register their interest and have these components passed through appropriate event arguments in order to provide additional behavior (ex. Animation advances in response to a position or velocity change). These relationships are established when a subsystem registers with the engine (in my system the WorldModel object is a singleton in the engine.

3. I want to be able to vary the entity data and subsystem data processing independently. This way if I decide to change my pathfinding system or change the tiles to hexagons, I can do so without disturbing the rest of the system.