back

rainy cloud - post mortem

2022/10/29

Thoughts about an adventure to write a game in Rust.

After being in development on and off since 2019 rainy cloud - a game written in Rust for practice by a friend of mine and me - is finally done. As so often, what was originally thought of as a "short project to gather some experience" turned out to be a several year long marathon...

This post mainly serves as a reminder to myself and to organize what I have learned from this project.

But first here is a trailer of the game:

Game design

Before diving into the technical stuff it is worth mentioning what went wrong about the game design. Doing game design without any real plan or experience turns to be (surprise!) really really difficult. Although the original goal of this project was to gain some experience in Rust development, we might have actually learnt more about game development (or about how difficult game design is) than about Rust.
more prototyping, less polishing
One of the first lessons we learned through this project was (the rather obvious)

Do a lot of prototyping and do not polish at the beginning.

We decided on a game concept early on in the development of the game and started implementing right away. We then realized that we would need to change many things for it to actually be a game but had then already invested too much time in completely unrelated parts of the game such as the panel design. Had we decided to create more throw away prototypes in the beginning, we would have probably been able to iterate more times and create an overall better game.
feature creep and scope limiting

One of the next big problems was feature creep. The longer the development took the more ideas about extra features popped up and we started implementing features which weren't in the original design. This was fun, but it also greatly derailed the whole process. Thus a year into the project the "game" had become this monstrous something. We then decided to cut a great deal of the features and changed the design to something that can realistically be implemented while also doing a full time job. (Which is why we discontinued conquest and made it to rainy cloud.)

Looking back, a decision that we should have done at the beginning of this project was to limit the scope of this game. This would have meant to create a minimal game design plan and stick to it without adding too many new features. Once the minimum game would be done we still could have added all those nice-to-have features. But the first priority should have been to actually build something that resembles an actual game.

Game development process

As already mentioned, although the main goal for this project was to practice Rust we found that there weren't as many obstacles as we anticipated here.
Rust!
As the main purpose was not to build a game, but to learn Rust one can say that we didn't choose Rust as an development language for a game, but rather a game as an exercise for learning Rust. If our primary goal would have been to finish a game most likely choosing Unity with C# or the likes would have been easier overall. Nevertheless here is our experience with using Rust for game development.
libraries
When we started the game there were some game engines in early development. We chose amethyst which was quite easy to pick up and use. Thanks to cargo there was no difficult setup needed and we were basically able to start writing from day one. This was especially moving to me as I expected a weeks-long setup process - something I was used from previous C++ projects... Sadly amethyst was deprecated some time into our development. At that point it wasn't really feasible to switch over to a different game engine. However we found that even the version of amethyst that we used was stable enough for our purposes.
cross compiling
This part surprised me the most coming from C++. Basically cross compiling just worked. We had some problems with external dlls missing, but nothing compared to the cross-compile hell in C++. Now that I have gotten used to Rust I sometimes wonder why C++ was just so cumbersome to use.
rust overall

Overall speaking it was very satisfying to write game logic in Rust. The first few weeks did result in some borrow checker fighting, but it never really hindered progress that much and once you get used to it, it feels weird to write code without it. Rust's type system also helped us to catch a lot of bugs during compile time and it most likely enabled us to actually finish the game after such a long time. When going back to a code base you haven't touched in some months and try to refactor some part of it, having a strict compiler checking what you are doing is really worth gold. Extending some enum and being reminded of all the other places where a new match case needs to be added was really helpful.

All in all I would choose Rust again as a development language for a game. The only real downside we experienced during the development process were slow compile-test cycles and the lack of libraries - both of are being actively worked on.

Actually finishing a project and battling perfectionism

There were some more things I personally certainly didn't anticipate when starting this project. Namely how hard it would be to actually finish something and that a software project is not only working on some peace of code but also with oneself.

Having started - and not finished - many projects I once again realized how difficult it is to really finish a project. What seemed to be a super small project somehow grew until you suddenly discover your interest for p2p systems or maybe learning a new language language or philosophy of mathematics. In short: Suddenly everything is interesting except this project. Pushing through this last phase was by far the most exhausting. There were suddenly so many excuses. "I have to concentrate on work." "I need to do exercise." "I need to clean the backside of the cabinet."

Most likely one of the biggest obstacle for the project was my perfectionism. When we started the project I had this very shiny perfect vision of the game. However the further we got the more I realized that it will not become a perfect game. This realization and the fear of actually releasing something imperfect would cause me to avoid the project or polish something a completely insignificant part of the game. In the end I had to face the truth that it would not be perfect and that people might hate it when actually released.

Conclusion?

Honestly releasing a side project after three years in development feels weird. According to plan it should have been finished in about one tenth of the time with double the functionality. But I guess that is what they tried to teach us in university that you will always underestimate stuff. But experiencing your own inability to estimate the scope of projects first-hand was a very humbling experience. Despite all of that pushing through until the end feels really rewarding - although releasing something so utterly different to the original vision is scary and maybe a bit disappointing.

If I decided to start another game project I would probably do more prototyping, use a more mature game engine library and fix the scope before actually starting the development process. Also if building a game would be the main goal maybe choosing Unity or any other mature library or framework would probably be best.

As for the language using Rust for this project was super pleasant so I would consider choosing it again. What surprised my was that despite my experience with other languages where you quickly grow to despise everything from tooling to the language design I actually grew to like Rust even more. If I had to summarize it I would say it just works. A big thank you to all the developer involved for all the great effort you have put into result!