Here is a strategy for time-poor working parents who are trying to learn new things: try to learn two new things at once. That’s what I did recently when trying to pick up a bit of Rust. For the uninitiated, Rust is a fairly new, relatively low-level “systems programming” language with an emphasis on speed and safety. I’ve been wanting to learn Rust for a while, and have been looking for a side project that could work as an excuse.
In my experience the subject of a side project, if you want it to be successful and to actually have a chance of finishing it or learning something from it, needs to be something you are passionately interested in (even if the passion is fleeting). I have lots of posts on this site with details about side projects related to my interests: elections, music, politics, emacs, mathematics. So for this project I chose another interest: cricket.
And here comes the second thing I wanted to learn: the ECS (Entity Component System) programming paradigm, commonly used in game development. So the project comes into shape: use Rust, and an ECS framework, to build a cricket simulator. Sounds like fun!
Initially I had thought to just build out a scoreboard that updates as you click through the deliveries of the game. This would definitely give me enough to work on, learning how to set up all the entities I need, the components, the systems that update the scoreboard. But I figured it would be a little boring to look at, so decided in the end to make a visualisation of the ground and even animate the ball being bowled, hit and fielded.
To do all of this, I used rltk, a game engine for Rust, originally designed for “Roguelikes”, a type of retro computer game with procedurally generated graphics and a “dungeon crawl” RPG mechanic. rltk provides a lot of very helpful structures to get you up and running; I just render a simple black square and use ASCII art to fill out my field, players, pitch, stumps and scoreboard.
Figure 1: The start of a new cricket match. |
At first I just hardcoded to make sure it rendered correctly. Then I set about replacing all of the things you see in the image above with entities, components and systems according to the ECS paradigm.
For example, there is a DisplayGlyph
component which contains the information required to display the correct symbol for a player (batsman, bowler, fielder, keeper, umpire). Then there’s the Position
component which describes where on the map to render the symbol. If you then insert an entity into the game, and populate it with components, you can define a display_system
to make sure the glyphs are rendered in their correct positions every loop.
Similarly, we have bowling_system
, batting_system
, fielding_system
which moves everything around the map according to logic, alongside the scoreboard_system
which updates the scoreboard and the match_system
which determines the ultimate winning logic and ends the game.
Figure 2: Through midwicket for 1 run. |
Overall this exercise was really fun and it taught me a lot about game development, ECS and in particular Rust. Rust feels really well suited to building games: its neat “structs”, cruel but fair type system and ingenious borrow checker are all very useful when you are writing code that needs to be performant and run every click. Writing a game also makes you think a lot harder about the loops you write, about data structures and memory and CPU efficiency. I enjoyed it a lot.
The code for this project is available on my Github.