Postmortem - making a quick jam game with Unreal Engine
Yesterday was the end of the first ever âSimple Jamâ - where participants were supposed to make small games. The explicit rules were âno more than 5 rules and no more than 5 assetsâ but those were flexible.
I struggled for a while over what to make, and after starting and discarding a few ideas I ended up settling on making a little kart racer game where you race around a track as fast as you can. (Itâs called Dash Karts, you can download it here: https://itch.io/jam/simple/rate/73383)Â Given the small scope it also seemed like a great project to dive in more with Unreal to see if I could get more comfortable with the engine. Â This writeup is my notes from using the engine, talking about the bits and pieces I used along with any oddities I ran into.
Overall Impression
Things went great! For the time I was able to spend (around 20 hours) Iâm very happy with how the game ended up. There was definitely a learning curve - I made heavy use of the following UE4 tools:
Splines & the SplineMeshComponent
Terrain
Blueprints
UMG
I only wrote about 20 lines of C++ during the project, and Iâll talk about that a bit more when I talk about blueprints.
Splines/SplineMeshComponent
Iâm not an artist - if you looked at the page for Dash Karts, you probably already realized this. I have a basic level of competency with tools like Blender but making more complex shapes would take a massive amount of time and probably eat all of my project time just trying to get that done.
The spline tools in UE4 let me build a basic segment of road and then apply it along a spline to build the road. Not only did this save me pain trying to make something in Blender, it also made the process of designing the track incredibly interactive since I could do a lap, tweak a point or two, and then test again - all without ever leaving the editor.
I ran into three problems while doing this that I had to work around. The first was that by default the road wasnât getting collision enabled, it sounds like thereâs a bug there and I worked around it by creating a new blueprint node to manually set the collision state on a spline mesh component.
The second problem was that by default the collision was a bit bumpy at the points where two spline mesh components (think: individual track segments) would join. To work around this I waited until the layout of the track was finalized and used the âexport to fbxâ option in Unreal. Then I cleaned up a couple of points on the track and reimported it all as a static mesh. This seemed to solve the bulk of the physics issues.
The third problem was due to my solution for #2 - as a giant mesh I couldnât figure out how to get lightmass baking to make good looking lightmaps for the track. There would be weird black splotches at different points and despite playing with things like lightmap resolution I couldnât figure out how to resolve the problem. So for the jam I just disabled baked lighting and set everything to dynamic. Longer term Iâd like to figure this out so I can re-enable baking.
Terrain
Unrealâs terrain editor is fantastic, and I know I only scratched the surface of what it can do. Once I had my basic track working I needed a world to go around it! so I made a basic landscape object that was big enough to surround the entire track and just started modifying the shape to fit. I think the biggest learning curve element was learning how to put together a simple landscape shader that supports painting layers, but the Unreal docs really helped with a step by step example.
I ran into two issues with terrain that I didnât learn how to solve in the time I had, but I plan on investigating after the fact. The first was I couldnât really figure out how to do sheer cliff faces with the tools. This might just be a limitation of the terrain system in general and the correct answer is to model those elements separately.
The second issue was finding a good way to make the terrain flush with the road in all the spots where they should be touching. If you play the game youâll see multiple spots where the terrain isnât quite flush (donât drive your kart into those spots and get stuck!). Iâm guessing thereâs a tool to help with this and I simply didnât find it in time.
Blueprints
About 99% of the game is done in blueprints. It was great to be able to quickly sketch out and iterate on ideas by throwing together a new blueprint, and quickly modify/and retest elements.
As blueprints would start getting bigger (the kart blueprint and the track builder blueprint in particular) I made heavy use of functions and variables to keep the graphs clean. Just like you would in code.
If I keep working on Dash Karts (and Iâd like to), finding the balance of blueprint vs C++ seems like itâll be an area that needs further investigation. My gut reaction right now is that the workflow would be something like:
Sketch out new idea in blueprint until it works
If the idea is something that we will build on/expand on with custom versions - move the core blueprint into C++ and then extend that for custom versions
If the idea is a one-off, leave it in blueprint unless thereâs a performance need to move it into C++.
The one concern I have as a project goes is making sure thereâs a clear delineation between what goes in BP and what goes in C++ - mainly so itâs immediately clear where you should be looking for the implementation of a given aspect of the game. Reducing mental effort to find things in large projects is important!
So what did I end up programming? I made 2 new blueprint nodes in C++ because the things I needed to call werenât readily available from BP. The first was a âFind Betweenâ node where you pass it two vectors and it returns a rotator that will rotate vector A to vector B. The second was a node to set the collision on my spline mesh components properly.
UMG
UMG is the latest UI tooling in Unreal Engine and despite not leveraging it heavily I really enjoyed working with it. For a simple UI adding the elements and wiring them up to the game state was very easy - I think I ended up spending about 30 minutes total reading up on UMG and then implementing the first pass of UI in the game. All the stuff in the UI ended up working as expected, there was one sticking point that took me a bit to figure out:
When showing the UI my initial reaction was to set the âHUDâ element on the GameMode, but it seems like thatâs from a previous iteration of the tools. Instead I had to create an instance of my hud widget and add it to the viewport. When I wanted a player to interact with the UI I had to set the input mode and cursor visibility, which is fine but I donât think it was immediately clear. I might have just missed this in the docs since it was closing in on midnight and I was rushing.
Miscellaneous
Material instances are great. I set up a common material that I used for all my world objects, and then just created material instances to override the colors/textures.
I love that UE4 has specialized editors for different game elements instead of trying to jam everything into the scene view. Different data should be treated differently!
You can effectively ânestâ blueprints by using the ChildActor component. As a unity user this is 110% as miraculous and amazing as it sounds.
Context senstive search in blueprints is great to help learn the system. e.g. when I was defining the kart physics Iâd often pull off a wire and type âphysicsâ into the search to see what my options were for getting/setting different options.
The collision tools in the mesh asset editor are great for defining a quick first pass of collision for new objects. You can always just use the mesh too by setting the collision option to always use complex collision.
In development builds of your game you can leverage all the debug drawing routines that you normally have in editor! Itâs insanely useful to be able to turn on collider drawing when youâre getting stuck somewhere to try and track down the culprit
One thing that can be confusing is dealing with settings that can be overridden in multiple places. Post-processing settings come to mind here - some can be set in the project preferences as defaults, they can be set on the camera component, and they can be set in postprocessing volumes. Itâs not bad that they can be set in multiple places, I can think of use cases for all of them. But when youâre trying to learn the basics trying to figure out where to do something can be overwhelming.
This is equally true for GameMode/GameState/GameInstance - it took me a while to really dig through and figure out what the differences are between those items, as well as how to best use them. In the end for a small single player game it doesnât really matter, the differences between these elements are much more important when you start making a multiplayer game. Still, itâs another thing to learn as youâre picking up the engine.
The Unreal Engine video tutorial collection is massive and amazing. Very impressed with how much content is available to dig through when you want to learn something about the engine.
Saving the most important bit for last: I had a ton of fun making this game and working with UE4! I made a best effort to work with the engine and use the tools it provided instead of just trying to jump in and do things âmy way.â I still have a massive amount to learn about UE4 (ai/behavior trees, navigation, animation, networking, more terrain stuff, etc), but this was a great project for solidifying some of the basics.












