ID:113905
 
Tackling the randomizing map generator was pretty hard, but it is done with some help*, and it finally works! Takes about 2 minutes to create a world now.

Here's a finished version of the demo I made last post.
Note: if it stalls for a bit let it finish up; usually happens when it reaches "placing dirt" step.

Here's some examples:


Now this is why I need the motivation. I'm not sure how I should go about doing map saving. Does anyone have any suggestions?

I need the maps to able to save at least every time the game shuts down, and perhaps periodically for safe measure. I may also need a way to encrypt it so people can't just edit their maps.


*Special Thanks goes to Fl0ak who recommended AbyssDragon's basic math library which let me make a smoother edge to shallow water. ;).
you totally builded your own net dream
Thanks.
That depends upon how you want to save the maps, whether you want it to be lag free, and whether or not you want to use SQL vs Write().

If you don't mind massive lag and possible crashes, just add every turf to a list and save the list, along with a hash, then rehash and compare the 2 at load to make sure it's the same map.

If you want to go with Write(), but don't want the massive lag of writing a giant list to a file, you can use a for loop on the turfs that defines a variable/I, writes the turf to savefile/F["[I]"], then increases I for the next one, then does the same with loading, with a for loop on the file with the same increment setup.

Either way be sure you turn off recursion checking or it will crash if you have a big map.

As for SQL, there are libs out there for it, and I really don't know much about it myself.

I don't see why you would need to save the actual maps themselves, though. Couldn't you just save the variables entered to create them and regenerate the same map when it's loaded, and only save the objects in the world? If all you need is object saving I have a working example of the second option(the one with tons of save buffers) from my work on Archipelago Remastered. Saves 3MB worth of objects in a matter of seconds with no lag/crashing.
The maps are random every time they're made, but can also be changed in several ways by not just buildings. Which is why just saving buildings like I did before won't be enough. I also would appreciate the example. Thank you.
proc
TestSave()
world<<"Saving objects!"
var/I = 1
var/savefile/F = new ("world.sav")
for(var/turf/T in world)
if(T.x)
T.saved_x = T.x
T.saved_y = T.y //location.
T.saved_z = T.z
F["[I]"] << T
I++
sleep(0)

That's a general example of what it should look like.
Actually, you can use rand seed to get the same generated output every time.
I didn't get much from Robertbanks2's jumble about SQL, but his advice about saving parameters rather than maps is sound.

Your map generation is not truly random, but psuedorandom. Accordingly, you could save a seed of a psuedorandom generator (simply a number) to represent a randomly generated map. Look it up, we even have an article about this somewhere in DreamMakers.
Duelmaster409 wrote:
Actually, you can use rand seed to get the same generated output every time.

If I understood the reference page correctly, this is not a good idea, since he will doubtless be using rand() elsewhere. The safer alternative is writing your own pseudorandom number generator.
Toadfish wrote:
I didn't get much from Robertbanks2's jumble about SQL, but his advice about saving parameters rather than maps is sound.

I didn't actually try to explain much of anything about SQL, as I personally don't know much of anything about it in the first place. Though I will admit to rambling a bit. I posted an example of what I WAS rambling about just a moment ago if you're interested in seeing what I meant.
I misunderstood, then. The code you posted is no better than adding all turfs to a list and saving that, which is what you said we should avoid! You and Jittai would benefit from reading about pseudorandom number generators and how they work.
That code wasn't actually used on turfs when I made it, it was used to save the massive amounts of objects produced in a similar game, and yes, actually, it is tons more efficient than adding them all to a list and saving them. Saving to a giant list then writing it is 2 huge operations, while this is a bunch of tiny, individually unnoticeable operations that are performed with small breaks allowing the game to continue processing other things while it's going on. My own testing and experience shows that it functions in roughly 1/4 the time, with quite a lot more stability, and next to no noticeable effect on the players/server.

With that out of the way, no, he shouldn't be using it with turfs, saving his seeds is a much better way of handling it, and there are always ways to avoid changing turfs that are much better than allowing them to be altered at runtime and then saving them later. That said, if he's going to do something like this anyway, I may as well provide him with the best way I know how to do it, and advise against it, rather than allowing him to use an even WORSE method of dealing with his turfs.

But really Jittai, just use a seed for turfs and ignore changing the turfs themselves, in favor of using objects placed on top of them to do what you need to.
No offense intended, but you should understand the process involved behind saving before claiming what you do. I know you want to help but when you don't get what you're talking about very well, you do the reader a disservice.

- There is no way your code takes 1/4th the time as saving from a list, because your code is saving from a list. That's exactly what for(var/turf/T in world) means.
- Your code saves turfs and not objects. If you want to demonstrate object saving, demonstrate object saving.
- I'm not sure what the "2 big operations" vs "many small ones" comparison was about.

This covered, I can also give you a few tips for saving objects:
- Save as little information as possible. If you have an overlay, for example, save the icon name or the cause of it rather than the icon itself.
- If feasible on a randomly generated map, separate your map into multiple regions, and treat them as having individual save states. This will allow streamlining.
This looks almost like a cellular automaton.
@ "Your map generation is not truly random, but psuedorandom." Actually, I'd say it's as random as it can get. The two settings "islands" and "intensity" aren't really parameters. The number the "Islands" setting is set to is how many start points are set in the map (locations randomly chosen in a range) and the "intensity" is how many sand making objects get sent out.

I take the size of the world, divide it by 4, and that acts as an allowance of land. Each time these objects move regardless if they place a tile or not eats up this allowance. This is why with 100 intensity the objects don't get far before they use up the entire allowance.

Which means, I'm not sure how I could use a seed with out rewriting how it's made.

Thank you for the advice everyone! I have at least a direction to look in.

Edit: @"Save as little information as possible", Currently the buildings only save at maximum four variables and only save when those particular variables are changed.
It is important that you realize the only thing random about most computer applications is the time you start them up. Computers can't generate truly random sequences of numbers. Rather, a formula is used to pick a psuedorandom number whenever you call rand(). For this reason, sequences of "random numbers" can be repeated given one knows the seed. Now think about how this relates to random map generation.

Currently the buildings only save at maximum four variables and only save when those particular variables are changed.

This is irrelevant, what's relevant is what those variables contained. If they contained a file (such as an icon), for example, things would quickly become very bad.
I don't use randomly generated numbers to place things. So, I'm not sure how rand_seed() would work from the definition it looks like there's a chance it can be unreliable, perhaps I should post the map generation code, it is all a work in progress/first attempt.

@ "This is irrelevant..." - They're numbers or short text. Name of owner, integrity, etc. Sorry I should of been clearer.

Edit: Did a short test; I made a proc that takes the turfs in the map (sand, dirt, water) gets a representational text-character, the x and y locations and adds it to a list. I then save that list as a file, entire file is 376kb. Both saving and loading time are almost nonexistent.
I don't know why you think your map generation is "truly random" and nonrepeatable if you don't even use random numbers. "Locations randomly chosen in a range?" So you use pick()? Pick() obviously uses rand(), or some variant of it.
After the initial placement of "island source points" pick/rand isn't used. On top of that loading a text file takes less time than to generate them initially.
Then think of what parameters are involved.