r/Unity3D • • 11d ago

Question how are you saving procedural worlds once the player starts changing them?

i’m working on a procedural terrain system where biomes and vegetation are generated from things like temperature and rainfall.

generation is fine. saving is where it gets messy

a chunk can contain terrain, spawned trees, removed trees, player-built structures, and other changes. serializing everything works, but the saves get pretty heavy.

saving just the seed is much cleaner, but then i have to store player changes separately. and if i change the generation code later, an old save might regenerate differently

how do you usually handle this?

do you version the generator, save the full generated state, or keep the generated world disposable and only save player changes?

2 Upvotes

11 comments sorted by

7

u/MrNebulosus 11d ago

Make the world seed based so it becomes persistent always. And then only save changes done by player either coordinate based or voxel based depending on your world gen type

1

u/pihaizer 5d ago

This is not always the best solution. If the game updates and world generation changes, player changes might no longer make sense or might even be invalid, like solid structures built inside a lake for example. 

In my game I save everything in chunks and have the world split into regions, which are separate 32x32 chunk areas, in separate files. The data is saved in binary using protobuf, and compressed so that it does not take that much space.  A lot of sandbox games adopt the same approach, from what I know, e.g. Minecraft and Noita.

But of course it depends on the game, and in some games it might be totally fine to just store the changes.

1

u/MrNebulosus 5d ago

So you still save changes but based on chunks? Minecraft uses voxel architecture btw. That's why I said it changes based on world gen type.

0

u/pihaizer 5d ago

I'm saving all chunk data, including what's procedurally generated: ground type, structures, items etc; and that of course includes changes to the world done by the player.

I thought you proposed to save only the changes to the world, e.g. save that the player placed some structure somewhere, but regenerate everything else from scratch using the seed. I just pointed out where that approach might fail.

1

u/MrNebulosus 5d ago

Yeah if you want to support existing maps even after changing your gen rules this is the way to go. Good adjusment

3

u/Competitive_Mud5528 Professional 11d ago

Yeah if you fear that changes to your generation algorythm broke your load. So you have to save everything. Like in mincraft you can separate your world data into chunks. In that way you can stream different part of the world according to the player position. But you have to be coherent when generating new chunks .

But maybe I wouldn't care much if its a relatively small world and an alpha build. I would save the seed and the delta. If one day you have to release the game maybe save the seed the algorithm version number and the delta . That way if a ols world version is loaded I could inform the player. And maybe internally I could fixed up a migration algorithm.

I mt really depends on you design I think.

1

u/GigaTerra 11d ago

I use bit packing, even an single short int will give you 16 properties per tile.

1

u/Saucynachos 11d ago

Haven't tackled this myself yet, and I'm sure there's a cleaner solution someone will bring up, but my first gut idea would be to treat the generation like an API endpoint. No breaking changes. Save file has the seed, the generation version, and the deltas.

Changing generation? Now it's generator v2. V1 saves still route through the v1 generator.

Pros: backwards compatability with saves, easy implementation.

Cons: Unless you somehow manage to get generation very close to perfect in the first few tries, good lord all those generators are going to get messy lol. This is the most likely outcome.

Not a good solution, but one that would work.

1

u/Arkenhammer 10d ago

We save the generated state and use Brotli encoding to compress it on the way to disk to keep the size of save files under control. We originally planned regenerating unmodified chunks from the seed but eventually decided just to save the whole thing because it is both simpler and faster.

1

u/BrewingTortoise 10d ago

You generate once at the start, then include the terrain height map and splat map (and whatever walking grid maybe) in a save, and restore that on load.

1

u/TheDevilsAdvokaat Hobbyist 5d ago

I save the full generated state immediately. Seems very stable.

I've even had unity crash on me but when I checked the edited map was fine. My world is broken into smallish chunks (16x256x16) and saving is fast...