Project Postmortem

LDGE

Custom 2D Game Engine built with C++, SDL3, and Lua.

Lead Developer / Product Owner Team of 4 C++ SDL3 Lua

Overview

LDGE is a custom 2D game engine made to be as simple as conceivably possible. As a team of 4, we completed the project in about 3 months. The engine was written entirely in C++ using SDL3 as a foundation and Lua 5.4 for scripting integration. It was one of the most difficult projects I have ever been a part of and I am proud of the whole team's contributions.

My Contributions

I was the sole software architect, lead developer, and product owner for the project. Although I contributed across most of the engine, my primary ownership was over the entity runtime model, core game loop, scripting system, and rendering pipeline.

For the runtime model, I designed and implemented a simple ECS from scratch in C++. Each entity is assigned a unique ID, which serves as the main way to identify, reference, and manipulate objects across engine systems. That simplicity helped keep the engine straightforward and made it easier to connect gameplay logic, scripting, and engine-side data without adding unnecessary complexity.

A major part of my work was building the scripting system and the interface between Lua and the C++ engine. I set the system up so programmers could easily access and modify entity data through an entity's ID, which made gameplay iteration much faster and reduced friction when writing scripts. I also implemented the script lifecycle and event callback model, giving scripts A major part of my work was building the scripting system and the interface between Lua and the C++ engine. I set the system up so programmers could easily access and modify entity data through an entity's ID, which made gameplay iteration much faster and reduced friction when writing scripts. I also implemented the script lifecycle and event callback model, giving scripts clear entry points for initialization, per-frame behavior, and event-driven logic. In addition, I created the interfaces that allowed Lua scripts to call into C++ engine functionality, which formed the bridge between high-level gameplay code and low-level engine systems.

I also worked heavily on the rendering side of the engine. The rendering system was built using SDL3's 2D rendering tools, and I was responsible for integrating that into the engine in a way that matched the runtime and component model. This included handling how sprite data was tied to entities and ensuring the rendering path stayed simple, readable, and practical.

Beyond the individual systems, I was responsible for the broader architecture of the engine. I made the major technical decisions, broke the engine into manageable systems for the team, and helped define how those systems would interact. That meant balancing simplicity, usability, and scope throughout development so we could finish a functional custom engine in roughly three months.

What I Learned

This was my first (and will certainly not be my last) game engine project, the hardest part by far was the beginning. We were working on a tight timeline and I had a little less than a month to teach myself everything I could about engine architecture and break it down into digestible parts for my team. This "trial by fire" thought be a lot in the process. For one I gained a deeper understanding and appreciation for all lower level game systems. I've become fascinated by the little things, how a game manages objects, when and how games load data into memory, what custom tooling teams make to help with development, how games handle spatial audio, the small rendering tricks used to squeeze out just a couple for fps. I feel like this exploration has given me a broader foundation as a game programmer.

This project also taught me many lessons about leadership in dev teams. While rare, there were times that I didn't have a specific enough answer to my team's questions. Some of these were not things I could just synthesize on the fly, and while I wasn't able to answer them immediately I always made sure to research the topic further until I give the answer they needed. It's okay to have gaps in your knowledge, it's not okay to leave those gaps unaddressed.