Log in

games, code, art and music

How I wrote my own 3D game engine and shipped a game with it in 20 months

My game Speebot is finally out on Steam! If you’re a fan of 3D platformers, be sure to pick it up while the launch discount is active. There’s also a free demo to try before you buy.

Speebot has been in development since January 2016, and I’ve been working on it in my spare time by myself as a hobby. I’ve done all the programming, game design, graphics and music. I’ve also written the game engine from scratch.

People often ask me why I’ve decided to write my own game engine in the year 201X, when there are multiple general use engines available for free. There are many reasons, but in retrospect I can say that “inventing my own wheel” was an even better idea than I initially thought it was.

One of the biggest advantages of a custom engine is the absolute code control. I can customize it literally any way I want and optimize it for my specific use case. Universal game engines are called that because they are designed for general use, which results in bloat and often considerable slow downs.

The second advantage is the workflow control. I find that an efficient workflow is crucial in game development, and this decision lets me integrate my own tools in a way that makes it easier and faster for me to produce content.

Of course, there’s also the benefit of not being tied to any ToS and not having to pay license fees.

Also, it’s fun. And that should be a reason enough, I think.

I started developing the engine in January 2016. I called it YUME (which means “dream” in Japanese), and it’s written in Haxe, C++ and OpenGL. I use a custom fork of the Lime library, which is a lightweight framework that enables things like asset management and access to the GL context.

This is what the YUME engine was capable of in its first week.
This is what the YUME engine was capable of in its first week.

I knew almost nothing about 3D game development when I started with YUME. I had to learn OpenGL from documentations, archived forum posts and tutorials meant for Java and C++ programmers. The 3D algebra was especially difficult for me, and sometimes I got stuck at problems for days. But I figured it all out eventually, and in a couple of months I had a pretty solid 3D renderer.

Besides the 3D renderer, I had to implement various other sub-systems, including: a 2D renderer, state machines, a timestep system (more on this later), a UI system, a mouse input system, a keyboard input system, a gamepad input system, dynamic shadows, a 3D sound system (using OpenAL), model loading (in my own file format based off IQM), skeletal animations, bone attachments, real-time reflections, bitmap text rendering and so on and so forth.

As a result, I ended up with a functional little 3D framework. Many of the things I listed are essentials that are no doubt found in every other game engine, but there are a few key differences that justify early YUME’s existence. One of those things is my timestep system.

A timestep system ensures that an engine displays frames at specific intervals. Unlike most current game engines, YUME does not have a framerate cap, i.e. it's not tied to 30 or 60 frames per second. In fact, the framerate can be anything from 1 to 250 frames per second, and the game will still appear to be running at the same speed no matter what the framerate is (only the screen will be updated at different intervals). This is achieved by separating game logic from rendering. Rendering a single frame can take different amount of time on different computers, so the render framerate depends on the program's performance. The logic cycle, on the other hand, is tied to a 64 tick rate - meaning the game logic is updated 64 times per second, no matter what the render framerate is. There are a few edge cases that the timestep system must account for, but the principle remains the same. As a result, the framerate decreases on weaker computers without ruining the game flow.

Early YUME demo.
Early YUME demo.

I had a framework, but not a game engine. It was time to start designing my game, and decide what features I need to implement. I’ve had a few ideas by that time already, and knew that I wanted to experiment with tilesets in 3D.

I began writing a map system that was similar to 2D tile maps that I was used to, but with an additional dimension. I made an editor for myself to speed up this process of map creation (spoiler alert: this feature ended up as the custom level editor that’s included in the final game). I made it so that the engine would automatically figure out which tile type to display based on its neighbors (some call it “autotiling”). I thought of a way to batch all the tiles into a single mesh, which means that the entire map was treated by the engine as a single model and could be drawn in a single call to the GPU. As a result, the performance was really good. I didn’t have to compile maps, and could edit and play them in real time. It was perfect for productivity.

I wrote a simple physics system – basic collision, frictions, nothing too complex – and began experimenting with gameplay… In a couple of weeks, I had a cylinder that was jumping around a tile map in 3D.

Thanks to YUME, I was able to prototype and experiment with the game in a really efficient way.

Speebot prototype in July 2016
Speebot prototype in July 2016

The YUME engine evolved as my progress on Speebot continued (I picked the name Speebot around this time). I found and recognized problems with my architecture as I worked with the engine, and refactored it twice. The engine now had a simple physics system, particles, water reflections, camera animators, interactive entities, ray casting… It evolved from a framework into a game engine.

I was adding new gameplay mechanics and figuring out what worked well. I kept what was fun, and removed or repurposed what wasn’t. I started experimenting with the art direction for the game, and made a little robot character in Blender. I found that the cartoonish rubber band animations for the character worked really well, they made the game feel lighthearted and juicy. I kept that look and feel for the future NPCs and entities as well.

Speebot was starting to look and feel like a game!

At that point I was working on a game, rather than a game engine. I continued to create new maps, props, NPCs and mechanics. The level editor grew with features, and so did the engine itself.

In the winter of 2016/2017 I took a couple months off from the usual game development routine, and focused on practicing composing music. I have no formal musical education, but I enjoy it, and I’ve written the soundtrack for my previous game Hypnorain in the past. I wanted to do better for Speebot, so I delved into music theory again and made a lot of practice tracks. I used SunVox for making music, which is a modular synthesizer and tracker program. The final version of Speebot has 23 tracks, which amount to about an hour of original music. I am actually really happy with the results. I will continue to improve my skills for the next game.

From that point, I was alternating between creating new levels, introducing new gameplay mechanics, writing music and fixing bugs. I really like this workflow, because it lets me control every aspect of the game, and when I get bored doing one activity I just switch to another.

After releasing a couple of demos, collecting feedback from players and improving the game – Speebot was released in October 2017. The final game has 200 stages, 4 worlds, a custom level editor, various extra modes, unlockable cosmetics and other side content.

No doubt one of the biggest challenges was to stay motivated and keep working on the game, every day after university/work and during the weekends. Still, it was great fun, and well worth it.

I will continue using and improving YUME in my future games. I have already started working on my next project. More information coming soon!

Speebot was my most ambitious project to date, and my best game so far.

But my next game is going to be much better.

35497 views, 25 comments


Anonymous posted on October 15, 2017:

Looks much better than games made by ready engines. Great job!

Anonymous posted on October 15, 2017:

Inspiring. Staying motivated is the biggest task for me while I am working on projects. Reading this gives me new incentive to continue working on a current game of mine. Thank you!

Anonymous posted on October 15, 2017:

This is awe inspiring, and I hope one day to reach your level of creating my own engine. Two questions: 1) was there a resource that was pivotal for you with helping you understand and create your own engine. If not, what would you say were the top three? 2) How did you tackle memory management in your engine ? Did you create your own custom memory manager?

Can't wait to play the game! Been following for at least a year.

KEYREAL posted on October 15, 2017:

Thank you!

1) OpenGL documentation, opengl-tutorial.org, video tutorials on YouTube by thebennybox and ThinMatrix.

2) I reuse resources as much as possible, and when there are no references left - I remove them. This behavior is hardcoded into my entity hierarchy system, so I don't need to do anything manually. The rest is handled by Haxe's garbage collector.

Anonymous posted on October 15, 2017:

https://learnopengl.com/ is one of my favorites - a lot of explanation and code snippets for everything :)


Anonymous posted on October 15, 2017:

Very impressive but... only Windows? Why no Linux support? ;(

rskgames posted on October 16, 2017:

Keyreal has answered this question in the following post


rskgames posted on October 16, 2017:

Congratulations on the release of Speebot and all the best for the games success.

KEYREAL posted on October 16, 2017:

Thank you for your support, as always.

Anonymous posted on October 16, 2017:

LOL it would have taken 10 minutes to do all of this in Unity. Trust me, I am a professional in the gaming industry. We use Unity because there is no reason to reinvent the wheel.

Anonymous posted on October 16, 2017:

How is that relevant? Now this person knows 3d rendering from the ground up and can likely easily hop into unity, unreal, or any other engine or framework they choose.

I very much doubt you're a "professional" in the industry. It is not professional to just shitpost on other indies games because of your opinions - and if you read the article they were satisfied with the amount of control they could get from a custom renderer.

There's nothing wrong with that.

Anonymous posted on October 16, 2017:

You're a fucking idiot.

Anonymous posted on October 16, 2017:

If you are a professional then you would never have undermined the efforts put here in learning all the core engine stuff...He now might be knowing much more than you do and he might as well get a job in unity itself to implement some more nice features that guys like you calling themselves professional might use and then disrespect the efforts put here.

Anonymous posted on October 16, 2017:

"I am a professional in the gaming industry"

Your post screams jealousy and insecurities.

Anonymous posted on October 17, 2017:

If you're a 'professional', you know that it would take a lot longer than 10 minutes to implement those features, even in an engine like Unity. Besides, as someone else pointed out, this game developer could probably get a job working on Unity itself.

Anonymous posted on November 04, 2017:

What do you expect? Once this was posted on /r/gamedev, this became inevitable. Nothing but Lowest Common Denominators over there.

Anonymous posted on October 16, 2017:

But that's no fun.

Anonymous posted on October 16, 2017:

Great work for one person building it from scratch.


TheGreatCabbage posted on October 17, 2017:

This is amazing work. Could I ask how many years you'd been programming before embarking on this project?

KEYREAL posted on October 17, 2017:

Thank you. I've been programming as a hobby for about 10 years, since I was around 13 years old.

TheGreatCabbage posted on October 18, 2017:

Thanks for the information. I unfortunately only started programming less than 2 years ago (age 18) , and I think I've got a bit more work to do before I can write any game engines! Congrats again :-)

Anonymous posted on March 18, 2018:

Awesome job! I am currently in the works of creating a framework on top of OpenGL.

Its a lot of fun and a lot of work, I hope to create such a game as this in the future.

What does HaXe do for you?

KEYREAL posted on March 18, 2018:

Haxe is my favorite programming language, it produces fast native-targeted binaries, has a good syntax and a bunch of really useful features, such as macros and conditional compilation.

Wilds posted on March 18, 2018:

Could you explain a bit how you handle collision detection and response and your physics?

How did you handle entity interaction?

KEYREAL posted on March 18, 2018:

The collision detection is simple swept AABB. In case of Speebot, there are several hardcoded entity groups (e.g. static terrain bounds, player bounds, bullet bounds...) that entities can listen to. The reaction behavior can be described in the subclass of each Entity individually. This simple functionality covered all physics requirements in Speebot.

In the newer YUME version, the physics engine has been rewritten - it's a lot more versatile, and I might write a full article about it one day.

Leave your comment

You're posting as Anonymous. Log in instead?

500 characters remaining, no HTML allowed.

Please enter the code that you see in the image (refresh?):