1 of 89

Game Engines

Intro + Foundations

Faculty of Mathematics and Physics

Charles University

10th March 2022

Karel Vlachovský (based on Jakub Gemrot’s presentation)

Based on “Game Engine Architectures”

and “Game Design Patterns” books

and various inet resources

2 of 89

Game Engine�Roadmap

  • Various parts of a game engine architecture
    • focus on foundations (unique topic in the context of game dev)
  • Other parts
    • Gameplay, AI, animations, etc. - already discussed
  • Game Engine specific topics
    • Memory
    • Asset streaming
    • Timing
    • Jobs

3 of 89

Game Engine�Why?

WHY DO YOU NEED�(3rd party) GAME ENGINE?

4 of 89

Game Engine�Why?

  • The problem
    • We choose particular GE for feature X
    • Later find that we need feature Y
    • But our GE is not prepared / cranky support for Y => workaround it a lot
  • This lecture
    • Get impression, what GE may consist of
    • Some tricks and technicalities of GE
  • The result
    • Compiling a list of questions to be answered when assessing particular GE for your game production

5 of 89

Game Engine�Why?

  • You are single indie
    • Who wants to make, e.g., 3D game and want all those nice shadows and post-processing effects
  • You are studio (10, 20, more people)
    • Who wants multiple people collaborating on a single game

  • In both case, you want to speed things up

  • The question is, would this particular Game Engine speed up your work?

6 of 89

Game Engine�What?

WHAT IS GAME ENGINE?

7 of 89

Game Engine�What?

  • Set of tools for easing game production
    • Integrated game development environment
    • Console tools for automating pipeline
    • Game agnostic (== extensible + reusable)
      • Feature rich
      • Data driven
    • Multi-platform

8 of 89

Game Engine�What?

  • Games themselves resemble kind of engine
    • Due to iterative development
    • Think of it as a moddable game
      • Different aesthetics
      • Different storyline
    • Multi-platform

9 of 89

Game Engine�What?

HOW DO GAME ENGINE DIFFER FROM �A FRAMEWORK OR A MIDDLEWARE?

10 of 89

Game Framework / Middleware�What?

  • Set of tools for easing some part of game production
    • No integrated development environment
      • Mostly oriented on programmers (set of libraries and console tools)
    • “One to a few subsystem(s)”
    • Not necessarily data driven
    • Not necessarily multi-platform
    • Middleware is not having own „execution loop“

11 of 89

Game Engine�For whom?

WHOSE WORK GAME ENGINE MUST SUPPORT?

12 of 89

Game Engine�For whom?

  • Game Engines are used from many perspectives
    • Engineers (have to efficiently code)
    • Artists (have to efficiently create the content)
    • Game designers (have to efficiently iterate ideas)
  • They work in tandem using Game Engine as an integrator of their work

13 of 89

Game Engine�For whom?

  • Game engine must not place excessive overhead onto create-run-play-test iterations (waterfall does not work in gamedev), which must be as short as possible
    • Import new content
    • Script new game mechanics
    • Immediately test in the game

14 of 89

Game Engine�What for?

WHAT FEATURES MUST GAME ENGINE PROVIDE TO GAMES?

15 of 89

Game Engine�What for?

  • Different genres => different needs
  • Killer feature for one game can be useless for other
  • GE should allow extensions

16 of 89

Game Engine�What for?

  • FPS / RPG
    • Large 3D worlds
    • Responsive camera
    • Weaponry/Magic
    • Minimal character model
    • High-fidelity animation
    • Small-scale multiplayer

  • Platformers
    • Dynamic environment
    • Puzzle-like elements
    • Third-person (+ complex camera movement)

  • Fighting games
    • Rich-set of fighting animations
    • Accurate hit detection
    • Complex user input
    • Single arena only

17 of 89

Game Engine�What for?

  • Racing games
    • Tricks for distance object rendering
    • Track divided into reusable sectors
    • Third-person (+ complex camera movement)

  • RTS
    • Hordes of low-res units
    • Terrain
    • Adjustable environment (buildings at least)
    • Various UIs
    • “Point-and-click”

  • MMOG
    • Scalable networking subsystem

18 of 89

Game Engine�What for?

RULE OF THE THUMB

  1. First describe the game you want to create
  2. Assess skills of your team
  3. Then choose a game engine or a framework that would support the game as well as your team-work the best. Use it yourself first!

19 of 89

Game Engine�Architecture Overview

GAME ENGINE ARCHITECTURE OVERVIEW

20 of 89

Game Engine�Architecture Overview – Game Specific

21 of 89

Game Engine�Architecture Overview – Game Specific

  • Each game has and needs to adapt heavily
  • The core of game business logic
  • Tailored specifically for each game

22 of 89

Game Engine�Architecture Overview – Game Specific

  • Real-world example:
    • Warhorse Studios decided to use CryEngine for KC:D
    • AI subsystem of CE designed for FPS
      • Short-lived NPCs
      • Villagers in the open-world RPG needed to live their lives
    • The whole AI subsystem of CE was completely replaced

23 of 89

Game Engine�Architecture Overview – Game “Agnostic” Layer

24 of 89

Game Engine�Architecture Overview – Foundations

25 of 89

Game Engine�Architecture Overview – Platform Level

26 of 89

Game Engine�Platform Independence Layer

  • Game Engine ~ OS
    • Own “language”, “memory management”, “threading / synchronization primitives”, …

27 of 89

Game Engine�Platform Independence Layer

  • Game Engine ~ OS
    • Often replaces standard C/C++ libraries and abstracts them with their own model
    • Own language => Hard to replace a single box here
    • Adding another 3rd party middleware SDK => wrapping into primitives the rest of the engine understands
      • However, a clash of versions of utility libraries (like SDL) that are integrated deep within the middleware can be a huge pain

28 of 89

Game Engine�Tools <-> Engine Integration

Independent

Built-in

29 of 89

Game Engine�As an Integrator

GAME ENGINE AS AN INTEGRATOR OF WORK

30 of 89

Game Engine�Asset Pipeline

  • GE should provide ways for the integration with other tools
  • Every import/export (or even update) should happen automatically or with “one-click”
  • Asset Conditioning Pipeline:
    • “Devel data” vs. “Cooked data”
  • Resource database
    • TXT + SCM / SQL

31 of 89

Game Engine�Resource Management

  • How assets are loaded, processed, adapted, thrown away (not only) during runtime
  • The path of the asset (Asset Conditioning Pipeline)
    • Digital Content Creation (DCC) tool

-> Resource Exporter (exports out of DCC)

-> Resource Compiler (adapts for GE)

-> Resource Linker (creates composite packages)

- e.g., character consists of a model, skeleton, rig,

textures and animations

32 of 89

Game Engine�Resource Management

  • Assets have dependencies
    • Asset Conditioning Pipeline must be driven by rules
      • Whenever some asset changes, it may imply rebuild of multiple assets
    • Dependencies must be tracked during life-time
      • To provide automatic load / unload
    • There can be internal (within file) as well as external dependencies (multiple files)

33 of 89

Game Engine�Resource Management

  • Resource Manager Responsibilities
    • Each asset is loaded only once within the memory
      • Auto loads/unloads when required/no longer needed
    • Manages the memory
    • Handles streaming

34 of 89

Game Engine�Resource Management

  • Loading assets
    • Map: GUID -> Resource
    • Very slow operation, may not happen during gameplay
      1. Either you have load everything at once at the beginning of the level
      2. Or do it asynchronously in the background (streaming) to prepare for streaming in another world chunk

35 of 89

Game Engine�Architecture Overview

A FEW COMPONENTS…

36 of 89

Game Engine�Core

  • Assertions
    • Game Engines are always adjusted during the game production – they are “in development” state
  • Math
    • Extremely important for space-efficient network protocols
    • Developers of Factorio had to write their own math library because of subtle differences in complex math operations between different HW
      • Otherwise the differences piled up and deviated the simulation in the end
  • Memory management
    • new / delete operators are slow

37 of 89

Game Engine�Core

  • Resource manager
    • Engineer – Artist – Game Designer meeting point
    • Different quality of assets given the target platform
      • You really don’t want to have a duplicated scene for different platform
    • Build - automatically flagging used resources that should be included
    • Many bugs are data-induced ~ should be runtime fixable
      • Swapping assets during runtime should be allowed

38 of 89

Game Engine�Rendering Engine

  • Multiple layers
    • Graphics Device Interface
    • Low-level renderer
      • Primitives, Material system, Dynamic lightning, Camera, Viewport
    • Scene Graph / Culling
      • Ideally “spatial subdivision” agnostic (SG customizable)
    • Visual effects
      • Particles, decals, light mapping, dynamic shadows, HDR, FSAA, etc.
    • Front end / HUD (2D)

39 of 89

Game Engine�Other components

  • Audio
  • Network
  • Physics
  • Animation
  • AI
  • Scripting
  • Event System
  • Profiling
  • Game subsystems

40 of 89

Game Engine�As Soft Real-time System

GAME ENGINE AS A SOFT REAL-TIME SYSTEM

And why you typically do not want to reinvent them…

41 of 89

Game Engine�As Soft Real-time System

GAME ENGINE MESSAGING SYSTEM

How do subsystems communicate?

42 of 89

Game Engine�As Soft Real-time System

http://www.gamasutra.com/blogs/MichaelKissner/20151027/257369/Writing_a_Game_Engine_from_Scratch__Part_1_Messaging.php

43 of 89

Game Engine�As Soft Real-time System

=>

http://www.gamasutra.com/blogs/MichaelKissner/20151027/257369/Writing_a_Game_Engine_from_Scratch__Part_1_Messaging.php

44 of 89

Game Engine�As Soft Real-time System

LOW-LEVEL OPTIMIZATIONS

45 of 89

Game Engine�As Soft Real-time System

  • Optimizations are the key to higher frame rates
  • Shift of the paradigms
    • Sequential => Parallel
    • CPU is expensive, Memory is cheap => CPU is cheap, Memory is expensive

46 of 89

Game Engine�As Soft Real-time System

  • Reality is complex nowadays
    • Intuition does not help:
      • Fewer instructions == faster code
        • NOPE
      • Data is faster than computation
        • NOPE
      • Computation is faster than data
        • NOPE

=> You have to profile, always

47 of 89

Game Engine�As Soft Real-time System

  • CPU Cores have multi-level cache + are pipelined

48 of 89

Game Engine�As Soft Real-time System

  • Code dependencies (and branching) + cache misses produce stalls

=> accessing a[++i] can be worse than a[i++]

49 of 89

Game Engine�As Soft Real-time System

  • Example of improved code

uint32_t digits10(uint64_t v) {

uint32_t result = 1;

for (;;) {

if (v < 10) return result;

v /= 10U;

result += 1;

}

}

  • Can we do better? …

50 of 89

Game Engine�As Soft Real-time System

  • Example of improved code

uint32_t digits10(uint64_t v) {

uint32_t result = 1;

for (;;) {

if (v < 10) return result;

if (v < 100) return result + 1;

if (v < 1000) return result + 2;

if (v < 10000) return result + 3;

// Skip ahead by 4 orders of magnitude

v /= 10000U;

result += 4;

}

}

  • More comparisons and additions, fewer /= … roughly 5x times faster
  • This is not exactly loop unrolling; or we can say that this is smart loop unrolling that cannot be done automatically as we’re performing the division only once!

51 of 89

Game Engine�As Soft Real-time System

52 of 89

Game Engine�Low-level Systems

MEMORY MANAGEMENT

53 of 89

Game Engine�As Soft Real-time System

  • CPU Cores have multi-level cache

54 of 89

Game Engine�As Soft Real-time System

  • There are some numbers you should have in mind

[2016]

1ns = 102x => 100 ns = 102x => 10µs = 102x => 1ms

55 of 89

Game Engine�As Soft Real-time System

  • There are some numbers you should have in mind

[2020]

1ns = 102x => 100 ns = 102x => 10µs = 102x => 1ms

56 of 89

Game Engine�Memory Management

  1. malloc and new are slow
    • Context switch to kernel-mode

=> Avoid dynamic allocation completely

  • Continuous memory access is the key
    • Cache misses may tear your time complexity (e.g., >20x slower)

=> Align your data correctly on every level

57 of 89

Game Engine�Memory Management – Avoiding Dyn. Alloc.

  • Provide custom memory manager
    • Allocate the memory at the beginning
      • Receive large byte*
    • Manage by yourself
      • Different strategies: stack-based (single/double side), pool allocators (different games favor different strategies)
      • Yes, become the master of your own memory

58 of 89

Game Engine�Memory Management – Avoiding Dyn. Alloc.

  • Own memory management => Own containers
  • (Dynamic) Array
  • Linked list
  • Stack
  • Queue
  • BinaryTree
  • good libraries allows you to supply your own memory manager

59 of 89

Game Engine�Memory Management – Aligning Data Struct.

  • The Problem

struct InefficientPacking

{

U32 mU1; // 32 bits

F32 mF2; // 32 bits

U8 mB3; // 8 bits

I32 mI4; // 32 bits

bool mB5; // 8 bits

char* mP6; // 32 bits

};

Compiler will not

optimize this!

Because of efficient

CPU Read/Write (CPU works

only with properly aligned data).

60 of 89

Game Engine�Memory Management – Aligning Data Struct.

  • When CPU is reading memory, it fetches usually more then required (HW dependent but ~64 bytes)

struct InefficientAccess

{

U32 a; // 32 bits

char[512] txt; // 512*8bits

U32 b; // 32 bits

};

Accessing a and b in a single expression => 2 cache misses

https://akkadia.org/drepper/cpumemory.pdf

61 of 89

Game Engine�Memory Management – Aligning Data Struct.

  • More on memory and CPU

62 of 89

Game Engine�Low-level Systems

STRING HANDLING

63 of 89

Game Engine�String Handling

  • Strings are human-readable representations of a number
    • enemy-tank-01 better than 20146
    • … but also slow (allocation, compare, copy, …)
  • Different kinds of strings
    • Unique identifiers
    • Debugging text
    • Game text (requires localization)

64 of 89

Game Engine�String Handling

  • String as Unique Id
    1. Use MACRO to translate strings into numbers
      • No debugging support but fastest
        • int id = TEXT(“tank-01”)
      • Combinable hashing functions:  djb2 and FNV-1a
        • TEXT(“tank”) + TEXT(“-01”) == TEXT(“tank-01”
    2. Use map to translate between string and id
      • Bi-directional for debugging
    3. Wrap it into a small object
      • Each unique string has own object instance
      • ID always present at the inspected place

65 of 89

Game Engine�String Handling

  • String as Unique Id

Have the best of both worlds!

Define custom types ID and macros for creating and manipulating those IDs, e.g. TEXT(...). And then, depending on the build type (devel vs. ship), include different implementations!

66 of 89

Game Engine�String Handling

  • String as Game Text and localization
    • Database of texts
      • Database chosen according to the language
    • Keys are Unique String Ids

=> No plain text ever used within the code

67 of 89

Game Engine�Loops

GAME ENGINE LOOPS

do { play the game }

while (ExitNotRequested())

68 of 89

Game Engine�Loops

  • The movement is the illusion of many frames per second
  • So every engine has (at least) its “render loop”
  • In general, game engines have “game loop”s running on various frequencies
  • There are multiple “loop” architectures

69 of 89

Game Engine�Loops

GAME ENGINE LOOPS

SINGLE THREADED

70 of 89

Game Engine�Loops – Simple Pong Example

void main() // Pong

{

initGame();

while (true) // game loop

{

readHumanInterfaceDevices();

if (quitButtonPressed()) break; // exit the game loop

movePaddles();

moveBall();

collideAndBounceBall();

if (ballImpactedSide(LEFT_PLAYER))

{

incremenentScore(RIGHT_PLAYER);

resetBall();

}

else if (ballImpactedSide(RIGHT_PLAYER))

{

incrementScore(LEFT_PLAYER);

resetBall();

}

renderPlayfield();

}

}

71 of 89

Game Engine�Loops – Simple Pong Example

void main() // ENGINE

{

initEngineAndLoadData();

while (true) // game loop

{

inputSystem.Update ();

if (isExit()) break; // exit the game

physics.tick();

gameplay.tick();

rendering.tick();

}

destroyEngine();

}

72 of 89

Game Engine�Loops – Windows Loop

  • Window Message Pump

while (true)

{

// Service any and all pending Windows messages.

MSG msg;

while (PeekMessage(&msg, NULL, 0, 0) > 0)

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

// No more Windows messages to process -- run one

// iteration of our "real" game loop.

RunOneIterationOfGameLoop();

}

73 of 89

Game Engine�Loops – Callback-Driven

  • Callback-Driven Loop (OGRE example)

while (true)

{

for (each frameListener)

{

frameListener.frameStarted();

}

renderCurrentScene();

for (each frameListener)

{

frameListener.frameEnded();

}

finalizeSceneAndSwapBuffers();

}

74 of 89

Game Engine�Loops – Event-Driven

  • Event-Driven Loop
    • Event system at the heart
    • Callbacks mimicked by periodic events that are allowed to be posted to the future
      • At the end of the event I schedule a new one

75 of 89

Game Engine�Loops

GAME ENGINE LOOPS

MULTI-THREADED

76 of 89

Game Engine�Loops

  • All systems are multi-core nowadays (even cell phones…)
  • It would be a waste not to utilize it…

  • One must be aware of the concrete architecture you are coding for
    • Sony PS3 was a bit exotic, now things are more standardized…

77 of 89

Game Engine�Loops

  • XBOX360

  • Sony Playstation 3

78 of 89

Game Engine�Loops

  • Sony Playstation 4

  • XBOX One

79 of 89

Game Engine�Loops

  • Fork-Join Loop
    • First attempt to make a game-engine multi-threaded
    • Parallelize only (suitable) parts of previously single-threaded loop that are CPU intensive

80 of 89

Game Engine�Loops

  • Thread-per subsystem
    • Subsystems invoked from the main thread as required
    • There are still blind-spots
    • E.g. Unity 3D (sort of)

81 of 89

Game Engine�Loops

  • Job model
    • Advocated in PS3 with SPURS library
    • Jobs are fine-grained and can be distributed between as many cores as one have
    • Whenever main thread has nothing to do, it crunches jobs as well!
    • E.g. Unreal Engine 4

82 of 89

Game Engine�Loops

  • Single Job model
    • Function pointer
    • Operates on some data
    • Each job mustn’t perform race condition
  • Criteria for a job:
    • Can be executed in isolation
    • Little data sharing, independent from other jobs
    • Self-contained
    • Cleanup their own initialization (like memory allocation)
    • No dependency on external code sequences
    • Can be pretty small, no problem with hundreds of jobs a frame
  • Performance Consideration
    • Align jobs according to their work, otherwise false sharing may occur

83 of 89

Game Engine�Loops

  • Example Job
    • Function pointer
    • Operates on some data
    • Each job mustn’t perform race condition
  • Performance Consideration
    • Align jobs according to their work, otherwise false sharing may occur

84 of 89

Game Engine�Loops

  • False Sharing
    • Hard to detect!
    • Each core writes to a different variables
    • BUT, those variables share the “cache line”
    • Cores are racing for ownership of the cache line => stalls

85 of 89

Game Engine�Data-oriented design

DATA ORIENTED DESIGN

Source: https://gamedevelopment.tutsplus.com/articles/what-is-data-oriented-game-engine-design--cms-21052

Source: https://www.youtube.com/watch?time_continue=4&v=yy8jQgmhbAU

86 of 89

Game Engine�Data-oriented design

Object-oriented programming is [...] both anti-modular and anti-parallel by its very nature, and hence unsuitable for a modern CS curriculum.”

  • Robert Harper, a professor at Carnegie Mellon University

  • Thread synchronization over objects even though you are working with one field causing unnecessary lock contention
  • Violating cache locality (object references other objects elsewhere on the heap)

87 of 89

Game Engine�Data-oriented design

Looks like a fork&join model, in theory can be jobified and streamlined.

/ Entity-Component-System (ECS)

88 of 89

Game Engine�Thanks you for you attention!

THAT’S IT FOR TODAY!

89 of 89

Game Engine�Thanks you for you attention!