ID:1761151
 
(See the best response by Mar big.)
Code:
N/A


So a common thing that I'm going to be doing in my game to change some defined paths that players may have differ to in their save file.

For example, in the first version of the game, I may have an atom like:

/obj/sword


where as in the next version, I might get smarter and create a new datum called:

/sword


is there a way before I call Read that the code can look at a save file and see if any paths in the file are still defined and if not, delete them. Usually, if you would do it with checking, you would get this error:

Warning: type read from file (/card/monster/MICH/the_phantom_knights_of_rugged_glove) is not defined Warning: type read from file (/card/monster/MICH/the_phantom_knights_of_rugged_glove) is not defined Warning: type read from file (/card/monster/MICH/the_phantom_knights_of_rugged_glove) is not defined Warning: type read from file (/card/monster/MICH/the_phantom_knights_of_rugged_glove) is not defined Warning: type read from file (/card/monster/MICH/the_phantom_knights_of_rugged_glove) is not defined runtime error: cannot append to list proc name: LoadFile (/mob/proc/LoadFile) source file: Saving and Loading.dm,13 usr: Dev (/mob) src: Dev (/mob) call stack: Dev (/mob): LoadFile() Dev (/mob): StartScreen(Dev (/mob)) Dev (/mob): enter()

Anyway to prevent this error and actually delete the undefined path?
Well, I don't typically use Read() or Write() in my saving procedures. I use a method that I personally find to be easier to manipulate. I'm not sure if this is better in all cases or even your case, but it seems worthy of presenting.

            proc
Save()
var/savefile/S = new/savefile("[playerPath]/[copytext(src.key, 1, 2)]/[src.key].sav")
S["level"] << src.level
S["xp"] << src.xp
S["max_xp"] << src.max_xp
S["stat_points"] << src.stat_points
S["stats"] << src.stats


What is being done here is that it pulls from the savefile certain variables. You can check things like so:
if(S["level"] && isnum(S["level"]))
S["level"] >> src.level

if(S["stats"] && istype(S["stats"], /StatsDatum))
S["stats"] >> src.stats


By checking the type and whether or not it exists, you can avoid incompatible data types. You can also just use istype() to check the type and make changes accordingly by typecasting it like so:

if(istype(S["stats"], /StatsDatum))
var/StatsHolder/StatsDatumNew/stats = S["stats"]


As long as StatsDatumNew holds all of the previous variables, procedures, and verbs as StatsDatum, it should run perfectly fine. Not even that, as long as you're only calling to this new variable for what it only has, it will work. Just don't check it for anything it doesn't have and don't call procedures it doesn't have.

Once you've made the new type cast, you can write to it again to overwrite the error.
Yeah I have tried creating my own saving data but the problem is that everytime I try it, I always seems to load the wrong things. Thats why I am having trouble :/

EDIT: If your interested in what system I am using, I am using Garthors Safe Save which works fine for my game.

This pretty much what I took out:

proc
//proc to make a hash from a text string, end-user should override to be unique
make_hash(var/text)
return md5("[world.hub_password][text]")

//saves the savefile F in a safe format under the specified name. Safe savefile is returned.
Write(var/savefile/F, var/name)
var/savefile/F2 = new(name)
F2["file"] << F
var/hash = make_hash(F2.ExportText("file"))
F2["hash"] << hash
return F2

//loads a savefile saved using safe_save. Readable savefile is returned.
Read(var/savefile/F)
//ensure that we have a file where we say we do
var/text = F.ExportText("file")
if(copytext(text,1,14) != ". = filedata(")
return null

//grab the savefile
var/savefile/F2 = new(F["file"])
//check its md5
var/check = F.ExportText("hash")
var/hash = make_hash(text)
if(check != {". = "[hash]"\n"})
return null

//file passes the check, so return it
return F2
Best response
Read this post by Lummox JR on savefiles here. Basically you need to keep track of your versions.
I'll gis a looksy later :) thanks