Hi, the past few days I've been evaluating the Voxel Farm Indie trial for a Unity project.

Some background: my product is developed in Unity, targeting Windows, and is multiplayer with an authoritative server. The world is designed to be hundreds of kilometers in diameter. I'm very comfortable with C#, and can work with C++ although my experience with C++ is much more shallow. So far I've looked through the examples and have a test project implementing some concepts from my own application combined with Voxel Farm.

In general so far I like what I see. I've been able to work with the C# API and the C++ DLL plugin code and make a couple modifications necessary for my project to both. The main things that attracted me to Voxel Farm are the LoD system enabling long distance views, and the engine performance. Some of the other features are extremely appealing as well, so I'd really like to make this work for my project.


1. I'm trying to understand how saving and loading/serializing the voxel data works. This is to answer two related questions: how can I save the current world state, and how can the server serialize and share the world state with new client connections?

My application uses a database save file. For my current voxel terrain solution I serialize the entire terrain state and save it to this database file. When players connect to the server, a copy of this data is sent to the new client. While the game is running, the commands such as placing/removing blocks are broadcast to all players who then perform changes to the voxel system locally. The actual saving and loading from the database happens asynchronously in a separate thread.

Of course there are two aspects to what constitutes the voxel data: the biomes created in Voxel Studio, and user modified content. Ideally when new players connect I want to serialize and send only user modified content in the region (say, within a kilometer) of the player, then update them as they move through the environment (I have a publisher/subscriber model based on location for network communication within the application). Otherwise I would need to synchronize the entire environment state on connection, then send all changes regardless where they are to all players at runtime.

How can this be accomplished with Voxel Farm? I'd prefer to work within the C# API if possible, but I've been going through the C++ plugin DLL trying to understand how everything interacts and I saw "CBlockIOHandler" and "CBlockDataCachedIOHandler" which I /think/ are used for saving.

Sorry if I'm all over the place with this question. I really just need to know how to serialize and deserialize different regions of the voxel structure so I can handle saving and synchronization myself. And going through the API I *think* I'd want to do it by Cell so that I can just synchronize players around the same Cells.

2. On the Unity Voxel Farm component, my understanding is "World Origin" indicates the center of the voxel structure to render (reference frame). My application uses a shifting scene origin to keep the user within 2000 units (meters) of the scene to avoid floating point issues.

World Origin is a constant value after Voxel Farm is initialized. How can I shift the origin at runtime so that my terrain is kept in the proper location? Is there a C# API for this or does it require changes in the C++ DLL? I already have a mechanism in my application for shifting and tracking the position of any objects in the simulation I just need to know how to transfer that to Voxel Farm.

3. Can I crop out a selection of voxels and turn them into a free mesh? Basically exactly like fragments when cutting down trees in the toon biome, except instead of relying on whatever Voxel Farm is doing under the hood I want to be able to say give me the mesh within the volume of (x1, y1, z1) to (x2, y2, z2).

4. In Voxel Studio, I would like to scale up the terrain data since in Unity I set the Voxel Farm world scale to a small value. I was playing around with the "Toon Biome" example changing the SizeX/SizeY/SizeZ values on the "Instances" like Stone2 or Stone3, but I don't see anything changing in the Render view. How I go about scaling an arbitrary Voxel Farm project?

5.  Does the indie license include the VoxelFarmPluginDLL (VoxelFarm/Plugin.DLL) C++ code or is that only include in Pro? 

0 0
1) It is possible to supply your own interface to loading and saving blocks. This is something that you would need to do on the C++ side for the plugin DLL. The full source code for the Plugin DLL is included in INDIE. You will find an example an object that implements the interface if you look for the definition and use "blockIOHandlerR40" property in the DLL code. This implements a loading/saving mechanism to a local folder. In your case, you would create something similar to "blockIOHandlerR40" and use it to store and load to your own repository. If no local saves are required, replacing the current "blockIOHandlerR40" by your own implementation may be the simplest approach.

2) World Origin creates an equivalence between the supplied Voxel Farm coordinates and Unity's 0,0,0 origin. If the Voxel Farm object is initially placed at 0,0,0 in Unity, in theory, you could move the whole object by the same amount you have shifted everything else in the game. We are not sure this will work, however, because the current version is not offsetting coordinates by the Voxel Farm's transform and instead it assumes everything goes to Unity's absolute 0,0,0

3) This is something the Voxel Farm engine can do, but it is not in the currently exposed API. You would need source code access (PRO) to access this code.

4) Distance/length units in Voxel Studio can have any meaning you want. You would not resize the world inside Voxel Studio, but inside Unity by modifying the world scale constant.

5) The INDIE license contains the full C++ source code for the DLL used by the Unity plugin.
1 0
Thanks for the quick response!

1. So I followed your suggestion in my test project and I was able to get the data to serialize the way I needed. I rushed it just to get a proof of concept working, but what I ended up doing was making a copy of CBlockIOHandler then wrote a custom class with similar signatures as CVoxelFileDB for the "blockDatabase". Instead of loading a file and reading/writing to it, I pass function pointers to C# delegates that handle the load, save, peek, erase, etc. commands. Then on the C# side I use a ConcurrentDictionary to cache data as it is being saved and loaded from the actual database. This works fine for now.

For multiplayer, the server would have all the blocks saved index by cell ID. As players move around, I can push the new regions of blocks to the player and update their local view of the saved block data, but then on remote clients how would I trigger Voxel Farm to refresh those regions so they are reloaded? Does ScanArea do this (trigger VoxelFarm to reload a region) or is that just for detecting fragments?

2. Yeah I noticed the generated GameObjects are not parented to the Voxel Farm client GameObject (I changed the HideFlags from HideAndDontSave to just DontSave to get a better idea of what was going on). I use a similar technique you described for my current terrain solution. I'll try parenting all the generated GameObjects to the Voxel Farm Client GameObject and then shift that. That should work, although I'll probably also have to compensate for the fact that the scene root position has moved so the Focus Target's position needs to be offset (and offset rays for carving and such), but that's not a big deal. 

3. Okay understood.

4. Yeah I understand that point, what I meant was when I modify the world scale in Unity (because I want higher voxel resolution than the default) it shrinks all voxel content. That makes sense, so I would need to modify the project in Voxel Studio to compensate. I'm more focused on evaluating the SDK side of the toolset at the moment so I don't have a strong grasp of how to work in Voxel Studio yet.

Using the Toon Biome as an example, I know I can go to the "Cartoonish Terrain" component and increase Heightmap Unit Size to increase the ground dimensions (basically the latitude and longitude), then I think if I increase Heightmap Unit Size that can increase the altitude (making mountains taller and so on). But what I can't figure out is how to scale voxel instances like the trees and rocks in the toon biome that get converted into voxel content. I'd assume that I would just change the SizeX/SizeY/SizeZ values in their Item Properties, but changing these values don't seem to do anything. I suppose I could just modify the source mesh, but that would be somewhat inconvenient. It looks like I can change the scale of a voxel instance when I'm initially importing the mesh.

Is there a way to change the scale of voxel instances after they have been imported? How about at runtime, or would that require working with L-Systems/prefabs (I haven't had a chance to read much up on this part yet)?

Thanks again!
0 0
1) Scan area is only for detecting physic fragments. To force a client view to recompute sections of the world, call the ClipmapView's "processModifiedCells". To this function, you can pass a list of cells you want to be recomputed.

2) Yes, besides changing the parenting of cell objects you will also need to transform the focus and edition coordinates.

4) You can scale the terrain by changing the "Unit Size" property, making each sample in your heightmap take a larger number of voxels. Voxel instances cannot be scaled this way because they are already made of voxels. They are similar to a 2D sprite in that sense, once you have an instance voxelized at a certain size, it can only appear at that size. To have larger instances you will need to re-voxelize them. If you are not using voxel instances (trees for instance) the meshes for the instances can be sized on the game-side.
1 0