Automotron

C++ Game Engine
Development Time: 90 Days
IDE: Visual Studio 2013
Middleware: Qt, GoogleTest
Tutorials/Sources: Jaime King
Overall Goal: Advanced Game Programing Concepts and efficient math programming techniques
Description: Started out as educational engine development, then wanted to create my favorite Fallout 4 mini game.

Goal Implementation

Screenshot of Fallout 4: DLC Automotron Mini Game

Overview of Implementation:
Entity-Component Design Pattern
Conditional Compiling
Object Oriented Paradigm
Custom Written Optimized 3D Math Libraries (Matrices & Vectors)
All Player Movements is in Vector Math
Handling memory on the stack -> the GPU
Test Driven Development (via Google Test)
OpenGL API
User Interface and Aspect Ratio's
Euler's Method (Velocity and Acceleration)
Linear Algebra
Return Value Optimizations
Dot Products / Projecting Vectors
Linear Interpolation


Gallery

Clips goes here

clips

clips here..

Why the Entity-Component Desing Pattern?
Entity Class -> GameObject (We remove our monolithic base class)
Contains an array of components (Sequence/List of components)
Component Class -> Boundery Handler, Lerping Logic, Enemy Logic, Rendering, KeyInput (inherits from Component)
Main Strength: We can add an entity main player object, then mix and match a component as needed
Problem with OOP as our main Paradigm: Inheritance trees factor out overlapping/common functionality but many game objects start inheriting functionality that they should not have

OOP Issues

AI needs velocity and boundary conditions but do we copy code from our Ship Entity?
Velocity and Boundary functionility can be added to GameObject but then our Lerping Instance has those qualities.
Picture comes from Jaime King

Entity Class
Contains an array of component pointers. Which will point to the various components in the design.
The entire class just adds components and initializes all needed components( boundary, lerper, rendering, etc.)
Position and Rendering are the only super elite instance variables.
Do we need a getter and setter? No. Unless we are threading and protecting the data but we are not protecting the domain of the position value, and since we will be using the position everywhere it is not needed.

Entity

Basic Functionality of our Entity Class

Cache and "new"
The problem with the "new" keyword
Heap -> Bunch of RAM with memory addresses
CPU has to retrieve data from RAM on Heap -> which is slow and time consuming
In games we are trying to save the frame rate! which leads to Cache!
L1 cache is closer to the CPU than L2
new and delete is like moving in and out of neighborhoods
new ship, new boundary -> which decides to put the boundary and ship data on the heap at a RANDOM memory address
It is scattered around the heap so on the CPU when we need the rendering and positional data
Governed by the OS -> I need data from n memory address from here to here -> which loads into cache
CPU is thrashing the cache(most frequent compact memory addresses)(cost time etc..)
You can do object pooling which is more cache friendly
Need to compactly putting the data together without calling "new"
C++ lays out the data sequentially

Cache Money

Minor Solution to cache coherency

Optimized Math Functions for Game Programming

Vector3D Normalize

Vector3D Normalize: Optimized to not call magnitude three times for each (x,y,z) value. We can call it once on the inverseMagnitude = 1.0f / Length(); and multiplying by each (x,y,z) value.

Vector3D Magnitude Squared

This can be called to determine the length of the vector when comparing vectors. We can use the dot product within the function because two of the same vectors are being dotted between each other. Meaning that they lay on top of each other so the cos(theta) between them is 0, and then cos(0) = 1. Effectively removing the angle in the equation.

Vector3D Magnitude

We can use our MagnitudeSquared function that we wrote above use.

Vector3D ProjectOnto

Project one vector onto the other with avoiding the expensive square root call (roughly 27 more expensive than the + operator). After doing the dot product we can then divide by the magnitude squared of the vector we want to project onto. Then multiply that scalar result by the vector we want to project onto. Thus eliminating the SQRT function.

Vector3D Dot Product

The highly important dot product function which will be used in all aspects of game programming. It plays an important role in lighting within the computer graphics field (Phong & Blinn Phong), the sweep (cos(theta)) between two vectors, & also helps determine player location and for projecting vectors.

Vector3D Linear Interpolation

The lerp function can be used for pathtracing between vectors, sending a player on a vectorized path.

Matrices

Overview of the Matrix3D Class

Matrix3D class(not the most optmized for a 2D game) but the math involved translates to a 3D game. I will show the more omptimized class Matrix2DH optmized class later. *Return Value Optimization -> Construct the object and return it at the same time (no temp variable is constructed within the stack frame of a function. We can eliminate a copy constructor call, etc..

Matrix3D Rotation Around the Z

Returns a matrix transformation with a return value optmization.

Matrix3D Translate

Game is in 2D, creating a matrix up one dimension enables translation as long as our Z vertices in our player is set to 1.0f.

Matrix3D Scale

Return value opmtization for a matrix by scaling the basis vectors.

Matrix3D Multiplication

Return value opmtization for multiplication of a vector hitting a matrix.

Matrix3D Matrix Multiplcation

Return value opmtization for matrix multiplcation.