
Emerald
​




About
Initially started during my coursework at SMU Guildhall, the Emerald Engine is my C++ engine written (almost) entirely from scratch for Windows games. Aside from a few libraries (fmod, tinyxml2, stb_image, and mikktspace) we were taught the theory and design behind major engine systems (input, game framework, event system, math library, dx11 renderer, 2D physics, dev console, networking, and other bits) and left to implement them as we saw fit with the occasional code review with our professors. I made multiple small games and tech demos in the engine and had the freedom to do a couple of self driven game projects where I chose to make an adventure game in the style of Monkey Island and a Diablo-style game using my own scripting language, Zephyr. Zephyr was my master's thesis project; a state-based, event-driven scripting language that could be reloaded at runtime and was integrated into my game framework to allow for entity gameplay logic to be implemented as data.
​
I continued the development of the engine in my spare time while working as an Engine Programmer at Splash Damage with work such as: converting entities to ECS, adding simple cylinder vs AABB3 3D physics (and refactoring my physics engine), refactoring how data files are parsed and managed, and adding more features to Zephyr scripts including a type system overhaul. Earlier, when adding engine types like Vec2, the type was explicitly added into the parser and VM which was not scalable when trying to expand with more new types. I've since redesigned the scripting engine code to use UserTypes (and a couple of built in types for VM functionality) which are variants that can hold arbitrary types defined in engine or game code. I've also integrated a memory manager I made for another project into the engine so that all Zephyr objects are automatically managed using a custom handle and pointer system. Along the way I've also done a bunch of smaller bug fixes, optimizations and refactors to make the language more stable and easier to use.
Engine and Tools
Personal Engine, C++
Development Time
Ongoing
Platform
PC
Projects
Starship

Starship is a single screen space shooter where the player pilots a space ship and fends off invading enemy ships while navigating an asteroid field.
​
New Tech: Basic game and engine framework with entities that update and render, an Input System with Xbox controller support, and OpenGL 1.0 triangle rendering.
Excerpt from InputSystem.cpp
Incursion

Incursion is a tile-based 2D tank shooter where the player fights enemy tanks and turrets across three distinct levels.
​
New Tech: Scrolling camera, texture and sprite animation support, tile vs entity and entity vs entity collision, FMOD sound integration, and a step-and-sample raytrace for enemy AI to detect walls and player.
Enemy Tank AI Code
Adventure

Adventure is a prototype for an action RPG with randomly generated maps using a variety of map generation rules.
​
New Tech: Dev Console, Event System, TinyXML2 parser integration for data-driven entity framework, procedural step based map generation. and mouse cursor support in Input System.
Map Generation Step Example
2D Physics Sandbox

The 2D Physics Sandbox is a demo to show off my 2D physics system. The system owns all colliders and rigid bodies in the game and updates them on the physics update step, which can tick at a different rate than the game.
​
New Tech: Disc and polygon rigid bodies and colliders, static, kinematic, and dynamic collision modes, friction and bounciness material parameters for colliders, GJK for polygon collisions, collision correction, linear and rotational impulses, collision layers, events on collision enter, leave and stay, triggers with enter, leave, and stay events, and support for scene affectors like gravity.
Collison Correction and Impulse Calculation
Doomenstein

Doomenstein is a 2.5D first-person shooter prototype in the style of Wolfenstein 3D and Doom.
​
New Tech: DX11 Renderer with support for 8 dynamic lights, shaders and a 3D perspective camera , debug renderer, multi-threaded job system, 8-direction billboarded sprites, raycast against cylinders and tiles, and a data driven tile map pipeline to draw maps in XML.
Raycast Against Entity (Cylinder)
Example Map Definition XML
Doomenstein Online

Doomenstein Online is the beginning of a networked multiplayer game extending the Doomenstein project. The most interesting work on this project was restructuring the game code to send messages from clients to servers instead of directly calling game methods from the clients.
​
The game currently works across LAN with up to 8 players, but networking across the internet and through NATs is still in progress.
​
New Tech: Server client game architecture, supporting both single player games with a single player client and authoritative server and networked games with a single authoritative server and multiple remote clients. TCP and UDP servers/clients, reliable UDP implemented with retry messages and acknowledgements, and basic prediction for movement.
Reliable UDP Example from NetworkingSystem.cpp
Post Mortem
What Went Well
-
Building the engine piece by piece with each new game helped to understand the problems that were being solved by each engine system.
-
Taking on a large C++ project with many different systems was a great experience in how to structure a large project and gain a deeper understanding of the language.
-
Working with data-driven game frameworks gave a new perspective on how game data can be authored.
What Went Wrong
-
Switching to a DX11 renderer from OpenGL required a ton of refactoring and some painful integration since another project was being developed using the engine simultaneously and needed to be updated with the new renderer.
-
For Doomenstein, the coordinate system for the game was changed to have the z-axis pointing up to more easily make the 2.5D game instead of having the z-axis pointing out of the screen like it had been in an earlier project. I found some code that had assumed z was always out of the screen which needed to be updated to handle the new coordinate system.
-
Implementing multiple threads in the engine's Job System added some new points of failure when threads try to access a shared resource, such as the dev console. Great care must be used when allowing threads to access other parts of the game engine.
What I Learned
-
There are many approaches to building an entity system, each with different pros and cons.
-
Data-driven game frameworks can be very powerful and allow for rapid iteration without recompiling any source code.
-
I've learned an immense amount about each of the engine systems I've implemented and how various game systems work together to make a game.