











Overview
// UE5 C++ — in-engine gameplay screenshot
C++ for Engines is a Level 5 solo module project (GDEV50010) at Staffordshire University, built entirely from a blank Unreal Engine 5 C++ project. No starter content, no framework to borrow from — just a blank slate and the task of constructing a fully working third-person action prototype, architectured around SOLID principles, Anonymous Modular Design (AMD), and a suite of industry-standard design patterns.
The prototype is a fast-paced, ability-driven action game inspired by X-Men Legends II: Rise of Apocalypse — mana-based spell casting, environmental destruction, and flight-style movement bursts — combined with a Giant Ball hazard enemy borrowed from Elden Ring's Silver Sphere. The player wields five distinct spells (Fire, Ice, Electric, Ice Spikes, Lightning Strike), engages Rotating Detection Turrets with a full state machine, and progresses through a world with Invisible Magic Path tiles, breakable objects, collectibles, and checkpoints.
Version control was maintained via a self-hosted Perforce depot (P4V, VPN over double-NAT on a personal PC) — a deliberate choice to mirror industry pipeline practice. All 146 C++ source files were written across 52 folders, covering audio, animation, components, enemies, gameplay, input, interactables, managers, Niagara VFX, player, save/load, UI, and a secondary TwinStick prototype mode.
Architecture
The entire project is built around Anonymous Modular Design (AMD) — a pattern where no class holds a direct dependency on another. All inter-system communication flows through a centralised UGameplayEvents bus (a UWorldSubsystem), which acts as the sole message router for the game. This eliminates spaghetti coupling and means any system can be added, removed, or replaced without touching anything else.
This approach means a Spell does not know the UI exists. A Breakable does not know the AudioSystem exists. The GiantBall does not know the camera shake system exists. Everything communicates anonymously through events.
Key architectural decisions:
Systems
// In-engine — system interaction 1
// In-engine — system interaction 2
// In-engine — system interaction 3
Design Patterns
Each pattern was documented in the forum thread with explicit C++ implementations, designer-friendly exposure, and contingency plans for when the pattern was not appropriate:
Gameplay
// Gameplay — mechanics in action
Engineering
Version Control
Rather than using Git, the project was managed with Perforce P4V — the VCS standard across AAA game studios. A personal Perforce server was self-hosted on a home PC with a VPN over double-NAT to create a secure remote depot. The depot was named CPPforEngines, workspace NomNom_CPPforEngines_WS, with a .p4ignore file configured to exclude UE5 intermediate build artefacts.
This was a deliberate engineering decision — the forum thread explicitly frames it as industry practice preparation, not just convenience. Self-hosting the server rather than using a service like Helix Teams mirrors the studio environment where teams manage their own P4 infrastructure.
Challenges
Roll / animation breakage — The original skeletal mesh had an extra bone absent from standard UE rigs, making animation retargeting impossible. The roll mechanic became a speedrunner glitch rather than a dodge. Ultimately cut.
HUD desyncs — Consecutive spell casts caused mana bar desync when events fired faster than the lerp completed. Fixed by always lerping toward the latest authoritative target value from AttributesComponent, not a cached local value.
Giant Ball overshoot — The Silver Sphere would continue charging past the player after collision. The charge state did not terminate on collision because the state machine transitioned only on a timer, not on an overlap event. Fixed by binding the reset to an OnCollision event that forcibly sets state to Recover.
HUD shake drift — Applying screen-space shake offsets without resetting the transform first caused incremental drift. Fixed by resetting to BaseTranslation before each shake tick.
Chunks not spawning — HUD chunk widgets were children of a Canvas Panel; grabbing them required the parent canvas reference, not the widget directly. A subtle UMG binding quirk that took considerable time to diagnose.