During this project, I ended up switching frequently between engine development and game code. On the engine side, I worked on systems like navmesh generation, funneling, a state stack, enum reflection, deletion, picking, and binary file handling. At the same time, I contributed to gameplay features such as enemies, breakable objects, and general bug fixing.
Since this was our first real opportunity to build our own engine, we were eager to implement as many interesting features as possible. In hindsight, that ambition led to a lack of clear scope and prioritization. As of writing this, Project 5 is still unfinished, which reflects how spread out our efforts became.
One of the more technically interesting features we developed was a custom funneling algorithm that works on 3D navmeshes. This made it possible to handle cases where paths overlap vertically—such as bridges—while still maintaining correct navigation. While I’m proud of the result, it took around three weeks to get working properly. In retrospect, that time might have been better spent improving more critical systems, like the rendering pipeline, which is still in a rough state.
I also implemented a form of enum reflection. It’s not a fully dynamic system and relies on preprocessor definitions, meaning enums have to be structured in a specific way. It was mainly built to support our editor, making it easier to expose enums, and it has been quite useful in practice. As for why we didn’t use an existing solution, I simply wasn’t aware of one at the time.
Overall, I’m proud of much of the work I did, especially where I had the time to focus on quality. At the same time, there are systems—like the 3D navmesh and funneling—that could be further optimized. Combined with time constraints, team illness, miscommunication, and unclear sprint goals, these challenges ultimately led to the project remaining unfinished.