In the summer of 2019, I had very recently started learning Rust and was looking for a project to work on in order to improve my Rust programming skills. I ended up deciding on making a game. I started searching for game engines using Rust and came across the arewegameyet website where I discovered the Amethyst game engine. Amethyst uses the entity, component, system (ECS) paradigm to organize data and logic. At the time my only prior game development experience was with Unity, Pygame, and LÖVE2D, so ECS was very new to me. However, despite my unfamiliarity with ECS, I ended up deciding to use the Amethyst game engine to make my game, currently called space_shooter_rs.
One of my favorite games of all time is The Binding of Isaac. To put the game simply, the player progresses through a series of floors each composed of a maze of rooms containing enemies. At the end of the maze there is a boss which the player must defeat before progressing to the next floor. Most of these rooms contain enemies, which the player can defeat by shooting with tears. On each floor there is an item room and a shop room where the player can collect items. When items are collected, the rules of the game are permanently modified for the rest of the run. Some of the items are simple stat upgrades, such as increasing the damage or fire rate of tears. Other items affect different parts of the game such as giving the player vision of each floor’s maze, modifying prices in shops, or allowing the player to see through walls. As I have worked on space_shooter_rs, I have frequently drawn inspiration from The Binding of Isaac.
The first thing that I wanted to implement in space_shooter_rs was a satisfying way to shoot at enemies. This is one of the many things that The Binding of Isaac does really well. In particular, in The Binding of Isaac, the velocity of shot tears are influenced by the velocity of the player who is firing the tear. This makes firing shots a lot more interesting than just pressing a fire button. It also creates a much higher skill capacity for shot accuracy which contributes to making the game more fun and replayable. In this commit to space_shooter_rs, I changed the blast firing to factor in the player’s velocity.
Since then the project has also gained a collision system:
“Barrel roll” active ability (with cooldown bar):
An item store with 12 items:
4 consumable drops:
A WIP boss:
Also, 3 enemies, an ally, a level phase system, sounds effects, animations, status bars, and 3D background objects.
Most of the front facing features in space_shooter_rs listed above were added in 2019. Around 2020 progress made on the project drastically slowed down to making no progress at all. This was in part due to other commitments I had, however, I attribute this more to the disorganization of the project. There were many days when I wanted to spend an evening working on a feature for the game, but soon after I would open the space_shooter_rs code to work on it, I would become overwhelmed and confused. I typically would end up not adding anything. This was very frustrating for me because I had a lot of cool ideas that I really wanted to add to the game. The state of the project was preventing me from adding the features that I wanted, and if I did add a new feature it would only dig a deeper grave for the game because the code for the feature would compound onto the already disorganized code.
Fast-forward to August of 2020 when an all online Rustconf is happening. When the speaker lineup was released, I looked over the topics people were covering and immediately noticed that Micah Tigley @tigleym was going to do a talk on her experience with ECS and the Amethyst Game Engine. After Rustconf, all of the talks were uploaded onto Youtube. This is where I watched Micah’s talk: “My First Rust Project: Creating a Roguelike with Amethyst”.
In the talk, she covers her experience learning ECS and Amethyst, how she implemented animations, and gives a great explanation of what ECS is. After I watched this talk, I was inspired to try working on space_shooter_rs again. I ran into the same frustrating roadblocks as before. This is when I began considering reaching out to Micah. She seemed like someone who enjoys working on games in their free time, had industry experience working at Mozilla, and seemed like someone that I could learn a lot from. I ended up reaching out to her to see if she was interested in teaming up with me to work on space_shooter_rs. She responded saying that she was interested, and since then we have worked on space_shooter_rs together for about a month.
For the past month Micah and I have been making regular contributions to space_shooter_rs mostly focused on refactoring code to conform more to ECS. Most of these refactors consist of dividing a single large component that is very specific to a particular type of entity into many smaller components that can be used in many different entities. For example, previously, I created a single component called “Spaceship” containing data for the entity’s hitbox, health, blaster, motion, etc. In this past month, we have divided this single large Spaceship component into a HealthComponent, Motion2DComponent, Hitbox2DComponent, BlasterComponent, and ManualFireComponent.
Since beginning our work together on space_shooter_rs, we have also added a few enhancements to the game. One of the issues that I worked on was refactoring the hitbox data used across many entities into its own dedicated hitbox component. After I was satisfied with the new Hitbox2DComponet, I implemented collision detection between rotated hitboxes using the separating axis theorem (SAT). In the future, this will allow us to add more interesting enemies such as missiles that rotate to face and home in on the player. I also currently give a rotated hitbox to the arms of the repeater boss, which spawns in the last phase of the game.
Micah added a new item that increases the visual size and hitbox size of blasts. When the item is acquired, it increases the scale of the blasts’ Transform component and increases the width and height dimensions of the blasts’ HitboxComponent.
Besides contributing to the game code itself, Micah has taught me a lot about collaborative coding practices using tools like git and Github. In the past I have done some collaborative projects, but they have always had some level of disorganization due to me not knowing about tools, or not effectively using tools to aid in collaborative programming. One very important thing that Micah brought to the project was a formal method of writing issues, making feature/development branches, making pull requests, and doing code reviews before merging. After just a week of working with Micah, I added her as a maintainer for space_shooter_rs. I could tell that she was serious about working on the project, so I didn’t see any harm in elevating her privileges. This gave her the ability to manage issues and pull requests without having to go through me. Which in turn allowed me to pick up on what she was doing and start doing it myself. The general process is the following:
Keep in mind the general process listed above is currently what we use between us both being maintainers of space_shooter_rs. When making a contribution to a project you are not directly involved with, you cannot have the expectation that your pull request will necessarily be accepted. This is why it is a good idea to let the maintainers of the project know your intentions by submitting an issue before working on a contribution.
Having started working on this game more than a year before Micah joined the project, I have had a lot of time to think about the structure and features that I want to include in the game. Now that there was another person working on the game, it was important that I get these ideas out of my head and into documents, so that we can be on the same page, and so that I can get a second opinion on the ideas. Since Micah joined the project, we have made many documents for logging ideas down. The first document I created was about the current state of the game. This document mainly contained an outline of the entities, components, and systems in the game. This was meant to help Micah navigate the already large and somewhat disorganized project. The next document I created was called the “Ideal State” document. At the time of creating this document, I already knew that large components had to be broken down into smaller ones, but this document was for logging exactly what smaller components I thought we needed at the time. Later as Micah became more familiar with the project, this document turned into a place where we can share ideas about features we think would be cool in space_shooter_rs. I think it has been very healthy for this project to have a place where collaborators can casually throw ideas around without needing to go through a formal issue filing process. The last document that I’ll mention here is our minimum viable product (MVP) specification. In this document we created two MVPs, one for space_shooter_rs as a public showcase game for Amethyst, and the second MVP for a potential release of a full game built off of the foundation of space_shooter_rs. Below is a rough outline of our current MVP for space_shooter_rs as a showcase game.
A couple weeks into Micah contributing to the game, I realized that I had a basic idea for the structure and flow of the game in my head that I hadn’t yet shared with her. Even though we are still pretty far from being at a point where we will be working on the game’s progression, I think it is still important to get all collaborators on the same page. This way we can start exchanging feedback and ideas now. I created a game progression flowchart that used basic flow logic to describe how a player would progress through the levels of the game. Here is a section of it as an example.
We also used drawings to share ideas on refactoring code. For example, Micah created a flow diagram to explain how event chaining would be used to manage collisions.
This diagram was very useful for me to reference when reviewing her code so I had an idea of what her intent was when making the contribution. This diagram will also be helpful for future contributors to the space_shooter_rs project when working on collision based features.
space_shooter_rs still has a long way to go before reaching the point that we specified in the showcase game MVP. We still have a lot more refactoring to do and we still have a lot of new features that we want to add after that. This project has made a lot of progress this month after I teamed up with Micah, and I’m excited to see where this game ends up in the future. Micah has also written about her own experience working on space_shooter_rs, you can find it here.