How do I make a large open-world game using map streaming?

Get help using Construct 2

Post » Mon Nov 23, 2015 2:53 am

Hello all!

My goal is to make a fairly large game world that is NOT randomized. What I would like to do is take the entire game world and break it into manageable 'chunks' and stream only the chunk that the player is in + surrounding chunks, while all other chunks are disabled so they do not waste memory. This does not seem like an easy task to me so I was hoping maybe someone would have an example to share, or perhaps some tips/advice!

Any help is appreciated. Thank you!
B
19
S
6
G
5
Posts: 98
Reputation: 4,484

Post » Mon Nov 23, 2015 5:01 pm

It's not as simple as you'd assume and it actually wouldn't save on memory so much, unless you Incorporated loading from disk. It could save on cpu usage by reducing the amount of objects to process, but it will also take some performance to do the chunk loading. Also while it works ok for static terrain it becomes more complicated if you want stuff to be changeable. Moving objects are a big problem with this as well as they can move around and it may not be desirable to save them to a chunk.

As a simple example with only horizontal scrolling and a screen size of 640x480 you could do the following. Say you want a chunk width of 640 pixels at any given time you could have 2 of them loaded, and for example we could define the center of the chunk to be it's location.

We need to know two things: when to load a chunk and when to unload it. What can do is as the chunk gets too far left of the screen it gets unloaded and a chunk on the other side gets loaded.

chunk.x<scrollx-640
> unload chunk
> set chunk x to self.x+640
> load chunk

Also it can be done similarly if two far to the right.

For the unloading I'd use instance variables on the objects that have the chunks id so you can pick them to destroy. For loading you'll need to store the object info in some kind of format. In the past i've used an array as json string to store the data. I'd store the values like this:
array.at(x, 0) = type
array.at(x,1) = x
array.at(x,2) = y
...

So to load it would loop over that array and create objects according to type. I've also done it so it's just a 1d array of dictionaries asJSON.

The chunks themselves could be stored in an array of those json strings.


I'd avoid all the above if I can. The goal should be to use less cpu. Just make the entire level in the editor. All the static objects are fine and you if you use a collision detection to pick the objects C2 has everything divided up into screen sized chunks so you can avoid processing far away stuff. Moving objects are the main issue to handle. A common thing is to disable or destroy them if they get to far from the screen.
B
94
S
33
G
118
Posts: 5,396
Reputation: 75,853

Post » Mon Nov 23, 2015 6:21 pm

So loading/unloading chunks manually wouldn't be the way to go? If I am understanding correctly, if something is outside the layout/player view, C2 can safely dispose of it and it won't consume memory unnecessarily, correct? So if I make one really large layout for the entire world, would it be a good idea to still split the background graphics into chunks so that only the necessary parts of the map are shown instead of having one gigantic graphic file?
B
19
S
6
G
5
Posts: 98
Reputation: 4,484

Post » Mon Nov 23, 2015 6:25 pm

Something Ashley is constantly pointing out to people is that the problem with one large background graphic is that if it's dimensions are over 2048x2048 then not many GPUs - especially mobile - would be able to render it.

Chopping the background into chunks then joining them in a massive Layout would be better.
If your vision so exceeds your ability, then look to something closer.
Moderator
B
137
S
31
G
87
Posts: 5,556
Reputation: 60,456

Post » Mon Nov 23, 2015 6:52 pm

Yeah that is what I meant (though, mobile is not my targeted platform). So maybe breaking the chunks down into something like 512x512 chunks might be a good idea then, and I would just need to make sure the appropriate map pieces are displayed at the appropriate time.
B
19
S
6
G
5
Posts: 98
Reputation: 4,484

Post » Mon Nov 23, 2015 7:34 pm

Sounds like you want to save video memory. My idea above does nothing for that.
Images are loaded/unloaded per layout:
https://www.scirra.com/blog/112/remembe ... our-memory

The most you could do is try do some juggling with animation frames, by just loading frames from a file as needed. Which would replace one image with another. I wouldn't go that route unless I was running out of video memory, and even then I would probably do something else since loading images from a file is slow.
B
94
S
33
G
118
Posts: 5,396
Reputation: 75,853

Post » Mon Nov 23, 2015 11:58 pm

Certainly ok a good question, because carrying gigantic images takes up a lot of memory and size end of the file, in my case I choose to compare the location of the player on the map and load the graphic frames according to the location on the map, that is where it should be a mountain for instance uses the same type of sprite a place where there are only woods but with the frame set to another position.
B
32
S
9
G
3
Posts: 280
Reputation: 4,262

Post » Tue Nov 24, 2015 1:56 am

You use tilemaps in combination with tiled background, and multiple sprite instances of varying dimensions.
Not many unique textures belonging to multiple objects.
Btw a seeded random can actually be useful here.
Image ImageImage
B
172
S
50
G
183
Posts: 8,443
Reputation: 115,605

Post » Fri Nov 27, 2015 4:19 am

After reading through these replies and through the manual quite a bit, it seems that creating a single really large layout using a tilemap/tileset would be relatively easy and effective, assuming that the overall number of unique graphics are kept to a reasonable level.
B
19
S
6
G
5
Posts: 98
Reputation: 4,484


Return to How do I....?

Who is online

Users browsing this forum: Yahoo [Bot] and 26 guests