FYNiX: Unmasking the Modern Game Engine
Clicking "Add Component" in a modern game engine hides a massive amount of complexity. Behind every clean user interface sits a terrifying labyrinth of manual memory boundaries, coordinate math, and strict graphics pipeline states.
I built FYNiX completely from scratch in C++ to step outside the safety of pre-built tools and master these core systems. What began as an aggressive 10-day challenge to display a basic 3D scene evolved into a rigorous two-sprint software engineering project. Developed across two hyper-focused periods—the first laying down graphics, skeletal animation, and physics fundamentals (July 13 to September 1, 2025), and the second introducing a highly parallel, multithreaded engine runtime along with a deep performance audit (June 8 to June 15, 2026)—FYNiX became my ultimate low-level coding playground.
The OpenGL Buffer Trench & Graphics Pipeline
When you build an engine without a pre-made wrapper, you quickly realize how much work goes into drawing even a single object on screen.
Rendering in FYNiX is driven by raw, direct OpenGL. I built custom C++ wrappers around graphics buffers to push 3D shapes to the graphics card without leaking system memory. During a performance audit in the second sprint, I resolved state leaks where graphics buffers weren't unbinding cleanly, causing rendering glitches. I also optimized the pipeline by shifting heavy coordinate transformations from the graphics card back to the CPU, pre-calculating light-reflection math only when an object moves. To prevent texture conflicts on complex models, the engine drives a strict slot manager that dynamically assigns texture units and flushes them immediately post-render.
Designing the Scene Hierarchy & Physics Sync
A real-time simulation needs a rigid layout, or the code quickly collapses into chaos.
I architected a modular Entity-Component System (ECS) alongside a proper parent-child Scene Graph. In early builds, the engine operated on a flat list of items; moving a parent folder didn't move its children. Worse, finding an item in the scene required scanning the entire dataset one-by-one. I redesigned this into a true top-down hierarchy where movements cascade naturally down to child objects. I also replaced sequential searches with a fast lookup table, reducing node queries to O(1) access.
To bring the world to life, I integrated the Bullet Physics library to handle real-time collisions. Initially, running physics alongside rendering led to severe lag. I fixed this by implementing a synchronization layer that locks visual objects directly to their physical collision bodies. To prevent high-speed objects from clipping through walls during frame drops, I clamped the physics simulation to a strict fixed-timestep update cycle.
CPU-Driven Skeletal Animations
Loading static 3D models is a start, but breathing life into a fully rigged character is a massive challenge.
Using the Assimp asset pipeline, I built support for skeletal meshes. A rigged model is a hierarchy of joints, each exerting weighted influence over surrounding mesh vertices. The animation system recursively traverses the bone hierarchy, interpolates keyframes using linear interpolation and quaternion slerp, blends bone transformations on the CPU, and ships the final matrices to the graphics pipeline in a streamlined update pass.
The Concurrency Core: Lock-Free Task Scheduling
As the engine grew, animation updates, particle simulation, physics synchronization, and asset loading began competing for execution time on the main thread. To eliminate these bottlenecks, I designed a multithreaded job system powered by a lock-free MPMC scheduler.
The scheduler is built around a Vyukov-style ring buffer and engineered to minimize synchronization overhead:
* Preventing Core Conflicts: Isolated producer and consumer queue state into separate cache lines using memory alignment boundaries, preventing false sharing and cache-line contention between CPU cores. * Simplifying the Math: Enforced power-of-two queue capacities, replacing expensive modulo operations in the hot path with fast bitwise masking. * Asynchronous Chunking: Built a custom parallelization framework that automatically partitions large workloads such as particle simulation and skeletal animation blending across worker threads. * Background Processing: Moved asset loading, particle updates, animation evaluation, and portions of physics processing away from the primary render thread.
The performance gains were substantial. In micro-benchmarks processing 100,000 independent tasks, the lock-free scheduler completed execution in 32.6ms compared to 410ms for a mutex-protected queue implementation, reducing scheduling overhead by roughly 92%.
Custom Serialization & Stress Testing
An engine is only as useful as its tooling. Hardcoding positions in C++ and recompiling to visualize simple changes is painfully slow.
I integrated ImGui to build an interactive editor viewport where I can tweak physics properties, lighting parameters, particle counts, and engine settings in real time. To persist these edits, I wrote a custom serialization system that recursively traverses the scene hierarchy and stores engine state inside a readable .fynx scene format.
To validate architectural stability, I stress-tested the engine with 900,000 active particles, 24 simultaneously animated skeletal models, and 8 dynamic lights. By offloading file loading to background workers and parallelizing expensive calculations through the lock-free concurrency core, FYNiX maintains a stable 144 FPS target on consumer hardware.
Below are some highlights of the engine in action (the GIFs appear choppy due to recording constraints, but the engine itself runs at a locked 144 FPS).