michael puskas

Creative solutions in UE4 framework building

In deciding on an engine for Fiend, my biggest concern was for what experience would be the most useful. I eventually decided on Unreal Engine 4, a partially open-source engine that traffics predominantly in C++. I figured that gaining experience in the workings of a professional game development engine, while also gaining lots of C++ experience, would be hugely beneficial. Unfortunately, the gameplay systems that I had decided on were largely unsupported by out-of-the-box UE4. This meant that I had to build a lot of infrastructure before I began to develop the systems—something that I was eager to do, since it gave me some meaty development problems to solve.

 
 

The current iteration of the text-based UI, as of this posting.


 

The first major task was to build a framework that facilitated my text-based gameplay. Since UE4 only has concepts for objects placed in the world, I would have to build my own systems for managing non-physical rooms, items, and interactions. The other half of this task was to build the UI to manage these systems, but I’ll save that for another post.

 
 

A diagram of one of the levels: rooms, containing objects.


 

Rooms and “objects” (the layman definition, not programming objects) aren’t very hard to conceptualize as code. Rooms are instances of a class that can contain objects, and objects are instances of a class that can exist in a room and that can be interacted with. The main trouble comes in developing these in a way that facilitates a smooth workflow. For example: objects will have default functions to respond to the game’s verbs (push, pull, use, take, examine), but how do you program a custom interaction? Say, for a door that needs to update its internal state when you pull (“open”) it?

 
 

The script-like workflow that I developed for easily adding custom flags and functions to objects (done in a level’s custom populator class).


 

For this, I originally jumped to the school-taught ideal of doing things in the most object-oriented way possible. I wrote a generic object class, and made each object that required custom functionality its own child class. However, as I built out the first level, my compilation times skyrocketed as the compiler was forced to slog through the nearly 100(!) child classes each time I tweaked the parent. This clearly wouldn’t work.

 
To fix the issue, I came up with a non-obvious solution that I’m really happy with. It isn’t the most ideal code, but it solved the problems perfectly and led to a very nice workflow.

 
 

The solution: make your own jury-rigged inheritance with function pointers!


 

The above array of function pointers is used like this: when a player tries to initiate an action on an object, the object’s function pointer array is checked in the appropriate slot. If the pointer is non-nullptr, that function is ran. If not, the object’s generic version of that function is ran. This way, we only ever need the single object class, and we can build and assign custom functions in a script-like way, drastically reducing the time it takes to implement each one.

 
 

The function that’s called each time an object is clicked.


 

Once the object issue was solved, the rest of the framework fell into place. The next step was to design and build the systems specific to my game, but that will have to wait for another post.

Leave a Reply

Your email address will not be published. Required fields are marked *

© Michael Puskas, 2016. All rights reserved.