CS 480/680: GAME ENGINE PROGRAMMING INPUT AND NETWORKING 2/7/2013 - - PowerPoint PPT Presentation
CS 480/680: GAME ENGINE PROGRAMMING INPUT AND NETWORKING 2/7/2013 - - PowerPoint PPT Presentation
CS 480/680: GAME ENGINE PROGRAMMING INPUT AND NETWORKING 2/7/2013 Santiago Ontan santi@cs.drexel.edu https://www.cs.drexel.edu/~santi/teaching/2013/CS480-680/intro.html Outline Student Presentations Handling User Input
Outline
- Student Presentations
- Handling User Input
- Multiplayer Games
- Networking Basics
- Client-Server Architectures
- Peer-to-Peer Architectures
- Client-side Prediction
- Project Discussion
Outline
- Student Presentations
- Handling User Input
- Multiplayer Games
- Networking Basics
- Client-Server Architectures
- Peer-to-Peer Architectures
- Client-side Prediction
- Project Discussion
Student Presentations
- Sean Bluestein:
- “An Extensible Trigger System for AI Agents, Objects and Quests”
- Kevin Burdick:
- “The 2009 Mario AI Competition”
- Mateusz Stankiewicz:
- “Convincing-Looking Glass for Games”
- Binggang Wo
- “Octree Construction”
Outline
- Student Presentations
- Handling User Input
- Multiplayer Games
- Networking Basics
- Client-Server Architectures
- Peer-to-Peer Architectures
- Client-side Prediction
- Project Discussion
Game Engine Architecture
HARDWARE DRIVERS OS SDKs Platform Independence Layer Utility Layer Resource Management Game Engine Functionalities Game Specific Game Engine Dependencies
Game Engine Architecture
Rendering Engine Animation Engine Collisions Physics Audio Subsystem Online Multiplayer Profiling & Debugging Gameplay Foundations (Game Loop) Artificial Intelligence Scripting
Handling User Input
- User Input:
- Keyboard presses
- Mouse movements
- Joystick
- Touch surfaces
- Cameras
- Microphones
- Remote input (from another computer over the network)
- Etc.
- Game Engine should process user input, and react
accordingly:
- Trigger character movements, etc.
Trivial Way (Do NOT do this!)
boolean cycle() { … If (key_pressed[SPACE] || joystick_button(BUTTON1) || bouse_button_pressed(BUTTON1)) { fireBullet(); } … }
Trivial Way (Do NOT do this!)
boolean cycle() { … If (key_pressed[SPACE] || joystick_button(BUTTON1) || bouse_button_pressed(BUTTON1)) { fireBullet(); } … }
Problem 1: Hard-coding input mapping. If we want to change the fire key to “m”, we have to look in the code for all instances of this.
Trivial Way (Do NOT do this!)
boolean cycle() { … If (key_pressed[SPACE] || joystick_button(BUTTON1) || bouse_button_pressed(BUTTON1)) { fireBullet(); } … }
Problem 1: Hard-coding input mapping. If we want to change the fire key to “m”, we have to look in the code for all instances of this. Problem 2: Hard-coding input devices. What if we want to have a player in a remote computer over the network? What if we want to make our game work
- n a tablet?
Handling User Input: The “Input Map”
User Input: Game Actions: Move Right Fire Switch weapon … ?
Handling User Input: The “Input Map”
- The “input map” is a table, or module that:
- Encodes the translation from user input to game actions/events
- Can be provided by the game engine
- Typically only used for in-game input (i.e. controlling
player character).
- But it could also be used to handle input for the game menus, GUI,
- etc. (with a proper design)
Handling User Input: The “Input Map”
- Input Map example API:
Class InputMap { public: void addKeyboardMap(int key, GameAction ga); void addKeyboardComboMap(List<int> keys, GameAction ga); void addKeySequenceMap(List<int> keys, GameAction ga); void addMouseButtonMap(int button, GameAction ga); void addJoystickMap(int koystickEvent, GameAction ga); etc. GameInput getInput(); }
Handling User Input: The “Input Map”
- Input Map example API:
Class InputMap { public: void addKeyboardMap(int key, GameAction ga); void addKeyboardComboMap(List<int> keys, GameAction ga); void addKeySequenceMap(List<int> keys, GameAction ga); void addMouseButtonMap(int button, GameAction ga); void addJoystickMap(int koystickEvent, GameAction ga); etc. GameInput getInput(); }
Class GameAction { int actionCode; int characterID; } The “CharacterActions” class is an abstraction that stores all the possible actions supported by your game engine (this example is
- versimplistic, you might need a
more complex structure), and whether the player triggered that action or not. Class GameActions { List<CharacterActions> controllers; } Class CharacterActions { bool left, right, jump, crouch; }
Handling User Input: The “Input Map”
- Input Map example API:
Class InputMap { public: void addKeyboardMap(int key, GameAction ga); void addKeyboardComboMap(List<int> keys, GameAction ga); void addKeySequenceMap(List<int> keys, GameAction ga); void addMouseButtonMap(int button, GameAction ga); void addJoystickMap(int koystickEvent, GameAction ga); etc. GameInput getInput(); }
Class GameAction { int actionCode; int characterID; } The “CharacterActions” class is an abstraction that stores all the possible actions supported by your game engine (this example is
- versimplistic, you might need a
more complex structure), and whether the player triggered that action or not. Class GameActions { List<CharacterActions> controllers; } Class CharacterActions { bool left, right, jump, crouch; } For example, for an “analogous” control engine (e.g. Nintendo Wii), you might want to include desired weapon rotation, etc.
Handling User Input: The “Input Map”
- Input Map example API:
Class InputMap { public: void addKeyboardMap(int key, GameAction ga); void addKeyboardComboMap(List<int> keys, GameAction ga); void addKeySequenceMap(List<int> keys, GameAction ga); void addMouseButtonMap(int button, GameAction ga); void addJoystickMap(int koystickEvent, GameAction ga); etc. GameInput getInput(); }
Class GameAction { int actionCode; int characterID; } Class CharacterActions { bool left, right, jump, crouch; } The GameActions class is just a list with all the input given to all the characters in the game (either by local players, AIs, or remote players). Class GameActions { List<CharacterActions> controllers; }
Handling User Input
while(!quit) { I = InputMap.getinput(&quit); G.updateAI(&I); G.updatePhysics(I); G.render(); FPScontrol(); }
The game loop calls the input handler to translate user input to game actions The AI controls characters also by generating game actions (identical data structure than user input) Physics/animation, etc. do not know if a player is controller by a player, or by an AI.
Handling User Input
Online Multiplayer Input Map AI Game Actions Network Rest of the game engine
Handling User Input
Online Multiplayer Input Map AI Game Actions Network Rest of the game engine Although depending on the multiplayer implementation, your game engine might not need to know the actions executed remotely.
Outline
- Student Presentations
- Handling User Input
- Multiplayer Games
- Networking Basics
- Client-Server Architectures
- Peer-to-Peer Architectures
- Client-side Prediction
- Project Discussion
Example Networked Multiplayer Games
- Multi-User Dungeons
- Early predecessors of today’s MMOs (used a client-server
architecture)
- Unbounded number of players
Example Networked Multiplayer Games
- MUDs have survived, and there are many modern ones:
Example Networked Multiplayer Games
- Bolo (1987)
- (relatively unknown) Mac-only game, one of the earliest
network games ever
Example Networked Multiplayer Games
- DOOM (1993)
- 4 players over local network (IPX protocol)
- Peer-to-peer: deterministic game, sharing actions over
network (numbered, to detect lost packets)
- Peers used broadcasts
- (saturated the network)
Example Networked Multiplayer Games
- Quake (1996)
Example Networked Multiplayer Games
- Quake (1996)
- Featured permanent servers, where players could meet
and play (before Quake, you had to coordinate in the real world on a time to play, and share your IP via phone with friends to play!
- Client-Server over the internet (not just LAN!)
- A new problem appeared (unknown till then): latency!
- QuakeWorld: update to Quake just to address latency. Introduced a
key idea called “client-side prediction”
Example Networked Multiplayer Games
- MMOs, e.g.: RuneScape
- network of servers
Outline
- Student Presentations
- Handling User Input
- Multiplayer Games
- Networking Basics
- Client-Server Architectures
- Peer-to-Peer Architectures
- Client-side Prediction
- Project Discussion
Networking 101 (for Games)
- Node: a computer/device in the network
- IP: Address of a node (e.g. 194.26.4.80)
- Packet: a piece of information transferred from one node
to another
- Typically a packet is sent to: (IP, port)
- IP: address of destination
- Port: (1-65535) identifies the service that should respond to this
packet
- Server: a node that offers some services
- Client: a node that requests a service from a server
Networking 101 (for Games)
- UDP:
- Simplest protocol
- Simply offers a service to deliver a packet from one node to
another
- No control of packet-loss, no persistent connections, etc.
- Summary: fast but unreliable
- TCP:
- Most complex protocol
- Packet-loss control, persistent connections
- Summary: slow but reliable
Most adequate for game
- networking. Most games
implement their own packet- loss protocol on top of UDP. Not as common in games, since it’s slower. And its reliability protocol is not designed with real-time games in mind.
Networking 101 (for Games)
- UDP:
- Simplest protocol
- Simply offers a service to deliver a packet from one node to
another
- No control of packet-loss, no persistent connections, etc.
- Summary: fast but unreliable
- TCP:
- Most complex protocol
- Packet-loss control, persistent connections
- Summary: slow but reliable
Most adequate for game
- networking. Most games
implement their own packet- loss protocol on top of UDP. Not as common in games, since it’s slower. And its reliability protocol is not designed with real-time games in mind. It’s more complex than this. But the rule of thumb is:
- Use UDP for real-time updates
- Use TCP for chat windows
(Google “TCP vs UDP games” for more)
Sockets
- Sockets:
- You can see a socket as a “pipe” that allows you to send data
between two nodes in the network.
- Once you have a socket open, you can send and receive packts
through it.
- Then can be configured to send using TCP or UDP
- All network libraries allow you to open/close/send and
receive through sockets
- If you are working on networking for your project, I’m
assuming you know how sockets work. No time for detailed explanations here.
Sockets
- Different libraries/languages will give you different forms to:
- Create a socket (TCP or UDP)
- Server: bind a socket to an address/port for listening to incoming
connections
- Client: establish a connection (to a particular IP/port)
- Server: accept incoming connections
- Send data through an open connection
- Receive data from an open connection
- Timeline:
Server: Client:
- 1. Create Socket
- 1. Create Socket
- 2. Bind
- 2. Establish
- 3. Accept
- 4. Send/receive
- 3. Send/receive
Communication Architectures
Peer-to-Peer Client-Server Hybrid Client-Network of Servers
Communication Architectures
Peer-to-Peer Client-Server Hybrid Client-Network of Servers All instances are “clients”, who send updates to each other, trying to keep the world simulation in sync.
Communication Architectures
Peer-to-Peer Client-Server Hybrid Client-Network of Servers One instance is special, the “server”. All clients send requests to the server, server maintains the game state, and informs clients of the changes.
Communication Architectures
Peer-to-Peer Client-Server Hybrid Client-Network of Servers Different game functionalities implemented with different architectures, for example: game state using client-server, in-game chat using peer-to-peer.
Communication Architectures
Peer-to-Peer Client-Server Hybrid Client-Network of Servers Each client associated with a
- server. Network of servers can
communicate using a peer-to-peer (or using a client-server, with a master server). Very scalable, but the most complex in terms of communication protocol.
Communication Architectures: Network of Servers Example (MMO)
Zone 1 server Zone 2 server Zone n server Master Server Account Server
… Client
Chat Server Patch Server
WoW had almost 2000 servers (derived from traffic data)
Communication Architectures
Peer-to-Peer Client-Server Hybrid Client-Network of Servers
Outline
- Student Presentations
- Handling User Input
- Multiplayer Games
- Networking Basics
- Client-Server Architectures
- Peer-to-Peer Architectures
- Client-side Prediction
- Project Discussion
General Socket Class
- Your can start by wrapping the socket class given to you
in your language in a class like this:
Class GamePacket { int getByteSize(); char *getDataPtr(); // … depending on your game engine } Class GameSocket { GameSocket(SOCKET sock, int localIP) send(GamePacket data); bool hasData(); GamePacket receive(); }
General Socket Class
- Your can start by wrapping the socket class given to you
in your language in a class like this:
Class GamePacket { int getByteSize(); char *encode(); void decode(char *data, int size); // … depending on your game engine }
This class stores one of the messages that your game will
- send. It should have at least 2
methods: one to encode the packet into an array of bytes, and the other to decode it from an array of bytes.
Class GameSocket { GameSocket(SOCKET sock, int localIP) send(GamePacket data); bool hasData(); GamePacket receive(); }
General Socket Class
- Your can start by wrapping the socket class given to you
in your language in a class like this:
Class GameSocket { GameSocket(SOCKET sock, int localIP) send(GamePacket data); bool hasData(); GamePacket receive(); } Class GamePacket { int getByteSize(); char *encode(); void decode(char *data, int size); // … depending on your game engine }
Your GameSocket class will be an abstract class (that you will exted with a “ServerSocket” and a “ClientSocket” class). But this one is handy, to organize the code.
Server Socket Classes
- We will then extend it for the server
Class ServerMasterSocket extends GameSocket { ServerMasterSocket (int port); init(int port); ServerSocket acceptConnection(int &IP); }
Just creates an instance, but does nothing else. We don’t want to
- pen the port right away after
creating the socket, since we might just be setting up the data structures.
Class ServerSocket extends GameSocket { ServerSocket (SOCKET s); }
Server Socket Classes
- We will then extend it for the server
Class ServerMasterSocket extends GameSocket { ServerMasterSocket (int port); init(int port); ServerSocket acceptConnection(int &IP); } Class ServerSocket extends GameSocket { ServerSocket (SOCKET s); }
This function does all the work of creating the socket: 1) Create the socket 2) Set the options (protocol, etc.) 3) Set the port 4) Start listening
Server Socket Classes
- We will then extend it for the server
Class ServerMasterSocket extends GameSocket { ServerMasterSocket (int port); init(int port); ServerSocket acceptConnection(int &IP); } Class ServerSocket extends GameSocket { ServerSocket (SOCKET s); }
When “hasData” is true, it means that a client is trying to connect. This function accepts the connection, and returns the ServerSocket that will be used for that connection.
Client Socket Classes
- We will then extend it for the client
Class ClientSocket extends GameSocket { ClientSocket (int port); connect(int IP, int port) }
The only extra functionality here is to connect to the server socket
Overview
ClientSocket MasterServerSocket
Client side: Server side: Step one is to create the MasterServerSocket, and have it listen for incoming connections.
Overview
ClientSocket MasterServerSocket
Client side: Server side:
Connection Request
When a client wants to connect, it requests a connection to the MasterServerSocket
Overview
ClientSocket MasterServerSocket
Client side: Server side:
ServerSocket
When the server accepts the connection, a ServerSocket is created and this is the one that keeps the connection open to the ClientSocket.
Overview
ClientSocket MasterServerSocket
Client side: Server side:
ServerSocket GamePacket GamePacket
GamePackets can be sent back and forth through this connection.
Overview
ClientSocket MasterServerSocket
Client side: Server side:
ServerSocket
For each new client, a new ServerSocket is created, but there is only a single MasterServerSocket, that is always open waiting for incoming new clients.
ServerSocket ServerSocket ClientSocket ClientSocket
Network Module
Connecting to the Game Loop
ClientSocket MasterServerSocket
Client side: Server side:
ServerSocket GamePacket GamePacket
while(!quit) { I = InputMap.getinput(&quit); G.networkUpdate(&I) G.updateAI(&I); G.updatePhysics(I); G.render(); FPScontrol(); } In the game loop, at each cycle, you call the network module, which would process all the GamePackets received through the socket (you should have an incoming queue, since packets arrive asynchronously). Then update the game state/input/etc. with the info from those packets. It should also send packets to the server with the user input (I).
Network Module Network Module
Connecting to the Game Loop
ClientSocket MasterServerSocket
Client side: Server side:
ServerSocket GamePacket GamePacket
while(!quit) { I = InputMap.getinput(&quit); G.networkUpdate(&I) G.updateAI(&I); G.updatePhysics(I); G.render(); FPScontrol(); } while(!quit) { G.networkUpdate(&I) G.updateAI(&I); G.updatePhysics(I); FPScontrol(); }
In the server game loop, at each cycle, you call the network module, which would process all the GamePackets received through the socket to get the actions the players want to execute, it will also send back to the clients the most updated game state.
Considerations
- Depending on the nature of the game, what is sent
through in the GamePackets will be different:
- In a deterministic game:
- Client/server only need to send actions
- In general:
- Clients send actions
- Server sends game state updates
- You can send global game state updates, or smaller chunks with
individual GameObject updates
- You can also optimize and only send to each client, updates of the
- bjects that are near the player (the rest, doesn’t matter).
Outline
- Student Presentations
- Handling User Input
- Multiplayer Games
- Networking Basics
- Client-Server Architectures
- Peer-to-Peer Architectures
- Client-side Prediction
- Project Discussion
Peer to Peer Architecture
- All computers are clients and servers
ClientSocket MasterServerSocket
Peer 1 side: Peer 2 side:
ServerSocket MasterServerSocket ServerSocket ClientSocket
Considerations
- All peers send actions and game state updates
- Need a policy to keep game state consistency
- Each game object should have an “owner” (one of the
peers). The game state sent by that peer is the one that will stay
- When new peers connect, or peers disconnect, game
- bject owners should be updated.
Outline
- Student Presentations
- Handling User Input
- Multiplayer Games
- Networking Basics
- Client-Server Architectures
- Peer-to-Peer Architectures
- Client-side Prediction
- Project Discussion
Client-side Prediction
- Consider a very simple client that simply takes user input,
sends it to the server, receives state updates and renders them.
User input Render Process input
Perceived delay
Client-side Prediction
- Consider a very simple client that simply takes user input,
sends it to the server, receives state updates and renders them.
User input Render Process input
Perceived delay
This can be multiple frames of delay!
Client-side Prediction
- Idea:
- Predict the update that will be received from the server
- Render the prediction
- When the update from the server is received, merge any
discrepancies
- Two main problems:
- Player prediction
- Non-player prediction
Client-side Prediction
- “Player prediction” simply simulates the effects of the
player actions directly (non-player characters are not predicted)
User input Merge States Process input
Perceived delay
Render Render
Client-Side Prediction
- The client also simulates the game state (physics, collision, etc.)
- Player Prediction:
- Effects of the player actions are simulated locally
- Non-player Prediction:
- Predict the actions that non-players will execute, and simulate them
too (for example, predict that they will keep moving in the same direction as they were in the previous frame).
Outline
- Student Presentations
- Handling User Input
- Multiplayer Games
- Networking Basics
- Client-Server Architectures
- Peer-to-Peer Architectures
- Client-side Prediction
- Project Discussion
Links to Interesting Game Videos
- Sugar Cube Bittersweet Factory:
- http://www.indieroyale.com/games/preview/sugar-cube-bittersweet-
factory
Remember that next week:
- Second Project Deliverable:
- Updated document from Deliverable 1:
- Address feedback that you got from Deliverable 1
- Any potential topic change
- Small description of how the game loop integrates with your demo/game
engine
- Source code:
- Do NOT send code as an attachment. Send a URL to your code, or to a
code repository (SVN, GIT, etc.)
- Submission procedure:
- Email to (copy both):
- Santiago Ontañón santi@cs.drexel.edu
- Stephen Lombardi sal64@drexel.edu
- Subject: CS480-680 Project Deliverable 2 Group #