Consistent world of Soulash
Hey guys, it's been a while. Sorry I had to skip last weeks blog post. I was busy fixing bugs and polishing the game before 0.2 alpha release. In case you missed it, it will be available on 21.06.2019, so only 2 weeks left. The trailer is also being done and it should be available next week, so stay tuned.
With that out of the way, the time has come to write more about the consistent world of Soulash. In this blog post, you will learn what do I mean by "consistent world", how does it differ from open world feature available in other games, and how it works.
Let's start from the basics. The smallest unit in Soulash is a tile. You can see colored background and glyph on every tile.
Only one glyph that belongs to an entity positioned at the top is displayed. You can hover over any tile while holding left shift key and see every entity that is there with a mouse wheel or tab key.
Every region map is a grid consisting of 64 x 64 (4096) of such tiles. You can see the name of the region you are currently in at the top right corner above the minimap.
Nothing unique or new about this, right? This is how it's done in many different games out there. You enter a region, kill some monsters, loot some chests, and move on to conquer another map. In some games, you go to an overworld area outside of the main gameplay that's between regions, where you can travel vast distances to give the game a feel of a bigger scale. These games are often categorized as having an open world - and rightfully so - because they allow players to go anywhere. You are not restricted to take a predefined route. You can figure out your own path to victory.
The world of Soulash is constructed from hundreds of such region maps. They are connected to each other forming one immense world. This also made some players confused when I announced the demo version had 4 playable regions. It basically played like a single map of size 64 x 256 tiles. This is what I call a consistent world. Technically it can be a single map or multiple maps, but it is one coherent world. It feels and plays differently from a world that has an additional overworld map uniting smaller, disconnected region maps.
Let's consider how this works. At any given time, there are up to 11 maps loaded and simulated at the same time.
- The region where the player is located.
- 8 neighboring maps.
- One map directly above and below the player.
Up to 45,056 tiles loaded at the same time. Not bad, but hardly a huge world, right? It's possible to load much, much more into RAM. Probably a couple of millions of tiles, perhaps around 300 region maps. Soulash uses about 100 MB, so not a significant amount. The purpose of loading so much more data would be to process it, and that's where the problems start. Calculating paths for entities around the world, processing effects, needs, simulating AI tasks, events - this would take significant processing power. I can see some performance issues with around 500 AI entities available when too many of them have to recalculate their paths at the same time. The number can be optimized much higher probably, but sooner or later there will be a hardware limit.
The 11 maps allow for an essentially infinite world while keeping similar performance. The real limit would be the hard drive space, but that's reasonably unlikely to be met with today's terabytes available. To accomplish this, whenever the player enters a new map, regions that go out of range are serialized and saved to the hard drive, while new maps are being loaded to memory.
In Soulash all loaded entities are being simulated, this means they will walk around and enter new maps from the available range. This includes minibosses. Magnus will not wait for you in a predefined place in Kabula, he could intercept you in the forests, or go somewhere else. This brings another level of difficulty when combined with the need to sleep. An enemy can find you while you take your rest, so if you didn't manage your stamina during fights, you could find yourself in a very tough situation.
There were some technical challenges associated with this approach. The biggest was probably the position. When rendering the neighboring map, the coordinates of its tiles are relative to the map where the player is, which makes them dynamic in the context of the world. The same needed to happen with particles of animations that play across multiple maps or targeting indicators.
Every map had its own set of entities assigned to it, so when it was reloaded it knew what needed to be saved to the hard drive. This was another set of mechanics to keep in mind when designing abilities for example. When an entity or player was moved by anything, all of its items and itself had to be reassigned to a different region, so they can be properly saved. Abilities that moved the player more than one tile, like Lunge, Phaseshift or other effects like Knockback had to keep that in check.
At this point, you might have a question - why bother? What does all of it bring to the gameplay experience? The purpose of this is better immersion. As soon as you see a loading screen or overworld map, the gameplay experience changes drastically. Often it's not necessarily a bad thing, just a different experience when playing a game, apart from some extreme cases that break the immersion completely with their excessive loading times (I really wanna love you Warhammer Total War).
I hope you found my approach to building consistent open worlds interesting. Soulash demo is available now and alpha with big world releasing shortly. I will leave you with some food for thought. With computers getting more cores and ability to process more data in parallel, imagine a game where killing one peasant has a butterfly effect on the whole, simulated world. Wouldn't that be an interesting experience to have any choice no matter how small to have the potential to affect the gameplay in a significant way?
Log in with itch.io to leave a comment.
Interesting read! I appreciate the include of technical stuff, it's always nice to see how things are implemented inside. Besides, it's just motivates to work on own project ;)
I'm glad you liked it. :)
I thought it was a pretty neat idea for implementation when I wanted to make that consistent world and it wasn't easy to figure out positioning and map reloading, so I thought description of how it works might inspire someone to make their own attempt.