top of page
GithubIcon.png

Custom Game Engine / Cuphead Recreation

Role

Programmer

Description

This project was a semester long project during my second to last semester in graduate school at FIEA. 

I was tasked to create a game engine from scratch in C++. This game engine had to be data driven and the engine had to be able to parse a custom format of JSON to allow users to create games with ease.

To do so, I created runtime polymorphic data structures, with the help of RTTI (Runtime Type Information), with an in depth readable API that focused on ease of use, with easy to manage ownership/responsibility.

To make sure everything ran the way I designed it to, I constructed a multitude of unit tests and made sure they all passed and that I wasn't leaking any memory.

Year

2024

Language

C++

Platform

Windows PC

Team Size

Custom Game Engine: Solo Dev

Cuphead Recreation: 8 other programmers

Custom Game Engine

Datum
 

The heart of the game engine. Datums are a homogenous, runtime polymorphic data container. They can store one of multiple supported types but once a user enters an object of a certain type into a new datum, that datum remains a container of that type. Types include: Int, String, Float, glm::vec4, glm::mat4, a Pointer to an RTTI Instance, and a Pointer to a Scope (Table).

Datums are also resizable and work much like how an std::Vector works. They may also wrap an object themselves, therefore owning that memory, or wrap a reference to an object, leaving the something else to deal with the memory of that object.

Scope
 

Scope objects are tables that create a dictionary of name-value pairs where Datum objects are the values and strings are used as the names.


Scopes are tables of Datum, some of which can be other tables (i.e. Scopes). Each Scope has a pointer to its parent, therefore forming a tree of Scopes.

Scopes are how my game engine organizes Game Objects into an effective, readable format.

Attributed
 

Attributed is an abstract child class of Scope. Attributed allows classes that inherit from it to be able to create "Attributes" or "Signatures" that basically are named Datums that wrap their member variables.

They serve as a bridge between C++ variables and Scopes and establish a clean two-way binding system between the two.

Game Object
 

Game Object is a child class of Attributed. It contains a transform variable to keep track of each object in world space, and a name. Each Game Object can have child Game Objects and child Actions associated with it.

 

Every Game Object contains an Update() function that gets called every "GameTime"  second and recursively calls the Update() function of each of it's children. Game Objects are very handy for implementing game logic.

Action
 

An Action is another Attributed child class that live in Game Objects. They are basically the gameplay elements that occur when a condition is reached or on Update(). They operate on Datums owned by their parent Game Object.

There are child classes of Action that include, ActionList, ActionListWhile, and ActionIncrement. Each helping users to better organize and use Actions.

Parse Coordinator
 

The Parse Coordinator is what enables users to use script-based game development within my game engine. Using the Chain-of-Command design pattern and the Factory pattern, it parses JSON data (using the JsonCpp library) to initialize and create Game Objects and their respective Actions using Handlers that can handle certain types of data.

Event
 

An Event is a class that uses the Observer pattern. It notifies all of it's Event Subscribers when to do something. This is particularly useful for notifying certain Actions that should only trigger when some specific condition(s) is/are met.

I also created an Event Publisher that handles the notifying of all event's contained within it. Additionally, I included the functionality of a "do once" option to Events that make it so that Event will only get notified once and then removed from the Event Publisher until manually inserted again.

Cuphead Boss Fight Clone

GithubIcon.png

Full playthrough of our clone

This is a group project using a conglomerated version of multiple programmer's (9), including my, custom game engines. We implemented OpenGL within our combined game engine to then recreate a Cuphead boss fight from scratch using assets we got in the game files. I was personally in charge of creating the sprite sheets for, and implementing the VFX and Post Process effect. I was also in charge of implementing Gamepad Controller support to the game, which made our game a lot more playable.

This project was created in a little under 2 weeks.

Post Process Fragment Shader
 

Using Shader Programming, Texture Multiplication, and Vector Math. I managed to faithfully recreate the post process old cinema effect from Cuphead.

This code takes into account the amount of frames in the post process sprite sheet to be able to play the animation for the effect and apply the blending to each frame with the game scene's current frame.

bottom of page