This is an expanded save/load routine I have come up with. It will save and load an global table. So all variables you want to have saved needs to be in that table. In my example it's called Setting, but you can name it what you want. Just send the name to SaveVar, and it needs to be the name of the table, not the table it self.
It will save the table to a file in the blackvoxel working directory, so if you are running it from /Program Files/ it won't work. And it does not distinguish between different universes.
Main program.
// Test of Loading and Saving variables
NeedLoad <- 0;
Pos <- [0,0,0];
// This is just an example testing all different kind of variables that can be stored.
Setting <- {
Len = 1,
Dir = 0,
Moves = 0
List = [1,2,3,4,"Hello World!"],
Ind = { A=[0,1,2], B={A=1,b=2}, [0]="Anka"},
Hello = "World!",
};
function Dump(var)
{
local i,v;
local s="";
if (typeof var=="integer") {
s = var+"";
} else if (typeof var=="string") {
s = "\""+var+"\"";
} else if (typeof var=="array") {
s = "[";
foreach (v in var) {
s += Dump(v)+",";
}
s += "]";
} else if (typeof var=="table") {
s = "{";
foreach (i,v in var) {
if (typeof i=="integer") {
s += "["+i+"]="+Dump(v)+",";
} else {
s += i+"="+Dump(v)+",";
}
}
s += "}";
}
return s;
}
function SaveVar(varname)
{
local c,s,filename;
s="";
filename = format("%d_%d_%d.save",Pos[0],Pos[1],Pos[2]);
if (varname in getroottable() && typeof varname="string") {
if (typeof (getroottable()[varname])=="table") {
foreach (i,v in getroottable()[varname]) {
if (typeof i=="integer") {
s += "::"+varname+"["+i+"]<-"+Dump(v)+";\n";
} else {
s += "::"+varname+"."+i+"<-"+Dump(v)+";\n";
}
}
} else {
s = "::"+varname+"<-"+Dump(getroottable()[varname])+";\n";
}
c = compilestring(s);
writeclosuretofile(filename,c);
}
}
function LoadVar()
{
local s;
s = format("%d_%d_%d.save",GetX(),GetY(),GetZ());
try {
dofile(s);
remove(s);
} catch(e) {}
NeedLoad = 0;
}
function SavePos()
{
Pos[0]=GetX();
Pos[1]=GetY();
Pos[2]=GetZ();
}
function Voxel_Load()
{
NeedLoad = 1;
}
function Voxel_Unload()
{
SaveVar("Setting");
}
function Voxel_Step()
{
local i,j,v,done;
if (NeedLoad)
LoadVar();
// Do stuff
SavePos();
}
If you place a programmable robot in the same spot that one was Unloaded before it would load it's variables. So to prevent that you need to have a script named 0.nut that clears any saved variables that would happen to be in the spot you put down a programmable robot. (It's not a good idea to have 0.nut do anything major anyway since it is always automatically started every time you place a programmable robot)
0.nut
NeedLoad <- 1;
function Voxel_Step()
{
local s;
if (NeedLoad) {
s = format("%d_%d_%d.save",GetX(),GetY(),GetZ());
try {
remove(s);
} catch(e) {}
NeedLoad = 0;
}
}
I would have liked to save the variables in a uncompiled squirrel file so you could see and edit it, but it seems squirrel can't write strings to files.
I'm still at a loss to why squirrel is used instead of lua. The trouble the author of squirrel had with lua garbage collection is long since fixed in lua.