An engine the team could build on
Liberation Engine 2D is the custom C++ engine and editor developed for Disobey during SEP3–4. In a team of five, my contributions covered the ECS foundation, serialization and prefabs, asset management, editor windows and integration between engine subsystems. The engine and its authoring tools supported the team’s game development across two semesters.
Explicit dependencies as a team practice
The hardest engine challenge was helping the team adopt dependency injection throughout the codebase instead of relying on singletons. Dependencies are supplied explicitly to the objects that use them: the ECS world receives its timer, game and event system, while editor windows receive the world, asset manager and other services they need. This made dependencies visible in interfaces and supported clearer ownership and cleaner code. Getting everyone comfortable with that approach was as much a collaboration problem as an architectural one.
A typed ECS with runtime coordination
I built a templated ECS that expresses system requirements as component types. Variadic systems work with tuples of component pointers, while an abstract system interface lets the world coordinate different concrete systems. The world tracks entity signatures and component pools, defers entity deletion, and supports configurable system order, pause control and single-frame stepping.
One description for persistence and editing
The component metadata layer exposes member references and names through macros and tuples. Template-based traversal uses that information for JSON serialization and deserialization, while the inspector uses the same exposed members to select property controls. Registration supplies runtime callbacks for operations such as adding, removing and copying components. This connects typed C++ component definitions to general-purpose engine tools without writing a separate property list for each consumer.
Tools for authoring scenes
My editor work includes the scene hierarchy, resource browser and component inspector, alongside drag-and-drop workflows, gizmo integration and undo/redo. Entities can be inspected and edited, components added, and scenes saved and loaded. These tools made the framework useful for building and iterating on the team’s content.
Asset references, prefabs and projects
I implemented asset-manager work including the migration to UUID-based references and metadata files. Resource libraries and extension-specific callbacks connect asset identities to their loaders. Prefab serialization, entity cloning, scene persistence and project configuration provide reusable content definitions and a path from the editor to a separate game application.
Integration across engine boundaries
My contribution history also records renderer-to-ECS integration, sprite-sheet and bindless-texture integration, graphics pipeline layering, animation support and event-system work. These contributions joined subsystems into a usable engine; the rendering and other specialist subsystems were team work. Disobey’s gameplay contributions will be covered in its own project story.
What I learned
An architectural choice only helps a team when its members can use it confidently. Introducing dependency injection meant making service dependencies explicit and helping teammates work within that model. The project also showed the value of reusable component metadata: a common description can keep persistence and editing aligned as new components are added.