I'm currently working on a 2D open world game loaded in chunks, initially I thought It would be sufficient to spawn entities randomly in a specific "radius" close to the player, and periodically remove distant enemies.
Though appealing, this system is inefficient unless you keep in memory the chunks surrounding the chunk the player is in (if an enemy needs to spawn on a chunk which is currently not in memory, you have no way of knowing wether you can actually place it in a specific tile or not, since it may be occluded by a wall) which is why I'm currently spawning enemies as soon as chunks are loaded, but there's a problem..
A massive complication arises when enemies are spawned with specific criteria. Assume a little dungeon spawns inside a chunk, it needs 2 enemies and a chest with loot in-between them. When you're done with it, it shouldn't respawn unless an hour passed. You can't just spawn those enemies inside the structure as soon as it's close enough to the player, otherwise you could go back 'n fort, kill the enemies and keep looting the chest's content.
Time to make a cache right? Let's forget for a moment any complication related to how you could make it memory efficient, and analyze this particular scenario:
- The player enters a chunk with said structure
- Enemies and chests are then spawned
- A cache marks this particular dungeon as "already spawned, check back in an hour"
- Instead of getting closer to the dungeon, the player moves in the opposite direction, until the dungeon gets out of view and enemies are removed since they're now too distant
- ..few minutes later, the player goes back where the dungeon is, only to find an empty dungeon because the structure was marked as "already spawned" and wont spawn again unless an hour is passed.
I thought about caching all enemies that where present inside a chunk when it gets out of view and restoring them as soon as the chunk is visible again, yet again this requires caching every entity inside a chunk and keep the entry available for an hour, and periodically check if in that particular chunk an hour is passed and we can spawn again enemies
Doesn't look too bad, but if a player moves in a straight line in my game for an hour I would need to cache about 200 chunks before cache entries start expiring!
Is there a better solution? How do modern games handle enemies spawn? How do they get around these difficulties? I'm particularly interested in knowing how online games do it considering the crazy amount of memory (which should be shared between servers) such systems may require