Back in August, I delivered my first technical talk virtually at RustConf 2020. The experience was a good step towards my desire to become confident about my public speaking skills as well as being able to deliver my knowledge about software development and Rust to a public audience. My talk gave an explanation about the Entity-Component-System architecture and how it was used in the Amethyst game engine. I was excited to share what I learned with others at RustConf and was happy to see that people found it helpful for their own learning. But I knew there was still a lot for me to learn: about Rust, Amethyst, and game development in general. The examples I set out in my talk were quite isolated and simple. And that was fine! The aim of my talk was for a beginner like me to share my knowledge and experience for people also starting out. But I needed to plan my next step in furthering my knowledge. That’s always been difficult for me, knowing “where to go from here”.
Shortly after RustConf, the maintainer of space_shooter_rs, an Amethyst showcase game, reached out to me. Carlo Supina had seen my talk on Amethyst and ECS and asked if I would be interested in collaborating on the game with him. At first I was uncertain if my knowledge about Amethyst and the Rust programming language would be enough to make a meaningful impact on the project. There were a few things that I thought would be problematic. The biggest ones being:
I have no significant experience with game development. How would I know if I could make good suggestions about making scalable code for a game? Amongst other things.
Rust isn’t my main programming language. Most of the code I’ve written for it has been for my own small projects.
My knowledge about using Amethyst was limited to what is shown in its Pong tutorial and what I had shared in my talk.
But I realized that doing this collaboration would give me the opportunity to work on these concerns I was having. Carlo also knew about the ins and outs of the code and knew what needed to be worked on. I could also tell that a lot of care and hardwork has been put into the project (check out that README!). It was clear there were a lot new things about Amethyst and Rust I could learn from him. Another nice thing about this was that there were only the two of us working on the project, so there’s freedom for us to make mistakes and learn from them.
I agreed to help out with refactoring the code for space_shooter_rs. Of course, as someone who was not at all familiar with the code it was hard knowing where to start.
Breaking down the work
One of the first things that was done to identify what needed to be worked on was putting together documents of the current state of the project and the ideal state we wanted to work towards. Carlo had put these together as a way to help give me a better overview of how the components, entities, and systems worked in space_shooter_rs. I was also invited to ask questions and make suggestions either inside the documents or over Discord.
I found it really helpful to discuss the documents over an audio call. This allowed us to quickly understand each other’s viewpoints on how something should be implemented while also jotting down more notes in these documents for future discussions. However, by the end of these discussions we always set a few weekly tasks that we could try doing outside of our regular commitments.
Managing tasks with GitHub issues
To help manage and track these tasks, I suggested we use GitHub issues. Even if it’s just the two of us, it helped establish a formal step in the contribution process. In these issues, I mimicked what I normally did when creating new issues/requests on the Mozilla Bugzilla tracker. This involved describing what the issue was about and what relevant code is involved. An example of this is the first issue I worked on as part of the refactoring effort for this project: which was replacing the
ExplosionComponent with a
I identified in this issue my reasoning for renaming the
ExplosionComponent to a
TimeLimitComponent. I also included a code snippet of what the component should look like, and also any files that might be relevant when implementing this. While something like this could have been easily communicated over Discord, I decided to take a more open approach to some of the decisions made while refactoring the code.
Breaking down components
One of the first refactoring tasks we identified was that the
Enemy components shared a lot similar attributes. I documented this problem in this issue. In summary, the
Spaceship (which was the entity the player controlled) and the
Enemy components shared duplicate pieces of data that could have been contained in separate components. An idea from ECS is to make objects as composable as possible:
Diagram breaking down the Spaceship and Enemy component’s attributes into the Motion2D component.
We have since introduced a number of new components that will allow entities to be much more composable:
What I’ve learned
Outside of the refactoring work, I was able to learn more about GitHub Actions. This allowed space_shooter_rs to have a basic continuous integration workflow for building the game on multiple platforms.
Refactoring collision systems
One of the bigger refactoring tasks was making collisions between two entities easier to manage. This was also the first place where I got to utilize Amethyst’s Event Channels. It was difficult to know where to begin with this, but I drew inspiration from a blog post called Event Chaining as a Decoupling Method in Entity-Component-System by Joël Lupien. I used this as a resource to guide my own implementation for using event channels. I also created a diagram to help visualize how I wanted to do this.
Diagram of using event chaining to manage collision systems.
I was able to implement my first approach on utilizing event channels to manage systems with the Amethyst game engine for this task.
The issue for refactoring the collision systems can be viewed here.
Creating the project mdBook
We agreed that documenting the game’s code as much as possible would be beneficial not only for ourselves as maintainers, but also potential new contributors. I spent some time learning how to set up mdBook for space_shooter_rs and also deploying the book to Github Pages.
There’s still a lot of work that needs to be done in this area, but it’s a good step towards effective documentation for space_shooter_rs. The book can be found at https://amethyst.github.io/space_shooter_rs/.
The issue for this can be viewed here.
Introduction to pixel art
Refactoring code can get tedious sometimes. It’s a good idea to take breaks every once in a while by playing around with something different. I was able to add a new “Blast size enhancer” item to space_shooter_rs. As the name describes, this item increases the size of the player’s projectiles for easier enemy hits.
Player’s spaceship using the new “blast enhancer item”.
This was also where I contributed my first piece of pixel art to a game. I’m not much of an artist and definitely don’t know a lot about creating beautiful pixel art, but I was pretty proud of my first attempt at a giant space-cannon-thing. I was able to do this with help from Carlo, who designed most of the space_shooter_rs artwork using a pixel art tool called Aseprite.
Spritesheet for “Blast size enhancer” item made with Aseprite”.
The issue for adding the “Blast size enhancer” item can be viewed here
There’s still a lot of work that needs to be done for space_shooter_rs. From refactoring code, adding an mdBook, writing tests, and introducing a CI workflow to the project, there’s several areas that need a lot of attention. But we were able to accomplish a lot in just a month. Some of the things that I’d like to focus on next are:
- Continue refactoring code
- Finish basic documentation for project’s code architecture
- Establish a way to write tests
Carlo also took some time to document his own experiences working on space_shooter_rs, which can be found here.