Currently in the process of making a game like Dwarf Fortress, so without graphics. I'm mostly thinking about how I want to implement everything. While writing code I keep stumbling on general game implementation problems that are really annoying me. Assume this:
We have a Map
class which stores Chunk
classes which stores Tile
classes which stores Player
s and Enemy
s currently on this tile.
class Map {
public:
std::vector<std::vector<Chunk>> chunks;
};
class Chunk {
public:
std::vector<std::vector<Tile>> tiles;
std::vector<Player*> player_need_update;
std::vector<Enemy*> needs_update;
};
class Tile {
public:
std::vector<Player*> players;
std::vector<Enemy*> enemies;
};
Now let's say I want to move()
a player to a different Tile
. For this I created a needs_update
vector storing entities that need to be updated on the game Map
. Every game tick we loop all chunks and loop all entities needing an update.
I think (thought) this is a logical way of doing this because we can have a tile that is independent of a chunk that is independent of a map. Same for entities. So let's say we want to move an Entity
:
void Entity::move(uint16_t move_x, uint16_t move_y) {
x += move_x;
y += move_y;
changed() // Notify chunk that something changed about us
}
This is already where it is going wrong. To be able to notify the chunk we have moved, we need to know ourselves in which chunk we are Chunk *in_chunk;
in class Entity
. And this breaks the structure I wanted to achieve (independence across classes).
Another example, suppose we want to attack an Entity
on a different Tile
. We would need to know there is an entity in the first place, but we would also need to know things about the enemy to then decide whether to attack it or not.
Player::attack(Enemy &enemy /* ?? */) {
// Attack
}
I think it is wrong to move a player by calling a function in Map
:
void Map::movePlayer(Player &player) {
// Do stuff to move player
}
So, how do you implement basic game structures like this, keeping things logically structured but while still being able to ie. move a player across the map?