Skip to main content
GameDev.net gamedev.net
🔒 Locked

Continuous World in a 2D game

Started by zerotri Jan 14, 2007 at 4:38 AM 3 replies 2.7k views
Original Post
zerotri
zerotri
(WARNING: This post will be hard to read for many) For the past few days, I have been reading about the Dungeon Siege engine and how it implements Continuous World. I have been pondering the idea of a Continuous World in a 2D RPG. I am imagining a seemingly endless world(until of course, you hit the unwalkable water tiles) where the player can freely walk about, without loading screens, without the jump to a different room. Don't you hate walking into a house in an RPG and then seeing just one room, surrounded by black? that seems like a waste of perfectly good pixels to me. I have been trying to come up with a method for solving some of these issues to create an perfectly continuous world, and I think I may have found a way. I am still working on implementing it. It is quite a large project for a simple tile engine where just loading a single map into memory at once would be easier, but the final product would be quite rewarding if done correctly. The method I have been working on requires several key rules. I will first tell you what these rules are, and then I will go into detail after I have introduced all of them. 1)The game world is divided into nodes, which I will be referring to as View Nodes(VNs). 2)All of the VNs have information about each of it's 8 surrounding VNs. 3)Every VN contains tile/layer data. 4)Layers do NOT take the form of a 3 dimensional array, but a 2 dimensional array of Linked-Lists(conserving memory on VNs with many layers) Now, time to go into a little more detail about why these rules are important If we say that a VN is the size of the Camera, that for example is 256x160, and tiles are 32x32 pixels, then there are 8x5 tiles per VN. To give the idea of a continuous world, we should load 9 VNs of the game: The VN which the Player is in, and the surrounding 8. This ensures that the player is never viewing any tileless areas unless purposely placed there. If we have 9 VNs though, each holding 8x5 tiles, wouldn't that be quite a bit of memory if we added a bunch of layers? Yes. This is why you could use Linked Lists for storing tiles instead of a straight array of pointers. This way if you have a small section of the VN that extends several layers tall, you will be using less memory than a several plain arrays of tiles for that same map, when only a small portion needs to be layered. as an example, look at the following ASCII drawing: 00000000 00000700 00007870 00000700 00000000 this is a VN from directly above. Each number represents the layer that the tile extends onto. Now, is this map was a simple 3D array of tile data, then we would have an array of 8x5x9=360 tiles just to represent the above map. now, if we used the 2D Array of Linked Lists approach, we would have: 8+ 15+ 30+ 15+ 8 = 76 tiles. That's less than a quarter of the amount of tiles needed to represent that small map. With this extra memory, This approach does have it's disadvantages however; When VNs don't take advantage of multiple layers, or only use one, then the memory needed for the Linked Lists themselves becomes larger than the 3D array approach would have been. Now, let's look at the following piece of a map: 00000000|00000000|00000000 00000000|00003000|00000000 00003000|00000000|00000000 00000000|00000000|00000000 00000030|00300030|00000000 00000000|00000000|00000000 00300000|00000000|03000000 00000000|00000000|00000000 --------------------------- 00000000|99999999|00000000 00003000|99999999|00000000 00000000|99999999|00000300 00000000|99999999|00000000 03000000|99999999|00000000 00000000|99999999|00030000 00000300|99999999|00000000 00000000|99999999|00000000 --------------------------- 00000000|00000000|00000000 00000000|00000000|00000030 00000300|03000000|00000000 00000000|00003000|00000000 00000000|00000000|00003000 00300000|00000000|00000000 00000000|00300000|00000000 00000000|00000000|00300000 Right now, you might be asking: what is that? That is the whole set of 9 8x8 tile VNs loaded. Again, each number represents the number of layers at a given position of the map. So why is the center VN 9 layers? Because it is a multi-story building that the player can quickly traverse without needing to load anything more than what he already had loaded when he was a VN away from his current VN(always the center one). So he had the multi-story building loaded before it was even visible to him. Nifty, no? Again, this approach has it's disadvantages. You now have to find a way to store all of this data in a file, while still giving your designers the ability to easily extend upon it. My suggestion is to set a maximum number of VNs allowed(I doubt you are going to be using more than a few thousand) so that you can preset a specific area of the header to point to each node. This also allows you to index each node, making it easier to refer to surrounding nodes when loading data. If you made it this far and understood any of that, I applaud you. This whole post was written in the course of a few hours, while I was living off of a Rockstar and barely able to think properly. I need to expand upod the information a bit more, but I think I got most of the basics covered. Any comments/criticisms/suggestions? I'm thinking about whether or not I will be writing an article to submit into gamedev, and I am not sure what areas I need to cover more to make it more understandable. I will be updating this post over the next few days with changes to make it more readable, and also to explain more in depth. (also, the article WILL be a COMPLETE re-write of this. I realize that this post looks nothing NEAR what an acceptable article would look like, I just wanted to get the concept out there for those who understood this.) Thank You for taking the time to read this post, -Wynter Woods(aka Zerotri)
Kylotan
Kylotan
The basic theme is: subdivide the map, and load bits in as you need it. The way you implement that depends on your needs really. What you said sounds reasonable. It's not really rocket science though; 2D RPGs have used this sort of thing for years (eg. Ultima VII back in the early 90s).

Quote:
Original post by zerotri
If we have 9 VNs though, each holding 8x5 tiles, wouldn't that be quite a bit of memory if we added a bunch of layers? Yes.


However I disagree with this. Unless you're programming for a 486 or Nintendo DS or something, 360 tiles is insignificant. Even if each one had 5 layers, that's still only 1800 tiles, and even if tiles are bloated enough to require 256 bytes each, that's 450K; not exactly a problem for semi-modern machines.
zerotri
zerotri
Quote:
Original post by Kylotan
Quote:
Original post by zerotri
If we have 9 VNs though, each holding 8x5 tiles, wouldn't that be quite a bit of memory if we added a bunch of layers? Yes.


However I disagree with this. Unless you're programming for a 486 or Nintendo DS or something, 360 tiles is insignificant. Even if each one had 5 layers, that's still only 1800 tiles, and even if tiles are bloated enough to require 256 bytes each, that's 450K; not exactly a problem for semi-modern machines.


Yes you are absolutely right about this. The method I am developing is meant o use as little memory as I can for the tile data, so I can focus on loading everything else associated with that Node such as tile graphics, scripts, and objects. I can see where this still isn't much of an issue though. My goal is to make the loading of data as hidden from the player as I can, while making the world seem fully continuous and connected.

I do appreciate the response though. I failed to mention that it is more of a HD loading issue than a memory usage issue that I'm concerned with. Do you think I could get away with loading all 9 VNs + their tile graphics + all associated objects and their scripts in a frame or two?

Thanks for the reply,
-Wynter Woods(aka Zerotri)
Monder
Monder
Quote:

I do appreciate the response though. I failed to mention that it is more of a HD loading issue than a memory usage issue that I'm concerned with. Do you think I could get away with loading all 9 VNs + their tile graphics + all associated objects and their scripts in a frame or two?


Well I guess it depends how long a frame is. However I'm sure you can load it in a sufficiently short amount of time.

What you'll want to do is have a thread which is just responsible for loading. Then you could have a queue where you put loading requests which get done by the loading thread. So when you enter a new sector you shove loading requests for the other sectors surrounding it into the queue and by the time you enter a surrounding sector it's been loaded.
OrangyTang
OrangyTang
Quote:
Original post by zerotri
Yes you are absolutely right about this. The method I am developing is meant o use as little memory as I can for the tile data, so I can focus on loading everything else associated with that Node such as tile graphics, scripts, and objects. I can see where this still isn't much of an issue though. My goal is to make the loading of data as hidden from the player as I can, while making the world seem fully continuous and connected.


I suspect you'll have more problems with loading and management of scripts and objects than the actual map data. Remember that not only have you got to load in new sections, but you've also got to save the changes made to the old sections.

The Dungeon Siege article touches on this, and theres all sorts of nasty cases to consider. What happens when a script is altering an object which isn't loaded at the moment? Or gets unloaded while the script is using it? And as your game progresses the database to store your world state is going to keep growing and growing, how do you deal with that?

IMHO the easiest way to do this would be to store the entire world in memory all the time. This isn't as bad as it sounds, as most data is only temporary. You might just need to hold the scripts and a certain subset of important game object. Then your world streaming would only concern itself with the "unimportant" data - collision data, tiles, sprites, sounds. All the stuff thats only needed when a player is actually present.

Obviously this means you can't have infinite worlds, but if you're doing this on your own in your spare time I think it's a much more practical approach.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.