Portfolio – The Death of Stars


Overview

This was an experimental, “minimalist” project that I made solo in two days. The core game concept involved jumping between foreground/background layers, navigating through odd structures and parallax scrolling obstacles. I also experimented with various visual effects – my goal was to have all assets generated at runtime and let effects bring them to life.

I build around 15 minutes of gameplay. I originally prepared many gameplay elements in case gameplay became stale, but I was surprised at the variety of obstacles and levels I was able to create with few tools. I believe it was the lack of classical obstacles like moving objects, jump boosts, and others that led to the minimalist appeal of the game.

Adding to the mysterious atmosphere, I designed the music to be strikingly unique. The music consists nearly entirely of a single grand piano, playing at a consistently fast speed. I also used a strange time signature – the music follows 4 measures of 12/8 time and is then followed by one measure of 6/8 time, making it hard to “keep your footing” with the music, especially without any grounding percussion or bass to keep track of the beat.


Programming this beast was a lot of fun, as I finally got to experiment with many of the visual effects I wanted to try out. I personally dislike using Gamemaker’s built-in libraries as they tend to not integrate well with my designs, so I developed everything from scratch.

Fundamentals

This image shows a basic line in Gamemaker studio, which is, rather unfortunately, as boring as you may expect. So, the plan is to add some kind of “glow” to the line, which Gamemaker does not support. However, Gamemaker does support transparency, so let’s try drawing many lines to attempt to “emulate” glow.

This is much better, but is not quite there. It looks more or less like a solid line with a cloud over it, so let’s try to make the base line more “fuzzy”. We will instead draw multiple lines with low transparency.

This looks pretty close to want we want. We will need to keep in mind that this function is quite expensive, so we will make sure to limit the amount of lines that will be drawn to the screen.

Now to handle collisions. My plan was for all structures to be built out of these lines, including background and foreground layers (both of which will have collision). I really dislike Gamemaker’s built in physics engine, so here we will make our own. Each line has a normal angle, determined by which angle it has when it is placed in the editor. We will classify lines as either walls, floors, or ceilings dependent solely on this angle, this distinction is important as it will determine which actions the player can take (e.g. the player can wall jump off of walls, but not ceilings).

As you can see, I calculate multiple variables all at once so that during gameplay, collision is calculated much more efficiently. The code for collision is quite complex, but essentially, it will calculate if the player is inside the line, and if it is, push the player to the boundary of the line determined by the type of line it is. It will also give the player certain permissions (like wall jump, ability to jump, etc.). There are a lot of cases to consider, such as corners, steep floors, and more, so I made sure to test and bugfix my code often.

Mechanics

For the player, I drew simple body and head sprites, these are some of the few assets that are not generated at runtime. To give the head fluid movement, it is given a “focus point” that it moves towards via an exponential function – the farther away it is from the focus point, the faster it will move. This is also how the camera functions, the camera move towards a focus point determined by the player’s position.

The main mechanic of the game is the “parallax layers” – there are multiple parallax layers of lines that the player has to navigate through. These layers are quite interesting – the lines never move, but instead, the location they are drawn at changes. 

Our draw function only needs the endpoints of the line. We draw the vector from the player to the real endpoints of the line, and scale them by a constant amount. This has the effect of making all lines on a specific layer scaled, and imitates parallax scrolling. This makes building gameplay much easier, as we can place obstacles normally, and they will be drawn properly during runtime.

Visual Effects

I implemented all effects with “intensity” values to determine how often or large the effect is, this makes effects easy to tune and also allows for certain effects to be more intense in time. All lines flicker in when the player approaches, and flicker out when the player is far away. Lines also flicker slightly at random, the chance lines have to flicker each frame is determined by the intensity. These effects are quite simple, there is a routine (here, a “timeline”) that when triggered on an object, toggles the object’s transparency in a regular manner.

Later in the game, the player is given the ability to transform for 4 seconds at a time, and we add a kind of “splitting” effect. When this effect is active, every line is split into three different lines that shift every 20 frames. The most straightforward way to do this is to choose three random points on the line, shift them slightly horizontally or vertically depending on the type of the line, and then draw all three lines.

The problem is, points can be quite close together, which can make the effect look a bit ugly. So, when choosing random points, we will make sure each segment is at least a certain length. It is also a bit disruptive to not be able to see the underlying line. Our effect only changes how the lines are drawn, not collision, so we also draw the underlying line at a lower image alpha. Below is what ended up in the final game.

The final effect in the game is quite interesting. There is a global angle and radius variable for this effect. When a line is drawn, it draws duplicate lines at distances equal to the global radius and translated in the direction of the global angle. The global angle is changed at a constant rate, and the radius increases over time to make the effect more intense. 

Overall, the game came out well! This game ended up winning the game jam, and I also won the gameplay/mechanics and audio categories. I always like to push myself in all of my projects, and I’m quite proud of what I managed to accomplish in just two days.