Can I develop games without a Game Engine?

You definitely can. However, you will be reinventing the wheel every time you want to develop a new game.

A game engine is a set of rendering and mathematical operations that simplifies the complexity of game development.

In layman’s term, it provides a set of tools that you can re-use every time you need to develop a new game.

For example, to build a house you need, at a minimum, the following tools: hammer, nail, saw, wood and a blueprint.

No matter how many houses you build, the only items that changes are the wood, nails and the blueprint. There is no need for you to manufacture your own hammer and saw. You simply buy them once and reuse them every time you build a new house.

A game engine provides you the algorithms and components, i.e., hammer and saw, to build a game. You simply provide the characters and the gameplay. i.e., nails, wood and blueprints.

So what exactly does a game engine provide?

A game engine provides you with the following components:

  • Math Engine: Responsible for all Linear Algebra computations, such as Space Transformations.

  • Rendering Engine: Responsible for interacting with the GPU and manages all Shaders (GPU programs) accountable for rendering 3D models and various graphics effects, such as shadows, lighting and particle systems.

  • Physics Engine: Responsible for solving the equation of motion

  • Collision-Detection System: Responsible for detecting collision among Convex objects.

You can definitely develop a game without a game engine, but you will need to implement the components mentioned above. Moreover, developing these components require a different set of expertise than what is required in game development.

What are the Pros and Cons of writing a game engine in C++?

C++ is efficient. It is as close to the metal as you can get(i.e., fast) and yet have all the Object-Oriented Programming features.

This efficiency comes, not at a cost, but with responsibility. As opposed to other Object Oriented languages, you are responsible for memory management.

C++ may be harder to grasp than other languages. And this may be a reason why people shy away from it. However, when it comes to Game Engine Development, the ”user-friendliness” of a language should not be the deciding factor. Its efficiency is.

The easiest component to develop in a game engine

By far, the easiest component to develop in a game engine is the Rendering Engine. However, to beginners, this is also the component that will cause a bit of frustration. The frustration is not related to complexity, but confusion — especially when using Graphics APIs such as OpenGL, Vulkan or Metal.

So why is the easiest component to develop, also the most frustrating to get it working?

The problem lies in the fact that for a device to render a 3D model on its display, three things must work synchronously: The flow of data, GPU Shaders, and Transformations.

OpenGL/Metal are mediums that take attribute data from the CPU to the GPU. They transfer attributes such as vertices, normal vectors, UV coordinates and textures from the CPU into the GPU.

However, the GPU will not know what to do with these attributes until GPU Shaders have been compiled, attached and activated. Only then, will the Rendering Pipeline be ready to transform the space of the vertices, assemble, rasterize the primitives and finally send the data to the frame-buffer.

Finally, for all this to work, you need to have a good understanding of Linear Algebra operations, such as Transformations. In Computer Graphics, the most common transformations are Model-World Space, Model-View Space, and Model-View-Projection Space.

In summary, to render a simple cube requires a bit of knowledge of the OpenGL/Metal API, how GPU shaders work and their purpose within the Rendering Pipeline, and Linear Algebra concepts. It is not hard to see why computer graphics can cause a bit of frustration and confusion for beginners.

However, once you have a good understanding of Computer Graphics, developing a Rendering Engine becomes relatively easy when compared to other components of a Game Engine.

A psychological trick to help you develop a game engine

Is going to be almost six years since I decided to develop a game engine. When I started, I knew that it was a crazy idea, and many people thought it too. But looking back, the craziness was not related to the technical complexity, but in the psychological battle that I had to fight with myself.

Throughout the development of the game engine, the desires of giving up was a constant thought. There was a period that I wanted to give up every single day. The constant whisper of "Just Give Up" was always present. And I did give up. I quit for about four months. It was just too much to bear.

But I came back to it. After my sabbatical, I started wondering "What would it feel, if I didn't give up," and "How would the engine look like in a year from now." The excitement of working on the engine again was slowly growing. But there was something that had an impact on my psychology.

Since the beginning of the development, I documented the progress of the engine through images and videos. One night, I started watching these videos. I watched all the small progress I've made and the slow evolution of the engine. Seeing with my eyes how far I've come, had a psychological impact on me. It gave me the energy to continue with my crazy decision to develop a game engine.

Here is a video of the evolution of the Untold Engine, from its inception five years ago to today.

 
 

Documenting my work have been a tremendous psychological tool. It has helped me keep going, and I hope it will continue doing so.

If you are embarking on a complex project, document your work through images and videos to remind YOU how far you've come when you are about to give up.

Thanks for reading.

How to approach Game Engine Development

A couple of weeks ago I was assembling a new piece of furniture for my apartment. As I was putting all the pieces together, I made sure not to tighten the screws until all the parts were in place. Such workflow reminded me of the process I took to develop the Untold Engine.

If you have been reading this blog for a while, you would know that when I started developing the game engine, I knew very little about Computer Graphics. Moreover, my C++ programming skills were weak.

Keeping into account my technical weaknesses and my desire to learn, I approached the engine's development the same way you would assemble a new piece of furniture. That is, I made sure not to tighten the screws until the end.

What do I mean with this phrase? I didn't focus on Perfection. I didn't write each piece of code to the highest standard possible. Instead, I focused on writing code that was Good Enough.

For example, the Collision Detection System is the most complex component you will have to implement. This system requires you to implement several algorithms such as the GJK, BVH, Sutherland-Hodgman, etc. My initial implementation of the GJK was very crude. However, instead of making it Perfect, I decided to move on and implement the Sutherland-Hodgman algorithm. Again, my implementation was crude, but it was Good Enough. Finally, I implemented the BVH algorithm.

I had all the major components working. Their implementations were crude, but they were Good Enough to detect a collision. I had in my hands a crude Collision Detection System, but I had learned a ton in the process. I learned how all these algorithms worked together to detect a collision.

After I understood how these algorithms worked together, I went back and re-read several chapters on Collision Detection and several articles on the algorithms mentioned above. Armed with new knowledge and experience, I was able to improve the Collision Detection System. I think I was able to do so because I saw the system from a holistic point of view. I understood the system weaknesses and strengths. I was able to see the whole picture.

Developing a Game Engine is tough. There is a lot to learn, and you will make tons of mistakes. In the beginning, avoid Perfection. Once you have a good grasp of what you are doing, go back and improve your code. Just like assembling a piece of furniture, do not tighten the screws until the end.