2

I'm trying to write a 2D game with an infinite world in Unity. It should be like Terraria except "infinite" in every direction. So chunks are generated, stored and loaded on the go as the player moves. My question is: how are chunks stored and later loaded into memory? I couldn't find any tutorials relating to this subject. I assume that such large arrays have to be stored on disc, but isn't disc IO slow? Let's say I'm trying to load a big square of 5 chunks around the player (the center chunk where the player stands and 2 chunks in every direction). Does that mean, that if the player keeps going back and forth between two chunks, I'll have to keep loading and storing 5 chunks from each side of that loaded piece? Wouldn't that be very slow?

H. Saleh
  • 554
  • 1
  • 5
  • 19
  • If loading takes a long time then you may want to spread it out across multiple frames to prevent hiccups. You can also use a larger unload threshold distance if you expect players to go back and forth a lot. – Pieter Witvoet Jul 17 '17 at 06:57
  • I don't know the exact answer but I've been wondering about the same thing recently and I think that dividing a world into chunks and saving these chunks onto disc is the best option. Of course when you load your world you first read ALL data stored on the disc - so you don't need to do that on the fly (since as you said - disc IO is pretty slow) - and then load chunk visuals that are close to you – Fiffe Jul 17 '17 at 06:58
  • First determine, if disk IO is really "too" slow. Of course it's slower than in-memory access, but the question is, how much data is in a chunk or to be more precise, how much data must be stored for a chunk. A few kilobytes shouldn't even be noticable. If the "window" of 5 chunks is too small, then simply keep 7 or 9 or however many necessary loaded. Do you need to unload a chunk immediately? Saving and then unloading can be done completely asynchronally. Does the player turn and run back? Then stop unloading. Player runs in one direction? Can you afford to load more chunks that way? – Corak Jul 17 '17 at 07:24
  • I'm only assuming it takes a long time... doesn't it though? It includes pulling a 2048x2048 short array from disc and deserializing it. And @Fiffe that's almost exactly what i was thinking. I have three threads: main UI thread, visible parts rendering thread, and disc IO thread. But isn't that too many threads? Or can most people run that already? Last footnote: I can't "read ALL data stored on the disc" at the beginning. i'd think that's too much for the memory after some playing time. – H. Saleh Jul 17 '17 at 07:29
  • Are there "base-like" chunks (chunks with more user-placed items)? Or chunks that are "more active" than others? Maybe "prioritize" them and keep chunks with higher priority loaded longer. Maybe even let the player select x amount of chunks to be "always loaded". – Corak Jul 17 '17 at 07:29
  • Minecraft has a huge memory footprint specifically because of this. While the loading of chunks does occur; they are often kept in memory afterwards. The only "unloading" that happens during playtime is visual unloading, where the chunks are not rendered anymore to improve performance. But they are still in memory. – Flater Jul 17 '17 at 07:29
  • @H.Saleh you could setup some limits on the amount of chunks stored in memory but it shouldn't be that memory consuming anyway. You'd need MBs of chunks data for it to be heavy on memory and since it's just binary data of positions, sprite ids, etc. they shouldn't weight too much even if there's thousands of them. – Fiffe Jul 17 '17 at 07:41
  • 2048*2048*int16 is 8MB (iicc). So yeah, this *will* be noticeable. But this should also cover a pretty large area, right? So assume chunks in memory are `a, b, c, d, e`, where the player is currently in `c`. If they go and enter `d`, you start loading `f`. And it would take all the way through `d` and most of `c` for the player to actually reach `f`. So depending on travelling speed, that should be more than enough. A "problem" could be if you have some kind of teleportation mechanic, where a player could "jump" to completely unloaded chunks... – Corak Jul 17 '17 at 07:43
  • How about making chunk sizes a lot smaller while still keeping basically the same area loaded? – Corak Jul 17 '17 at 07:44
  • Also, does a chunk need saving? If it was just loaded "at the edge" because the player might've gone there but never actually went there, then nothing changed, no saving needed. -- as for the amount of threads: don't worry. If they *can* be parallelized (enough CPUs/GPUs), they will be. If not, then parallelization is "emulated" by the processing unit(s) by switching processes every x amount of ticks. Everything done for you, nothing for you to worry about. :) -- and if one thread has nothing to do, it won't bother any other thread. – Corak Jul 17 '17 at 08:04
  • Okay, thanks for all the answers. I'm gonna try to implement it with smaller chunks (256x256), and come back if problems come up. Thanks again for the answers! – H. Saleh Jul 17 '17 at 08:05
  • Hey and @Corak thanks for the threading fact, that really makes me feel much more confident playing with threads :D – H. Saleh Jul 17 '17 at 08:07
  • 1
    Most importantly: *first* make it work, *then* make it fast. *Some* level of optimization can and should be done beforehand, but other than that, only optimize if there is an actual performance problem. – Corak Jul 17 '17 at 08:08
  • The only thing to worry about with working with threads are race conditions and/or deadlocks... so keep a special eye out for those. – Corak Jul 17 '17 at 08:10
  • 1
    Re: teleporting: don't worry about it. Players inherently understand that there are hardware limitations and as long as mobs can't attack them and kill them before the world actually loads around them, they won't care about the void-view. – Draco18s no longer trusts SE Jul 17 '17 at 15:26
  • I give up. It's been 3 weeks and I'm struggling with even the most trivial parts like mapping world coordinates to chunk coordinates. And I haven't even started working with threads. That's why my last question in this thread is (And I'm sorry it took so long): where can I read some open source code that handles something similar? Minecraft would've been perfect but I know it's not open source, so what other options do I have? – H. Saleh Aug 06 '17 at 11:12

1 Answers1

1

What you can do is load chunks if the player is 2 chunks away but don't unload them unless the player is 4 chunks away.

So let's say the player is walking right: (here X is the player, a b c.. are the chunks, in [] are loaded chunks in the loading radius, and in () are loaded chunks in the unloading radius)

a b c (d) (e) [f] [g] [X] [i] [j] k l

If he decides to go back to chunk g, then chunk e doesn't need to be loaded (it already is) and chunk j doesn't get unloaded (it's not outside the unloading radius).

a b c (d) [e] [f] [X] [h] [i] (j) k l

If he wants to go back to chunk h, again, no chunks need to be loaded or unloaded. So he can hop back and forth between chunks without any loaing/unloading.

Pluto
  • 3,911
  • 13
  • 21