https://www.youtube.com/watch?v=wcGcFfD17kE&feature=youtu.beChunk streaming and rudimentary character, item, and prop placement:
Context:
The problem I am tackling now is related to how to properly handle a large chunked procedural streaming world, while at the same time placing story-elements such as characters, items, and props in specific locations. There are a few interesting challenges to this that weren't immediately obvious to me - but as usual, they are solvable.
In the video above you'll see a demonstration of the current implementation, made more visible with debug flying. When the player is loaded the streamer is "focused" on the player's location. Then when the player moves the world streams new chunks around the player's new location. Chunks that are not within some threshold are stomped.
The vertex shader includes a horizon bending algorithm so that if the player is traversing the world normally the streaming margin is generally not visible. This still needs to be tweaked because it is also dependent on the frequency and modulation of the terrain.
Streaming runs on a separate thread (which still causes locks from time to time, especially during focus). This keeps the framerate from hitching as you move around and chunk files are accessed, or procedural generated.
Problem:
The first problem is that when the player is created the world doesn't exist. There are no chunks streamed, because streaming focus is based on the player's position. However, when creating a new game file I want to create story objects in the immediate area. The current implementation creates those objects before the world is streamed. But what height will the ground be at the specified X & Z? Unknown. So I had to expose terrain height generation function to give Y for XZ. That solves the problem fine for now. But, what if the object is dynamic, like a character, and he needs "physical" ground to stand on? I have to disable his physics until there is ground, which is what I'm doing in a sort of cheap way.
The second problem is with far away story elements, like the tower that is approached. I want to place that on new-game as well, and there is no way the world will be streamed out there for some time.
The current solution for all of these things involves calling a function during initialization and adding the desired elements to global lists in a World structure, so they're basically always there, but still have to handle the fact that the ground might not be under them yet.
I created a system called World.PushDynamicObjects and World.PullDynamicObjects. When a chunk is unloaded, this checks if the world object lists have objects within the chunk's boundary, and then pushes the object into the chunk, boots it out of the world, and saves it with the chunk. When a new chunk is loaded I procedurally generate it, and then load dynamic objects for it if there are any. So that's kind of a nice system for pushing and pulling objects. This feature is disabled in the video above.
But there's a problem with that too. Push and Pull is based on chunk streaming distance, and tall objects like the tower should be pulled much sooner than an item that might be 2 feet tall.
So I could summarize the entire problem like this: When a new game is created I want to place world-wide story elements, but I don't want them to exist in the world until the player is close enough to care about them. So I need some way of telling the world "Here's what I want, eventually. You handle it."
Solution:
Now we get to the discussion part. My idea so far is to add a Map class to the world Class and let it keep track of all story element knowledge. The World class is then delegated to watching the player's position, observing the map, and deciding what should and should not exist in the near-area - that's actually pretty close to how a 2d tile map game works between a map and a camera. My world is much larger, but density much lower, so maybe it just works.
I haven't decided if the number of story elements is so large that keeping it all active at once is viable. It definitely is for now.
When creating a new game, I ~could~ add everything to the World.Map, and then tell the map to "bake" everything it knows about down to the chunks by creating chunks where necessary, and then pushing dynamic objects down, and saving. Then completely emptying the map. In that case the map is useless to the world after baking and the world will just have to load chunks and pull dynamic objects as usual. That still leaves the problem of tall, distant props so I think the Map knowing more than the World is still important. But maybe it's selective. Maybe I flag up each element when it is added to the map. Some are "distant" and permanently known by the map, and others are "baked" into the chunks.