Hello, World! One day, out of the blue, I found myself a game developer, and I feel I need to write this piece for all the curious folks out there. I'm not going to dive deep into how it all happened but would like to share some thoughts, pics, and emotions about what I do now.
First, about a year and a half ago I started to learn Rust and I really appreciate the language. I don't consider myself an expert programmer, I have no time to learn many, even a few, languages extensively. Now that I have Rust, I can do whatever I want almost exclusively with it alone. I've already tried to make things like GTK+ hierarchical note-taking app (WIP), password manager with CLI and Web interfaces, able to run on desktop and Android.
Now I'm playing with Bevy, and I love it. For me, it's a totally new way of dealing with data, thanks to ECS, and it's real fun.
Welcome Tribes
Many years ago, I conceived a strategic board game with elves, hobbits, and all that fantasy stuff. I never tried to make it into reality though, and now I wonder if a computer game engine can be a handy tool for developing board games and fine-tuning their mechanics.
As for the game I'm working on, it inherited some of the features of my board game idea: it's a strategic game with a hexagonal map. It's about the tribes of hunters and gatherers who compete for resources to survive. So I call it Tribes.
And because I'm a «Magic: The Gathering» fan, it also has some deck-building mechanics. Not sure about the real magic, but I plan to add shamanic rituals eventually, and who knows how it'll play out. 👹
Now that you have a context about Tribes, let's move to the boring next part – the development and things I learned in the process. I hope to learn more from your feedback, by the way.
What I learned
When I started with Bevy, it was really challenging to follow the separation of concerns principle at first. I split my code into plugins from the beginning, but nevertheless, I ended up with a few huge systems, hundreds of lines of code each. It's so tempting to process all relevant stuff in one place, and it's a really fast way to move when you're on the first iteration and eager to see things work as soon as possible.
Trying to refactor this, I discovered I can use events to split my code into different systems. All I need is to fire an event and then catch it with on_event
condition. This works great in general, but in one case it led me to an unexpected obstacle.
I tried to create new entities in one system, send the corresponding events, and then process those entities in another system. However, on a scale of a single frame, this doesn't work because new entities aren't added to the World yet. I guess one can get around this with a custom condition employing Added
filter, but I didn't try it yet.
After two months of growing my codebase and refactoring, I deduced the general rule of thumb: if a system in plugin A mutates resources or components from plugin B – I'm on the wrong path. Not sure if this proves correct in the long run, but now it seems optimal for avoiding mess with all those myriads of entities1 you have in games – although at the cost of even more entities.
And by the way, the small story regarding entities. At one point I had a total chaos with naming. The same entities had different names in different (or even similar) contexts, and I decided to do a Great Renaming. Choosing variables' and other entities' names is always the hardest part of a developing process, so after a few days, I chose new names for everything. I opted for more inspiring names, so instead of units and members I have heroes now; areas instead of hexes, locations, and tiles. And to my surprise, additionally to peace of mind and a cleaner code, it had an unexpected effect on me – it revived my interest in developing Tribes, and I was a bit tired of it at that moment. A wonder!
What I have now and what's next
At this stage I have basic mechanics ready:
- unit movement and placing many units in a single area
- card drawing/discarding
- viewing draw and discard piles
- an exploration of resources on a map
- hunting/gathering and resource consumption
- which can result in deaths from starvation or births of children, who, after 10 turns, become adult members of a tribe: hunters or gatherers
Here you see a young new hunter, age 10. 👆
There are a lot of things I'd like to add, but at this point it's hard to test all my assumptions about different mechanics and their effects. So the next step is to implement a multiplayer game where the real contest can begin. Also, I plan to change all art assets2 to make Tribes more visually appealing and have a unique vibe. This, I expect to have the same important effect as entities' renaming.
And the last thing you might be wondering about: at the moment, I have no plans to make Tribes open source. This may change in the future, however.
That's all for now, thanks for reading, I hope it wasn't too boring with just two pics. I'm open to any feedback. 🙃
Related:
Footnotes:
From this place onward in the usual sense of the word.
Big thanks to Kenney.nl for wonderful free assets I use now.