Acorn2D - A Custom Game Engine

This blog is going to introduce Acorn 2D, a game engine made by myself and Joshua Mobley. Acorn 2D is a custom engine built using C++ from scratch. It uses OpenGL for rendering and some other libraries for things like hot-reloading, math, logging, mod support, and profiling. The engine also has multiplayer support. Multiplayer was the last part we worked on so it still needs work in order to be easy to use.

For even more info, read Josh's blog about Acorn!

Why a Custom Engine?

I am usually against making anything custom when it comes to making games unless what you need to create cannot be made without any custom work. For indie development, this is definitely not something I would recommend. So why did we decide to make a custom engine? During our time at university, we were given an assignment where we had to make a game engine and then a game within this. When Josh started this assignment, I had already done it the year before. However, watching him work on this made us both want to see what we could create with more time. It was a learning opportunity for both of us. We decided to design a simple game and see how far we could get with a custom engine.

The Engine

Acorn 2D is set up using a static library. We have two other projects associated with the engine. Firstly, we have a game project which is linked to the engine. This is where we would work on the game and test any engine features. Secondly, we have a project which is used for our editor. This editor never really saw the light of day but it was fun to create.

The engine features sprite rendering (OpenGL), custom rendering layers, render axis ordering, an event system, logging, an animation system that supports layers and event, mod support using lua scripts, basic UI, scene management, hot-reloading for data types such as sprites, optional update loops for objects, and even multiplayer.

Below is a video that showcases small pieces of Acorn 2D:


Tools Used

For Acorn2D, we have used a few libraries to help us get to the right path. We would be crazy if we tried to do everything ourselves so we didn't.

Aixlog

Aixlog is a C++ logging library that we used to make our console neat. It helps us append stack traces to make it easier to see where things have gone or right. It is a simple library and is quite efficient. Below is an example of what our logs look like with our configuration:

Tracy

Tracy is a realtime profiler that we used to figure out our performance issues. Using Tracy, we can add manual "ZoneScopes" into our code which defines a starting point for a new profiling sample. This, combined with the GUI provided made it super efficient to visually see where we could improve code. Josh used this a lot when he was writing the renderer.

Sol2

Josh wanted mod support from the start. We both agreed that if our game's resources were data driven and the engine had custom hooks for scripting, anyone could make the game awesome. He decided to use Sol2 which is a C++ wrapper for lua. This allows us to expose our engine to lua and allow users to write their own scripts.

The game engine searches for any lua scripts when starting up and applies them to the game. Josh made it so that every hook combines which means you could technically write libraries for other modders to use. All lua scripts can be hot-reloaded which means you can change them while the game is running. This is a great feature for modding as it allows you to test things without restarting the game.

Steam Networking

Steam is our primary use for networking. This uses steam networking sockets to send messages between the client and the server. For test project, we had movement, the generation, and the health of trees networked. This means that destroying a tree would also destroy it for other players.

Protobufs

Protobufs was used to serialize any data including network packages. This made is super simple for the game and engine to know what messages were without having to include a shared project. With the use of protobufs, we could also have made lua scripts accessible to networking, allowing modders to sync their content between players.

Other

Above were the main external libraries used. We obviously still had to write our own implementation for most of them since a library doesn't do all the work for you. However, besides those, we also used a few minor parts such as GLFW, GLM, Freetype, and ImGui.

My Contributions

I have talked a lot about Acorn, but what exactly did I do? This is a two man operation so we have given each other input on most parts, sometimes teaming up. However, below are my main contributions:

  • Event system.
  • Input.
  • Scene management. Although this was later a joined effort to resolve bugs.
  • Timer manager. This includes being able to call code in x time.
  • 2D physics.
  • Animation system with layers and animation events.
  • Acorn Editor.
  • Game design for test project and gameplay, including main menu, the player, trees, island generation, the inventory, interaction, items, and the chest.
  • Basic UI system.

What's Next?

Acorn2D is an engine that we worked on quite a while ago and as of today, it currently has not received any updates for months. This is because our focus has shifted to other projects. Although we loved working on this engine, I doubt that we will continue too much. It was a fun learning experience and we ended up with a solid engine. We may revisit this in the future, but for now, we are focusing on other projects.