Intro

My initial idea was to design a simplified version of Hotline Miami with these milestones:

Leveraging my familiarity with Unreal Engine, I could easily realize these features in the UE5 environment where most development tools are built-in. However, I was curious about the prospect of independently implementing many of these tools. Consequently, I expanded and enriched the existing code base while endeavouring to maintain its core.

For a more comprehensive understanding of my development journey, I've attached the development journal. This document was consistently updated throughout the entire process, offering detailed descriptions of nearly all the features I implemented.

Dev Journal

Here I will provide all the implementations I’ve done through the project, as well as thoughts and complications I’ve encountered while developing.

Sorting the Billboards

In the current project state, the programmer has no control over the order of billboards - we cannot specify which billboard should be rendered above the others, and which - below. To solve this issue, I introduced the DrawPriority field for Shaders. Now, the Renderables map is sorted based on the following logic:

struct ShaderComparator
{
	bool operator()(const IShader* lhs, const IShader* rhs) const
	{
		return lhs->GetDrawPriority() < rhs->GetDrawPriority();
	}

};

std::map<IShader*, std::list<IRenderable*>, ShaderComparator > Renderables;

UPD: After a couple of days I found out, that the following code might provide interesting errors:

Result = new DirectX11Shader(Context, VertexShader, PixelShader, InputLayout, TextureIn, DrawPriority);
Renderables.insert(std::pair<IShader*, std::list<IRenderable*> >(Result, std::list<IRenderable*>()));

Here (given the comparator I provided earlier) C++ might make an interesting assumption. If we have shader A with DrawPriority X and shader B with the same Draw Priority, C++ will decide that they are equal, because both A < B and B < A is false. In this scenario, it will just override the values, resulting in losing some of the textures on the level. To fix this issue, I had to add some changes to the comparator:

struct ShaderComparator
{
	bool operator()(const IShader* lhs, const IShader* rhs) const
	{
		if (lhs->GetDrawPriority() == rhs->GetDrawPriority())
		{
			return lhs < rhs;
		}
		return lhs->GetDrawPriority() < rhs->GetDrawPriority();
	}

};

Flipping the texture horizontally