Hey there, I'm new to Rust and trying to make a basic ECS system. I'm pretty sure what I did sucks and afraid of sharing it, but I got to learn some how.
At the end of the post I'll share a playground with my full and very brief example code, but here's a (slightly) TLDR version:
I instantiate both managers and add components to the fist entity in the array:
// Add a Player Component to Entity
entity_manager.entities[0].components[0] = PLAYER_COMPONENT;
// Add an Inventory Component to Entity
entity_manager.entities[0].components[1] = PLAYER_COMPONENT | INVENTORY_COMPONENT;
Then I finally loop through all entities and their comonents, and update their systems:
// Loop through all Entities
for y in 0 .. MAX_ENTITIES {
let entity = entity_manager.entities[y];
// Loop through Entities, components and check for N components
for x in 0 .. MAX_COMPONENTS {
// Update Player System
if entity.components[x] == PLAYER_COMPONENT {
let mut _comp = component_manager.players[y];
println!("Update Player Component");
}
else if entity.components[x] == PLAYER_COMPONENT | INVENTORY_COMPONENT {
let mut _comp = component_manager.inventories[y];
println!("Update Player Inventory System");
}
}
}
Again, I'm pretty sure this is kind of bad, but if any of you have any tips or even references to pages that teach me how to make ECS systems in rust, I would greatly appreciate it.
There's no one implementation, there are multiple ones, each with their pros and cons. So there's no real answer to "how close am I?" except if you base your design on a specific implementation.
However, arrays are a (very) bad idea, stack vs heap isn't a problem here (if ever).
In your systems, it shouldn't be an else if, just another if.
In the end it's not a great implementation but you can make a game with it. I'm not sure a game of what size though.
For resources there is this faq, these blog posts explain one way to make an ECS, this Overwatch talk but it's more advanced I'd say and there's this blog post exploring ideas.
And of course looking at diverse implementations, specs has already been mentioned. It's the most used (and recommended) in Rust but there are others. Rust is a young language so you can look at what C++ or Unity is doing.
Excellent answer leudz, I'm marking this as the Solution.
I do have one more question if you don't mind:
You mentioned arrays are a bad idea, may I ask why? I'm ready to refactor my code but I'd like to know technically why and if vectors are a better solution.
Rist doesn't accommodate arrays very well, especially when they are larger than 32 elements. So they aren't used all that much.
The only traits that are imemented for arrays larger than 32 elements are Clone and Copy. Other traits like PartialEq or AsRef are only inplemented for arrays of up to 32 elements.
First they are on the stack, this means you'll have to adjust the size of your stack. By default Rust will give you 2MB but your game will most likely need more.
Currently you are doing entity_manager.entities[0].components[0], but that's because you only have very few, you'll probably add a length fairly quick, you already have a capacity so why not use a Vec, it already does all that for you.
Plus imagine how many Pos you are going to have as oppose to, for example delta_time. With MAX_ENTITIES you're wasting a ton of memory.