1 / 49

The game loop, events, input

The game loop, events, input. Mark Nelson mjas@itu.dk. 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

dacian
Download Presentation

The game loop, events, input

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. The game loop, events, input • Mark Nelson • mjas@itu.dk Fall 2013 www.itu.dk

  2. 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

  3. Top-level loop while(1) { run_game_tick(); } Main considerations: Factoring out logical components How does the passage of time interact with everything?

  4. Pong top-level loop while (true) { readInput(); if (quitButtonPressed()) break; movePaddles(); moveBall(); collideAndBounceBall(); if (ballImpactedSide(LEFT_PLAYER)) { incrementScore(RIGHT_PLAYER); resetBall(); } // likewise for the other side… renderPlayfield(); }

  5. Pong loop features Updates as fast as it can Gameplay and update logic is hardcoded in the main loop

  6. 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

  7. 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

  8. 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

  9. 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?

  10. Missing deadlines It’s been 1/30 sec since the last frame, and we’re still computing What happens?

  11. 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)

  12. 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?

  13. 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

  14. 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

  15. 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

  16. 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

  17. 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?

  18. 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(); }

  19. 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

  20. 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

  21. 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

  22. 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’)

  23. 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?

  24. 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

  25. 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;

  26. 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

  27. 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

  28. Input Sometimes, just another kind of event Other times more continuous Has various complexities

  29. 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

  30. Event-based input Discrete events queue up, perhaps by the OS/framework Ignore ones not of interest, use the rest Some issues: Repetition Latency

  31. 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

  32. 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?

  33. 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.

  34. 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

  35. 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

  36. 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

  37. 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

  38. Nonlinear mapping example Rolling Explosive Device (ITU Spring 2011)

  39. 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

  40. 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

  41. 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

  42. Input management for platformer Is any management needed? What kind?

  43. 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

  44. 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

  45. 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

  46. Multithreading strategies Two main architectural styles Threading per-subsystem Physics thread A.I. thread Animation thread Threading per-object

  47. 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.)

  48. 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

  49. Assignment #1 Platformer 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 design What input will you receive? What will be affected? What subsystems? Does it needs to be transformed (events<->polling) or adjusted?

More Related