Top Banner
Mark Nelson [email protected] The game loop, events, input Fall 2013 www.itu.dk
49

The game loop, events, input

Jan 16, 2016

Download

Documents

Cantale Dacian

The game loop, events, input. Mark Nelson [email protected]. Today ’ s lecture. How to manage the top level of a game Typically structured in the form of a game loop that checks and generates events , and performs updates based on those events - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: The game loop, events, input

Mark Nelson [email protected]

The game loop, events, input

Fall 2013 www.itu.dk

Page 2: The game loop, events, input

Today’s lecture

How to manage the top level of a game

Typically structured in the form of a game loop that checks and generates events, and performs updates based on those events

Engine often provides a particular style of game loop

Page 3: The game loop, events, input

Top-level loop

while(1) { run_game_tick(); }

Main considerations: Factoring out logical components How does the passage of time interact with everything?

Page 4: The game loop, events, input

Pong top-level loopwhile (true){ readInput();

if (quitButtonPressed()) break;

movePaddles(); moveBall(); collideAndBounceBall();

if (ballImpactedSide(LEFT_PLAYER)) { incrementScore(RIGHT_PLAYER); resetBall(); } // likewise for the other side… renderPlayfield();}

Page 5: The game loop, events, input

Pong loop features

Updates as fast as it can

Gameplay and update logic is hardcoded in the main loop

Page 6: The game loop, events, input

Update-as-fast-as-you-can

Classic style of game loop Exposes some strange features, though

Faster CPU faster gameplay Sometimes a problem if you try to play old games

More CPU-expensive stuff happening slower gameplay Can exploit that on some old games

Page 7: The game loop, events, input

Frame-locked updates

More regular updates

Fix a framerate, e.g. 30 fps

Game loop runs once per frame

If there’s extra time, wait for next frame

Page 8: The game loop, events, input

Soft and hard realtime

Hard realtime system Fixed time windows, hard deadlines Every frame takes 1/30 sec or less to prepare and render MUST meet the deadline!

Soft realtime system Programming model generally assumes results within deadlines But we should be able to sometimes miss it without disaster

Page 9: The game loop, events, input

Soft and hard realtime

A few systems impose hard realtime requirements Atari 2600 updates

Modern systems don’t, and cost of getting it right is high

So, prefer soft realtime

What to do if we don’t meet the deadline?

Page 10: The game loop, events, input

Missing deadlines

It’s been 1/30 sec since the last frame, and we’re still computing

What happens?

Page 11: The game loop, events, input

Option 1: Frame-locked, late frame

Finish our computation, frame will render when the code finishes running

Both screen update and game-world time are delayed

E.g.: if an object is rotating 3 degrees per frame, it’s now rotating fewer degrees per second (fewer frames/sec)

Page 12: The game loop, events, input

Option 1: Frame-locked, late frame

Can also see this in network games: Starcraft starts lagging when updates are coming in too slowly

But, might not be desirable

Can we keep the game running the same apparent speed?

Page 13: The game loop, events, input

Option 2: Separate game-world time

Even if we can’t render 30 fps, might want game-world time to stay constant Object rotates N degrees/sec, not dependent on framerate

Game world has to update more per frame Dropped frames make it look like stop-motion of a constant-speed world Instead of a slowed-down world

Page 14: The game loop, events, input

Option 2: Separate game-world time

Keep track of deltaT: time since last frame Game-world updates don’t assume 1/30s per frame

Parameterized by deltaT

Instead of X-per-frame, objects move/rotate/etc. x-per-sec Calculate how much that corresponds to for this frame and update

Bonus: changing framerate (e.g. 30fps->60fps) is easy But fallback if deltaT is unreasonably large

Page 15: The game loop, events, input

Delaying computation instead of frames

Not everything is equally important Is it worth delaying the next frame due to path re-planning?

If something’s taking a long time Either it delays the next frame Or we can delay it to a later frame

Page 16: The game loop, events, input

Delaying computation instead of frames

Single-threaded, time budgeting Example: A.I. code knows how to do only a limited amount of work per frame

Multi-threaded, preemptive Scheduler interrupts code taking too long, tells it to finish up

Multi-threaded, multi-frame work threads Stuff taking too long keeps running, but we don’t wait for its results

Page 17: The game loop, events, input

Structuring updates

Brings us to the other issue with the Pong loop

Specific code in the main loop

How do we structure game logic more generally?

Page 18: The game loop, events, input

Less-hardcoded loop

Common to use a generic top-level loop with phases

init_game(); while(1) { run_physics(); poll_input(); move_player(); run_ai(); update_screen(); }

Page 19: The game loop, events, input

Subsystem managers

Phases often associated with managers Separate bit of code (e.g. a class) responsible for an area

Physics system AI system etc.

Each has internal data structures, and a way of getting information to/from the other subsystems

Page 20: The game loop, events, input

Event-driven approach

Common way to factor a game based on activity/reactions

An event is just a ”thing that happens” Define your own Can be in an inheritance hierarchy Can have parameters/data

Some code generates events Other code registers to react to them

Page 21: The game loop, events, input

Event-driven approach

A function that will be called when an event happens is called a callback

Callbacks register the events they want to listen for

Main loop: Call event-generating functions (check input, check for collisions, etc.) Foreach event: call registered callbacks Render frame

Page 22: The game loop, events, input

Event hierarchy

Structuring events tends to be engine-specific

Level of granularity varies InputHappened KeyPressed KeyAPressed

Events are classes that can have data: KeyPressed(’A’)

Page 23: The game loop, events, input

Platformer events

Take 5 minutes and brainstorm:

What entities and events are there in a platformer game? What do they do? What parameters do they have?

Page 24: The game loop, events, input

Event-management styles

Events can be enum symbols SDL_* examples

Or, can be classes Inheriting from a base class (Event or something similar) These can have parameters, and can define behavior

Page 25: The game loop, events, input

Event hierarchy: data versus separate class

Dispatch on separate classes E.g.:

Some callbacks listen for any InputHappened Others only want to be called for KeyPressed

Very far down the hierarchy, may be easier for callbacks to just immediately return based on data if (keyPressed.key != ’A’) return;

Page 26: The game loop, events, input

Event-management styles

Runtime modifiable?

A full event/callback system lets you register callbacks, remove them, etc. all at runtime

Various strategies for maintaining and dispatching Simplest: map from events to function pointers or functors

Page 27: The game loop, events, input

Event-management styles

Modular but compile-time User code shouldn’t have to modify the main loop But doesn’t need to be runtime-modifiable

Event.handle() User code overrides Foo.handle() with its own functionality

Bit simpler to implement, and can be more efficient

Page 28: The game loop, events, input

Input

Sometimes, just another kind of event

Other times more continuous

Has various complexities

Page 29: The game loop, events, input

Two common types of input

Event-based ’A’ key was pressed Events are queued, and serviced by an event framework

Polling-based Is spacebar currently pressed? Current status is queried when needed by input manager

Page 30: The game loop, events, input

Event-based input

Discrete events queue up, perhaps by the OS/framework

Ignore ones not of interest, use the rest

Some issues: Repetition Latency

Page 31: The game loop, events, input

Polling-based input

Gives instantaneous state

The only kind that makes sense on some devices Mouse’s current position Joystick axis values Steering wheel angle

But, can miss ’events’ Or duplicate them

Page 32: The game loop, events, input

Some input questions

What should this input do over time?

What should happen if key is mashed lots of times in a row?

What should happen if key is held down?

Page 33: The game loop, events, input

Converting polling to events

Why?

Higher-level events on top of low-level input manager ”Moved mouse to hover over unit X”

Build custom event-based input Ignore OS keyboard driver, so we can control rate of repeat/etc.

Page 34: The game loop, events, input

Converting events to polling

Why?

Manage a ”curent state” Example: if we only get keydown/keyup events, can produce an isKeyDown()

In general, engine should determine when an input makes sense as an event or polling, and convert either way if the hardware/OS gives the other one

Page 35: The game loop, events, input

Other kinds of input management

Handling repeated keypresses: one kind of input smoothing

Directly coupling input to game actions isn’t always intuitive Players want game to do the ”smart” thing

Other kinds of smoothing: Nonlinear mappings Time damping

Page 36: The game loop, events, input

Nonlinear mappings

How to map mouse movement to in-game movement Depends!

Sometimes linear is what’s expected

Other times, hard to control or feels unnatural

Page 37: The game loop, events, input

Nonlinear mappings

Small vs. large movement sensitivity: Want precise control w/o also having to move mouse across a huge desk Small movements: low sensitivity to allow fine-tuned control Large movements: high sensitivity to allow macro-level actions

Snapping to values E.g. zero when close to zero Bias mouse movements towards straight lines

Page 38: The game loop, events, input

Nonlinear mapping example

Rolling Explosive Device (ITU Spring 2011)

Page 39: The game loop, events, input

Input smoothing

Transform noisy input stream to a cleaner/smoother one

Dropping repeated key events is one kind of damping

Another simple kind: moving average

Page 40: The game loop, events, input

Input smoothing: moving average

For polling-based input

Instead of using the current value, use average of past N

Smooths out transient spikes, shaky movements

Improves robustness to errors Pitch-tracking in a music game

Page 41: The game loop, events, input

More advanced input devices

Wii controller, Kinect, etc.

Need to map very noisy, not-gameplay-interpretable space to higher-level space

Often done with machine learning Via built-in SDK or third-party tools

Page 42: The game loop, events, input

Input management for platformer

Is any management needed? What kind?

Page 43: The game loop, events, input

Scene graph

Representation of objects in the scene In platformers, often a ”flat” model: list of objects Can be useful to have a hierarchical model

Many possible uses and criteria Way to keep the scene organized Efficient indexing Data structure for rendering

Page 44: The game loop, events, input

Spatial indexing

Logical organization can be augmented with spatial indexes

Example uses Find objects near the player avatar (e.g. for generating interaction events) Exclude objects that can’t possibly be viewable

Data structures Octree, kd-tree

In platformers, segmentation

Page 45: The game loop, events, input

Multithreading

Big topic

One style: asynchronous with callbacks Main loop calls registered callbacks in new threads (Or worker threads) Doesn’t wait for them; checks on data later

Can also have longer-lived threads Which may themselves call asynchronous callbacks

Page 46: The game loop, events, input

Multithreading strategies

Two main architectural styles

Threading per-subsystem Physics thread A.I. thread Animation thread

Threading per-object

Page 47: The game loop, events, input

Multithreading strategies

A few pros and cons

Threading per-subsystem Can match specialized hardware Synchronization across each subsystem is easy (e.g. all physics updates in one place)

Threading per-object Easier to get massive parallelism Local synchronization is easy (e.g. animation that depends on A.I.)

Page 48: The game loop, events, input

One more main loop complication

Networking!

Tricky to get right, impacts engine deeply

Game-world timelines must be consistent between players

Local/global updates, message cycle

Page 49: The game loop, events, input

Assignment #1Platformer engine, due September 27

Does not need to be networked or multithreaded

Pick a strategy for the game loop and use it consistently.Recommended: deltaT-style framerate-independent updates.

Input:Plan out (perhaps initially on paper) your input/event/entity designWhat input will you receive? What will be affected? What subsystems?Does it needs to be transformed (events<->polling) or adjusted?