Mobile Game Engine Programming in C++

Corey Auger
6 min readJul 9, 2018

--

I have always wanted to build games. The possibility of creating a brand new world and all the tiny details that comprise a totally new universe is a pretty thrilling prospect. I don’t have any experience building games or game engines for that matter, but I’ve been coding for a long time. And I figure there’s no time like the present to dive in — and to share my experience here.

To start, I looked at some of the engines that are out there. I decided on Unreal Editor 4, which was mostly due to the fact that it could be compiled in and work under linux. UE4 and Unity are probably the 2 most powerful and full featured game engines on the market. With power comes an enormous amount of complexity. These commercial engines contain many features that abstract away the coding complexity and hide it behind visual interfaces.

As a result, I spent many hours going through documentation. To make matters worse there are often a number of conflicting ways to complete a task depending on the context of the approach (artist / scripter / programmer). An example of this in UE4 is doing things in C++ (prefered for me) but finding many references to BluePrint which I did not want to be working in.

In the end it always felt a little like cheating. After all I grew up in the days of John Carmack writing doom.

This is when I decided I wanted to dive in and write my own game engine. This blog serves as a way to document my work and provide reference for anyone else that is motivated to do the same.

Design Philosophy

I am choosing to attack the problem in a very iterative manor: coding to produce simple usable results and only adding complexity and abstraction when necessary. The goal is to achieve basic gameplay really fast and clean, and then iterate to become more modular and support more features. Also since I have very little engine design experience I will be looking to research and experiment with a number of different approaches and find one that feels right.

Did I mention that it needs to run in linux ;). I am very opinionated when it comes to how companies operate and influence the field of computing. (I could rant for an hour about my issues with Apple… but I will spare you — for now.) Let’s just say that one of my requirements is that it will be developed entirely in a linux system. This of course means it should play nice with other operating systems

High Level Requirements

Let’s keep this really simple to start. I am only going to have a few requirements to start and we will further refine the list as it makes sense to do so during development.

  • Support modern C++ framework and idioms (at least the c++ 11 standard)
  • Mobile first gaming platform means it must support android and IOS (uhg!)
  • Support modern rendering capabilities.

With these basic requirements in hand let’s dive in and start to explore.

Sprint 1

The goals for this sprint are as follows:

  • Get a cross platform window that we can render to.
  • Render something simple to the window using OpenGL ES2
  • Verify that we can compile and run this on an Android device.

Simple DirectMedia Layer — SDL2

Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D.

SDL officially supports Windows, Mac OS X, Linux, iOS, and Android. Support for other platforms may be found in the source code.

This is exactly what we need to get things going. For installation instructions you can follow this page here https://www.libsdl.org/download-2.0.php

Note that on linux you can use apt-get to install the precompiled libs:

sudo apt-get install libsdl2-dev

see others behind libsdl2-* as well that you may require.

However you will also need a copy of the sdl2 source in order to compile Android and (cough!) iOS. Go ahead a grab the latest stable source release.

For the following example I have added a small github repo located here:

https://github.com/coreyauger/sdl_app

Simple SDL Window

Compile:

$ g++ -std=c++11 window.cpp -lSDL2 -o out/window

Success a window :)

OpenGL ES2/3 Render

Read more about OpenGL ES here:

https://en.wikipedia.org/wiki/OpenGL_ES

For our next trick we will simply get a window with something rendering in it.. Anything at this point will do :)

Note that we also make use of a C++ 11 lambda function.

Compile with:

$ g++ -std=c++11 triangle.cpp -lSDL2 -lGL -o out/triangle

And our results…

It works .. Brilliant !

Cross-Compile for Mobile

At this point we would like to prove to ourselves that we can actually compile and render this on a mobile device.

To get started let’s follow the guide here:

https://wiki.libsdl.org/Android

First off we need to make sure that we have Android Studio and the NDK (native development kit) installed. Next we will need to use the sdl script to generate our android project and JNI bindings.

To do this navigate to the location that you installed the SDL2 source. Then run the following comand:

SDL-2.0.8/build-scripts $ ./androidbuild.sh <com.your-namspace> ~/projects/sdl_app/triangle.cpp

If all goes well you should see the following message:

To build and install to a device for testing, run the following:cd /home/suroot/projects/SDL-2.0.8–12019/build/io.surfkit.simple

./gradlew installDebug

Following those instructions I now cd into the new project directory and use the gradlew script.

For me this generates a number of compiler errors in the form:

SDLControllerManager.java:792: error: cannot find symbol

class SDLCapturedPointerListener_API26 implements View.OnCapturedPointerListener

symbol: class OnCapturedPointerListener

location: class View

/home/suroot/projects/SDL-2.0.8–12019/build/io.surfkit.simple/app/src/main/java/org/libsdl/app/SDLControllerManager.java:617: error: cannot find symbol

x = event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);

Some googling and it looks like AXIS_RELATIVE was added in Android API level 24. Not sure why SDL would generate a file with version set to 19. No problem simply change the version level in your gradle.build file

$ vim app/build.gradle

This gets us to our next error

Android NDK: INTERNAL ERROR: The armeabi ABI should have exa/chtolmye /sounreo oatr/cAhnidtreocitdu/rSed kd/enfdikn-ibtuinodnlse/.b uFioludn/dc:o r’e’/

Say whaaaa?

Running the actual build command in the console produces more meaningful error messages, like so:

/home/suroot/Android/Sdk/ndk-bundle/ndk-build with arguments NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=/home/suroot/projects/SDL-2.0.8–12019/build/io.surfkit/app/jni/Android.mk NDK_APPLICATION_MK=/home/suroot/projects/SDL-2.0.8–12019/build/io.surfkit/app/jni/Application.mk APP_ABI=armeabi NDK_ALL_ABIS=armeabi NDK_DEBUG=1 APP_PLATFORM=android-24 NDK_OUT=/home/suroot/projects/SDL-2.0.8–12019/build/io.surfkit/app/build/intermediates/ndkBuild/debug/obj NDK_LIBS_OUT=/home/suroot/projects/SDL-2.0.8–12019/build/io.surfkit/app/build/intermediates/ndkBuild/debug/lib APP_PLATFORM=android-26 APP_SHORT_COMMANDS=false LOCAL_SHORT_COMMANDS=false -B -n

Android NDK: INTERNAL ERROR: The armeabi ABI should have exactly one architecture definitions. Found: ‘’

That is better :) .. ok so it appears we are missing the architecture for the build.

Again editing out gradle.build we can add abiFilters

Compiling now gets us to a new error, this time about our c++ 11 support.

Add the following lines to your app/jni/Application.mk

APP_CPPFLAGS += -std=c++11

# Instruct to use the static GNU STL implementation

APP_STL := c++_shared

This again gets us around the compiler error and to a new error:

triangle.cpp:6:10: fatal error: ‘SDL2/SDL.h’ file not found

#include <SDL2/SDL.h>

Some digging around in app/jni/src/Android.mk yields the following

SDL_PATH := ../SDL

LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include

So the path problem is because we reference “SDL/headers”. Again I am not sure why the build script would not account for this.. But let’s try adding the SDL directory to our include and copying all the headers there.

$ mkdir app/jni/SDL/include/SDL2

$ cp app/jni/SDL/include/*.h app/jni/SDL/include/SDL2/

One more compile and BAM! We have our basic triangle scene running on Android… well that was easy ;)

Note that I also hit this problem when working inside Android Studio:

https://stackoverflow.com/questions/49525708/ioexception-failed-to-find-byte-code-when-upgrade-to-android-studio-3-1

The solution for now was to disable Instant Run.

Next post we will look at getting some more interesting things to render. Thanks for reading and see you next time :)

References:

http://lazyfoo.net/tutorials/SDL/index.php

https://wiki.libsdl.org

--

--