Engineered a database backend with SQLite, enabling designers to easily add new shop items and balance data without direct engine interaction.
Built a Python 3 tool allowing designers to convert CSV data from Google Sheets into SQLite format, streamlining development of new shop items.
Implemented the full UI system in Godot using GDScript, including a modular shop screen with dynamically created pinballs and board components.
Prototyped a programmatically-driven animation where the player's current pinballs slide down an adjustable spline path, created by utilizing a teammate's custom command pattern tool.
Developed debug tools for the shop screen, accelerating debugging by allowing designers to preview what items would look like in the shop.
Responsible for creation of the SQLite database and its integration in engine using the godot-sqlite wrapper, as well as the database reader script for use by the rest of the team. This database underpinned much of the game's functionality and made it trivial for designers to create new items, or tweak existing variables like how many points a pinball is worth or how heavy it is, simply by editing the corresponding table.
Integrated BBCode rich text labels into the database, so that text with BBCode tags could be parsed and displayed correctly when displayed in engine. This change added an incredible amount of readability to the item descriptions, and overall added a lot of flare to the shop.
Built an in-engine GUI to add pinballs and query data during early SQLite integration; later deprecated during content production, but extremely valuable for debugging item retrieval in the shop.
Learned Python 3 to develop a specialized tool used to convert item and pinball data from CSVs into the SQLite database, saving days of manual work and ensuring consistency. Improved usability by turning it into a double-click executable, added support for features like variable type preservation, and documented the workflow for the team.
Developed a shop debug tool that integrated SQL queries with the game’s shop system, allowing designers and programmers to fetch items or pinballs by unique ID from the database and instantly instantiate them in the shop for testing.
Designed a data-driven item creation system for the shop screen. The system would query the SQLite database for random items of a certain rarity, and convert that data into prefabricated UI nodes. This proved to be an efficient and very computationally performant way to create new shop items.
Developed a feature for the shop that would display the player's current pinballs and the ones for sale by having them slide down a chute. The UI utilized an adjustable Path2D converted into motion by a series of actions created through code. Cut from the final project due to a reduction in scope, but this design philosophy proved to be extremely flexible and able to be adjusted quickly by designers.
Collaborated with a teammate who developed a custom action list system (command pattern–based sequence of actions which can block or delay other actions). Leveraged this tool extensively while working with the UI to creatively to deliver features with smooth animations and dynamic interactions.
I'd love the chance to use SQLite more. This was a shorter game project than I'm used to, only lasting about four months, and the team was able to get everything out of the technology that we needed for the basics of this game. I was completely new to SQL going into this project, but simple operations like adding/removing rows or retrieving all data from a column were simple to learn and implement within a week or two. However, in the future I want to try and experiment with some of SQLite's more complex features -- for example, storing each item's texture directly in the database as a BLOB (Binary Large Object), or storing Godot callable functions in the database to alter an items' function without hardcoding it.
During this project, I struggled with balancing my workload and motivation in my senior year of college. I was still able to put in the amount of work required by the team, but I was personally unhappy and would have loved to put more flare into the game's UX. The experience taught me the importance of time management, task prioritization, and maintaining sustainable work habits — lessons I consistently apply to ensure steady contributions and avoid burnout.
Implemented the main menu, options menu, pause menu, scoreboard, and HUD in a back-and-forth collaboration with the UX Designer, balancing juicy UX aesthetics with technical feasibility within sprint constraints.
Integrated Wwise into Unreal Engine alongside the Audio Engineer, crafting a dynamic sound manager to handle music and SFX events with precision.
Built a modular, flexible UI framework in Unreal Engine using Blueprints, streamlining iteration and debugging for all in-game widgets.
Empowered the UI Artist and UI/UX Designer by mentoring them on Unreal Motion Graphics, distributing implementation duties, and accelerating development.
Developed a lightweight CSV parser to efficiently serialize and deserialize saved high scores, powering a scoreboard widget that enhances the competitive high score design pillar of the game.
Designed a stack-based UI controller to manage all interactable game UI. The system provided an easy framework for widgets to communicate with each other as well as other actors in the scene. The architecture proved very useful for the other programmers and designers, and streamlined UI/UX development.
Implemented full support for the options menu (including Video, Audio, Accessibility, and Controls). Built a system for saving and reverting options changes, integrated with a game singleton to adjust Unreal Engine settings based on player preferences.
Programmed several dynamic assets for the in-game HUD, such as score popups, an expanding smart pistol reticle, dash bars, the Slimetime progress bar, and item pickup fanfare. Designed these assets to include adjustable variables and animations, empowering the UX designer to fine-tune visual effects while ensuring clarity in fast-paced gameplay.
Collaborated with the team's audio Engineer to implement Wwise audio middleware into Unreal Engine. Using Wwise functionality let the team get much more ambitious with dynamic sound effects & music that adapt to the player's actions. For instance, background music can get more intense as the player picks up speed, and smoothly transition between area themes without any audio distortions like stuttering or pop-in.
Designed a sound manager system as an interface to use Wwise events through Blueprint code. This solved the problem of SFX code being scattered throughout code by organizing all Wwise function calls into one place and exposing functions that other programmers on the team to use. Abstracting code like this also made it so the audio engineer didn't have to check multiple files out of source control at a time to edit the game's sound design -- freeing up those files for the tech team to work on, increasing development speed.
Mentored the tech team in use of the sound manager by creating a short slideshow. The slideshow illustrated how Wwise events are imported into Unreal, as well as how the sound manager works and how they were expected to interface with it. The entire slideshow is viewable though my blog post: Calling Wwise Events in Unreal.
Engineered the backend architecture for the game's scoreboard, which tracks and displays completion times. This system handled writing player names and times to a local CSV file, sorting the top ten results, then reading the data back in to dynamically create UI widgets for each entry.
Developed a custom CSV reader tailored to this project's needs, providing a more flexible alternative to existing Unreal Blueprint CSV plugins. This method proved a very user-friendly and valuable tool for the UI/UX strike team, streamlining scoreboard development and iteration.
Participated in regular meetings with our team of 6 programmers, leading weekly code reviews, discussing progress on the game, and evaluating current goals for the sprint. This brought the tech team closer together, resulting in a better understanding of where the game stood and what tasks needed to be completed week-by-week.
Directed the UI/UX strike team, coordinating tasks between the UX designer and artist to ensure efficient workflow and continuous iteration on all UI elements.
Worked closely with the art and design leads, ensuring that in-progress prototypes of the UI met both aesthetic and functional requirements. I also had the privilege of collaborating with the UR specialist to revise and iterate the in-game UI according to eye tracking and playtesting data.
Implemented the FMOD core library into the custom engine, utilizing C++ functionality to refactor my old implementation and make the game more performant.
Built a UI system backend using OpenGL allowing buttons to trigger callbacks and send custom signals upon interaction.
Scripted custom behaviors in Lua managing all in-game UI, such as the main menu, options menu, and HUD.
Designed and edited JSON data files to customize the deserialized level states and menu layouts.
Implemented the FreeType software library to render text with custom fonts efficiently, creating high-quality programmatically generated typefaces in game.
Shroom & Doom's engine was built in C++ entirely from the ground up, with no starting framework or supplemental libraries. Myself and the rest of the tech team were given free reign as to how we wanted the architecture to be laid out, and we collectively agreed on creating an Entity Component System similar to Unity's.
All four programmers on the team were each given certain engine functionality to implement, and I chose to take control of the Sound System, UI system, and Text system. Half of the development time, around 4 months, was dedicated to the team programming & debugging engine features.
When all was said and done, the ECS engine utilized OpenGL for rendering, FreeType for rendering text, FMOD for sound, the Lua language for scripted component behavior, and JSON for entity de-serialization and storage.
In this project I had to build the entire system underpinning UI rendering, collision, and game logic -- and make the whole thing fit cohesively into the engine, AND make it work with the OpenGL library, which I had never used before this point. Sounds simple, right? Luckily by this point in development the engine had been given a custom Signal System similar to Godot. I used signals extensively in the UI system, emitting one whenever the mouse entered/exited a button's Axis Aligned Bounding Box to trigger modular logic in observers. This proved a very effective way of decoupling UI logic from game logic.
One of the parts of this project I'm the most proud of is my custom Text Rendering System built using the FreeType library. It's what we used for dynamic rendering of 90% of in-game text, using open-licensed typefaces. It was my first time using this library, but once everything was implemented the team was able to quickly display any UI text we wanted in game, without having to bake it into a texture first. I also took the initiative to implement the OpenDyslexic typeface into the game using TrueType, which dramatically enhanced the game's accessibility while being relatively easy to implement.
I had experience working with the FMOD sound library during Palette Knight's development, so I chose to implement similar architecture in this project to speed up development time. However I had to refactor all existing code to make the switch from C to C++, as well as accounting for the ECS engine's capabilities and file layout. For more information about this refactoring process, I go in detail with my blog post: Upgrading an FMOD-based Sound System.
One issue that the team faced early in development was: how to get Lua behavior scripts to interface with the C++ engine's backend? To accomplish this I had to program the Sound System with a data driven interface; i.e. the Lua files could call an Invoke function with abstract JSON data, which would be read by the system and converted into the correct function and arguments in C++.
Another way I improved on my earlier implementation of the Sound System was utilizing FMOD's channel group functionality. I go more in depth on this in the previously-mentioned blog post, but basically, I wanted a way to give sounds the property of being "fire-and-forget", or being "remembered". If a sound is remembered that means you can check the status of if it's playing and how long it has left, dramatically decreasing sound bugs for the entirety of the project.
Developed the main menu gamestate, as well as transitions between play and options states within the game engine's state machine.
Created reusable, modular button objects with flexable behaviors for use across the main menu and pause screen.
Implemented the FMOD core library into the custom engine, enabling efficient loading and playing of sound effects, as well as streaming music tracks directly from a file.
Took on sprite art responsibilities for level tiles, stepping up as the primary artist in the absence of a dedicated art team.