Hi Matej,
MatejZajacik wrote:For instance, a pickable item, let's say a key. I imagine the game object (GO) will have components:
[...]
So this would be the skeleton for all pickable items, and every item would only have a different pickable-derived component? Is this anything close to what you have in mind?
Yes, absolutely!
Considering that we have a working component system for GUI windows already, and that many of the core features will be re-used in the entity component system, I think that it is safe to say that your example very well outlines how the entity component system will work.
I'm also thinking about various ways you can do broadcasting events. One that comes first is that when a component wants to broadcast a message, it tells the game object (GO) and then GO tells other components that listen for the particular event. So on init, components that need to listen for certain events do register themselves as listeners in GO. Say, a collision component calls an "onTouch" event, coupled with a (Lua) table filled with data such as who the toucher is (most likely the player), point of touch, etc., and then GO looks through its list of listeners and send the data table to all who listen for "onTouch". The listener simply checks the table and behaves based on it.
Your approach sounds sound, but I'm not sure yet if we'll need such a (moderately complex) event handling system after all.
Currently, in the (admittedly quite simple) GUI system, if an event occurs, the code where the event originated simply calls a scripting callback function. It is then up to the scripting code to have supplied an
OnXyzEvent()
function beforehand, that at runtime acts as the event handler and is appropriately implemented to handle the event.
In your example with the pickable item, the Collision component might detect that it has been touched by the player entity, and call its
OnTouch(entity, direction)
script callback with the related data (touching entity, direction, etc.)
Of course, this leaves open the question how we can teach the "pickable item" prefab a default implementation for
OnTouch(entity, direction)
, e.g. one that runs "if entity is a human player, then add item ... to his inventory".
This is also in the GUI system one of the few not-yet-complete features (this, and prefabs; I can't think of anything else). In essence, we'd need a "prefab-local" or "GO-local" script. This in turn could possibly be achieved by a component of type "Script" or "Behavior". It would be up to this script to provide
all the callback implementations of all its components that its GO might need / be interested in.
I have already started to look into these issues (the Lua modules system might come in very handy here), but honestly have not yet thought through all the details. But this is certainly among the next things to tackle.
Another topic is the Transform component. In Unity, EVERY GO has the Transform comp by default. It implements position, rotation, scale and all the necessary functions to modify these values. To me, it seems like this could be directly implemented in GO class itself, since every single GO instance has the Transform comp anyway.
That was exactly my thinking too. I even had started to implement it like this, but then I realized that components are very well prepared for binding their variables and methods to scripts, to show them in the graphical editor and handle changes to their values, to generate reference docs from them, etc. -- and all of this (semi-)automatically!
If name, position, rotation, scale etc. where directly implemented in the GO, each place that naturally handles abstract components already would have to be special-cased for the variables in the GO.
This would have turned code that is short, concise and beautiful into a much less attractive show, as well as making extensibility and maintainability a lot more difficult. And so I changed my mind and, for GUI Windows, added a component "Basics" (which holds the name of the window, and the "is shown?" flag) and another component "Transform" (Position, Size, etc.).
Doing it like this went exactly in the spirit of components, and thus I'm now thinking that having an explicit Transform component also for GO's is the Right Thing to do.
Btw., I'll soon be ready to upload the new reference documentation for the GUI system. In it's components you'll be able to see much of what we've discussed so far.