Event handling in component based game engine design
Asked Answered
M

4

10

I imagine this question or variations of it get passed around a lot, so if what I'm saying is a duplicate, and the answers lie elsewhere, please inform me.

I have been researching game engine designs and have come across the component-based entity model. It sounds promising, but I'm still working out its implementation.

I'm considering a system where the engine is arranged of several "subsystems," which manage some aspect, like rendering, sound, health, AI, etc. Each subsystem has a component type associated with it, like a health component for the health subsystem. An "entity," for example an NPC, a door, some visual effect, or the player, is simply composed of one or more components, that when together give the entity its functionality.

I identified four main channels of information passing: a component can broadcast to all components in its current entity, a component can broadcast to its subsystem, a subsystem can broadcast to its components, and a subsystem can broadcast to other subsystems.

For example, if the user wanted to move their characters, they would press a key. This key press would be picked up by input subsystem, which then broadcasts the event and would be picked up by the player subsystem. The player subsystem then sends this event to all player components (and thus the entities those components compose), and those player components would communicate to its own entity's position component to go ahead and move.

All of this for a key press seems a bit winded, and I am certainly open to improvements to this architecture. But anyway, my main question still follows.

As for the events themselves, I considered where an event behaves as in the visitor pattern. The importance of what I want is that if an event comes across a component it doesn't support (as in a move event has nothing directly to do with AI or health), it would ignore the component. If an event doesn't find the component it's going after, it doesn't matter.

The visitor pattern almost works. However, it would require that I have virtual functions for every type of component (i.e. visitHealthComponent, visitPositionComponent, etc.) even if it doesn't have anything to do with them. I could leave these functions empty (so if it did come across those components, it would be ignored), but I would have to add another function every time I add a component.

My hopes were that I would be able to add a component without necessarily adding stuff to other places, and add an event without messing with other stuff.

So, my two questions:

  1. Are there any improvements my design could allow, in terms of efficiency, flexibility, etc.?
  2. What would be the optimal way to handle events?
Mailman answered 14/9, 2010 at 3:17 Comment(0)
B
1

I have been thinking about using entity systems for one of my own projects and have gone through a similar thought process. My initial thought was to use an Observer pattern to deal with events - I too, originally considered some kind of visitor pattern, but decided against it for the very reasons you bring up.

My thoughts are that the subsystems will provide a subsystem specific publish/subscribe interface, and thus subsystem dependencies will be resolved in a "semi-loosely" coupled fashion. Any subsystem that depends on events from another subsystem will know of the subscriber interface to that subsystem and thus can effectively make use of it.

Unfortunately, how these subscribers get handles to their publishers is still somewhat of an issue in my mind. At this point, I am favoring some kind of dynamic creation where each subsystem is instantiated, and then a second phase is used to resolve the dependencies and put all the subsystems into a "ready state".

Anyway, I am very interested in what worked out for you and any problems you encountered on your project :)

Brittle answered 28/10, 2010 at 22:25 Comment(0)
U
1

Use an event bus, aka event aggregator. What you want is an event mechanism that requires no coupling between subsystems, and an event bus will do just that.

http://martinfowler.com/eaaDev/EventAggregator.html http://stackoverflow.com/questions/2343980/event-aggregator-implementation-sample-best-practices

etc

Unmerciful answered 21/12, 2010 at 9:39 Comment(0)
A
1

this architecture described here http://members.cox.net/jplummer/Writings/Thesis_with_Appendix.pdf There are at least three problems I encountered implementing this in a real project:

  1. systems aren't notified when something happen - only way is to ask about it - player is dead? wall isn't visible? and so on - to avoid this you can use simple MVC instead of observer pattern.
  2. what if your object is a composit (i.e. consists of objects)? system will traverse through all hierarchy and asking about component state.
  3. And main disadvantage is that this architecture mixes all together -for e.g why do player need to know that you pressed a key?

i think that answer is layered architectures with abstracted representation...

Amosamount answered 21/5, 2011 at 17:54 Comment(0)
E
1

Excuse my bad English.

I am writing a flexible and scalable java 3d Game Engine based on Entity-Component System. I have finished some basic parts of it.

First i want to say something about ECS architecture, I don't agree that a component can communicate with other components in a same entity. Components should only store data and systems process them.

In event handling part, I think the basic input handling should not be included in a ECS. Instead, I have a System called Intent System and have a Component called Intent Component which contains many intents. A intent means a entity wants to do something toward a entity. the Intent System process all the intents, When it processes a intent, it broadcasts the corresponding information to other systems or add other components to the entity.

I also write a interface called Intent Generator. In local game, you can implement a Keyboard Input or Mouse Input Generator and in multiple-player game, you can implement network intent generator. In AI system, you can also generate intents.

You may think the Intent System processes too many things in the game. But in fact, it shares many processing to other systems And I also write a Script System. For specific special entity it has a script component doing special things.

Originally when I develop something, I always want to make a great architecture which includes every thing. But for game developing sometimes it is very inefficient. Different game object may have completely different functions. ECS is great as data-oriented programming system. but we can not include every thing in it for a complete game.

By the way, Our ECS-based game engine will be open source in near future, then you can read it. If u are interested in it, I also invite u to join us.

Ellingson answered 13/5, 2014 at 2:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.