Improbable Icon


Supporting large worlds - applying SpatialOS in Unity to very large stiched/tiled terrains using the new Streamed Queries


I’ve spent some time looking into how to support my 20km x 20km tiled terrain in SpatialOS (where I have 20 1km x 1km terrain pieces all stitched together using unity’s terrain SetNeighbors functionality). Especially with the new streamed queries functionality in 13.4, it seems now easily doable via setting up these terrains as entities.

This allows dynamic information to be attached to the terrain via components (gameplay related logic, destructable terrains, etc…), and streaming can be automatically handled by the pre-existing Spatial system on all workers (clients/server/physics/etc…) - just be careful with your entity radius values, or you might have entities sitting on top of the terrain falling into oblivion

Specifically, in the streaming query you are setting on workers - (sidenote: do they need to be authoritive? What about workers that just need to check-out the terrain for use, such as client workers?) - on Terrain, make sure that the radius you are sampling for is at least equal to the full length of your terrain tile’s sides, suggesting 25% more than that.

ie. if your terrain tiles are broken into 1km x 1km chunks (1000 world units x 1000), you would want to set your bounded query radius at least 1250 for your terrain streaming queries (assuming your world units are set to be 1m : 1) - this will ensure that any worker that has authority over (or checks out??) a terrain entity will ALSO pull all neighbouring tiles as well, and get updates on them, for use in visualizing what’s going on with the terrain, as well as physics and the like. If, due to the view distance in your game, you want to enable players to see further then one full tile out, you would make sure the clientWorker’s query is set 2x or even larger on the radius. This also gives you the flexibility to load in more or less terrain based on the worker’s needs (ie. a client currently flying a plane might want a large number of tiles to be visible, where a clientWorker on foot, on the ground, might only need a small number of neighbors being loaded.)

I haven’t actually finished prototyping it yet, but it seems that to handle the actual instantiation of the terrain for each worker to actually use, you can simply make sure that the terrain entity holds data about the name of the “scene” that represents that terrain (there are other ways to do it, but with the latest Unity updates i’ve found that doing it from scratch, as well as assets such as Sectr Streamer, most are going with using scenes to encapsulate the terrain, since it is usually static in terms of world location). ie. Scene named “world_tile_1-1” - terrain entity “world_1-1” would have, in one of it’s components, “world_tile_1-1” as the scene reference, from which either your scratch built, or asset-supported, scene loading would work.

In summary, SpatialOS can be used as the “intelligence” behind when each worker needs to pull terrain data, as well as allowing terrains to be infused directly with gameplay related data such as resource densities, spawners, etc… All of this works pretty well alongside a scratch-built, or asset-led scene-based terrain streaming solution, where data on what “scenes” to load up come straight through Spatial.

Regarding navigation of agents in this large world - all sources I have seen at the moment point towards the easiest way being simply to use the API and dynamic abilities of the A* Pathfinding project asset to get things working cross-scene, and long-distance. I’m sure there is also a way to scratch-build things, using multi-scene navmesh baking, but I wasn’t able to pull up any information on how to actually use that in a working solution. If anyone has information on how Unity’s nav mesh system could be set up to support scene-based terrain tile loading like this, I would be very happy to hear it.

I hope this initial post, as well as discussion thread, helps others trying to put together large-world game prototypes using Spatial and Unity. It seems to me that this info is crucial, considering SpatialOS is billed as a solution for large worlds, and yet we don’t have any examples/GDKs yet that actually have large worlds in them. :slight_smile: