Jake Rogers

Welcome to my portfolio site! I am a Chicago-based programmer with a Master's degree in Computer Science. With my degree comes an emphasis on software development and strong interest in game development and computer graphics!

Here you can view some of my independent project work and accomplishments as a graduate student. More content will be added in the future!

Game Development

Game development is an amazing opportunity to combine so many technical disciplines into a single artistic expression. For me, there is no greater satisfaction than fully bringing the vision of a game to life!

Below are some noteworthy game development projects I have worked on.

Repulsor

Things get crazy in later levels with a high density of dangerous enemies. All enemy types are seen in the above image of level 29 "Cold Fusion".

In response to a request from a beta-tester, a small character customizer was implemented, allowing two-tone color control.

For my first publicly released game, Repulsor, I challenged myself to build a larger game in a short, focused time period by making use of strong up-front planning and time management.
Repulsor is a level-based action game rapidly developed in twelve days.

High-Speed, Iterative Physics Action

Repulsor is composed of thirty, very short and frantic levels where the player can only defeat enemies by pushing them them into hazards, or vice versa, or enemies into enemies!

Being a game heavily reliant on physics, the design leans into a very frantic style: the player is always moving, enemies are aggressive, and projectiles fly all over the place, and everything dies in one hit.

While Repulsor is very action-y, the extremely fast pace actually makes many gameplay scenarios too quick to reliably react to. This interestingly has the effect of requiring the player to plan out their route to beating a level ahead of time- eventually building up a strategy which can fully tackle the level (However, there is a limited slow-motion slide ability to help line up tricky maneuvers).

Persistent Data

This was my first project which made extensive use of persistent data. Levels needed to track high scores and the number of points earned per level, as the cumulative point count is used for unlocking more levels.

To store this persistent data, I coded an entire system for serializing level completion data, settings, unlocks, and customization. As an added piece, I also figured out how to make beta save files backwards compatible!

Godot Gridcannon

Gridcannon uses a 5x5 grid of card decks, where the outer ring is filled with enemies which are killed using decks in the inner rings.
A highlighting feature shows off valid decks for the next card (upper right) to go to.

In learning another engine, Godot (v3.5), I worked on recreating a unique card game designed by game developer Tom Scott, Gridcannon.

Card games can be surprisingly tricky to implement for a few reasons! They require a lot of input validation, complex state machines to match the many game states, and effects / transitions to guide player's attention. Many rules in card games can also be somewhat non-trivial to translate to code.

This project also featured a pretty hearty save system which would also double as an undo / buffer system. Saving information about where every card needs to go and the game state to a file was an interesting challenge to implement, as I wanted reloads to occur smoothly during gameplay without creating unnecessarily large files. I eventually managed to save everything in just 624 bytes!

This project is unfinished, though I would like to return to it or re-implement it in Godot v4 one day.

Independent Game Developers Organization (IGDO)

During my last semester of my masters program, I cofounded my university's game development club! This was an awesome opportunity to build a community of game developers for students to join, share their works in, and have an avenue to learn game development through.

As the Vice President of the club, I was responsible for community management, creation of club media, and creating and giving presentations on game development concepts. I also helped in planning the club's activities into the Summer and future semesters.

During this role, I also got a lot of experience managing open-source repositories during the creation of two collaborative projects, setting up project boards and branch protection schemes to ensure members could not accidentally make destructive or unfocused changes.

Game Developer's Library

One of the projects I headed in the IGDO was the website Game Developer's Library (GDL).

This site serves as a community-contributed source of video game development information. Any IGDO members are given the opportunity to create and add articles, guides, and tutorials about anything related to game dev, adding to our repository of knowledge that we can direct new users to.

The GDL is ran via GitHub pages and a docs framework called MkDocs, meaning that IGDO members can create articles on the page in a simple markdown format reviewed via GitHub pull requests. This means that the GDL not only serves as a knowledge base, but a low-stress opportunity to learn about open-source workflow- one of my favorite aspects of the project.

As part of staging the GDL, I also wrote heaps of articles on it to help out new developers getting into game development- primarily with Unity. I am very excited to see new contributions, and we already have some really interesting articles about Win32 graphics programming from one of our new officers!

The GDL is a publicly-visible site that anyone can check out! Click the link below to give it a look.

Computer Graphics

I have a particular passion for Computer Graphics, a CS field which employs tons of incredible tricks to produce combine artistic design and mathematics into awesome effects!

The projects labeled "RD" are implemented via a recreation of Dr. Duffin's RD_View rendering engine, which itself is heavily based off of Pixar's RenderMan specification. The recreation is written in C++ as part of the rendering course via Dr. Duffin's guidance. You can read more about the RD_View render engine at the link below.

Marching Cubes [RD]

A marching cube render of a data set with a single radial focus.

Two radial foci merging together

Three radial foci meeting together.

The Marching Cubes algorithm is a technique which generates an isosurface from a 3D field of scalar values. The isosurface created is a surface which straddles between data points in the field which transition across a particular threshold value.

Marching Cubes was originally developed for and saw much usage in the realm of medical imaging coupled with CT and MRI scans. By obtaining a 3D scalar field of densities within a scanned patient, an isosurface of particular tissue can be rendered by using the known density of the tissue in question. For example, doctors could create a isosurface of the patient's skeletal tissue from the scan to observe abnormalities.

RD_View Implementation

The algorithm itself involves evaluating each data point as a voxel whose edges could potentially indicate a threshold-transition across two points in the data. There are 256 possible shapes within each voxel depending on which edges possess a transition! My RD_View implementation only covers 180 of the 256 cases (which is why there are "holes" missing in parts of the surface), but this is enough to demonstrate the algorithm.

Smoothing

In order to increase the smoothness of the created isosurface, trilinear interpolation is used to ensure that each voxel's transition points are moved to the exact point of threshold-intersection within the data set (rather than at the middle of the voxel edge). This makes the resultant isosurface look less 'cubic'.

Furthermore, the gradient at any given isosurface point was calculated via bilinear interpolation across the surface, which can then be applied to the vertex normal to remove jagged edges and create a much smoother appearance.

Both of these smoothing features can be toggled on and off via command line options, as there may be some cases where smoothing is undesirable or obfuscates the observable data.

Bézier Curves [RD]

This waving flag is implemented via a textured bezier curve, whose control points are modulated by a scrolling sinusoidal function which gets stronger near the end of the flag.
Some random noise is also applied to the flag to make it look more natural, which is best seen by watching how the light scrolls along it (and observing the right-most edge of the flag).

In graphics, it is often desirable to model curved surfaces which appear remarkably smooth without having to explicitly place create thousands of vertices.

To achieve this, curves are often expressed as mathematical functions between points which are modulated via control points. This expression is seen in Bézier, NURBS, and B-Splines curves.

In RD_View, we implement Bézier curves as our curve solution, which allows curves to be rendered and modulated via at least three control points. The De Casteljau algorithm is leveraged to perform interpolation between the series of control points in order to find vertex positions across the 2D curve.

Further, a 3D Bézier Patch can be created by interpolating between two or more Bézier curves spanning the same direction, creating a very smooth, curved surface.

Particle Systems: Cannons [RD]


The animation above demonstrates a dynamic particle system demonstration created via the RD_View engine. It presents a scene of cannonballs flying through the air (followed by a motion-trail) and impacting the ground in a dramatic explosion of dirt and debris.

This particle system requires ticking hundreds of small particle elements with physically based movement updates each frame, and contains a large number of parameters to customize how their speed and momentum should be handled over time. It is worth noting that since RD_View is just a rendering engine, some custom physics tick needed to be implemented to handle object transformation over time.

One interesting thing to note is that all three of the dirt particle groups use the exact same movement behavior code, but are parameterized differently to create distinct effects.

  • Dust cloud (White): Particles expand in all directions uniformly, and have a high velocity dampening so they do not travel very far. Each particle is given a very slightly randomized speed to add variance.
  • Light Debris (Light Brown): These particles shoot out in the direction of the cannonball's reflection vector upon impact with the ground. A gaussian offset is added to said reflection vector (and their speeds) per-particle to create some variance in their motion paths. They have strong dampening (not as strong as the cloud), which causes them to suspend in air after the initial burst.
  • Heavy Debris (Dark Brown): These particles are similar to the light debris, but have much greater variance and very little dampening, giving them a heavier, more chaotic motion.

Get in Touch

Feel free to contact me through the following methods for any inquires, job opportunities, or questions about my projects!