Author Topic: Saving And Loading Vars  (Read 2345 times)

How would I go about saving and loading a player's vars(Example: %client.Gold)?

I haven't worked with it myself yet, but I believe the thing Badspot put in recently would be appropriate here.

http://forum.blockland.us/index.php?topic=174411.msg4480468#msg4480468

$jes::player[%client.bl_id]::gold = %client.Gold;

export("$jes::*", "config/server/jesPrefs.cs", False);

Do not try to export into a .zip file. I accidentally did that once (./ in the command) and it created ghost data that broke the game. Basically, the computer shows no file in the zip or outside of it, but the game says the data is partially there and broken, so it doesn't execute the add-on. Remaking the zip would not delete the ghost data, it was unattached and the only program that could see it was Blockland. My only solution was putting a blank version of the file in my .zip. This happened on Windows XP, not sure it could still happen.

Dang it, Truce... Forgot about that.
« Last Edit: December 07, 2011, 12:13:14 PM by MegaScientifical »

I haven't worked with it myself yet, but I believe the thing Badspot put in recently would be appropriate here.

http://forum.blockland.us/index.php?topic=174411.msg4480468#msg4480468
I don't understand that completely.
$jes::player[%client.bl_id]::gold = %client.Gold;

export("$jes::*", "config/server/jesPrefs.cs", False);

Do not try to export into a .zip file. I accidentally did that once (./ in the command) and it created ghost data that broke the game. Basically, the computer shows no file in the zip or outside of it, but the game says the data is partially there and broken, so it doesn't execute the add-on. Remaking the zip would not delete the ghost data, it was unattached and the only program that could see it was Blockland. My only solution was putting a blank version of the file in my .zip. This happened on Windows XP, not sure it could still happen.
But how would I load it? It says the red is a syntax error:

$Skill::Client[%client.bl_id]::Gold = %client.Gold;
« Last Edit: December 07, 2011, 02:28:45 PM by jes00 »

Do not try to export into a .zip file. I accidentally did that once (./ in the command) and it created ghost data that broke the game. Basically, the computer shows no file in the zip or outside of it, but the game says the data is partially there and broken, so it doesn't execute the add-on. Remaking the zip would not delete the ghost data, it was unattached and the only program that could see it was Blockland. My only solution was putting a blank version of the file in my .zip. This happened on Windows XP, not sure it could still happen.
You sure it didn't just go into a folder of the same name, in the same directory as the zip?

You sure it didn't just go into a folder of the same name, in the same directory as the zip?

... Weird, there's a folder of my zip... For forgets sake, if that's really what happened, I'm going to be pissed. I directly transferred my entire Blockland folder to the new computer, so I never got to test but... Wow, I had asked lots of people when it originally happened, and you're the first to say that. Seems to make sense, too, because there' a vars.cs is here... Holy forget.

Soooo yea, syntax error:

$Skill::Client[%client.bl_id]::Gold = %client.Gold;

Soooo yea, syntax error:

$Skill::Client[%client.bl_id]::Gold = %client.Gold;

You can do $something[%client.bl_id,"gold"] = %client.gold;

To retrieve the data:

%client = someclientobj;
%clientGold = $something[%client.bl_id,"gold"];

I don't understand why we are using global variables though..
« Last Edit: December 07, 2011, 03:19:17 PM by Superb »

Not workin D:
Code: [Select]
function serverCmdSaveMe(%client)
{
$Skill::Client::Gold[%client.bl_id] = %client.Gold;

export("$Skill::" @ %client.bl_id @ "*", "config/server/Skill/" @ %client.name @ "'s vars", False);

echo("Saved!");
}

function serverCmdLoadMe(%client)
{
exec("config/server/Skill/" @ %client.name @ "'s vars");

echo("Loaded!");
}

I don't get where you got the idea to mess with the export command like that. You're telling it to look for "$Skill::18831*" which you never make, and then trying to make individual files for each person, which would be console spam to reload them all one by one. You also removed the filetype, and gave it ' marks and crap which could forget with some code. You shouldn't load individuals if you expect a lot of people:

Code: [Select]
function serverCmdSaveMe(%client) {
$Skill::Client::Gold[%client.bl_id] = %client.Gold;
export("$Skill::Client::*", "config/server/Skill/ClientPrefs.cs", False);
echo("\c2Skill Client Saved.");
}

function serverCmdLoadMe(%client) {
exec("config/server/Skill/ClientPrefs.cs");
%client.Gold = $Skill::Client::Gold[%client.bl_id];
echo("Skill Client Loaded.");
}

It's set up a bit wonky since I don't have the full thing you're trying to do, but I trust you understand after this and can adapt it properly. Apologies all around.

I don't get where you got the idea to mess with the export command like that. You're telling it to look for "$Skill::18831*" which you never make, and then trying to make individual files for each person, which would be console spam to reload them all one by one. You also removed the filetype, and gave it ' marks and crap which could forget with some code. You shouldn't load individuals if you expect a lot of people:

Code: [Select]
function serverCmdSaveMe(%client) {
$Skill::Client::Gold[%client.bl_id] = %client.Gold;
export("$Skill::Client::*", "config/server/Skill/ClientPrefs.cs", False);
echo("\c2Skill Client Saved.");
}

function serverCmdLoadMe(%client) {
exec("config/server/Skill/ClientPrefs.cs");
%client.Gold = $Skill::Client::Gold[%client.bl_id];
echo("Skill Client Loaded.");
}

It's set up a bit wonky since I don't have the full thing you're trying to do, but I trust you understand after this and can adapt it properly. Apologies all around.
It works.

I desired them to be in separate files with the users name so then it won't load a hundred people's vars when anyone joins.

Options:
Build you own system out of a FileObject.

Use something like $someprefix::client[%bl_id, ...], then export("$someprefix::client" @ %bl_id @ "_*");


First one is the most flexible, but also the most work. The second one forces you to put all of the details in the []s, rather than organizing it with ::s.

It works.

I desired them to be in separate files with the users name so then it won't load a hundred people's vars when anyone joins.

If all works correctly, you shouldn't have to. You manage the variables in the game, and only load them on first startup so the information is ready. Of course, if you have enough people, individual files might be better, but you can't expect that many. You might want to export maybe every time people leave to make sure a server crash doesn't lose as much information, though. Just execute the file on server startup, export in joins or leaves or something, and once more for regular closing. Stuff like that.

Badspot recently made a default saving system which Truce already linked to. It should do everything you want.

Add-On developers:  You can use player persistence to save any tagged field on the client or player object by using the RegisterPersistenceVar() function.  Here is some example code:
Code: [Select]
//load the persistence add-on now, if they have it enabled.
//you can also use ForceRequiredAddOn if your add-on doesn't work without persistence
LoadRequiredAddOn("Script_Player_Persistence");

if(isFunction(RegisterPersistenceVar))  //quick way to check if the persistence add-on loaded
{
   //usage: RegisterPersistenceVar(string <tagged field to match>, bool <match all>, string <datablock classname>);

   RegisterPersistenceVar("myVariable", false, "");             // save %client.myVariable and %player.myVariable to persistence file (if those values are set)

   RegisterPersistenceVar("myPrefix", true, "");                // save any tagged field on %client/%player starting with "myPrefix",
                                                                // eg %client.myPrefixFoo %client.myPrefix_24, etc.
                                                                // This is more expensive than a straight match and can have unintended consequences, so be careful

   RegisterPersistenceVar("myDatablockRef", false, "ItemData"); // save %client/%player.myDatablockRef to persistence but verifies that it is of class "ItemData"
                                                                // and translates the id number into a datablock name before saving. 
                                                                // Datablock id numbers will vary depending on the order and number of add-ons loaded,
                                                                // so use this if you need to save a datablock reference.
}

//optionally, you can package into the apply persistence function if you need to do custom stuff to fully restore the player's state
package <MyAddOn>PersistencePackage
{
   function GameConnection::applyPersistence(%client, %gotPlayer, %gotCamera)
   {
      Parent::applyPersistence(%client, %gotPlayer, %gotCamera);
     
      //Do custom stuff here...
   }
};
activatePackage(<MyAddOn>PersistencePackage);
Player Persistence files are saved as config/server/persistence/<blid>.txt

Badspot recently made a default saving system which Truce already linked to. It should do everything you want.

It's not as nice as it seems.

1) You can't stop it from saving tools or positions
2) You can't separate one set of persistence values from another (ie for one set of add-ons as opposed to another) which can result in data loss if you run a server with persistence enabled but don't register every value you want to keep (for instance if your RPG mod isn't enabled and persistence runs, you lose all that RPG data for anyone who joins)

Persistence, in my opinion, still needs a lot of work but Badspot's pretty goddamn notorious for not listening to anyone.