Recent games i played rely a lot on event-driven programming and scripts. This post is about the idea i got from playing games like Fallout, Morrowind and Oblivion about their event-driven systems in a very light perspective but i hope it can still be of some use.

Every game engine relies on several components or sub-systems: graphics engine, controller, ai, sound, database, etc. A complex game will most of the time drive the graphics engine step by step and provide at least a sort of task manager or scheduller that will drive the game in indendent tasks (possibly with their own distinct schedulling times), which are the rendering task, the input pooling task and the logic update task.

This "task" manager should be flexible enough to either work in a single-thread or multiple threads in a transparent way freeing the engine programmer from the burden of having to choose how many threads and how these should be used if the game is going to run in different platforms.

The game logic is responsable for determining what game actors will be updated (AI loding), when to load/unload a scene, when to add/delete actors to the scene, when to activate/deactivate actors, when to suspend/resume the game (doesn't suspend render or input), when to transform input and output from the game guis and convert basic events to logical events. Input transformation is the part where the game translates primitive input events using the keyboard and mouse bindings table into logical events like jump, run forward, fire, use, heartbeat and stuff like that.

Once the translation process is complete and there are new logical events they are dispatched to the active actors in the game. An event filtering criteria determines which actors receive which events. The player sends events from the use of the keyboard and mouse that are excluvly addressed to the player avatar or what the player controls at a certain moment.

In a simple event dispatching scheme we can consider an event has a piece of info having an event timestamp, event origin and event destination. Event data is exchanged only between the controler and the active actors and never directly bewteen actors. The controler acts as an intermediary for all comunications.

This scheme implies two things. One is that actors don't modify themselves or the game state directly but instead announce what they intend to do, which is very convinient because that may not be what realy is supposed to happen. Second actors must interpret what event patterns they receive (as well as inspect the scene directly) and update their decision variables acordingly.

This is tipical event-driven programming and it is a completely different programming paradigm from imperative programming. Execution takes place during the ocurrence of certain events and unlike imperative programming we cannot predict with 100% certainty which events will occur and in what order.

So in event-driven programming we have another element that is a pattern of events. Each actor decides what to do next in relation to the patterns he has stored in his local state. When a new event is received its patterns are updated or if no event is received for a long time old patterns may be forgotten.

A pattern may be encoded with something as simple as a finite set of boolean variables for example to represent the state of a gui button, or something as complex as a prolog theory.

The actor reaction maybe a simple state-machine that decides what to do based on the values encoded in its pattern boolean variables, or something that involves AI search on its theory and in this case an actor is called an agent.

The next example is taken from Starflight beta design doc and explains how combat works in this old game. The purpose of this example is to show that little has realy change in game engine design and that the foundations of game engines are still mostly based on actors and event driven programming (simulation part) with reactive agents (AI part) using a central data model to link all game components.

Modern games like Morrowind and Oblivion don't add much more complexity to the simulation and AI part. Instead the complexity increase happens in other components that have little effect on gameplay. The graphics engine is much improved. The amount of graphical detail and content available to the player has increased a lot. Game engines use external components like tools to create a face and customize the character in many different ways. There are external components to simulate realistic forest and physics. Games are starting to use more than just reactive AI solutions but are still mostly scripted environments which amounts to reactive AI. There is a search involved in path-finding, following and escorting but nothing that uses advanced AI.

Now to start with the example to the describe the behavior of Starflight ships in an encounter scene.

Events Sent by Ships to the Game Controller-------------------------------------------

Fire Missile(s1,s2) - create missile at s1 pos and seek ship s2Fire Laser(s1,s2) - create laser at s1 position and target s2 (instantaneous)MoveToXY(x,y) - player ship move to x,yMove Away(a) - from player shipApproach(a) - player shipMove Randomly(a) - around player shipEvade(a) - maintain distance from player shipRaise Shields(s) - alien or player ship raises shieldsLower Shield(s) -Arm Weapons -Disarm Weapons -Call More Ships(a) - alien ship calls for more ships to aid him in combatScan Ship(s,x,y) - scan location x,yPick Cargo(s) - pick all cargo in debris near the shipHail(s1,s2,p) - player hails at alien ship or alien ship hails at player in posture p

Note: Aliens do not tell the controler where they want to move, instead they request from the controller a certain movement style and the controller decides to each specific location the alien ship should move. The player ship specificaly issues a move to xy command because the player controls the ship directly.

Note2: Starflight is optimized so that these are actualy direct funtion calls inside the game cycle.

InComm is et when the game enters comm mode and cleared when exits comm mode.Cleared when scene starts.

boolean InCombat

Player has selected the Navigator combat option. Cleared when scene starts.

boolean Terminated

Game has left comm mode. Cleared when palyer enters comm mode again.Cleared when scene starts.

boolean Surrender

Player has requested to surrender. Cleared when scene starts.

boolean Attacking

Attack is set to true when any alien ship fires a weapon at the player. Attack is reset when no alien ship has fired a weapon for 2 minutes or when communications was entered.Cleared when scene starts.

boolean NothingHappening

If there was no communication within 2 minutes. Cleared when scene starts.

boolean PFiredMissile

Player has fired a missile that hasn't exploded yet. Cleared when missile explodes or timeouts.Cleared when scene starts.

boolean AFiredMissile

Alien has fired a missile that hasn't exploded yet. Cleared when missile explodes or timeouts.Cleared when scene starts.

boolean Dead

Ship has been destroyed and become debris. Cleared when scene starts.

float Damage

Set to the number of hit points damaged when ship is attacked.Cleared when scene starts.

boolean Call

Reinforcements have been called. Cleared when reinforcements arrive.Cleared when scene starts.

Performance has been improved in the last years enormously due to quicker hardware which means we get lower waitingt times in games and nicer graphics. User friendliness has also been improved so that we have more live interfaces that easier hint the user what to do and this has also alot to do with the increased performance since with computers 20 years ago you would not have the CPU power to do it.

However gameplay and AI still has alot of improvements to do. For instance, I seen so many modern games which are almost totally deterministic meaning if you pay $50 then you always succeed and with $49 bribe you always fail. This is what creates those "gamey" games that has no feel. This is bad design and much of it also goes into AI. Deterministic behaviour will only work in a deterministic game (like chess).

To make a real AI with intelligence, you need fussy logics, genetic algoritms and neural networks and if you do not have all those then I think someone has to down the line identify the factors that the AI should count as factors.

A human can come up with factors on their own but the computer of today cannot.

So, therefore when I program I try to make something in between, not deterministic event driven and not self learning but instead it should

1) indentify the alternatives2) create a score for each alternative where score is weighted value of factors plus a random value3) Always pick the alternative that got the highest score (since the random value can be set high enough that the actual score is not the best alternative when excluding the random)

Works quite well, and the only disadvantage is that the factors the AI takes into account must be made by a human

Where does collision detection fit into this event-driven paradigm? Let's say I have a hero backed against a wall, and three zombies charging towards him, all set to collide in the next frame. What I would expect, from my personal experience being bum-rushed by zombies, is that we would end in a state of equilibrium as long as the wall can absorb the force of the hero's falling back into it. Which of the actors, then, would be responsible for really handling the collision in this update cycle?

Where does collision detection fit into this event-driven paradigm? Let's say I have a hero backed against a wall, and three zombies charging towards him, all set to collide in the next frame. What I would expect, from my personal experience being bum-rushed by zombies, is that we would end in a state of equilibrium as long as the wall can absorb the force of the hero's falling back into it. Which of the actors, then, would be responsible for really handling the collision in this update cycle?

Thats interesting actually. Having actually created an event drive "game system", I found that collision detection is enormously hard to integrate properly. Your question is slightly in the wrong direction because the equilibrium calculations would fall on the physics engine, not the entity firing event system. But actually firing off events about what entity collided with which and what collisions are important is rather hard.

I ended up coding OR, XOR and AND gates with variables attached to each where you connect them together like puzzles (sort of like a miniture circuit) and made it generate Java code from that....worked quite well actually as an initial framework, you can then carry on fillin in the gaps regarding response.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org