-
Notifications
You must be signed in to change notification settings - Fork 136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Game map questions (Resource vs Entity) #279
Comments
Both of your questions depend on the type of game. Let's assume a turn-based roguelike.
It is more common to store it as a resource. There's no advantage to having it as an entity. Multiple systems would need access and you'd have to do cumbersome queries to retrieve it. It doesn't gain anything by having a composable component style layout.
No, it's not. Options are: (1) Store position only on entity in ECS; (2) Store position only in game map by associating the entity ID inside a cell as you've described; (3) Store position in both. (3) is not great because after the turn you have to query a position in the ECS anyway so you can update your map contents. (2) is bad. imagine just trying to render the map. not only do you have to iterate the (1) is the winner. The fastest setup is a 1 byte TileType. Do not have variants containing extra information as it will resize all of your enum variants to the largest variant. On a 80x50, 4000 tile map, you'd be only using up 4000 bytes, sweet. And your cache hits will be bananas if it's stored as a 1-dimensional array. Query the blazing fast ECS for position and you can relate any entity position to any map tile using the map methods. enum TileType { Floor, Wall, Tree, ... }
struct Map {
pub tiles: Vec<Tile>,
pub width: i32,
pub height: i32,
pub map_count: usize,
}
impl Map {
pub fn new(width: i32, height: i32) -> Self {
Self {
tiles: Vec::new(),
width,
height,
map_count: (width * height) as usize,
}
}
pub fn get_idx(&self, pos: &Point) -> usize {
(pos.x + pos.y * self.width) as usize
}
pub fn get_pos(&self, idx: usize) -> Point {
Point::new(idx as i32 % self.width, idx as i32 / self.width)
}
} |
Hi,
I hope it's ok to open an issue to ask questions rather than reporting an issue. I have a couple questions on how to handle game maps.
The first question is : Should the map be an entity or a resource ?
The map is a central piece of the game and many systems need to access it, so it makes sense in my opinion to have it defined as a resource.
This has worked fairly well for me so far but i'm now implementing saving and loading in the game, and it looks like resources can't be serialized with a simple function call like the world can.
I'm curious how other people are handling that.
Second question : Is it ok to store entities in map cells ?
My map is a vector of cells, and each cell has a entities field which is a
Vec<Entity>
, a vector of all entities currently in that cell. This allows me to easily get the list of entities in a specific cell.I'm not sure if that design is correct. it feels like the ECS way of doing it would be to iterate over entities that have a Position component and return the list of entities which have the position i'm looking for. But that also seems like a huge overhead when you start adding a lot of entities in the game.
Is there an agreed-upon best way to let the map object provide this basic "list what is in place X" function ?
Thanks for taking the time to read,
Peace!
The text was updated successfully, but these errors were encountered: