Game Event handling – part 1
For this first post for iDevBlogAday (FinallyIt’s important to state that I’m not an expert and I’m always open to suggestions, so feel free to post your thoughts so we can all learn and share our ideas.
Let’s talk about Game Events first….
What are game events ?
A Game Event (will just call them Events) is anything of interest that happens while a Game is running. An explosion going off, the player being sighted by an enemy, an item being picked up – this are all events.
Games often need some way to notify interested Game Entities when an event occurs and also make it possible for those entities to react to events of their interest in various ways. When this happens, we can say that a Game Entity is handling an event. The way a Game Entity handles and reacts to different events becomes a crucial aspect of that Entity behavior.
I would like to make a distinction (which is personal) from what I call Custom Events and Engine Specific Events.
For instance an SCREEN_TOUCH_BEGUN is an engine specific event. The Input Manager broadcasts this event when the screen is touched, and that event is then passed and thus handled by all the game entities that listen (or are interested) in SCREEN_TOUCH_BEGUN events.
On the other side E_EXPLOSION is a custom game event (or user defined) game event. An explosion is not applicable to every kind of game, just think about Tetris. There are no explosions going around in Tetris (actually, there are explosions in some Tetris clones
), so maybe in Tetris a more useful custom event would be E_PIECE_PLACED, and it could be triggered each time a piece position reaches it’s final state.
After this brief distinction, it makes a lot of sense to support an easy way to define and handle our game specific events. Because we can easily see that a pinball game could have a very different set of event types when compared to a shooter or a tower defense game.
So, how could we design a simple event system ?
Basically an event is composed by two parts, it’s type (item picked up, explosion, player injured, monster slain) and it’s arguments. The arguments often contain specific information about the event in question, which monster was slain, what item did the player pick up, etc.
One possible way of modeling an event is to encapsulate the event type and the event arguments inside a structure or class.
Example:
struct Event { int MAX_ARGS = 8; int arg_num; EventType type; EventArg args[MAX_ARGS]; };
This is a very simple way to represent an Event, there could be more complex events, like some events deriving from a root event class and having some data structure like a list or map to hold the arguments that the event needs to carry.
Encapsulating an event inside a structure has many benefits, but I think two of the most important are:
- An entity doesn’t need to know the specifics about an event and could just forward the event to other Entities that could be interested in it. For example an Entity that holds a sword and receives a “sword broken” event, could just forward that event to it’s items and let the items handle it properly ( this could be handled in different ways actually, but it works as an example).
- With this rather simple approach we can get away with using only one function to pass events to an Entity. This allows our Event Broadcasting Class to easily broadcast events to Entities that implement an event_handler function. We only need to construct the Event structure that the event_handler should take as an argument.
void Entity::event_handler(const Event &in_event) { switch(in_event.type) { case EVENT_EXPLOSION: //Explode break; case EVENT_MONSTER_SLAIN: //Earn experience break; default: //We only listen for Explosions and Monsters being Slain. break; } }
This approach would require a definition for EventType, which could be something like:
enum EventType { E_PLAYER_HIT, E_MONSTER_SLAIN, E_EXPLOSION, ... ... //on and on };
Problems:
- We need to define all of the EventTypes in the enumerator/whatever you are using, and it will have to be included in every Entity that wants to do some event handling ( a lot of Game Entities
). - All of the implementation resides in the C/C++/Obj-C side, so we will have to recompile when creating new Events. This can slow down your workflow, and that’s not good if you where planning to do some fast prototyping because even the smallest changes will require recompilation. It get’s worse when you are working with more people and everyone is tinkering different game entities event handling.
Solution:
In the next part of the series I will present some ideas that could improve our design. They involve going data-driven and using scripting languages to tackle most of this issues and make our design even more flexible and simple.
I hope you guys liked it and any suggestions are very welcome!
Comments
Trackbacks
- Tweets that mention Game Event handling – part 1 -- Topsy.com
- Game Event handling – part 2
- Thoughts about scripting languages in Game Engines




Triton December 17th
While that first approach is really simple to implement it has a few drawbacks.
First, it broadcasts all events to all entities. In a simple game that might not be a problem, but as your game gets bigger with hundreds of entities, that could be some significant overhead.
Second, you lost type safety in the language. You didn’t describe how that works, but I guess EventArg is a wrapper around the real type, maybe similiar to the boost::any or something.
For this type of event handling in C++, I think delegates are really cool. You get type safety, and only subscribe to the events you are interested in. You also don’t need to provide the event definitions to every game entity. It’s somewhat more verbose than your approach though.
Looking forward to your second article on scripting and data-driven approach. I’ve also been thinking about and it will be cool to see your ideas.
Nicolas Goles December 17th
Correct!
Those are the problems of this approach. Some people goes so far as passing a void * to handle “custom” args. In box2d you can see something like that for box2d bodies, it’s not for event handling… but still.
boost::any could also be an option, and there are several more.
Thanks for sharing your thoughts!
Cheers!
Add Yours
YOU