Game Architecture and best practices Reinhold Preiner Thomas Weber Institute of Computer Graphics and Algorithms Vienna University of Technology
Feb 23, 2016
Game Architecture and best practices
Reinhold PreinerThomas Weber
Institute of Computer Graphics and Algorithms
Vienna University of Technology
2
Topics for today
Software Architecture for Game DevelopmentRules of software engineeringEntity ManagementScene-RepresentationBasic Game-LifecycleThe Render-LoopResource Management
Best Practices and Useful Tips
Institute of Computer Graphics and Algorithms
TOPICS FOR TODAY
Software Architecture for Game Development
Institute of Computer Graphics and Algorithms 3
Reinhold Preiner & Thomas Weber 4
Some Rules of Good SW-Engineering
SCALABILITYBe able to extend your System with minimal effort
MAINTAINABILITYBe able to change/adapt your System with minimal effort
MODULARITYIf you have to do the procedure in different corners of your System, do it once in one module (class) and call it wherever you need it.
These Concepts interact with each otherBut: Beware of Overengineering -> you only have one Semester!
5
Entity management
Character::update() handles user inputVehicle::update() controlled by AITree::update() does nothing
Institute of Computer Graphics and Algorithms
SceneObject {abstract}+ update( double timediff )+ draw()
Character Vehicle Tree
Reinhold Preiner & Thomas Weber 6
Scene-Representation
Which data-structure for object organization?Depends on your needs2 Basic approaches:
Linear List (e.g. std::list<SceneObject*>)Advantage: Easy to implementDisadvantage: Bad for hierarchical scenes
Scene-Graphs:Ideal for hierarchical animations (e.g. solar system)
You can also use both (or none ;) )
Reinhold Preiner & Thomas Weber 7
Basic Game Lifecycle
Load Content
Render-Loop
Update Content
Cleanup Content
User Input
Display Output Draw Content
Reinhold Preiner & Thomas Weber 8
Resource-Management
Load Content
Render-Loop
Update Content
Cleanup Content
User Input
Display Output Draw Content
Reinhold Preiner & Thomas Weber 9
Resource-Management
Common Design-Concepts:RAIIResource managing module
Reinhold Preiner & Thomas Weber 10
RAII
“Resource Acquisition Is Initialization”Constructor: Resource acquisition
Textures, shader, meshes etc. Destructor: Release resources
Advantages:Simplifies programming workException safe
Disadvantage:Beware of shallow copies (see C++ talk / part 2)
Reinhold Preiner & Thomas Weber 11
Resource-Managing-Module
Central resource manager class handles all resourcesHas methods like: loadMesh, loadTexture, etc.Loads resources once and returns referencesInternally stores resources in mapsCould also support reference countingHandles cleanup at application end
Reinhold Preiner & Thomas Weber 12
Resource-Managing-Module
Resource* loadResource( "resourceName" ){
if ( "resourceName" already loaded ) return lookup( "resourceName" );else{res = loadFromFile( "resourceName" );storeInMap( "resourceName", res );return res;}
}
Reinhold Preiner & Thomas Weber 13
Render-Loop
Load Content
Render-Loop
Update Content
Cleanup Content
User Input
Display Output Draw Content
Reinhold Preiner & Thomas Weber 14
Render-Loop
while( <running> ){
double dt = <Calculate time Delta to prev. Frame>;
foreach SceneObject* so in sceneObjectList so->update( dt );
foreach SceneObject* so in sceneObjectListso->draw ();
<Swap Buffers>}
SceneObject {abstract}+ update( double timediff )+ draw()
Character Vehicle Tree
TOPICS FOR TODAY
Best Practices and Useful Tips
Institute of Computer Graphics and Algorithms 15
16
OpenGL C++ Wrappers
Wrapper objects for OpenGL functionsFor things like textures or shadersExample usage
Shader shader(“my_shader”);Mesh mesh(“teapot.mesh”);shader.bind();shader.setUniform(“color”, vec3(1,0,0));mesh.draw(&shader);shader.unbind();
Write code before implementing wrappers
Reinhold Preiner & Thomas Weber
Reinhold Preiner & Thomas Weber 17
Config-Loading
Don’t hardcode constant valuesUse a config fileExample syntax:lightColor 1 0.5 0.5lightPosition 10 10 30shaderName “shader/myShader”Tweak values without recompilationExample Config class:Config config(“game.config”);String shaderName = config.shaderName;
18
Time Measurement
Most frameworks support timer functionsClamp longer time differences
Useful for debugging, pause state, etc.double last = 0.0, logicTime = 0.0;while (running) { double now = glfwGetTime(); double dT = min(config.maxDT, now-last); last = now; logicTime = logicTime + dT;}
Reinhold Preiner & Thomas Weber
19
FPS computation
Each frame do
++frames;if (now – last > config.framerateUpdateTime) {
msPerFrame = 1000.0 * (now-last) / frames;last = now;frames = 0;
}
Encapsulate in function or classFPS = 1000 / msPerFramems/frame is preferable metricFPS just better known
Reinhold Preiner & Thomas Weber
21
Input handling
Polling for time spanning actionsPressing forward keyFiring machine gunglfwGetKey(‘W’);
Events for single key hitsESC, F-keys, etc.Firing grenadeExecute actionvoid GLFWCALL keyCallback(int key, int state) {…}glfwSetKeyCallback(keyCallback);
Reinhold Preiner & Thomas Weber