My current project is a 2D platformer where the whole game is made up of a series of "rooms" (like a level of Shovel Knight, but without a world map to split it up).
My rooms are currently defined like this (pseudo code):
room = {
tilemap = "tilemap.tmx",
init = {
// Perform the initialisation of anything not in the tilemap, e.g. enemies and collectable items
},
// Other irrelevant stuff
}
Each time you enter a room, the init code is run and all of the enemies/collectables you killed/picked up/whatever are all back in their original place. This is exactly how I want this to work.
At the moment saving the game is simple, I just serialize out the state of the player, which room they are on and that's it.
The problem I'm having is that I'm now at the point where I want to add one-off collectables (like the morph ball in the Metroid games) or one-off enemies (e.g. an extra hard one that spawns only once), once you've collected/defeated them, they are gone - and when you enter/re-enter a room they shouldn't be re-spawned along with everything else.
I'm struggling to come up with a concept to handle this without some kind of global manager to look after everything which feels a bit wrong to me.
I'm working with an ECS architecture (as a purely educational exercise, I don't want to go into the merits of ECS vs. non-ECS), and I know that I shouldn't try and force everything into it, but it feels like this is a problem that I should be able to solve with it.
As a rough stab at it I was thinking of the following:
- a Persistence component which stores a key
- a PersistenceSystem which keeps track of these keys and their state
- when a Persistence component is added to an entity, if the PersistenceSystem says the entity shouldn't exist anymore, destroy it (this is to handle the case when I reload a room)
- when I save the game I serialize the keys and their states from the PersistenceSystem along with my other data
Is this is a sensible approach? Is this something that should sit outside of the ECS? How have other people tackled this problem?