Personal Blog

Development, gaming, programming,

ideas, thoughts and more!

Building and creating video games (and software) is hard. How hard? It can be a difficult thing to describe and understand. The public perception, at least in my eyes, appears to fall onto one of two perceptions; That software is complex and basically magic or that of being incognizant of the hidden workings of the software behind the interface. I often get asked, "So how do you actually make games? How do you make things that appear on the screen". The real answer to this requires thousands of hours of knowledge, study and understanding across multiple disciplines. In simple terms though the answer really is mathematics and logic combined with physics and electronics. Many years of very smart people building technology and layers of systems and mechanics combining to where we are today, able to make incredible 3D simulations with highly detailed graphics and interaction.


"Why does this crappy game keep crashing?", "Why is this software broken?".


These are common questions, and frustrating when you are an end user. Unfortunately, like vehicles, infrastructure and other complex technology, software is no different in that it can have faults, deteriorate over time and just flat out break.


I think it can be hard to comprehend just how complex software can be. Why is it so hard to make X or do Y?


Building a complex video game is like contracting a skyscraper: Hundreds of thousands of moving parts, millions of interactions and connections, safety mechanisms, backup systems, hundreds of different feature requirements and aspects, you get the point. Software and games also have some other fun parts to consider. Video games are built and compiled from source code into machine code (at least in compiled languages such as C++) using software that itself has millions of lines of code and is also running on more software (your operating system) which itself is communicating and working on top of the hardware of your computer which has its own low level mechanisms and features. Programming does not exist in the physical space (at least in the general perspective, compared to traditional engineering), which means anything can interact with almost anything else. To compare, that is like every wall being able to touch and connect with every other wall in your skyscraper, as well as your wires, plumbing, flooring, air vents and everything else. Changing one small thing like the carpet in your 5th floor could accidentally break the door to the bathroom on the 50th floor. Of course traditional engineering has it's own difficulties and I am not saying a game is more difficult to make than a sky scraper; not even close. But the idea is that software is in the same vein of complexity and likely has a lot more happening that you might realise.


You can create software from nothing which can be a great benefit, unlike traditional engineering. Although this means more people making software and very low requirement for entry versus if you were an engineer or architect, you'd need tools, resources, money and usually a whole team. This results in a lot more software being made by people with a lot less knowledge, care, or planning.


Because of the lack of resource requirements (material wise), and the ability for software to be adjusted and changed (relatively) easily, at least compared to traditional engineering, simple projects can scale up to massive ones. This means it is far more common to have a project that ends up far out of scope and design that was originally intended, which contributes to having more bugs and more unforeseen outcomes / problems etc.


Bad software (usually) won't cause harm or death to users, whereas bad engineering absolutely can. Thus the restrictions, policies, safety checks and rigidity of traditional engineering is much higher compared to software.


Another fun aspect of software is that it is equivalent to basically creating an entire skyscraper, with all of these layers of complexities, and then shipping that skyscraper to someone's location and placing it there, relying on their foundations, environment and supports to make sure it works. Every end users PC is different: Different hardware, different operating systems, different software, different versions, different internet connections, the list goes on. Traditional engineering would create a product designed specifically for a scenario (specific city, location, environment, setup, requirements etc.) but that just can't be done realistically with software. Of course there are exceptions to this but the idea is there. It doesn't help that a lot of software is cheap (or free) and easily accessible (online) so many people will try to run software or games that their system can't even handle. Then they complain that the product is terrible, when it is like shipping a skyscraper into the desert with no support and wondering why it doesn't survive.


There are so many variables, so many layers of technology, so many moving parts and complexities that it shouldn't be too surprising when every now and then your program crashes, or lags, or displays some information correctly. Technology is complex and the layers we have built to allow for the creation of things is unbelievable. None the less, we as humans clearly have the capability to create unbelievably complex systems with fail-safes and methods to stop problems occurring, and we should strive to make things that never break, or if they do, to fix themselves quickly without resulting in any damage of inconvenience. There are always two sides to the story. With every complex bug that only occurs on one guy's pc who hasn't got a graphics card nor updated his software in 5 years, there's a story of simple typo in an obvious place from a neglecting programmer that causes everyone to crash on startup. Software needs to get better and become more reliable, and people need to become more understanding and aware. After-all, we as programmers don't want you to crash and have a bad experience!


Next time your software crashes or game bugs out, have a think and appreciate the skyscraper (both as the analogy and as a metaphor) of complex code that is running behind the scenes to make that thing tick!

Updated: Mar 21

How I created a strange design pattern and how it proved to be so incredibly useful.

Like many amazing finds or new things, this particular solution came from a tricky problem. To understand the issue best, I have created a small diagram below that shows a simplified hierarchy of the action classes:

*This diagram is not an actual representation of the classes, it just demonstrates the basic idea.

As you can see at the bottom of the hierarchy, a particular action has 3 classes (a shared implementation and then child classes for both the server and client specific code). This means the client and server implementations derive from a common base and it is easy to write common code for both as well as functionality for client / server using either separate calls or virtual functions that are overridden. Above these leaf classes we have many parent classes that handle various different functionalities.

The issue here, which is actually a relatively common issue, is this:

What happens when we need one of the parent class functionalities to have common server or client code? It would look like this:

Ah, the classic diamond inheritance; Both the shared implementation and the server or client specific parent need to derive from the classes above, because their callbacks and variables rely on that information. I guess you could draw the diagram with the connection either how it is (with Fireball a child of Projectile Client) or Fireball Client as a child of Projectile Client. Either way, the issue is the same (the client has ambiguous parent classes). What we need is for Fireball to have derive from Projectile Client, but only on the actual client (because otherwise Fireball Server will be trying to derive from a class that it doesn't know about.

In the past, the solution has just been to put virtual functions in the shared implementation and then for each child that needs to, will implement the functionality themselves. This is especially annoying though when there are many classes and/or when the implementation is almost identical. Bonus annoyance if there is a lot of code for the implementation(s).

So we solved this by coming up with the idea of what we called 'template parent insertion'. I am sure there must be a formal name for this but I have not been able to find it (let me know if you know!). At first glance it appears very similar to The Curiously Recurring Template Pattern (CRTP), but in reality it is quite different, and is actually solving a different problem.

So how does it work? First of all, here is a diagram to help explain:

*I will attach some source code below to complement this diagram.

Basically the idea is that the shared class (Fireball in this case) is a template class which derives from the template itself, The child classes derive from this and pass in the class that they want Fireball to inherit from, via the template. Hence why, at the time, we sort of called it 'template insertion'; because it allows you to stick a class in-between. The server or client can insert different classes to each other, or one can insert a class and the other doesn't need to, which provides a great design for class hierarchies like this where we have a separate client and server implementation with a shared base.

Pitfalls:

The main issues I faced with this design is compiling with GCC on Linux. Firstly, in the base class (in this case Fireball), when referencing functions or members from the parent class (the template class), I had to always use this-> or it would be a compilation error. The other issue, in the same scenario but for template functions called from members or functions from the parent class, I had to always use the following syntax:

this->GetObject().template GetComponent< Health >();

Instead of:

GetObject().GetComponent< Health >();

Details of this issue can be read here.

So there it is, a relatively nice solution to a common problem. Although I'm sure in most situations you are better off rethinking your design such as trying to use free standing helper functions, or creating a separate implementation that doesn't derive from the Projectile, or even just using regular composition (storing a member that handles the specific implementation that can't be in shared code). For myself and the situation I had, this proved to be the easiest method to achieve what I needed, so maybe it will prove useful for others too. Programming has infinite possibilities and there is no perfect solution to everything. What is important though, is having as many patterns, tricks, designs and knowledge as possible to construct the best possible solution you can for a particular problem!

Example source code available here.


I have started work on a new game! I recently bought Super Motherload for quite cheap and played it through. Super Motherload is a Steam release sequal to the original free Miniclip game Motherload. There was also a paid version called Motherload Goldium which is now bundled with Super Motherload. They are all great games, with the latest being mostly a reskinned version of the original (new graphics, different characters) but also with some small new puzzles and things. It is surprising how addictive and enjoyable the game loop of these games is. The simple game loop works as follow:

- Mining down to get ores / resources

- Returning to the surface to sell them

- Purchase new upgrades in order to go deeper

- Repeat

The game limits you by having a fuel tank that must be refuelled and a hull damage meter. The joy of going further down into the ground and finding new rare ores and resources, which in turn allow you to upgrade your vehicle, is really fun and is very similar to the "Mine" in "Minecraft". Exploration is the key here, finding new places and being rewarded for your effort.

After playing Super Motherload I thought that the game was good, but had the possibility of being so much more. Firstly I did not like that the level is limited in width (you cannot go past a certain value left or right, which is wider than your screen). I also was not a huge fan of the puzzle elements involving the various bombs. I enjoyed them, but when a large percent of the best ores was gated behind puzzles I quickly got bored of them. There was just too many puzzles everywhere which made them less interesting. Lastly I am not a story kind of person and so I didn't really enjoy that the game just ends after killing the final boss, although it was quite fun and challenging. I would of preferred further potential for game-play without just replaying it the exact same with a different character.

For this game I would like to incorporate combat, as well as fog of war. I am also messing with the idea of a mode where you have a tower defence element on the surface, but I am not sure about this just yet.

I have also decided to use Unity to create this game. Two main factors contributed to this decision: Firstly, I used c# for my last project (rock climbing training app) and I really enjoyed it. It is such a nice break from c++ without memory management and dealing with libraries and includes etc. Secondly, after working for quite a while on my 2D engine with SFML, I felt like I wanted to focus more on the game development side as opposed to engine development. It took a huge amount of time to get the engine up to a usable level and even still, it is far from good and full of features. Implementing the smallest things would just take so much time, partially because I was focusing on optimisation and the design so significantly. Unity also has the bonus of being able to ship to multiple platforms, having a great community, having endless features and is also another great skill to add to my knowledge base.


© Alex Denford, 2021