Download

Is there any way my system can place objectives in a level without loading it?

My game uses very aggressive level streaming, so the vast majority of the game’s geometry isn’t loaded into memory at any given instance. If the entire map were loaded at once, creating a quest to, for example, “Go fight the monster at location [x,y,z]” would be trivial- I’d just select a section of the map, use my navmesh to generate a random reachable point within a radius, spawn a monster at that location, and return the coordinates to the quest generator.

How am I supposed to accomplish the same thing when none of the map is loaded until the player draws near? MMOs and quest-driven RPGs do this constantly, so there must be some reasonably simple way to accomplish it, but at present I’m having an awful lot of trouble conceptualizing of how a quest generator that lives in the persistent level could “see” geometry or special items in un-streamed sublevels and assign a quest that uses them.

as a 1st idea, if the map is not randomly generated, put some “monster spawning” locations on the map in the editor, store them in a database, then in the game select one randomly from the database, and mark it as “used”.

Just pulling this idea out of my ear: how about having a “Current Quest” level that’s always loaded, and covers the entire playable space, but the only thing that exists in that level are markers for quest monsters and rewards that just have some sort of overlap volume around them. By the time you get near the marker, the level around the marker has already streamed in, then the volume overlap will initiate the spawn of the monster/reward.

Have no idea if this works or not, but just throwing something against the wall to see if it sticks.

Adding to kirk’s answer, you could make your maps separated in, at least, two parts: the stuff that is always there, and the stuff that is there only when the player is close.

So you can maintain the permanent stuff always loaded and the more processing intensive stuff only when the player is near it.

Hmm, making the actual markers persistent is a really good idea, but it would also mean making quest locations semi-permanent: if you play long enough, you’ll learn where every location is, and noticing the repetition can start to grate on you. As an alternative, I suppose I could simply stream a level in for a split-second, randomly find a location within its navmesh, then stream it out again before anything lags.

There’s also a slight performance challenge inherent there, since at least a portion of my quest markers are components in actors (doorways, computer terminals, that sort of thing), and I wouldn’t want to keep dozens of actors in memory even when the player was far away, so I’d need to place the actor in one layer and the component in a separate layer, and write a separate system to couple/decouple them so the correct objects were highlighted and labelled as you drew close.

You don’t have to show all the markers all the time, only the ones the player is currently using (if I understand your problem correctly), the rest just stay invisible.

Ideally, you’d need a system where you can set some properties and configure some logic, that gets stored and then subsequently executed when the specified level is streamed in. So in a sense you delay any quest initialization that is dependent upon actors in unloaded levels, and only run it when the level gets loaded.

I think making a system to do this properly (basically dealing with anything like this relating to unloaded levels) and in a flexible way is a pretty huge undertaking.

That’s what I was concerned about, thank you- it seems as if it’ll be easier to simply avoid requiring any knowledge of unloaded content.

How about split all your nav-data into separate level, load it when player enter into world and keep it persistent? Then you can use your “entire map were loaded at once” solution, with 1 exception - you can’t just spawn monster in unloaded location(monster would fall through nonexistent ground), instead you need to spawn actor-spawner there, and when location around this actor-spawner would loaded(i.e. your player is near) actor-spawner should spawn monster, when you kill the monster and complete quest, actor-spawner should be destroyed.

The only thing: I’m not sure is it possible to save only nav-meshes into separate level.

That’s a good question, and one I’m not sure on- the way I’ve handled nav-meshes is to build one giant honkin’ navmesh generation volume that encompasses the entire space within which levels can appear- my understanding is that whenever a level is streamed in or out, the navmesh regenerates itself to include/exclude new terrain.