Any theories on how to make a wrapping world? Also, how to change stream distance over C++? And could use suggestions on what world tile size max view distance and terrain scale to use

So far I was putting my world together with the World Browser using tiles in a layer with a certain draw distance.

First I would like to know would the best way would be to make a wrapping world. Basically be able to walk in one direction and end back up where I started. The world will be big enough so you cant see to the same place again. I would also like this to work over multiplayer. I also thought that UWorld:SetNewWorldOrigin was implemented and called when entering a new map tile, but that doesn’t seem to be the case? My pawn’s coords are still increasing/decreasing when walking over to new tiles.

Then I would also like to know how to change the tile stream distance during runtime with C++ so I can change it together with the view distance.

Also, any suggestions how big in m/km a tile should be and how far the max view distance should be? And to have a more detailed terrain would it be ok to use a terrain scale of 50 instead of 100 or would the performance hit be to great?

Thanks for any help and suggestions.

Thanks a lot for taking your time to answer my questions.

I might add that I wish to implement this wrapping world in multiplayer as well.
I have more questions to further my understanding and elaborate or on what you said.

  • How do I handle the coordinates at wrapping sections? I was thinking about using SetNewWorldOrigin at certain sections of the map. But how performance intensive is this function?

  • When networking, every object being simulated, be it players or animals - would need to have the origin for their simulation in that section of the map changed. How would I go about this, or would I do this at all?

  • The custom streaming logic. I think it would be best to implement it into the world tile system. Where should I implement this? I was unable to find the classes responsible for the streaming logic of world tiles. And is there any thing I should know before proceeding with the information you will share with me on this?

  • The recommended tile sizes. I was planning on using the recommended settings that are in the landscape documentation (there is a table), but with my question, I meant how big should the tiles be in m²/km² - should I prefer having smaller tiles, not bigger than 250m² or bigger tiles that are 1-3km²? Are there any performance tradeoffs?

  • How performance intensive would it be to use a landscape scale or 50 instead of 100 when creating them? Basically to double the resolution and possible detail.

Thank you again for your help.

Hi,

First I would like to know would the
best way would be to make a wrapping
world. Basically be able to walk in
one direction and end back up where I
started

It is possible I guess, but you will need to write a special streaming logic to achieve that, so it can stream-in tiles in a way that makes illusion of wrapping world.

I also thought that
UWorld:SetNewWorldOrigin was
implemented and called when entering a
new map tile, but that doesn’t seem to
be the case?

UWorld:SetNewWorldOrigin gets called when your camera is further than WORLD_MAX/4 distance from origin. You can see it UWorld::EvaluateWorldOriginLocation, it does not depend on tiles.

Then I would also like to know how to
change the tile stream distance during
runtime with C++ so I can change it
together with the view distance.

You should look at UWorldComposition::GetDistanceVisibleLevels, it could be modified to accept some scaling parameter for a streaming distance.

Also, any suggestions how big in m/km
a tile should be and how far the max
view distance should be

Landscape scale basically means how big quads will be in a landscape mesh. So for 100, you will have 1x1m quads. For 50, you will need 4 times more quads to cover same area, so performance depends on visible area.
On streaming side I recommend to use landscape patches no more than 8x8 components in it. More components in one patch may cause streaming hitches.

I was thinking about using SetNewWorldOrigin at
certain sections of the map. But how
performance intensive is this
function?

SetNewWorldOrigin applies a shift vector to all actors in the scene. So it depends on how dense your scene is. Generally performance is similar to one GC run (a few milliseconds). It will not work in multiplier. Using SetNewWorldOrigin on clients will result in different world origins on those clients, so actors absolute positions will not match on clients and server. Origin rebasing is intended for single player games with a big worlds (Skyrim?)

The custom streaming logic.

Level streaming is controlled by ULevelStreaming. For each tile you should have a separate ULevelStreaming object. ULevelStreaming is quite simple and you should find some useful properties in it, like level transform (you can apply a custom transformation to tile when it loaded)

I don’t see a way right now how you can implement world wrapping without changing the source code. You should look at UWorld::UpdateLevelStreaming function, this is where level streaming is done. This function gets called every tick and has current view information. For tiles management you should look at UWorldComposition::UpdateStreamingState. This is where engine decides which tiles should be streamed in/out depending on distance.

The recommended tile sizes.

It depends on how big your world is and how dense it is. With a small tile size for a big world, you will need to create thousands of tiles, which is hard to manage. Landscape tiles should not be bigger than 8x8 components, size in meters does not really matter. I think you should experimentally choose what size your tiles can be. Tile should be small enough to not cause hitches in streaming and big enough to reduce total count of them. Streaming performance should be checked only with cooked content.

So SetNewWorldOrigin does not work in multiplayer. Will the function be called on the clients even tho they are connected to a server when moving far enough away from the world origin? Hence I need to disable it?

Considering this wont work on multiplayer, do you have any suggestion on how to implement a wrapping world that will work in multiplayer?

Thanks for all your help.