Cheryl Engine is a modular C++ game engine designed to provide a reusable, extensible foundation for real-time graphics projects. The second major version represents a shift from incremental modification of an existing engine to a ground-up architectural redesign, driven by practical needs around modularity, compilation boundaries, asset management, and threading.
Earlier iterations evolved from a lightweight teaching engine, which proved valuable for rapid prototyping but imposed limitations around interfaces, input handling, and build workflow. Version 2 was conceived as a clean separation from that lineage, with the goal of building an engine whose structure could support multiple projects without repeated integration cost.
Architecture and Structure
The engine is divided into three primary libraries: glEngine, AssetFaculties, and GameFramework. Each library has a distinct responsibility and a clearly defined dependency boundary.
glEngine is a standalone rendering and application layer. It initializes the window and OpenGL context using GLFW, manages input callbacks, and provides a registration-based interface for update and draw execution. Runtime execution is split across three threads: update, render, and input polling, allowing input latency and frame progression to be managed independently.
AssetFaculties is responsible for all asset lifecycle management. Assets are allocated through centralized memory management and pooled by type to minimize allocation overhead. Loading is handled through dedicated loaders, after which assets are registered with a manager for later retrieval. Factories provide a clean interface for asset creation, while the AssetFaculties object itself acts as the integration point for allocation, loading, and lookup. Asset definitions are currently included in this library due to coupling requirements, a design decision identified as a future refactor target.
GameFramework serves as an architectural convenience layer. Rather than duplicating project scaffolding across applications, common structure is abstracted into a reusable framework that links rendering, assets, and input into a cohesive runtime. A modular system allows discrete GameModules to be attached to a central Game object, enabling projects to define lifecycle behavior through a consistent interface (Init, Deinit, Process, Update, PostProcess, Buffer, Draw).
Design Goals
Version 2 was driven by a clear set of objectives: modularizing the engine into independent libraries, supporting multi-threaded update and rendering, and building a generic asset system capable of handling textures, shaders, meshes, sprites, and game assets through a unified interface. Additional goals included automatic asset loading, directory-based asset registration, pooled allocation, and a framework flexible enough to support both 2D and 3D projects without structural changes.
Challenges and Outcomes
One of the primary challenges was managing header dependencies across interconnected systems. As the engine grew, circular dependencies emerged that required deliberate untangling. Generating documentation with Doxygen proved invaluable in visualizing include relationships and systematically eliminating redundant or implicit dependencies.
Another significant challenge involved asset creation and memory layout. Early implementations incorrectly initialized pooled assets as base types rather than derived types, leading to subtle runtime errors. Resolving this required a deeper understanding of object layout, pointer arithmetic, and allocation semantics in C++.
Despite these challenges, the core architecture stabilized and met its design goals. The asset system became fully generic and reusable, and projects no longer required recompiling the entire engine for small changes, eliminating costly rebuild cycles.
Results
Cheryl Engine v2 provides a clean, modular foundation for OpenGL-based projects, enabling new applications to be created quickly with minimal setup. Assets can be registered by directory, loaded automatically, and retrieved on demand without manual file management. The separation into libraries reduced compile-time coupling and improved iteration speed across projects.
While not presented as a finished or final engine, version 2 successfully established an extensible architecture that continues to support ongoing experimentation. Future versions are planned once additional experience is gained in procedural generation, larger game systems, and 3D workflows, but the current design remains a stable and productive foundation.
Hypermaze Prototype
Word Search with Threads
Shirly
Cheryl Engine
A* Pathfinding