Thoughts on developing game efficiently solo without game engine

I put the last project I blogged about (Raceground) on hiatus. Instead I’m now working on a smaller project 2D mobile game. The plan is to check how viable the mobile game market is for me.

I started prototyping with Unity and soon ran to performance and scalability issues using the build-in systems (Tilemap etc). To battle those I would need to build custom systems for those anyway, so I again decided to move to just plain C++. The game is procedural so luckily I don’t need a dedicated editor. This time I tried to focus on building a game instead of starting building a game framework (entity systems, filesystems, other abstractions etc..) before actually working on the game itself.

To reduce boilerplate as much as possible and to make refactoring fast and easy, I don’t use C++ headers for my code. I have one .cpp file that is compiled which includes all other .cpp dependencies I have. Much of the game code resides in a single .cpp file which is now around 5000 lines long. I have a build.bat that just uses the MSVC compiler and only use Visual Studio for debugging purposes.

In my code I don’t use classes at all. Just plain structs and functions. I do use templated structs and functions for arrays. I don’t use STL at the moment. Basically, I only use dynamic or fixed array as a container, so I wrote support that myself. I avoid abstraction as much as possible and only do it when it clearly improves code readability and understanding. I do use third-party libraries such as SDL for windowing and input, stb_image for image loading, stb_truetype and fontstash for ASCII text rendering and bgfx for graphics.

This way has worked well for me, keep iteration time low and motivation up. Results come up fast and I don’t spend time thinking code structuring, abstractions, system refactoring or should the new class to be named XYZManager. At the moment, time to compile and run the game is much lower than script reload and play in current Unity!

Developing a casual racing simulator – Raceground

I’m car enthusiast and I just love the mechanical side, speed and sound of performance cars. I’ve been playing idea of building racing sim for over ten years! During that time, I’ve accumulated quite lot of experience in software development and have done many failed attempts too at games.

For the past two months, I’ve been building a custom game engine and ground work for the car game, and I have good feeling for this one, a casual racing sim which I’ve decided to call “Raceground” for now.

Goals for the car game

I have set couple goals for the game what it should be about.

  • Great audio and engine sounds.
    • I’ve actually prototyped with synthesized engine sounds that feel and sound promising to me!
    • For me, the sounds are 50% of the sim experience.
  • Fun and engaging tyre physics.
    • I’m not a physicist, so not going to target hyper-realism, but still trying to achieve plausible simulation.
    • Drift through corners and do epic burnouts!
  • Tweakable and tunable cars.
    • I feel that some of the best feelings come when getting the tune / tweak right for the car and blasting down the track!
    • Create RWD-Mini with 500hp turbo engine? Let’s do it!
  • Dynamic environment and atmosphere.
    • Set any time and weather.
  • Modding support.
    • Modding is huge in car / racing sim scene.
    • Give editor and tools for the community to tweak and add everything!
  • Great community.
    • Positive and enthusiastic community thrives!
  • Fast download and epic performance.
    • Although, I have fast internet, computer and plenty of disk space, I don’t like huge downloads and stuttering games.

Currently, I work on the game as side project along side my full-time job and with other life commitments, so the progress is quite slow. I hope to get some kind of early access release to be done at the end of this year, which could provide some funding to move to full-time development mode for the game.

Custom game engine?

At the beginning, I also evaluated both Unity and Unreal Engine for this project. I actually started prototyping the game using Unity at the beginning. Although those engines have many many upsides, they aren’t good fit for my project in my opinion. Mainly it comes down to these five things why I won’t go with Unity or Unreal:

  1. I just like building game engines.
  2.  Size / bloat of the development environment.
    • I still use laptop from 2013 which works fine as secondary development machine, but running Unity or Unreal just won’t work with that.
  3. Easy and unrestricted modding support.
    • Both Unreal and Unity supports modding, but you have to go trough the hoops for proper low-level modding support.
  4.  Performance and compatibility with older hardware.
    • I still use my old laptop from 2013 with integrated graphics card. I wan’t that to be the min spec’ed machine that can run the game 60FPS at low settings.
  5. Long-term stability
    • It’s gonna take a while to build the game. I don’t want the game engine to take direction I don’t see any value or future.

Btw, you can read some general thoughts about custom game engines in my previous blog post.

To the next post!

Lightmap baking on CPU using Embree and OpenImageDenoise

I wanted to have a portable lightmapper that is part of a custom map editor that I was building in C++. Thus I chose to build CPU powered lightmapper.

And to my amazement, it is really fast as OpenImageDenoise works like magic and the noisy CPU path tracer result gets smoothed out. The lightmapper is based on design described by the creator of Bakery-addon for Unity.

First, it creates the lightmap UV space GBuffer with multipass rendering to emulate conservative rasterization. Secondly, it offsets the sample position by raytracing from each sample position. It checks if the sample position resides inside geometry and offsets it to redure shadow leaks. Thirdly, using Embree it path traces from the sample positions and builds the lightmap. Finally, the lightmap is filtered using the OpenImageDenoiser.

The only downside is that the OpenImageDenoise is huge. The .dll takes around 45 megabytes (compared to my exe ~700KB). Anyway, I think it is worth having as it speeds up the path tracing result significantly. Here is a screenshot of preliminary result.

Denoised lightmap result in 20 seconds on Intel i7-5820k

Developing own custom game engine from scratch in 2021

Unreal Engine 5 is soon to be released with new groundbreaking features, Unity dark mode is finally free and Godot 4 plans to take over the indie gamedev community. Why as an indie dev, would you skip all of those (plus many other production-ready game engines) and build your own custom game engine in 2021?

Next, I go through some of the decision reasons of choosing between Unity / Unreal / Godot vs Custom Game Engine. Lastly, I go over the reasons why I did choose to build my own custom game engine for my game project.

When it is better to use Unity / Unreal / Godot?

  • The game will be a cross-platform game

Cross-platform is hard to get right even for seasoned developers as there are many moving blocks and undefined behavior. Most popular game engines are already tested and have built-in workaround for many issues.

  • You need proper content pipeline

If your game depends on or uses many imported 3D models and materials it is crucial to have working content pipeline. Content pipeline transform the imported 3D models and textures to game engine specific data format. If you want to import wide amount of different 3D model formats and have working texture compression, you might want to use off-the-shelf game engine.

  • You need to have realistic or next-gen graphics

As an indie, it would be hard to stay at the same levels or even bring a new game engine to the levels of current off-the-shelf game engines.

  • Game has to be build in the shortest time possible

It is hard to beat time-to-market with a custom engine. This doesn’t need any explanations.

  • You need to find people with existing skills to use the engine

When you bring new people to the team in the later stages of the game’s development, you will be better of when they would have experience from the game engine you are using.

  • Game is a mobile game that ships for Android

It’s pain in the ass to develop OpenGL ES for Android. Be prepared for graphics issues. There are so many different phones and OpenGL drivers with undefined or wrong behavior. I would chose proven game engine for mobile games (Unity / Defold).

  • You don’t have any specific or good reasoning for building a custom engine

Lastly, if you don’t find any good reasons business or game design wise to develop a game engine.

When it is viable to build a custom game engine?

  • You care about fine-tuning underlying technical side

You need to tinker the fine details to have the minimal possible game distribution size and achieve the best performance. When you have access to source code, you can customize or optimize the whole stack from raw input to rendering. This is also possible on off-the-self engine, if you have access to the engines source code.

  • Your needs are well known before building the game

You can estimate the features needed for the game engine to build the game. This way you can have rough estimate, how long it will take to build the engine. And how big of a job it is to build the game engine.

  • Your content pipeline is simple and limited

For example, if your game design allows you to stick with one 3D model format and exclude textures with alpha.

  • The game doesn’t require next-gen graphics

This is self-explanatory. Sometimes less is more.

  • You think the game development will take more than two years or you want to provide updates for the game many years after the game release

After starting to build with Unreal / Unity / Godot, those will receive updates and the upgrade process for your game can bring game breaking changes that would need reworking levels and/or game mechanics. I have seen this happen for AAA game.

Why I have chosen to build custom game engine for my gamedev project?

  • It has to achieve lowest possible network and input lag

I need to have full control over the rendering loop, present swapchain and also input polling to fine tune the input and network latency.

  • It has to be ultra-light and ultra-fast

I want the game to be small in distribution size, have ultra-fast start-up time and minimal loading times. Also the game performance should be excellent on low-end machines. I want the game to be non-intrusive, lightweight and accessible by people with low-end machines.

  • It has simple visuals

This is both a game design choice and it also enables us realistically to develop custom game engine. We believe that visuals are very important but highly-realistic or candy graphics distract the core gameplay. Simple visuals also means simple content pipeline and simple rendering engine for the game engine.

  • I want to provide the map editor for the community

Yes, you can also build map editor with Unreal / Unity / Godot. But this comes as a bonus while building the map editor for the engine. It brings a bit more extra work to polish the editor for external users but I think it is worth it.

  • I’m in it for the long term!

It is much easier to support future Windows versions and fix upcoming issues related to new hardware when I have control over the whole stack. If I would have chosen Unity or Unreal I would be stuck with the version we started to design with. If they would, for example, change the ray casting engine, physics engine, AI navigation engine or any core part of the engine in future versions, it could potentially change the gameplay drastically and to unwanted directions!

  • It is PC-only game

It easy to focus developing the game engine to support only single platform. By focusing on single platform, I miss the headache of developing cross-platform abstractions and separate implementations.

  • I’m software engineer first, game designer second.

In the end, I just like to tinker, read and develop things around new techniques and possibilities.

Sound and audio in competitive FPS game

Lately, I have been thinking sound design in my a multiplayer FPS game prototype.

Audio is very important in games. Sounds gives clues and reference about the current game situation and environment the listener is in. Both silence and high volume sounds have their places, but is important that the audio volume levels are correct.

In competitive FPS game, 3D positional audio plays important role when locating opponents. Headphones are must have to be competitive in multiplayer FPS game.

When working on the audio and sound design for my multiplayer FPS game, I take account the importance of audio occlusion, clues, directivity, effects and more.

Audio occlusion

Occlusion happens when there is physical obstacle (medium) between listener and audio source. Often the sound doesn’t completely get blocked because the sound either reflects from nearby walls which bounce the sound waves to the listener. Also lower frequency sound waves are good at traveling through mediums.

In games, audio occlusion test is often implemented using raycasting. Most likely a good estimation of audio occlusion is done by raycasting multiple lines from the listener to points near by the audio source. Path tracing can also be used to compute better reflection and realistic audio directivity.

In multiplayer FPS games, I argue that realistic audio directivity will cause confusion for the player. For example, gun shots or footstep audio should be seemed to be coming directly from the true audio source and not reflected from walls. Although it isn’t realistic, it is important from gameplay perspective to avoid confusing the player.

In my FPS game prototype, the audio occlusion implementation is still work-in-progress. Currently I use multiple raycast testing to define audio occlusion. The audio is simply low-pass filtered and reduced by volume depending on the obstace medium size.

Improving audio directivity with HRTF

For audio, I leverage OpenAL Soft audio library. It comes with an excellent HRTF (Head Related Transfer Function) implementation. In short, HRTF simulates how ears will hear the sound from a certain point in 3D world. Headphones has to be used when HRTF is enabled. With HRTF player gets much better immersion of the sound direction, especially on the up/down axis.

Minimizing input latency for games

I feel that input latency should be as minimal as possible. Input latency affects the game feel and is especially important when the game requires fast reactions, such as fast-paced multiplayer FPS game or racing sim.

I’m currently working on a project with custom game engine where low input latency is important. I take input latency seriously and do my best to minimize it. One part of minimizing input latency is to make the frame rendering as fast as possible.

How to minimize input latency

In order to minimize input latency, the game needs to postpone the frame’s input processing as late as possible before frame present. Also the game should only have single buffered present.

Naively by default, games use triple buffering. Triple buffering is best choice when smoothness and larger frametime budget is required. For example, when using single buffered present with 60hz screen, both the CPU and GPU must have computed the frame under 16.6ms to be ready for the next vblank.

When using double or triple buffering, both GPU and CPU have 16.6ms of time to process the frame, giving the best throughput with cost of additional latency. Thus single buffered rendering reduces the system parallelization. CPU has to wait for GPU to complete the present and then GPU has to wait for CPU to start pushing rendering commands.

In my current project, I use single buffered rendering. The game waits for GPU to complete present before processing input for next frame. This achieves theoretical input latency between 16.6ms – 33.2ms on 60hz refresh rate.