Sunday, November 20, 2011

The (Dirty) Entity System: World, Systems, Components

I will just explain this concepts fairly quick, to give some more detail about the design I am making use of.


The World:


The world is what I call my "Game Manager", this is the one that does the most basic and important calls of the game, which are "Input", "Update", and "Draw".


The reason why I made Update and Input separated is because of the systems, I will get more into that in a second.


Again, the world holds and knows about all that happens within it, meaning that has full knowledge of the little rules that are being applied to it, even though the world has rules it does not know a thing about the inhabitants it possess, only about the systems.


The Systems:


The systems are the "rules" that govern over some entities, for example, if you were to have a weight component, and there was a gravity system, and you are within this system, then you are ruled by gravity, simple concept but powerful, this is the main reason why this model of programming is more flexible and easier to modify than Object Oriented Programming.


"Wait.. why?" In my opinion (and I can't stress that enough), Object oriented programing tells an object that is affected by gravity, by making use of inheritance, meaning that it come from "weightedObject" base, to turn into "HumanoidCreature", which then became "FatPerson", why it became "FatPerson"? because it needed an extra function "EatAllTheCookies", but then again this "FatPerson" (oh by the way, I am fat and happy!) class turned also into a "FatChildren" because they needed to add a "CryWhenOutOfCookies" function, and so on and on.




The main point there is that Object Oriented requires a lot of steps to be able to define a single object, this is because Gravity affects all the "WeightedObject" and not every single class that inherits WeightedObject separately, unless you wanna make something that manages all the classes that they came out and pass gravity to every single one of them like this (yes, one manager per inherited class, not likely).




So, we made a WeightComponent, made a gravity system, made a dog, a bird, a box full of newts and a glass of yogurt, all of them containing this WeightComponent, being affected directly by the system. "But wait! not all these objects behave the same way!", of course not! that's why we have specific data inside the Component.




Now, for the reason to separate input from update, is because Systems are linked to one of these, and one of these only, when something is modified by input, the system only cares about modifying the data inside the components, and nothing else, it does not do any kind of "reaction" for something happening, is more like the actual trigger, and the update phase deals with anything that falls under the static logic of the systems.




The Components:




A component is the most simple yet descriptive piece of data, in a nut shell (literally), is a collection of information regarding an specific aspect of an object (wow that sounded fancy... to me), the component is filled with useful information that can (or might not) be modified by the systems, depending on the system and current state of the component, let me give you an example with the gravity once again. We have a weight component, but we might also have a position component, this components are used by the gravity system, the gravity systems reads the information from the weight and position components and makes the conclusion that you are floating at the moment, then it makes use of a third component that you have, the velocity component (you could add the weight and velocity plus some other useful information and make it a single component), by doing this now the velocity component has a velocity towards the origin of the gravity, what does this do? not much really, but then we have another system, let's call it "PhysicsUpdateSystem", this system grabs the information in the velocity component, reads the elapsed time from a timer and then changes your position according the direction your velocity is pointing, and voila, we have gravity working.


Fascinating thing, you suddenly want to change some properties of the entity, simply change the data in the component at the moment of creating the entity and you will have a different behavior, add an extra component that modifies some of the behavior of a system to create a different result within the position (feather component perhaps?), the thing is that you don't need to override anything, you can either add or take off components, but I don't think you will need to override them, in some cases you might want to add more data to them.




I know I said I was going to be quick, but I rather prefer to explain this the best I can, if I failed on that... (Sorry!!!), more to come on the design.


Thanks for reading~

No comments:

Post a Comment