2020-09-16
I have recently started working on an RTS-style game with (what I hope will be) some cool mechanics. I've had a general idea of what I wanted to make for a while, but I haven't had the time to get into it until this summer.
This post acts as a sort of design document/progress report/shill for Bevy.
It all started one sunny day in August, when I saw this post about the Bevy game engine posted to the r/rust_gamedev subreddit. I had previously tried Amethyst for a bit, and Bevy looked really simple and intuitive to use in comparison.
In all fairness, it's also true that Amethyst was my first ECS game engine, which made it harder to understand at first, but I still think doing things in Bevy is very straightforward. For example, making a system is Bevy is as easy as creating a function:
fn print_position_system(position: &Position) {
println!("position: {} {}", position.x, position.y);
}
and then registering it:
fn main() {
App::build()
.add_system(print_position_system.system())
.run();
}
If you're interested in using Bevy for a project, I recommend you take a look at the book, check out the examples and join the Discord server. The book and the examples will give you an overview of how to do most stuff you might want to do, and the Discord server is always full of people willing to help out newcomers.
The game I'm working on is a bit of a mix of concepts. I'm not really sure if it's going to work, but I'm going to keep iterating on the general idea, keeping what's fun until I have something good.
The main mechanic I want in this game is that there is no "magic floating camera". In normal RTS games you can see the world with a camera that has no connection to anything. It just floats there and you can move it various means, most of the time by dragging the mouse to the corner of the screen. Instead, what I want is for the camera to always be attached to a Unit, which most of the time will be a flying drone. In my opinion this will add interesting choices, as the flying drone might be shot down by the enemy, causing you to lose visibility and having to take control of a different unit. If all your drones are removed, you'll have to control your army from the ground. I have no idea if this will be fun to play, but that's what prototyping is for!
A part of that, I want to make it PvE, like They are billions or Factorio 1.
As for the theme, I'm thinking about making the player be an AI of sorts, tasked with cleaning up a planet full of Tyranid-like alien creatures, and to do that the player has a huge arsenal of Mechs, kind of like the ones the Tau has 2.
Image source here
Finally, I'd love to be able to add some sort of evolution for the enemies. This is the fuzziest part I have in the design, because I don't have a clear concept of what's possible or how feasible. For example, if there's a hive to the north of your base which usually has a lot of small critters, you might want to use flamethrowers to deal with them using AoE (Area of Effect) damage. Then, this hive might develop stronger fire immunity, so the game will be a constant back and forth of adaptation between the player and the enemies. I want this to be natural, not something hardcoded into the enemy AI. And I want each individual hive to evolve independently, so maybe this hive north of the player base evolves fire resistance, but another hive to the east evolves flying creatures to deal with your melee mechs.
I don't know what the end goal is in the game, it will probably just be an endless game with some "victory" condition like in Factorio 3, where you launch a rocket, but you can keep playing forever more. I know I said that the player is tasked with clearing out the planet, but I think I want to make it an infinite game, like in Minecraft.
In short, I want a mix of Factorio and Dawn of War: Dark Crusade, with a bit of Titanfall 2 sprinkled in.
The game is currently in very early stages. You can check the GitHub repo here. As of time of writing, the latest commit has the hash c91f9b278d8baa2337fd63662285a762eed9eed7
4.
Currently I have unit selection (both with single click and drag to select), basic unit movement, both in first person mode and in RTS mode, and a system to change the camera from Unit to Unit. There's no physics or anything else much, really.
There's two types of units at the moment, first are Walkers, which will be normal terrestrial walking mechs, but will probably end up including tanks and things with wheels too, who knows. The second type are Drones, which can fly around do other drone stuff.
The selection is implemented using bevy_mod_picking, a plugin for selecting entities and getting world positions in the game. The camera controls for drones are stolen from inspired by bevy_fly_camera.
Here are some gifs of the game in action. Cubes are Walkers, Spheres are Drones. There are no models yet, because Gltf support in Bevy is still a bit WIP, and all the cool models I've found on Sketchfab don't work well.
Demonstration of selection with single click and drag to select.
Demonstration of changing camera to control different units from first person view.
Next steps in the Roadmap are to get physics working, some enemies, a bit of combat, and basically most of the stuff you'd need in an MVP of an RTS game.
Who am I kidding, I'll start adding random features that look cool but serve no real purpose at this stage in development. Like for example something like avy's avy-goto-char
to select a unit to move the camera to, or a command that selects all units currently on screen, or maybe flocking behaviors, or who knows what else I might come up with tomorrow!
Yeah, all throughout this post I haven't mentioned the game's name even once, and that's because I don't know what to call it yet! I'm pretty horrible at naming things, so I'll just wait until something cool comes to me in my dreams. If you have any suggestions let me know!
I know Factorio isn't exactly an RTS, but it's pretty similar to what I want to make in terms of player vs the world.
In case you can't tell, I really like the Warhammer 40k Universe.
Yes, I also really like Factorio.
This is so you can check out how the code was when I wrote this. Link.