Controllers

1 view
Skip to first unread message

Michael Cann

unread,
Jun 28, 2010, 3:20:36 PM6/28/10
to swft-fr...@googlegroups.com
Ello All,

Another hot topic for discussion as I see it is controllers and where they should live.

I have been discussing this with Ben Garney (lead dev on PBE) off list and he disagrees with my thinking, as its a rather fundamental departure from PBE I dont blame him for disagreeing :P

Controllers are components that do exactly what their name implies, they are the controller in an entity. In my experience they have tended to contain the large bulk of an entities business logic, listening for frame updates, moving spatial coordinates based on velocity, handling collisions etc. Due to thier central role in making an entity function they tend to have a great many dependencies, relying on many if not all of the other components in an entity.

Because one of the central premises for Swft is to have typed-entities with hard-coded references to components I thought why not just move the controller logic into the entity. This also gives a clearer separation of  responsibilities. The business logic for an entity is contained within the entity, and the components provide specific modules of functionality which the entity can manipulate and listen for events/signals on. This hopefully would also promote code reuse by making components modular with a specific set of dependencies.

An example of this would be the Bullet class from the shooter example:


Now there are a few confusing examples in the examples where I have used the word 'Controller' in some components such as the 'BloonController' from the BloonBlaster example: (http://github.com/mikecann/Swift-Examples/blob/master/BloonBlaster/src/co/uk/swft/bblaster/components/controller/BloonController.as). Perhaps I should rename this to 'Mover' or something like that to reflect that it isnt actually doing the controlling, rather is just moving the balloon about.

There is however nothing stopping the controller logic being implemented in a controller component a-la-PBE rather than in the entity.

I'd really like to hear others thoughts including Ben's (if he reads this ;))

Cheers,

Jos Yule

unread,
Jun 29, 2010, 10:32:58 AM6/29/10
to swft-fr...@googlegroups.com
Again, without having spent too much with the code (and really, what is my opinion worth unless i've actually built something!), it seems to me that the Entity is already tied to the different components. They are injected into it, so it has to know about them. Where is the advantage of moving the "brains" out into a separate class? Unless you can somehow see re-using a controller for multiple entity types, where is the reuse coming from?

Perhaps in a more dynamic setup, you might want to have the "brains" in a separate class from the entity itself, but in a more statically defined Entity, it makes sense (i think) to have that logic more local... Unless you would want to generalize the Entity and its associated Components - ie. some kind of setup that you would use in multiple games - then moving the specific logic into a game specific class would be helpful.

Perhaps the Chain of responsibility would be helpful here?

http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern

I think i need to think about this some more...

j


Jos Yule
Digital Hyakugei

Glidias

unread,
Jun 30, 2010, 12:15:26 PM6/30/10
to SWFt Game Framework
Note that with registering many updatable component classes per entity
being created (through an UpdatableEntityComponent base or IUpdatable
interface), there's no explicit priority given to the chain of
updatables being added to the update list. Currently, a push() is
being used, which turns out fine in this example because (I assumed)
you registered the WindManager first, which allows the WindManager's
updates to resolve prior to the entities' controllers. But again,
you're depending solely on one update to handle calculation and render-
validation through each given update of the controller.

What happens if there are multiple controllers, and some might need to
be resolved prior to the execution of the next controller update? One
of the balloons might be controllable by player keyboard upon being
selected, together with other components (eg. Collidable) and other
forces which affects the eventual velocity of the entity during
collisions? What if a particular collision prevents the player
keyboard controller from working because it disables the selection of
the balloon? Different collision resolvings between different type
groups of entities will eventually affect the eventual *visual* result
of the entity. As such, your framework would need to account for a
collision detection phase, a calculation phase, and a render phase.
It should also have (unlike OOP) have a single controller to handle
the precise order of how things should run given specific phases. One
of the problems with orienting your control to objects (OOP), is that
you'd have to look through many different components/object classes,
without clearly seeing the order priority from which they're being
executed. For more complex games, this can become unmanagable due to
the numerous amount of components being used across many packages.

Given the complexity and scale of a game, each component could simply
be a lightweight modifiers which modifies the eventual velocities of
the entity (though certain things like player keyboard control should
be managed after environmental factors are considered), leaving the
eventual visual result to a final render phase that is handled by
render order. However, if a physics engine (such as Box2D/Motor2)
already has that, you could already include wind and other forces
which affect the entity's position, and your entities (or components
thereof) merely holds the data to be fed to these engines. As such, a
controller class isn't needed per entity (as it results in numerous
class instance duplication), since there's no central engine being
used to define where your entities should be.

I'd prefer a framework that allows you to easily inject the required
references/properties into existing engines (such as Haxe/Alchemy-SWC
compiled engines or externally loaded .swf engine packages), so that
those engines can handle the outcome of your entities in a homogenous
manner through each given phase of a game's cycle. This can result in
a more data-oriented (vs object-oriented) approach though. Rather than
executing the operations from the bottom/bottom-up, you execute them
from the top-down, and certain components are useless without an
engine implementation of it, so why not just register some components
to an engine/manager that can keep track of everything from the top-
down? This approach is more engine-centric though.

I wished if there was a way to pre-process injector settings and bake
a SWF's classes' [Inject] code to inline dependency code generation,
that would really rock . Think of it as a compiler than can auto-
generate inline DI code for your classes based on metadata, assuming
that all dependencies can be clearly spelled out/resolved at compile
time (either specifying a wiring to a 1.static reference, 2. a class
to be made singleton, 3..a class to be generated, or a 4.static
provider factory method). For case no.2, the code generator even auto-
creates the static singleton-boiler plate method for you. Yes, compile-
time SwiftSuspenders inline preprocessor would really rock as it bakes
everything for you.

Michael Cann

unread,
Jul 5, 2010, 2:42:47 PM7/5/10
to swft-fr...@googlegroups.com
Hi Jos / Glidias,

Alot of different points there. 

First Jos, I hadnt ever heard of the Chain-of-responsibility pattern, cheers for the link ill be sure to give it a read over. I think you are also agreeing with my opinion of having the controller code in the Entity, tho I definitely do recommend try writing some code using Swft and see if you can spot any flaws in the method.

Glidias; firstly your point on the updating. Although not strictly related to the post it is a good point and needs to be discussed. At present you are totally correct there is no update priority so IUpdateable's can be updated in an arbitrary manner. As it stands it isnt a problem as the Swft examples so far have been exceedingly simple and have either just worked, due to luck on the order of their instantiation, or because the 1-frame difference in the order of updates isnt apparent at 60FPS. There are a several ways updates could be tackled all with their merits. I think its out of the scope of this post so ill spin off another thread for discussion on this topic.

As for your second point. Im not entirely sure I follow you 100% but I think you are advocating using black-box APIs to handle the grunt work of an engine. Now im all for that. I certainly want to try to try to integrate Box2D and other well-known APIs into the mix. This could probably be quite easily achieved by writing component wrappers for Box2D's Body objects. These components could even implement ISpatial2D component interface and hence be used with existing components that depend on ISpatial2D with ease.

I have to be careful around this ground however as I am working in a games company and my employers are fairly finicky about this stuff. Im thinking that Swft needs an area for 'Engine' stuff so that alot of these utility components can be gathered together. Perhaps ill do that when im back in the UK.

Mike


Reply all
Reply to author
Forward
0 new messages