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

  • 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!

  • 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.

  • 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?

  • 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.

  • 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.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • 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.

  • 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.

  • 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.

  • 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.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)