ID:148969
 
Ok, I'm making a map editor program for Final Fantasy Flashback. I'm using a base 100X100 grid, and a single proc goes from tile to tile, reads the variable info from each turf, and records it in the save file. Only thing is . . . the save files are huge! The last one I generated was 175MB (with little turf modifications). Does that math sound a little bit odd to anyone else? 100X100 . . . . That's just 10,000 tiles. 175MB/10,000 = 17.5kB/turf?? Why would each turf take up so much memory? As I said before, I don't store the whole turf, only the vars (a max of about 6 per turf).


Also, what exactly does this mean as a run-time error?

ERROR: maximum number of strings exceeded (65535)!
What do the vars in the turf refer to? If they refer to other mobs/objs/whatever in the world, those mobs/objs/whatever will also be saved with the turf, which could hugely inflate your save file.
Gakumerasara wrote:
Ok, I'm making a map editor program for Final Fantasy Flashback. I'm using a base 100X100 grid, and a single proc goes from tile to tile, reads the variable info from each turf, and records it in the save file. Only thing is . . . the save files are huge! The last one I generated was 175MB (with little turf modifications). Does that math sound a little bit odd to anyone else? 100X100 . . . . That's just 10,000 tiles. 175MB/10,000 = 17.5kB/turf?? Why would each turf take up so much memory? As I said before, I don't store the whole turf, only the vars (a max of about 6 per turf).


Also, what exactly does this mean as a run-time error?

ERROR: maximum number of strings exceeded (65535)!

Do you store everything in its vars list, or do you manually store 6 variables? To see if its storing the correct things etc. ExportText() the savefile to a .txt file and read it.

Alathon\\
In response to Alathon
I've been using a file system similar to this (not exactly the same):


mob/verb
save_turfs()
var/savefile/G = new("maps/test.sav")
G["turf path [location_modifier]"] << some_turf.type
G["turf name [location_modifier]"] << some_turf.name
G["turf density [location_modifier]"] << some_turf.density
G["turf icon [location_modifier]"] << some_turf.icon
G["turf icon state [location_modifier]"] << some_turf.icon_state


etc.
Keep in mind that while some-turf and location_modifier here are undefined, I said this isn't the exact code. The save part works, but the load part crashes (too large a save file I guess?). I use it in various for() loops. Those are all of the vars being stored for the default turfs. Other turfs have 3-5 more, but I haven't even started using them yet. Is this not the most efficient way?
In response to Alathon
I tried using the ExportText() method as per the example in the reference section. For a 10X10 section, the file size was 2.4MB. That would mean for the entire 100X100 grid, the resulting text file would be 240MB. o.O This obviously isn't the way to go. Any other suggestions?


edit - I tried compressing the 2.4MB text file and it compressed to 48kB!!!?!?!? Where does the inefficiency lie?


edit 2 - even more bizarre: The original 175MB .sav compresses to 1.6MB. That's great if you want to send files back and forth, but the host had better have a huge hard drive. o.O Again - why is the byond save system so inefficient?
In response to Gakumerasara
Gakumerasara wrote:
I've been using a file system similar to this (not exactly the same):


mob/verb
save_turfs()
var/savefile/G = new("maps/test.sav")
G["turf path [location_modifier]"] << some_turf.type
G["turf name [location_modifier]"] << some_turf.name
G["turf density [location_modifier]"] << some_turf.density
G["turf icon [location_modifier]"] << some_turf.icon
G["turf icon state [location_modifier]"] << some_turf.icon_state


etc.
Keep in mind that while some-turf and location_modifier here are undefined, I said this isn't the exact code. The save part works, but the load part crashes (too large a save file I guess?). I use it in various for() loops. Those are all of the vars being stored for the default turfs. Other turfs have 3-5 more, but I haven't even started using them yet. Is this not the most efficient way?

The one thing that makes me see why the file is so big, is your saving every last turf's icon, I did this as a test, I took one DMI, with a one-color green square, thats 34 bytes, now, 100x100 is 10,000, 34 times 10,000 is 340,000. I believe thats 340KB. Now, take every iconstate in that file, lets say they all equal 34 bytes to, times that by 10,000 for everystate.. It adds up preaty fast as you can see. I think that might be your problem. One way you could take care of that is save a text var for the icon's name, and when loading up the turfs make their icons equal the right iconfile.
In response to Darkness
Good call. Thanks.
I agree with the suggestion that your savefile is huge because of icon info getting written for every single turf. Fortunately, if used correctly, savefiles will automatically avoid this sort of redundant information storage. What you need to do is write the turf map as part of a single object, so that it can treat the whole thing as a single operation.

Example:

MyMap/Write(savefile/F)
   F.cd = "turfs"
   for(var/z=1; z<= world.maxz; z++)
      F.cd = "[z]"
      for(var/y=1; y <= world.maxy; y++)
         F.cd = "[y]"
         for(var/x=1; x <= world.maxx; x++)
            F.cd = "[x]"
            F << locate(x,y,z)
         F.cd = ".." //back into y directory
      F.cd = ".."    //back into z directory
   F.cd = ".."       //back into turfs directory
   F.cd = ".."       //back into the original directory


You would then write the whole thing like this:

var/MyMap/map = new
F << map //write it all in one operation


Also, what exactly does this mean as a run-time error?

ERROR: maximum number of strings exceeded (65535)!

This is a limitation that will be removed in the future. It probably happened because you created a unique directory name for every turf in the map. The heirarchical structure that I used in the example above would avoid this.

Unfortunately, this method of saving the map will probably still be slow. See how it goes!

--Dan
In response to Dan
Dan wrote:
I agree with the suggestion that your savefile is huge because of icon info getting written for every single turf. Fortunately, if used correctly, savefiles will automatically avoid this sort of redundant information storage. What you need to do is write the turf map as part of a single object, so that it can treat the whole thing as a single operation.

One other thought here: Are the turfs also saving their contents?
I haven't experimented much with this kind of savefile, but I think it'd be nice if there was a really easy way to prevent a turf from saving its contents, so they could save themselves instead. This would get around screwy errors caused by a copy of a mob getting saved, for example. As far as I know, the only way to save less than full information is to implement the soft-coded version of Write() as listed in the Blue Book.

Lummox JR
In response to Dan
Dan wrote:
Unfortunately, this method of saving the map will probably still be slow. See how it goes!

How slow is slow in this case? Seconds, minutes on a fairly large map?


/Gazoot