ID:147702
 
I am using a regular map with turfs on areas and objects in those turfs. I would like a portion of the map defined by an area (area/savezone) to be saved. Here is what I got so far:
area/savezone
atom/var
saved_x
saved_y
saved_z

world/Del()
var/i=1
var/savefile/F = new("data/areas.sav")
var/area/Area = locate(/area/savezone)
for(var/turf/T in Area.contents)
for(var/obj/O in T.contents)
if(istype(O,/mob/)) break
O.saved_x = O.x
O.saved_y = O.y
O.saved_z = O.z
F["[i]"] << O
i++
F["count"] << i
..()

world/New()
if(fexists("data/areas.sav"))
var/area/R = locate(/area/savezone)
for(var/turf/T in R)
for(var/obj/O in T)
del(O)
var/savefile/F = new("data/areas.sav")
var/count
F["count"] >> count
for(var/i=1, i < count, i--)
var/obj/O
F["[i]"] >> O
O.loc = locate(O.saved_x, O.saved_y, O.saved_z)
..()

It 'works' (as in no runtime or compile-time errors) BUT references are not preserved. When the map loads some of the objects(especially objects that run on strings of references [see note 1]) lose their references. I heard that when you save a reference the object being referenced is saved as well. The circle like action (that occurs VERY often) may be what is causing the problems.

Note 1: Objects such as wires that have 2 variables. Each one of those variables points to another wire which in turn points to another wire which in turn... There is a chance that these form a circle of references aka
Obj1.ref = Obj2, Obj2.ref = Obj3, Obj3.ref = Obj1.
It's very possible they -are- being saved, but what's being loaded is a new instance of the object that was referenced, absent any information or instructions re: location.

What I do when I need saved objects to "link" back up with each other is have the references converted to tags during saving, and then locate(the tag) a moment after loading.
In response to Hedgemistress (#1)
Which procedure do you think would do the job better?
New() or Read()
In response to Exadv1 (#2)
You could do it either way, in world/New() as part of the loading proc, or in Read()... my inclination would be Read(), though... keep the stuff specific to a given object within that object's code.
In response to Hedgemistress (#1)
even nicer is... That \ref[src] will give me a tag!
In response to Exadv1 (#4)
You realize if you're not assigning a tag prior to generating the reference, the next time the game is loaded, another object may be created with that same ID before the objects are finished loading, which (if both objects are things that need to be saved and re-referenced)could lead to funky conflicts?

Depending on what you're doing, this conflict could be anywhere between likely or impossible... but I'd still recommend, as a good habit, generating your own unique ID numbers.
In response to Hedgemistress (#5)
Here is hwat I developed for a simple 1 line input device (but all the others are really the same anyway)
var/s_tag
Write(savefile/F)
F << "object\ref[src]" //s_tag
F << ((line1)?("object\ref[line1]"):null)
line1 = null
..()
Read(savefile/F)
F >> s_tag
F >> line1
..()
tag = "[s_tag]"
spawn(50)
line1 = locate("[line1]")

Sadly when I start using the 'precise' same code as last time it gave a runtime error (cannot modify null.loc referring to line O.loc = locate(...) )
and when I prefixed with if(O) (which shouldn't have to be done!) it just crashed :/