Learning Unreal Engine 4: Conway’s Game of Life

So recently I’ve been learning Unreal Engine, both with blueprints and with C++. I decided to implement Conway’s Game of Life in Unreal Engine as a project, because I’ve wanted to do my own implementation for a while, and it seemed like a good way to get started with UE4.

While you’re reading this, you can download the executable and try it out for yourself. Note that the more cells you have in the grid, the more memory and render time it takes, so you might not want to spawn thousands of cells right away.

I’ve heard a lot about UE4 and people seem to like it a lot. It is also a strong competitor against Unity, and with good reason. Unreal Engine has been popular among AAA studios for a long time now, but a few years ago, with the release of UE4, it is gaining popularity among indie developers. Through the Blueprints visual scripting system, it is much more beginner-friendly for programmers as well as level designers than it was before.

I will be comparing UE4 a lot with Unity in this post, since I have more experience in Unity and that previous experience has helped me to migrate knowledge into UE4. The cube mesh used in the simulation is from the standard puzzle example.

Learning the engine structure

The first thing I started to look into was the engine structure differences between UE4 and Unity.

Unity’s base structure is comprised of modules, assets, game objects and components. Modules are how the engine divides it’s functionality into different categories (input, graphics, audio..), assets are files such as data files and textures, game objects are objects in the game world and components are basically what make game objects do something. Each game object must have a Transform component, which stores the object’s position relative to the object’s parent object, or global position if it does not have a parent. For someone who hasn’t used Unity, this structure may seem a bit complex, but it’s much more simple than that of UE4.

UE4 consists of modules, actors, components, controllers, pawns and game modes. Modules have the same idea as in Unity, they are used to categorize different parts of the engine. Your own C++ code will also reside in a module. Actors are all objects that reside in the game world. Unlike in Unity, actors are not only holders for components, they can be inherited, and they can have their own properties. An actor can have multiple components of the same type, and scene components can be stacked in a hierarchy, so they also function differently to that of Unity. Actors also need at least one scene component, but this component is created if it is not present. Controllers are an interface between pawns, players and AI. Pawns are controllable objects in the game world, either controlled by a player or by an AI. Game mode decides what object types to use as pawns, player controllers, spectator pawns, and so on.

So UE4 has a lot more parts in it that you need to get familiar with. But complexity in this case is rarely a bad thing. In Unity, you have to do a lot of things from scratch, or download/buy them from the Asset Store. The complexity of UE4 is, in most cases, useful, and makes your game more structured and easier to maintain.

Of course, the structure of both engines are not really as simple as stated above, that was just an oversimplified comparison. I suggest looking into the documentation of both engines if you want to find out more. I will probably talk more about those on game engine development posts.

Blueprints

blueprints

I was very skeptical about blueprints when I started learning UE4. I’ve always thought of visual scripting as a tool only useful for the basics of learning how to program, and as a useless gimmick in practical use. However, Unreal’s blueprints are a much more sophisticated visual scripting system than anything else I’ve seen before. So I decided to go with it for a while. I thought it was a good way to get to know how the native object types work and how actors interact with each other in the game world.

All was good for a while, although getting used to dragging nodes around was still a bit tedious. That was until I started making the Game of Life simulation logic. Here is a picture of it, in all it’s glory. (click to enlarge)

dontdothis

This is just the basic logic of counting the amount of living neighbors a cell has. Not only is it difficult to read without zooming and dragging all around the place, it was also slow in performance. The game froze even with a 20×20 grid.

So at this point I came to the conclusion that while blueprints are sophisticated and can do a lot of things, they still aren’t a good option for programming more complex functionality. They are slow and messy. They are more useful in adding some small level-specific features to an object, and also UMG, which I will talk about later.

Then I started migrating the project into C++.

C++

I have to say that UE developers made the right choice when sticking with C++ as an option, and adding features such as hot reloading to make rapid prototyping with C++ much more enjoyable. While I miss the simple clutter-less C# code, I don’t mind working with C++ at all, especially since Unreal has a lot of functionality ready to be used.

The first thing I wanted to figure out was how to use Qt Creator with UE. The reason for that is because I absolutely love Qt Creator, and think it’s a far better IDE for C++ than Visual Studio is. It’s faster, more lightweight, cross-platform, somewhat portable and I’ve used it a lot when developing Qt applications. Thankfully, I found a solution, and I didn’t need to use Visual Studio. Yay!

Reflection

cpp_pawn

The Unreal Property System is UE’s reflection system. A reflection system basically gives you the ability to inspect C++ objects, methods and fields during runtime. Like the program is looking at a reflection of itself. This system allows UE to instantiate objects into the game world when it reads the level assets or blueprints. It also allows Unreal Editor to see what kind of classes exist within the C++ codebase, so it can associate them with blueprints and levels.

So the property system is an integral part of UE development, but when creating new object types, you don’t need to do much to make it work. You simply include an automatically generated header file, add a couple of macros (UCLASS, UPROPERTY, UFUNCTION, etc) and let the Unreal Header Tool do the heavy lifting for you. C# has a built-in reflection system, but then again, C++ is a lower-level language.

Input system

The input system in UE is very different from Unity. In Unity, you access the Input static class to get the status of different inputs each frame, where as in UE you bind methods into an InputComponent that will detect changes to that specific input. Unity only has input axes which are used for both buttons and analog input, while UE splits these two into actions and axes, which makes more sense given the input binding mechanic. The pawn class even provides a useful overrideable method for binding input into the player’s pawn.

void AGOLPawn::SetupPlayerInputComponent(UInputComponent* InputComponent)
{
    Super::SetupPlayerInputComponent(InputComponent);

    InputComponent->BindAction("ChangeCameraMode", IE_Pressed, this, &AGOLPawn::ChangeCameraMode);

    InputComponent->BindAction("MoveCamera", IE_Pressed, this, &AGOLPawn::MoveCameraBegin);
    InputComponent->BindAction("MoveCamera", IE_Released, this, &AGOLPawn::MoveCameraEnd);

    InputComponent->BindAction("MoveCameraFurther", IE_Pressed, this, &AGOLPawn::MoveCameraFurther);
    InputComponent->BindAction("MoveCameraCloser", IE_Pressed, this, &AGOLPawn::MoveCameraCloser);

    InputComponent->BindAction("MoveFaster", IE_Pressed, this, &AGOLPawn::MoveFaster);
    InputComponent->BindAction("MoveFaster", IE_Released, this, &AGOLPawn::MoveSlower);

    InputComponent->BindAction("ToggleSimulation", IE_Pressed, this, &AGOLPawn::ToggleSimulation);

    InputComponent->BindAction("ActivateCell", IE_Pressed, this, &AGOLPawn::ActivateCell);
    InputComponent->BindAction("ActivateCell", IE_Released, this, &AGOLPawn::ClearActivationStatus);
    InputComponent->BindAction("DeactivateCell", IE_Pressed, this, &AGOLPawn::DeactivateCell);
    InputComponent->BindAction("DeactivateCell", IE_Released, this, &AGOLPawn::ClearActivationStatus);

    InputComponent->BindAxis("MoveCameraVertical", this, &AGOLPawn::MoveVertical);
    InputComponent->BindAxis("MoveCameraHorizontal", this, &AGOLPawn::MoveHorizontal);

    InputComponent->BindAxis("RotateCameraVertical", this, &AGOLPawn::RotateVertical);
    InputComponent->BindAxis("RotateCameraHorizontal", this, &AGOLPawn::RotateHorizontal);
}

I personally like UE’s input system over Unity. It’s much better structured and you don’t have to put all your input logic on a tick function. You also don’t have to think about where to put your input logic; pawn is your character, so you process input for that character. I reckon that makes multiplayer game code much easier to manage.

Game of Life functionality

Creating a custom pawn for camera controls was a trivial task; bind input, add speed properties, add lock/unlock logic and that was pretty much it. Simple and functional.

The Game of Life functionality could’ve been more simpler but I wanted to focus more on performance. Whenever I needed to query the value of a cell by it’s X and Y position, I could’ve made a method such as this:

bool ALifeSimulator::GetCellValue(int32 gridX, int32 gridY)
{
    for(int32 i = 0; i < mCells.Num(); i++) {
        ALifeCell *cell = mCells[i];
        if(cell->GridX == gridX && cell->GridY == gridY)
            return cell->Value;
    }
    return false;
}

However, this is slower than getting the cell value from a two-dimensional boolean array, like this:

bool ALifeSimulator::GetCellValue(int32 gridX, int32 gridY)
{
    if (!mGrid) return false;
    if (gridX > mSize || gridY > mSize ||
        gridX < 1 || gridY < 1)
        return false;

    return mGrid[gridX - 1][gridY - 1];
}

Not only that, but having cell values in an array makes it faster to copy it during a simulation tick to apply the next state as the current state

for (int x = 1; x <= mSize; x++)
    for (int y = 1; y <= mSize; y++) {
        mGrid[x - 1][y - 1] = mGridNextState[x - 1][y - 1];
    }

Only after the next grid state is ready, we apply the values to the real cell actors

for(int i = 0; i < mCells.Num(); i++) {
    ALifeCell *cell = mCells[i];
    bool value = mGrid[cell->GridX - 1][cell->GridY - 1];
    cell->SetHighlighted(value);
}

So now the only performance limitation we have is how much pretty lights and cube meshes UE4 and the hardware can render, as the two-dimensional array can process thousands of cells with a single tick.

Unreal Motion Graphics

Now that the base game was complete, I wanted to create a nice little user interface for the simulation. Unreal Motion Graphics (UMG) is the de facto standard for creating UI in UE4. UMG is done a bit better than the UI system in Unity. Because of Unity’s simpler engine model, the UI also exists within the game world, which can become a bit tedious when working with it. UMG is not part of the game world; it is added to the local player’s viewport. It can interact with the game world, but it’s not part of it. And this is fine, because it makes little sense to have the UI system within the game world, right?

I used blueprint scripting in UMG, since the logic wasn’t very complex, and it was mostly used for calling C++ functions on actors anyway. Here’s an example:

umg_blueprint

You can code UI elements with C++ as well, so same as actors, don’t stay on blueprints if your logic gets too complex.

Creating standalone releases

After finishing the UI, it was time to pack up the game into a standalone executable. This worked without problems for exporting to Windows 32-bit and 64-bit, but you need to setup a cross-compiler for packaging to any other platform. This is because you need to compile your C++ code to that specific target platform’s native binary format. This probably wouldn’t take more than an hour to set up, but I got lazy at this point, so I only compiled my project for Windows.

Conclusion

After a couple days of intensive jamming, the game simulator was complete! It’s a pretty basic example of an Unreal Engine project, but it was a useful learning experience.

If you missed it, you can download the executable on the top of the post, or just get it here. 🙂

Also, if you want to read more about Conway’s Game of Life, it has an entire wiki dedicated to it.

Introduction

So, this will be the first post on this blog. Now that I finally got around and made a blog, I don’t know what else to put here right now so I’m just gonna talk about my background a bit.

Starting with Garry’s Mod

I have been doing programming as a hobby for some time now. At the beginning of 2010 I started to look into source engine modding out of curiosity, and entered the magical world of C++. Because Valve’s documentation clearly stated that you need to know C++ before doing source mods, I started with some basic hello world applications. I didn’t even get to the source modding part in the end, as my interest shifted towards Lua coding in Garry’s Mod. Lua coding was much more beginner-friendly, and you could do a lot of stuff with it in Gmod, so I pretty much left C++ coding altogether.

In 2011, I also developed interest in making stop motion videos in Garry’s Mod. I did get some following on these videos, but the biggest projects that came out of these was two tools, Stop Motion Helper and Ragdoll Mover. These were my biggest and first public coding projects I did. Years later, these tools are still used by a suprisingly high amount of users. I still occasionally work on these projects, and released a whole new version of Stop Motion Helper about a year ago.

C# and Web Development

At the end of 2012 I got introduced into C# when I stumbled upon the SteamKit2 library, allowing the creation of standalone applications communicating with the Steam network. This got me interested into making a chat bot for Steam. I learned a lot of C# and database programming during this project, as I wanted to create a functional chat log and perform statistics on users and chat messages.

Through database programming, I moved to learn web development, both backend and frontend. I mostly did small website projects, but one project I can recall is VhostManager, which also became my thesis for vocational school. I learned a lot of HTML, CSS, JavaScript, PHP and Python from these projects.

Game development

In the summer of 2013, I got interested in game development. Well, I was interested before, but now I actually started learning. I discovered Unity, and pretty much went with it for a long time, since I already knew C# and Unity was easy to learn and use AND it had the best support for rapid prototyping.

Six months went by, and I had made a dozen prototype projects that never saw the light of day, but I still had a lot of fun doing them. At the time, I had zero experience with collaboration, all my previous projects I had done alone. So in January 2014, I participated in Global Game Jam. It was a lot of fun working with like-minded people, and we even managed to make this thing.

During a game programming course in summer 2014 I started developing a game in Unity that turned out to be my first official release. After a lot of learning, mistakes and procrastination, I released NumberShock in December 2014. With help from DasBoSchitt, the game also got some exposure, with a total of over 5000 downloads as of today. I got a lot of positive feedback, but the game quickly faded away, and not many are playing the game anymore.
Mistakes were made, mistakes were learned from, expectations were crushed, crushed expectations were accepted. All in all, I accept it as my first official game release.

Conscription

So 2015 was a very busy year in my life. In January 2015, I started military service. And I almost ended it the same day. But I stayed, and later, when the rookie phase was over, I applied to a programming job for the rest of my service. For 6 months during March – September 2015 I was a software developer, mostly developing a single application using C++ and Qt. I also did a mobile application to easily check the food menu, using node.js and Ionic.

So yeah, that went better than I had ever hoped for. I gladly finished my service and left with plenty more C++ experience, and a job certificate.

Present day

Starting from September 2015, I am studying for a gamedev-centric software engineer’s degree in Kajaani University of Applied Sciences. This was a pretty clear choice, as I didn’t have much contacts in the software industry, so getting a job would’ve been very difficult. I have met many like-minded people who are all interested in the same things as I am, so no regrets!

And that’s about it. Wow.. I rarely look back at my previous projects like this. But anyway, my next post will probably be about learning Unreal Engine, which I have been doing recently. I will also start blogging about developing a game engine.. soon-ish.