Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

The list of what I'd change are practically endless, but here are some of the first things that come to mind:

1.  Make modifications to my Entity Component System:
When profiling my application on the CPU side, I found that the time it takes to "submit" entities to be rendered takes up a significant portion of time. Instead of iterating over ALL entities and checking if they can be rendered I would add a callback function for when components are added to entities. That way, when a render component is added to an entity I can implement some sort of listener to add that specific "Render Component" to a vector. Now when I make render submissions, I would iterate over the vector of Render Components as opposed to iterating through all entities and checking if they are valid to render every frame.

Another great addition would be cache friendliness, the first technique that comes to mind is spatial locality for components. There is a high probability that if a specific component type is accessed, other neighbor components of that type will be accessed in the near future (for example, we iterate through all SkeletalAnimationComponents to process bone transforms). By grouping component types in contiguous memory, it will reduce the number of cache misses. In other words, copying a block of memory after a cache miss will improve access speed for subsequent components of that type.

2. Make the engine more flexible:
Initially, the engine was designed to use OpenGL ONLY.  At a certain point down the road I thought "wouldn't it be nice to maybe try out DirectX or Vulkan?" I obviously couldn't without subjecting my code to some serious changes. If I had to go back and change that, I would add and API that takes advantage of interfaces/pure virtual classes. This would allow each graphics library to have its own implementation of my custom-defined interfaces which would allow us to switch between graphics libraries easily.  Take the class "VertexBuffer.h" for example. I'd imagine that the way DirectX and Vulkan make you define vertex layouts differ from OpenGL. To combat this I would add an IVertexBuffer class (interface) which could have any number of implementations. With that, I could now switch between graphics APIs very simply. Note that this is just ONE example of how I could use interfaces in my engine, there are plenty more opportunities to use this.

3. Error handling:
This one is pretty obvious, but as it currently stands I have little to no error handling, or even warnings when an error takes place for that matter. Adding something like this would make debugging significantly easier.

4. Implementing sound into the game:
Even though my demo is generally visually appealing, the atmosphere doesn't feel as immersive without sound. Adding some ambient noise, footsteps, sword swooshes, etc would be a massive help to making the game feel better.

5. Spatial partitioning:
As it stands, my only form of "graphical performance enhancement" is frustum culling. This reduces the amount of draw calls that needs to be made by "getting rid" of the things the camera can't see, but what if the game world is massive? Doing frustum culling in a massive world can be very problematic due to the sheer amount of iterations you'd have to do over every renderable "thing" in the game world, thus causing a slow down on the CPU. To combat this, we could divide our game world into smaller regions. With the game world now divided into regions, we can find the region that the player currently resides in, and only do the culling in the regions we specify, thus reducing the amount of iterations. Now obviously this would make almost zero difference in my demo because the world is so small, but as someone who is developing an "engine" this is definitely something I have put some thought into. 

Non technical stuff:
1. The tech stuff is great, but it's also important to consider the non-technical stuff. The thing that immediately jumps at me is how much time I spent and the procedural dungeon generation. I spent a great deal of time messing around trying to get my dungeon to generate in 3 dimensions. If I were to settle on a more simplistic rendition of that earlier I would have been able to implement some more interesting game mechanics like AI.

2. Another huge time sink was finding assets and making my level. Even though it's generally simple, the time it took to collect all of the necessary assets and actually make the level was around 3 days. I feel that I should have took some of that time to implement one of the technical features above.

Honorable mentions:
One thing you'll notice in my code is that I use no smart pointers. I know that everyone has a different opinion on the relevance of smart pointers, but for me I feel that there is a time and place for both. Obviously if you are trying to squeeze the absolute most performance out of an application, using raw pointers will reduce overhead by a small amount. On the other hand, I can totally see how in a larger project, memory management becomes an extremely daunting task, thus making smart pointers a great option.

Anyways, I'll leave it at that for now, I don't want to write my entire autobiography here haha. On the other hand, if you'd like some more examples/improvements, I'd be happy to provide them.