starandserpent / java-TerraServer

Terra - Voxel octree of chunks, made for Rituals of the old
MIT License
18 stars 2 forks source link

Limit and prioritize chunk generation and loading #59

Open Pilvinen opened 5 years ago

Pilvinen commented 5 years ago

Currently the world is loaded as a square area centered around the load marker which follows the player.

The world is loaded in the direction of movement by generating the sides of the square area in rows.

However this is not an efficient for the purposes of showing the player as much terrain as possible as fast as possible.

I suggest that we change how world generation and loading is handled by prioritizing important chunks and giving less important chunks a lower loading priority.

1) The most important terrain is where the load marker aka player is directly located, all around that spot and not depending on frustum. That terrain has to be generated and loaded ASAP.

2) Second highest priority is loading the terrain that is in the frustum - in the direction the player is looking towards, and starting from the player and moving further away.

3) The third highest priority is for terrain which is on the sides of the player, but not in the frustum. The player might turn slightly and that terrain should be ready.

4) Fourth priority is given for any terrain which is located behind the player and is not urgent to load.

These priorities cannot be fulfilled in order. Instead of fulfilling them in order (ie. that means do 2, and then do 3 and only after that do 4 - that's not what we want) we need to divide the generation time each priority gets. The highest priority gets the most generation time, the second highest priority gets less generation time, etc.

In effect I'm suggesting that after X number of blocks has been generated from priority 1, we generate Y number of blocks from priority 2, after that we generate Z number of blocks from priority 3, and so on. Each priority group gets some generation time - and how much depends on how high the priority is.

Other factors may weigh in on this too, like for example, if the player is running forward we might wish to skip world generation happening behind the player at that time at allocate more resources to generating the terrain in the frustum, etc.

Generally when the player is standing still long enough we will eventually load all of the terrain that is inside the view distance. This change concerns only prioritizing the loading order.

Couple of images illustrating how the chunk count divides among the frustum with FOV 72 with and without such optimization:

https://www.ritualsoftheold.com/images/sketches/concept/cone_of_view_and_chunk_loading.png

https://www.ritualsoftheold.com/images/sketches/concept/cone_of_view_and_chunk_loading2.png

Now the problem is mostly about how to sort the data dynamically and efficiently without doing anything silly which would kill the performance.

The priority areas are always the same (sans FOV changes), but depending on the direction the player is looking at the content is always different.

Furthermore a simple queue just won't work, because we need to be able to dynamically respond to changes as they happen and not get caught up loading a ton of data which has become obsolete (for the moment).