Holiday, Components, and more!

Hello SunBurn community!

We'll be out of the office until Monday for the Thanksgiving holiday, we hope everyone has a great weekend!

I will be checking in occasionally to see how things are going, but may not be able to answer some questions until back in the office.


Object-level Components

We've been working on the latest SunBurn 2.0 Game Engine feature - object-level components - and already have a good portion of it up and running. :)

I thought it would be cool to kick off some discussion on the subject as we want a lot of feedback from the community.


So How Does it Work?

SunBurn’s object-level components allow you to plug custom code, behaviors, and modifiers into any entity, scene object, or light.

The system exposes the same object events already available in SunBurn:

UpdateEvent – called once per-frame to apply time based-changes to the object.
CollisionReactEvent – called when the object collides with another object.
CollisionTriggerEvent – called when an object passes through a trigger object.

However instead of writing event handlers for each of these you can write a single component class that takes care of any number of events and can easily be reused, inherited, and more.


Avoiding Component Clutter

One issue we were very careful to avoid is loosely typed components - that is allowing components with specific applications to be assigned to any object type (and in many cases the wrong object type). This causes a lot of confusion, for instance adding a mesh component to a light may not work, why not? Well they were not designed to work together.

SunBurn avoids this by using strongly typed components, which clearly state the relationship between components and their target object types.


Simple Example

As a quick example let’s create a component that works with any scene entity (and also scene objects as they derive from entities), and applies a simple spin to the object:


  // Derived from SunBurn's built-in BaseComponent class, but like
  // all of SunBurn it's modular and you can implement your own
  // using the IComponent interface.

  class SpinComponent : BaseComponent<ISceneEntity>
  {
      public override void OnUpdate(GameTime gametime)
      {
          // Calculate the elapsed rotation based on the time.
          float angle = (float)gametime.ElapsedGameTime.TotalSeconds * 4.0f;
          Matrix rotation = Matrix.CreateRotationY(angle);

          // Apply the rotation to the parent object (owner of the component).
          ParentObject.World = rotation * ParentObject.World;
      }
  }


This can be plugged into any scene entity, scene object, or avatar, and can be reused, inherited, and more.

Also multiple components can be applied to the same object to stack their features and effects.


Other Uses

Another interesting use for SunBurn components is applying custom properties to an object.

For instance let’s say you want to add the following properties to your game’s destructible scene objects:

Damage – how much damage the object has taken.
Destroyed – whether or not the object is dead or alive.

You could create a DestructibleObject class derived from SceneObject, which is an ok solution.

Or instead you could create a simple component that exposes the properties, and can be plugged into any scene entity or object regardless of which class it’s derived from. Using the component any scene entity or object can become destructible.


  class DestructibleComponent : BaseComponent<ISceneEntity>
  {
      // How much damage the object has taken.
     public float Damage { get; set; }
     // Whether or not the object is dead or alive.
     public bool Destroyed { get; set; }
  }


More to Come

There are a lot more awesome features to come, but we definitely want to see some community discussion around SunBurn’s object-level components!

What do you guys think? Let us know!

-John Kabus

 


Posted 11-25-2010 1:34 AM by JohnK "bobthecbuilder"

Comments

CJ Bailey wrote re: Holiday, Components, and more!
on 11-25-2010 3:13 PM

Enjoy the hols and Happy Thanksgiving to all of you stateside!  Now have a few drinks and put your feet up.... you deserve it.

:)

Israel wrote re: Holiday, Components, and more!
on 11-25-2010 3:58 PM

Hi

Very good info but I think you have been working a lot, do you sleep? :)  . Happy Thanksgiving.

CJ Bailey wrote re: Holiday, Components, and more!
on 11-25-2010 4:21 PM

Now I've had a read through, I have to say.... NICE!  I look forward to using these component features!

Philippe Da Silva wrote re: Holiday, Components, and more!
on 11-26-2010 3:30 AM

Hi John and ThanksGicing us such a great middleware! (you all diserve the cash I spent on SunBurn! ;)

I must tell you that you just broke 10% of the work I brought in my own game engine using SunBurn with this blog entry. :(

With such design, you cut all the code I wrote to extend SceneObject class so that I could plug my behaviors and custom rendering (for alpha).

But I confess that is the right way to go and I don't understand why I didn't go this way.

I always dislike the Game component approach for XNA because it plugged your code in the Game instance level while here, by providing such component system at the Entity level, you allow us to bring a clean way to design our game entities' behaviors.

For instance, one of the missing elements I had to overcome with previous versions was that most of the time, you want to attach a 2D sprite to your entities such as an impostor for long distance rendering or maybe add a text label on top of your character to name it or provide players with some information (number of damage taken or the like).

With this design, we will have it all built in. ;)

Just make sure to provide your components a way for us to:

A. Initialize the component and Load content

B. Get access to major game properties such as the SceneInterface instance and its managers but also the Game instance itself.

C. Push/Pop components on a stack instead of giving a integer based ordering system.

For the last point, that is my personal taste but I prefer having a Stack collection of components where I can push/pop/insert before or after a named component instead of stating which order number should be set.

It avoids me to remember (or look for) each component order number and just tell the system that I want my component to be before or after this other component.

Anyway, I really like the approach and I have now to work back on my framework to make sure I can plug my game code within this ;)

Finally, I imagine you cannot share with us when we could see that delivered to us but some clues would be nice so that we (I) know if I need to rework on my game code now or later.

Thanks

CJ Bailey wrote re: Holiday, Components, and more!
on 11-26-2010 4:22 AM

"I must tell you that you just broke 10% of the work I brought in my own game engine"

Count yourself lucky.  I've spent the past 6 months developing a simple collision/physics system and map editor.... D'OH!  Sunburn 2.0 has 'broke' about 80% of my game.  Oh well... back to the drawing board.  It will be better in the long run.

paul_blamire wrote re: Holiday, Components, and more!
on 11-26-2010 7:10 AM

Looking good :-)

Another decision to be made is whether to allow direct component to component communication, i.e let each component discover other components attached to the same entity so they can interact directly, or implement some pub/sub style component messaging where interested components can subscribe to say a TakenDamage message and handle it if interested.

Have people who've worked with them got a preference? (I've only implemented a little POC, I opted for messaging but have never used in the wild. So I don't have an opinion on what actually works best). I'd love to hear what other people think.

Another thing is pre-requisites, some components will inevitably require that other components exist on the entity (the most common cases have been neatly side-stepped by putting the standard movement, orientation, physics stuff, etc directly on the sceneobject). It would be nice to be able to specify prerequisites so that an entity can validate it has all the required components. It's also useful for the editor so that if you add one component you can automatically add the other ones it requires. First thought is a [RequiredComponent(typeof(Health))]

That is my first stream of thoughts anyway,

Paul

Philippe Da Silva wrote re: Holiday, Components, and more!
on 11-26-2010 11:54 AM

Personally, I dislike when there are interactions between components: components should be stateless as much as possible while the root component should keep the overall state.

To follow your example, if you have two components that need to be informed when Health changed, then the Health property should reside in the SceneObject instance (or better, your own SceneObject inherited class). Therefore, all your components can test for Health in the root class and perform their action.

This is simpler to maintain too: if you change one of your components, you don't care about dependencies which are the hell of programming from my perspective ;p

But that is solely my point of view :)

paul_blamire wrote re: Holiday, Components, and more!
on 11-26-2010 1:07 PM

Hi Philippe,

I don't like coupling between components at a technical level, but I don't have a problem with interaction between them.

If I understand right, this way of organizing the code came about because inheritance hierarchies would get out of control. If you push back the state to the root object then yes you've solved the problem for behavior but the same problem will still exist for state. e.g EntityWithHealth, EntityWithHealthAndInventory.

In a round about way I do kind of agree with you though as in an ideal world each component would be completely able to function without a reliance on other components. Given though that we don't live in a world where things always shake out like that then you end up with a few options (there are probably many more than this)

1) Put all the state on the entity. Downside, the entity object becomes a god object or you end up with some kind of inheritance hierarchy again.

2) Make each component entirely responsible for it's own state. If two behaviors need health, then they both have a health property and are responsible for keeping their copy updated when a DamageTaken message is received. Downside, potential duplication

3) Allow components to be aware of other components. Downside, we've now introduced coupling but the data is in one place and there is less handling of messages required

4) Handle state in the same way as behaviours. Have a HealthState class and allow each entity to have a collection of applicable states. Each component that asks to use the health state for it's work gets given the same instance to work with. The entity object is now generic again (so no hierarchy), there are no inter-component messages to required to keep data sync'd. Downside, now instead of coupling to a another component, two or more components are dependent on the same state, so we've swapped one type of coupling for another.

p.s. don't take my lengthy reply to mean I disagree with you, your way seems like it would be fine if most objects tended to share a lot of the same base data.

I don't know anyone to speak with about with this kind of stuff, so I'm always keen to discuss stuff like this as much as possible so I can learn

The purist in me says I prefer 2, I've not really seen 4 discussed which makes be think that it's an idea that gained no traction. The pragmatist in me says 3 is probably a decent compromise, and seems to be the approach I've seen other forum dwellers take.

Anyway that's enough from me for now, this comment will already be massive.

Paul

Philippe Da Silva wrote re: Holiday, Components, and more!
on 11-26-2010 3:12 PM

Don't worry Paul, there are as many ways to program/design your application there are developers ;)

I'm no professional game developer (my daily job is on the Marketing/Online Business side of things) but I did work with many game developers and they all shared with me one common point: OOP is great but games aren't meant for such design. When you get some processing and state management, try to separate the two.

They explained to me components are great but as soon as your project gets complicated, the less classes you have to operate your Entities, the better for code maintenance and optimizations.

Even events aren't very easy to work with because at some point it gets really difficult to know what and when something gets called :p

At the end, I think it would be up to Synapsegaming to decice (well, obviously :o) but most of all because they are the sole ones to know where they want to push SunBurn to: keep it as primarly an API targeting Developers or become a ToolSet with scripting (even in C#) like Unity.

The answer to this question will bring a lot of decisions on how it should be designed ;)

paul_blamire wrote re: Holiday, Components, and more!
on 11-26-2010 4:48 PM

Cool, glad we're on the same page re discussing this stuff, some people are very dogmatic about their opinions.

I'm really interested to hear what you've said about keeping the number of classes small for code maintenance and optimizations. I'm not a professional game developer either, although I am a professional coder, so I'll bear that in mind if I think I'm over-complicating. That said it doesn't really resonate with me. I find my code easier to maintain, and probably by extension optimize, when really try to bear in mind things like SRP and not let the same kind of logic spread out over my codebase. I think I'll take that one under advisement.

Your point about event ordering though is something I really understand. I used a system for a little demo I worked on to try and work around it, it's probably the wrong way to do it but hey-ho. It worked for my little project.

1) I defined a pipeline of managers, e.g Input, Ai, Physics, Render

2) When creating an entity and it's components, I notified each manager in turn that a new entity exists.

3) Each manager then decided which if it was interested in one or more of the components the entity held. If so it would cache the component references in local lists.

3) In each update I would iterate through the pipeline and call the update method on each manager in order, in turn it would call the update method on the entity component lists in whatever order made sense for that manager.

4) When an entity is destroyed the pipeline is again notified so that the references to matching entity components can be released from each manager.

Given our discussion so far I'm guessing this probably sounds like massive overkill, and re-reading it it might be :-)

It did allow things like having Team based AI components run before Player based AI components. The AI manager could just cache ITeamAIComponents and IPlayerAIComponents into two lists and then in its update just propagate the update call to one list before the other. The code was definitely more manageable than trying to set numeric values for which component should run first.

Of course you're absolutely right in that SG probably have a really good idea of the direction they want to take it. Doesn't stop us shooting the breeze though :-)

Paul

Philippe Da Silva wrote re: Holiday, Components, and more!
on 11-26-2010 5:42 PM

Since you went into explaining how your components/entity workflow, I'll go for my point of view ;)

1) I define a pipeline of Managers as you do + an EntityManager that holds a reference to my game entities

2) each Entity has Load, Update, Unload methods with a statefull object that holds a reference to each component so they can subscribe, unsubscribe when required (I for instance remove my Entities when their Dispose method is called)

3) In the EntityManager, each entity submitted in the graph gets updated with this statefull object and they perform their own logic based on the Component states.

I could get the same TeamBasedAI behavior applied before the Player based by simply checking in the Entity state if it is controlled by the Player or not and applying the right behavior.

As I stated previously we can reach the same goal in many ways, I think it is a matter of taste. ;)

paul_blamire wrote re: Holiday, Components, and more!
on 11-26-2010 6:00 PM

Hi Philippe,

Thanks for posting that, I'd kind of hoped you would :-). I absolutely agree that it's down to taste, and I'm not for one minute trying to change your opinion. It's really interesting to see how other people approach the same issues.

I'm kind of hoping a few others might jump in with how they do things, for instance I know BigDaddio is a big torque guy so I'd be interested to see what he has found the pro's and con's of entity based systems to be. I'm going to think over your last post as we don't seem to do things radically differently.

Thanks for taking the time out to explain your views, it's really helpful to me

Paul

Cygon4 wrote re: Holiday, Components, and more!
on 11-27-2010 4:50 AM

From what I read out of John's post, SunBurn is only planning to add the ability to attach a kind of controllers to SceneObjects - it would make no sense to have things like Initialize()/LoadContent() in there, considering that SceneObjects are constructed from already loaded and ready resources. Which is a good thing imho, as it means there is no such thing as an unloaded SceneObject (which would add complexity to anything that interacts with SceneObjects).

I too think that XNA's GameComponents are not a good match for a game's entities/actors, but I also believe that they're not meant for that purpose anyway. XNA itself and its examples use them only for high-level managers (like GraphicsDeviceManager, ScreenManager, ParticleSystem). The multi-stage initialization (you can have two kinds of /invalid/ GameComponents - that is, instances where Initialize() or respectively LoadContent() haven't been called yet) is rather terrible, but I understand that to avoid initialization order dependencies without introducing a full blown dependency injection system it is a required compromise.

Regarding SunBurn's components (I'd call them 'controllers' or maybe 'behaviors'), this sounds like a potentially useful expansion, but I'm wondering what direction you're planning to take this idea. Maybe you could elaborate your future plans a bit further?

Currently, I understand SunBurn's SceneObjects as just that - scene-objects, not game-objects, meaning that the overall game logic is still my game's / game engine's job and SunBurn only gets told about the stuff I want it to render. If I had a doom clone, I'd only create SceneObjects for entities/actors in the player's vicinity (and dynamically add and remove them when the player enters different areas of the map).

- Is SunBurn moving to take over game logic? In other words, in the future, would it be right to just dump my entire map as SceneObjects into SunBurn's ObjectManager and let SunBurn figure out the PVS, object activation and stuff? If so, I'd wish for more control and a less monolithic design, ideally a separate library. Also, in this scenario I'd want more control over the scene's PVS (something like Ogre3D's SceneManagers where you can back the PVS with an Octree, BSP, brute force, paging sector map and more).

- If, on the other hand, this is just a convenient way of extending the visual scene (which is what I hope :D), how will it integrate into a game? For example, I may need collision detection for things outside the visible scene (think of a multiplayer race game where the other player is way ahead of you and knocks over stuff that will be in your way soon), without rendering that part of the scene. Would this be a special case that SunBurn's built-in collision detection is not intended for?

Epidemi wrote re: Holiday, Components, and more!
on 11-28-2010 5:54 AM

I definately like this! While I had my doubts when a similar architecture was introduced in TorqueX (it can be hard to see what is going on when reading source code), I definately appreciate the fact that it will result in cleaner code. No more sceneobjects that can do everything (which, I guess, in turn will reduce the complexity of code when reading it). This will even go a long way in allowing the editor to integrate with the game, if the editor will support this :)

The following are features that I would like to see:

* Components implemented as base class, not as interface. I hate having to code a lot of standard properties and events (UpdateOrder, Enabled, etc) that should just be there

* Editor support. This will be a great way to extend the editor and actually make the aggegration model more visual. As this seems to be one of the things people like about Unity, I think adding support for this in the editor might make the engine more friendly to new users

* Allow components to have a relationship to an interface, not just a class. This allows for increased usage of the component later in the development (less refactoring)

* Allow a scene object to access it's own components so that it is possible to extend the events that components have

* Keep it as type safe as possible. I dislike how TorqueX handles this. Example from the TorqueX docs:

owner.Components.GetInterfaceList<TorqueInterfaceWrap<IT2DForceGenerator>>("force", String.Empty, _forceGenerators);

this looks up a component interface called "force", but this is hardly type safe. In my opinion, better would have been: GetComponent<ComponentType>().

On the last point: I am not sure if and how component interaction should take place. I have nto much experience with this architecture and I don't know what works best.

I realize some of the features are already visible in John's post, but I just wanted to mention them in case someone decides to change it ;)

Philippe Da Silva wrote re: Holiday, Components, and more!
on 11-28-2010 4:46 PM

Some of the comments here made me think twice on the SceneObject being able to load content itself.

What is your prefered design? Do you prefer to define in your SceneObject classes what content they should load by providing a virtual LoadContent like method or to define in your Game or game state classes what SceneObject content should be loaded?

If you prefer the latter, how do you manage multiple instances of a given SceneObject? Clone method? Static content?

Cygon4 wrote re: Holiday, Components, and more!
on 11-30-2010 6:34 AM

@Philippe Da Silva: I prefer the latter (as my comment above showed already :D).

I have a logical model that maintains the world's state and manages the game logic, but doesn't reference anything graphical. A bit like this:

World

.Players [IList<IPlayer>]

.Regions [IList<IRegion>]

.Projectiles [IProjectileManager]

Island : IRegion, IBuildingGround

.Buildings [IBuildingManager]

.HeightField

.MaterialMap

FlakBuilding : IBuilding

.ctor(IBuildingGround, IProjectileManager)

The SceneObjects for SunBurn are created and maintained by the rendering layer, which is completely decoupled and "observes" (as in the observer design pattern) the logical model - for example, the IBuildingManager provides BuildingAdded, BuildingRemoved events that the ConstructionRenderer, responsible for rendering all buildings, subscribes to:

WorldRenderer

.ctor(SceneInterface, World)

.RegionRenderers [IList<IRegionRenderer>]

IslandRenderer : IRegionRenderer

.ctor(SceneInterface, Island)

.ConstructionRenderer

.BuildingRenderers [IList<IBuildingRenderer>]

FlakBuildingRenderer : IBuildingRenderer

.ctor(SceneInterface, IMapContentService, FlakBuilding)

So when a FlakBuilding is constructed on an island, the ConstructionRenderer is notified and creates a new FlakBuildingRenderer which, upon construction, builds the SceneObject and adds it to SunBurn's ObjectManager. Each building renderer simply loads the 3D model from a shared content manager and constructs a new SceneObject.

XNA's content manager will return the same instance of the 3D model if multiple buildings of the same type are constructed and, as the SceneObject constructor doesn't copy the model's vertex or index buffer, I haven't put any effort into cloning SceneObjects or pooling them. Building destruction is a rare event (speaking in terms of game loop cycles), so while my game loop is garbage-free on a frame-by-frame basis, I accept that some garbage occurs when a building is razed. Adding pooling for that would be very easy - if it ever becomes an issue.

I hope I didn't spam the thread! 'thought it might be interesting for the SunBurn devs as well to see how their project is being used by others. As you can see, my design doesn't quite achieve parity with SunBurn's planned features (to use SunBurn's collision system, for example, my logical model would have to be wired up to the SceneObject's CollisionReactEvent - which would mean tight coupling between the game logic and rendering again - but I'll cross that bridge when I design my next game to use SunBurn's new features. It's not uncommon to have a limited two-way connection between the model and the renderer (for example, a GUI TextBox control needs to know text metrics from its renderer if it wants to support cursor positioning by mouse click).

JohnK "bobthecbuilder" wrote re: Holiday, Components, and more!
on 12-01-2010 3:41 AM

Hi guys, great feedback!

I just wanted to mention that like all of SunBurn’s systems using the components is not required and you can still use your own instead. :)

Ok, lots of great feedback – I’ll try to cover a number of the questions / comments:

Components are ordered in the collection, meaning you can add / insert them as if in a list.  You can also specify that a component should be inserted after another of a specific type.

Both objects and other components can query for a component by type (modeled after SunBurn’s managers and SceneInterface), allowing components to interact directly with one another:

ParentObject.Components.GetComponent<MyComponent>();

There is a BaseComponent to speed up development (see the code in my blog for details).  Not only does it provide a base implementation for all of the required interface members, it also wires up the initialization calls and provides streamlined SendMessage() methods for inter-component messages.

Loading assets can be done on the game level or via game specific static properties that point to the ContentManager(s).  SunBurn doesn’t interact directly with the ContentManager(s), so providing access to them is not in the API.

Providing access to SceneInterface is not clean atm.  So instead we’ve added a new static member SceneInterface.ActiveSceneInterface, which is a temporary solution, but provides a lot of possibilities until we work out a better implementation.

SunBurn’s ObjectManager already uses an oct-tree style system and does great frustum culling, though additional room-base visibility is a great performance gain if possible in your design.  Hidden objects (Visibility set to None) still collide and interact with the scene.

We’ll be adding a lot of new engine level features via components, and some may overlap with game level code.  But SunBurn’s API will not become closed, if anything we’re exposing more functionality to customize.

Based on feedback we’ve also added:

-OnInitialize(), event method for when a component is assigned its parent object

-Component messaging

-Dependencies, adding a component automatically adds any missing components it’s dependent on

We’ll likely roll this out soon, though initially it will be code driven (while we allow the component api to settle down), then we’ll roll out editor support as well.

Wow, that’s a long post! :)

paul_blamire wrote re: Holiday, Components, and more!
on 12-01-2010 1:07 PM

Hi John,

Thanks for the feedback. I love the fact you've taken the time to support multiple ways of doing things to depending on the programmers style.

Paul

JohnK Blog wrote SunBurn Game Engine: Transparencies, Player Controller, and More!
on 08-17-2011 1:15 AM

Hello SunBurn community! If you follow my blogs you know we’re adding a number of unannounced features

JohnK Blog wrote SunBurn Launches Powerful new Community Plugin System
on 10-16-2011 3:16 PM

Hello SunBurn community! Last night we rolled out a development preview of the SunBurn Game Engine’s

JohnK Blog wrote New SunBurn Community Resources Portal!
on 11-01-2011 5:45 PM

Hello SunBurn community! Two weeks ago we rolled out a powerful new resource system for the SunBurn Game

JohnK Blog wrote SunBurn Game Engine: A Whole New Level of Flexibility!
on 11-16-2011 5:06 PM

Hello SunBurn community! Today we’re announcing the last couple of features in the upcoming SunBurn

JohnK Blog wrote Orbitron: Revolution blasts onto Xbox LIVE Marketplace!
on 12-05-2011 9:52 PM

Hello SunBurn community! Talk about an exciting weekend! The awesome team at Firebase Industries just

JohnK Blog wrote SunBurn 2.0.17 Released – Advanced Lighting, Transparencies, and tons of Enhancements!
on 12-09-2011 4:45 PM

Hello SunBurn community! It’s here! Today we released the SunBurn Game Engine 2.0.17 update –

JohnK Blog wrote New SunBurn Documentation and Silverlight WP7 Example!
on 12-12-2011 9:09 PM

Hello SunBurn community! We’ve just updated the SunBurn Getting Started documentation to ensure

JohnK Blog wrote Starting 2012 with style: SunBurn Game Engine 2.0.18 Preview!
on 01-27-2012 2:01 PM

Hello SunBurn community! We're kicking the year off with a huge new update to the SunBurn Game Engine

JohnK Blog wrote SunBurn Game Engine 2.0.18: Built-in Character Controller!
on 02-04-2012 4:50 PM

Hello SunBurn community! Last night we delivered a feature-complete preview of SunBurn Game Engine 2

JohnK Blog wrote SunBurn 2.0.18 Released - Physics, Char Controller, More!
on 02-14-2012 3:46 PM

Hello SunBurn community! This morning we launched the much anticipated SunBurn Game Engine 2.0.18! The

JohnK Blog wrote New sgMotion Plugin and the SunBurn 2.0.18 Refresh!
on 02-23-2012 4:49 PM

Hello SunBurn community! We just rolled out two exciting new updates for the SunBurn Game Engine ! The



Please login to post comments.