Working with larger environments

Izzy posted this 30 October 2017

I'm messing around with an action adventure demo, something similar to dynasty warriors. So far picavoxel and rigify have worked fine even on my really slow rig, but the map currently consists of just one large volume with a huge voxel size.

Its kind of hard for me to articulate the exact scale I have in mind, since I'm just kind of playing around right now, but if you watch a playthrough of most warriors games, sengoku basara games or even ninja gaiden you'll understand.

I guess I'm just wondering what exactly am I looking at here?

Longer loading times? Having to load maps in chunks? Highly efficient map design?

It seems to run fine having even hundreds of rigged voxel models on screen. And right now I only have two goals in mind and that's lots of enemies at once and large, mostly static environments.

EDIT: Say like.. maps the size of the rpg demo times 10, 25 or 50 (or more if you think that's possible)

Last edited 30 October 2017

Order By: Standard | Newest | Votes
GarethIW posted this 30 October 2017

There's a lot to think about with a question like this, and there's a reason that I say in the FAQ that PicaVoxel is not built for large worlds; it involves a lot of work and will be different for every game.

I wrote a thread about large volumes here, so read that first so you can get an idea about the kind of data sizes you'll be dealing with:

So with a large world, the first thing you'll need to think of is scale. On one end you've got Minecraft, where each block is roughly a metre or so, so a player can stand entirely inside a voxel. Minecraft works by streaming in chunks from disk and rendering them as you move around the world. This only really works because of the large scale - you have to run quite far before you get to the next chunk.

On the other end, you've got a game like mine, Jarheads, which works on a very tiny scale with an RTS-like camera:

The map at that timestamp in the video is one of the largest sized maps in the game, and it only takes 10-15 seconds to walk across in a straight line. In Jarheads, I load the entire map into memory at once because of the scale involved. You can simply see too much of the map and move around it too fast for on-the-fly loading and meshing to work. A map that size, by the way, uses around 2GB of RAM.

The Jarheads map code is all-custom; it doesn't use PicaVoxel (it was actually made before PicaVoxel)

The other thing you have to think about is content: how are you going to design the map. If you're going to work with PicaVoxel only, then you have two options: procedural generation, or drawing in an external editor and importing.

For Jarheads, I created my own editor to suit the purpose: It has terrain painting and then the ability to place objects that are made with Magica. Again, all custom, not based on PicaVoxel.

So this has been a bit of a stream of consciousness to get to the point I'm trying to make: it's up to you. You'll need to experiment and do the work. PicaVoxel is a very generic tool that gets you up and running with voxel stuff pretty quickly, but it can't be everything to everyone.

Lastly, some actual practical advice to answer your question. If you're going to try and do this with PicaVoxel, then you have two options:

  1. Have the world be one large volume
  2. Split the terrain up into a grid of volumes

If you use number 1, then you'll need to alter the way that PicaVoxel works because you're going to have to figure out a way of rendering in PicaVoxel chunks on the fly according to character position. You will also have the entire world's data in memory at once (the voxel array stored in Frame.Voxels[]). This will be quite convenient in some ways, but it'll likely use a lot of RAM.

With option 2, you'll have an easier time of getting on-the-fly loading working. You can have one volume for each "grid" tile of your world, and you can use the built-in PicaVoxel functions Frame.ToCompressedByteArray and Frame.FromCompressedByteArray to store and load volumes. You could even make use of the Magica/Qubicle importer code to load volumes from those formats, which will give you the option of using those tools to create your map.

Izzy posted this 30 October 2017

Thanks for the response. Assuming I split the terrain up into a grid of volumes. You're saying I would then use ToCompressedByteArray for the chunks of the map that are currently "invisible" to the player, and then FromCompressedByteArray to populate the world with them once they become visible, correct?

GarethIW posted this 30 October 2017

Well, sort of. But that's only a small part of the problem.

If you had previously written your volumes to disk using ToCompressedByteArray, then you could read them in using FromCompressedByteArray. You might do that if you were making a Minecraft clone with procedural generation of landscape. I get the impression from your original post though that you're after more of an authored experience, where you are creating the map by hand.

In that case, you would be creating the map in a Unity scene, probably by importing your created map tiles from Magica or Cubicle and stitching them together. But even if you did manage to make say a 25x25 map where each volume is, say, 128x128 voxels (plus an unspecified number of voxels high in the Y dimension), that would be a massive amount of data to hold in one scene.

So you would then need a Unity editor script to save those imported volume map tiles to disk, and then at runtime load them in one by one according to visibility. At that point, it would instead be best to load them directly from Magica .vox files, or Qubicle .qb, using the same code that I use in the Magica/QubicleImporter.cs editor scripts. Sorry, this is all train of thought stuff.

I think at this point you probably need to ask yourself the following questions:

  1. What is the scale of the game
  2. How are you going to make the map (authored/procedural)
  3. What level of interaction with the terrain is there (static, destructible)

And then do some tests in Unity to see if you can make a flat world at the size you require. And then work from there.

Last edited 30 October 2017

Izzy posted this 31 October 2017

Thanks again for the quick response, everything you've said has been very helpful and has given me much guidance in terms of design questions.

I think PicaVoxel will work just fine, most of the environment would be static. And the bits of the environment that aren't static would mostly be subject to controlled demolition (so likely it'll be me using the constructor/destructor to construct a pile of rubble from a structure or something to that effect) with a few exceptions within gameplay.

Our 127 members have posted 466 times in 112 discussions