Optimizing: Open World

Check out the Repo here!

Chunk Neighbours

During the development of my open world streaming project I ran into may technical challenges with serialisation, instantiation and resource management. This dev-log highlights how chunk data was intelligently used in conjunction with in-game events and how it increased overall performance.

A small sample scene created with the streaming system

A small sample scene created with the streaming system

Serialisation & Contextual Data

Because the system was designed to work independently of game engine utilities, I opted for a simpler sorting method that loops through each of the stored chunks to check their bounds in accordance top the players new position.

The loop executed when the player leaves his current chunk

The loop executed when the player leaves his current chunk

However, due to their potentially being a very large number of chunks in the game’s system, I needed a way to better search stored chunks for relevant results. One of the best ways I reduced the time complexity of searching through serialised information is by holding local chunk data inside each of the chunk json files.

I achieved this through storing integer values of neighbouring chunks on initialisation of chunk data, removing run-time costs by storing accessible data during the collection phase designed to be performed by a designer and not by players or on finalised versions of the world.

An example of  a Chunk JSON file: The “Chunk Neighbours” collection at the end of each file determines the search query for when the player leaves that chunk.

An example of a Chunk JSON file: The “Chunk Neighbours” collection at the end of each file determines the search query for when the player leaves that chunk.

This reduces the time-complexity of the search query dramatically to a fixed total, either 3, 4, or 8 depending on the location of the chunk in relation to the rest of the chunk bounds in the system.

Further Reductions

After determining the new chunk to load, we can further reduce the actions needed by comparing the neighbours of the old and new current chunk, giving us the chunks in common that we don’t need to process, as well as the old ones that no longer exist that need to be de-loaded and the new ones that need to be loaded.

Old neighbours compared against the new neighbours of the current chunk to further lower performance costs.

Old neighbours compared against the new neighbours of the current chunk to further lower performance costs.

Previous
Previous

Generics and the power of Factory Patterns