Prune 2D Game Engine

A screenshot of the platformer scene type prototype in Prune. Multiple platforms, hazards, a spawn point and a character

Prune is a C++ 2D Game Engine where the game and editor exist within the same runtime. It is not trying to be a traditional engine where the editing happens in one mode and gameplay happens in another. The core goal is a play-and-build system where the editor is part of the runtime.

Prune has a shared editor shell. Different scene types reuse the main shell and then define their own behaviour, tools, panels, inspectors, object semantics, defaults and how to save their own data.

I pushed the initial commit to GitHub on the 2nd April 2026 and have been working on it steadily since then outside of my work and other commitments.

This is not my first attempt (Prune 2D) at building a 2D Game Engine in C++, I’ve tried a couple of times before; once from scratch and one using a template from The Cherno, a C++ YouTuber. Both previous attempts failed for the same reason, I leaned too far into building a general-purpose 2D game engine and all the required pieces, not what I needed and I didn’t even consider the editor.

Prune is different, this time the project has a clear purpose, I am building it for four reasons:

  • I have limited time to work on Prune. It is a hobby project so I need to be efficient with my time.
  • I want to improve my C++ knowledge.
  • I want to be able to build games with my children.
  • I want to create a system where the editor and runtime coexist.

The approach

My development approach is simple, I’m only plan a few phases each time, I’m always validating that everything works across of the game slices and I’m only developing the tools and features which are immediately useful to one or more game slices, or solve real UX problems.

The repository has an active record of what is happening, along with documentation explaining why decisions were, and were not made.

NOTES details what I will be working on in the short term and the goals for each phase.

DECISIONS is an ADR (Architecture Decision Record). The ADR details important decisions made during development. The most important entries are often why something is not eing done, along with the rationale behind it, these help me ground the project and retain focus.

The Goal

Prune has a specific goal which I have detailed above. The README includes a “Ready for users when…” section. My immediate larger goal is releasing a 0.x version of Prune, that section details what I need working before I consider the project ready for users at large.

I will blog more on Prune in the future, when I reach specific milestones, make important decisions or feel like explaining a more about the project.

I have not blogged for a few years, Prune felt like the right way to get started writing again.

REST API Tests

API Testing - White text on a blue background with multiple software based terms related to testing

If you review the tests for the Costs to Expect API, you will notice two things; I have a heavy preference for functional tests and I don’t tend to mock anything.

API tests and Mocking?

I don’t mock any services; I want my test environment to match my intended live environment as closely as possible. This means using all the services used by live, I want to know of integration issues prior to going live, all my API tests will run as though they were running on the live environment.

Additionally, my tests write data. They write data using the same system as live. If live writes to a MySQL database, so do all my API tests, I have never seen the point of using a different engine for testing, you are not testing like for like.

Functional tests

Most of my API tests are functional tests, they test a process. Unit tests are incredibly useful, but most of your tests should be functional or integration tests.

My goal with API testing is making sure everything works as expected for the user and any clients. Testing all the scenarios a user or client is likely to see, this means all the possible “400 errors”.

The unhappy path

We need to test the happy path but we should focus most of our effort on the unhappy path, this is where the awkward bugs lie and the bugs we didn’t find during development. In addition to testing the happy path, I include tests to validate the structure of data. I’m a massive fan of self-documenting APIs and include response tests which validate that the generated OPTIONS response matches what I expect.

My API action tests will include the expected, create, read, patch, and delete tests. They are not my priority, I create many more tests to ensure the correct validation messages are returned, ensuring parameters work as expected, testing where a user or client is likely to get stuck.

If there is a validation rule against a field, group of fields or some other explicit logic (PATCH body can’t be empty), I add a test to ensure it works as expected.

Postman collection vs local API tests

Up until recently, the API tests for the Costs to Expect API existed as a Postman collection. The collection worked until it didn’t. It is still a fantastic API monitor but as the scope of the API grew, it became painstakingly difficult to ensure the code and tests were inline, authoring tests is also tedious and slow with Postman.

I have/am moving everything local and testing with PHPUnit, I couldn’t be happier, tests can be tied to releases, I can run them without cost and although I’m still functionally testing, I’m not limited to setting some fixed input and testing only the generated output.