Friday, May 22, 2009 at 3:17 AM |  
Interaction system. It's funny how the simplest and most important piece of a game engine could be so difficult to design. If there's no interaction, then there's no game at all. Hence, a game engine MUST have a unified way to deal with interaction.

When talking about interaction, input controls come to mind. Keyboard, mouse, gamepad or even those driving force feed back steering wheels. These controls would be bound with the in game characters, crafts or even turrets.

However, here lies the question. What about characters, crafts or turrets that are not controlled by the player? AI comes to mind. Better still, what about replays? Or how about in a multiplayer environment where certain crafts are controlled by some other players over the network?

These scenarios shows one thing. A controller that controls any element in a game should be abstracted from the physical input devices. They should only care about what to simulate when a certain command is executed without needing to know who is executing it.

Hence, I came up with what I call the Action System.

As you can see, the core of an Action System lies in the ActionManager. It will manage a list of action controls. These action controls are basically action devices(in red) bound to a controller(green) through what is called an ActionMap(blue).

Action devices can be anything that handles action inputs. It can be a real input device(keyboard, mouse or gamepad), AI device, Replay device or a Proxy. A proxy device is simply a device that clones whatever the true controlling device's(Owning devices) state. The proxy device is meant for network use only.

Bellow is a rough idea of how it would look like in a network environment with two clients connected to a server.


Now, the underlying structure of an ActionMap holds the key to how one interacts with a controller. It holds a list of actions that defines what is a toggle button, what is an analog axis or even a world vector for FPS styled games.

Having that, the next complicated one is the physical input. How does one bind a physical input to the ActionMap? Here's how I devised it to work. An action input device will hold a list of InputMaps. These InputMaps basically defines the bindings of the input to an action in the ActionMap. This design allows the designer to constraint what input type an action should use while allowing the players the freedom to define their own input within that constraint.

To cap it up, bellow is how the InputMap and ActionMap interaction will look like for an FPS.
Note the vector action doesn't have a direct input from the InputMap. It instead receives it's input from the controller that calculates the look-at of a player through the mouse axis input.

That's it. Next up I'll be talking about buffering the ActionMap for network prediction and Replay. Stay tuned. ;)
Posted by Lf3T-Hn4D

9 comments:

Prometheus said...

Excellent stuff !

May 22, 2009 at 6:31 AM  
James said...

Did you draw these diagrams yourself or use a particular program? They look pretty awesome!

May 22, 2009 at 7:11 AM  
Lf3T-Hn4D said...

Thanks :D I did that with Inkscape. Most of it is self art except for the silhouette with the gun. That one I basically traced an image I found online with gimp and turn it into vector through Inkscape.

Though some might argue about what's the point of doing all these pretty stuff, it's a way for me to encourage myself to code all these designs. :P

May 22, 2009 at 10:56 AM  
Jesús Alonso said...

This is some great design :) Good job!

May 22, 2009 at 5:10 PM  
James said...

Yeah it is pretty cool, I might have to learn how to use Inkscape! I want to do some similar diagrams for a system I'm modelling and it would be great to make them sexy like this :)

May 23, 2009 at 4:57 AM  
Lf3T-Hn4D said...

Hehe.. glad that you find it inspiring :P Have fun with Inkscape :D

May 25, 2009 at 3:46 AM  
Vlad said...

Thank you for this post! I spent a lot of time trying to come up with optimal design for input and networking, but i kept running circles. It's like i know i want it to be flexible and optimal, but i don't know what it really means in terms of design ;). I like your idea for networking, you don't explicitly separate code for client and server, reminds Unreal's approach.

May 30, 2009 at 3:25 PM  
Joshua Maines AKA FJGamer said...

I couldn't make a lot of sense out of the diagrams, but the text explanation seems solid. If I ever code a multiplayer game, I'll simply give everything a name and have the input command functions include the object name they affect. Then, all I will have to do is store the player's object name whenever a game loads. That's what I call the "Action Target" system, and it's much easier to understand.

June 11, 2009 at 8:59 AM  
darkstrife said...

Nice Inkscape work! I keep staring at the diagrams. So pretty!

Personally, I view all buttons the same, weather they are from the keyboard, mouse, or joystick (including digital dpads). Though, I handle mouse axis and joystick analog axis specially. But otherwise, I view physical input as largely homogeneous.

Also in the client, I have an event queue which processes physical input into data structures for sending to the server. Such data may be intended player movement, item usage, etc. The queue also receives data from the server which may contain new player positions, damage updates, etc. From this single event queue, everything is dispatched to the appropriate handlers. Everything in the queue is time-stamped so that it can be recorded and played back (as in demos).

This makes for a far simpler and more practical implementation. Your design, while very intriguing, strikes me as too over-engineered. But you guys are doing an awesome job already, so why not make an awesome input system. ;-)

June 15, 2009 at 8:05 PM  

Post a Comment

Liquid Rock Games and Project Aftershock. All Rights Reserved.