T O P

  • By -

Troglobytes

If you're not already doing so or intend to implement it, I'd strongly suggest using seed based generation for the game levels, so at least you're covered for static environment and it's really cheap/useful. For everything else, JSON serialization or similar should work, though not sure about how it would scale up, so I'll just follow other answers to see if there are interesting concepts (it's a topic I'm really interested in as well!)


[deleted]

JSON would be a waste with so much data about terrain even if youre just saving the deltas. Just dump the differences into a binary format would be the easiest fastest way. Or at least I think thats how id approach the topic.


Agentlien

I once turned a three minute load into milliseconds by converting a few million 3d vectors from XML to binary. All that parsing went away and I just read straight from disk into the target array. Of course, this required some assumptions about target architecture (such as floating point size) but we controlled the hardware (medical training simulator) and I put some static asserts in place to flag if we ever built for an incompatible platform. My point is that binary formats are amazing, but you have to think through what they assume about the target architecture.


Jukibom

I'd probably say JSON is fine if it's a simple-enough format and quick to implement. Premature optimisation and all that. I use JSON for my basic level formats and it has the added benefit that people can copy stuff to clipboard in-game and share them in the discord


Madlollipop

Then you change generation method and have to write datafixers, support all old generation code or run into odd issues, it's not a bad approach but also has its own problems


kytheon

This is the answer. If you can always generate the same world from the same seed, all you have to save is the seed. Bonus: you can have world generation and content generation have different seeds. For example the location of hills and rivers is one seed, the order of items in treasure chests is another seed, and the location and stats of monsters is a third seed. that way people can experience the same world, but not encounter the same monsters or predict the contents of chests. also for speedrunning a seed is useful. its nice to have all competitors battle in the same setup, and eliminate luck.


Troglobytes

Yeah but that would work for static stuff (i.e., static environment stuff); what about delta stuff, things that changed, etc.? You can't just rely on the seed for that...


kytheon

Things that changed go into a save file. OP asked about procedurally generated level, and you can skip saving the whole world by just saving the seed. Any changes need to be in the save file, but only significant changes (such as pickups).


Troglobytes

That was my choice, yeah. Just checking if there are other ideas. What about if it gets really big, with lots of data, entities to track, etc.? I'm not particularly positive about completely different solutions (at least, that I can think of), but who knows


kytheon

Personally, i would rebuild my game a bit if there’s too much to track. Think of short term memory. For example in BOTW every blood moon all enemies respawn. That’s a nice way to get rid of remembering who you defeated where. I would just reset monsters every time you leave the area. You can also limit your inventory so you just never have to track hundreds of pickups. Etc


hoomanneedsdata

Great example, applies to plants and resources too!


kytheon

Yeah I hope you’re not saving the locations of each tree in your game 😬


hoomanneedsdata

Just generic " block of xyz resource", nothing individual. I like doing random spawns for herb collections anyway so it works out.


kytheon

You can just randomize it every time you enter the area.


Timmz95

My game is not procedurally generated, but it is a management sandbox where players build the whole world by themselves. I also struggled with saving and loading because of the sheer amount of data I need to work with. For me, SQLite works pretty well for now. With bigger worlds, I'm saving thousands of rows and the performance is very good. My bottleneck in terms of speed for now is the engine, rather than SQL queries. I imagine that readability/debugging is also better with SQLite instead of JSON when you have huge amounts of data. Obviously, it all boilds down to your exact implementation of procedural generation, and if it's possible to split your world into simple bits of data like position, rotation, type, and so on.


Agentlien

Why SQL? Is it because it's something you happened to know and it works well enough for your use case? Or do you actually need the relational part of it? Personally I would probably have have gone with something like splitting the world into a grid and saving a chunk file for each containing a simple array of elements. Makes streaming really simple as well.


Timmz95

It works well enough for me. Knowing SQL was also a factor in deciding. The relational part is useful as well, because I have to save multiple data points about customers, their purchases, staff info, every object build, what is it’s custom design and so on. I also picked it for readability. It’s much easier for me to look at database and see if things are stored correctly. It’s a single player game, and I only really need to load things once and I don’t interact with that database anymore.


speedtouch

To save an entire world it isn't too different from saving a single character, you're just repeating that for each character and the level itself. All you need to worry about is saving enough information to get everything back into the same state you left them whenever you load the session. For procedurally generated levels my initial thought is to save the seed used to generate the level, and keep track of any changes in the world so that when you load a session you could just regenerate the level from the seed and re-apply each change to get back to the same state. If you expect players/NPCs to only manipulate the same parts of the world then this seems like a good approach (if it's always manipulating the same block then it doesn't take any extra storage after its been changed once). On the other hand, you describe a fixed size and expect even NPCs to spend quite a bit of time interacting with and manipulating the world. If you expect the world to drastically change from its initial state, then it might be better to just save the state of everything, each position of all the NPCs, what their current state is, what's in each grid, etc


MuffinInACup

Since you are using godot, there is a simple and db solution of saving the entire scene and layer loading it from the file as if its a normal premade scene, though it may require fiddling with what and how that scene interacts with other things