Projects

Once Upon A ___

A game made for a week-long game jam. All programming done by me, and all writing and player animations were done by my partner for the jam. Once Upon A ___ is a narrative-focused puzzle platformer where you rewrite the Prince's story as you play. Rearrange sentences to solve puzzles and watch as the Prince's story unfolds before your eyes. This was a particularly fun game to work on because of the dynamic text. I had to figure out how to measure the text glyph sizes and manually position the text. I also had to figure out how to make a system that would let me set up logic gates for what objects should be visible or activated depending on the state of the game. I also had a single race condition that would only present itself in an official build and not in the editor :( The game at the end of the game jam had no animations, and no dynamic text spacing. All that work was done after at a slightly more leisurely pace. I'm currently working on adding a page turn animation made by capturing the last frame of the current level and rendering that onto a page-turn animation. I didn't want to do any actual 3D rendering in the game (yes, I know Unity 2D is just 3D but with a fixed camera but whatever) so I pre-rendered the UVs and lighting and use a shader to mix between the current level and next level. It actually works out really nicely, since I can use the R and G channels for UV coordinates as is standard. Then I can use the B channel to indicate whether it should use the current or next level, and the A channel stores the brightness multiplier for shading.

Click to play. You can also download the game from Itch.io
Very much in-progress demo of the page turn animation. Unfortunately due to Unity limitations it stutters a bit in the editor. In a proper build the stutter isn't present.

Nomai Pebble Watchface

This was just made purely for fun; I really like Outer Wilds (enough so that I've done a few speedruns of the game), and wanted to make a watchface that reflected that. I traced the Nomai mask from a game screenshot, and modeled the time display after the oxygen/fuel gauges in the suit's HUD

A GIF of the Nomai watchface
If you have a Pebble smartwatch, you can try out the face on the Rebble Appstore!

Bad Apple!! for the Pebble Smartwatch

This was a really fun project. The Pebble smartwatch is quite limited on space, the oldest model only allows 128KB of app resource files total, and all newer models allow 256KB. Of course I could just stream the animation from the phone and display it on thw watch, but where's the fun in that? I had to figure out how to fit 2,629 frames into that small space. At first I tried XORing each frame and run-length encoding the resulting data stream, but it was far too big still. After much experimenting, I eventually settled on encoding each frame as a quadtree, storing a 1 if the cell should be split into 4 or a 0 followed by a 1 for white and 0 for black. This afforded me enough granularity in the encoding that I could sacrifice some quality for the oldest platform and still fall under the 128KB limit. I've started working on the project again, some of the newer watches have a speaker so I wrote a MIDI parser and now it can play the song at the same time! I've also been experimenting with compressing the animation as a ZIP file, and decompressing it on the watch. The official DEFLATE spec (the compression algorithm I'm using for my ZIP files) dictates that data blocks can backreference blocks of data up to 32KB prior, which is simply infeasible to keep in memory on the Pebble. So now I'm currently experimenting with streaming a DEFLATE-compressed file with a custom backreference limit so I only have to hold ~2KB of data in memory while decompressing.

If you happen to have a Pebble smartwatch, you can install the app from the Rebble Appstore!

Crochet Stitch Counter

I made this because I learned how to crochet and wanted some way to keep track of my progress in the pattern. I made the initial prototype in Godot, then decided that the web builds for Godot were not suitable for anything that requires text input. So I switched to a purely web build. I had recently learned React and discovered that while it was nice to use as a dev, I really didn't like the... slowness of it. I foudn a lightweight reactive library called VanJS that provides basic data binding, and I re-write it using VanJS. I'm especially pleased with the system for saving and loading patterns from the URL, and the way it saves your progress in the background.

A GIF of the crochet counter in action
An example project, this is for a cat. You can try out the app here, or load the demo pattern here

Gartic Autodraw

A program that uses a greedy gradient-descent algorithm to draw ellipses, rectangles, and lines in the online Gartic Phone application to approximate an arbitrary target image.

Screenshot of Gartic Phone, with a drawing of Kirby in it
This is drawn by the program, drawn with a total of 750 different shapes

Crystal Forest

Made for Artistic Game Development I at WPI, this explores the use of stylised paint-stroke-like geometry. I made this by first modeling the base geometry in Blender, then making a procedural geometry nodes system to instantiate plans on the surface of the object for paint strokes. I also made a spritesheet of a few different paint strokes to use as an alpha matte, and I baked out low-resolution textures for each object that set the colour of each paint stroke. Using a custom shader, I set the alpha of the plane using the paint texture, and colour from the colour texture, using two different sets of UVs for each plane.

You can download the game to play for yourself on Source Code
A 3D render of a painterly-style tree
A test render of the style I was aiming for in the game demo

WPI Humanities Practicum

Exploration in art with light, using projection mapping onto a 3D-printed sculpture.

View the 3D rendered animation here

Haybaler

A game made in a few days for a WPI game development class.

Click to play. You can also download the game from Source Code

Color Tiles

This is a game recreated from the UNDERTALE colored tile puzzle.

Click to play. You can also download the game from Source Code

K-Means

Implements a simple K-means clustering algorithm to try to classify clusters of points. Currently increases the number of clusters based on a simple heuristic using the relative size of the largest and smallest clusters.

Click to try the demo

Inverse Kinematics

Implements an iterative 2D inverse kinematics algorithm to connect two targets with a linkage.

Click to try the demo

Get Canvas Assignments

Uses the public Canvas API to pull assignments into a checklist in a local Markdown file.

Screenshot of example output for the Canvas assignment project
This is an example output from the console, so you can see which assignments it's importing into the markdown file

Trim Video

Lightweight WPF application with an intuitive UI for quickly cutting video files to the desired length.

Screenshot of the trim video project
This is an example of the UI. The left window is the startup screen, the right window is the cutting UI

Convert Workday Class Schedule

Reads the data in an Excel file and creates an iCalendar file to easily import class schedules.

Screenshot of the Workday class coverter project
This is an example of the console output. The left window is the Excel spreadsheet, the right window is the console output, which reflects the contents of the generated iCalendar format

Parse Pearson Expressions

Uses context-free grammar structures to convert from a proprietary mathematical expression format to a more commonly used format.

Screenshot of the Workday class coverter project
This is an example of the console output. You can paste in the Pearson format, and it will output the general expression, as well as the calculated value