Jump to content
Sign in to follow this  
nazer1290

Save data using a script?

Recommended Posts

I have seen various Dedicated Servers that save for example:

Cash

Rank

Position

ect....

Anyways, How can I achieve this?

Share this post


Link to post
Share on other sites

This is just a set of a rough pseudo code to help you get the idea (will probably work too).

client_save.sqf

_cash = mycash; //predefined mycash variable
_pos = getpos player;
_rank = rank player;
_uid = getPlayerUID player;

call compile format ["%1_saveVar = %2; publicVariable '%1_saveVar'; ", _uid, [_cash,_pos,_rank]];

client_load.sqf

_uid = getPlayerUID player;

call compile format ["_data = %1_saveVar", _uid];

if (isnil {_data}) exitwith {hintsilent "No savefile found"};

mycash = _data select 0;
player setpos (_data select 1);
player setrank (_data select 2);

In the editor:

myFlagObjectPlacedInEditorName addaction ["Save Status","client_save.sqf"];
myFlagObjectPlacedInEditorName addaction ["Load Previous","client_load.sqf"];

This last part can be done in many ways, checking when the player disconnects and so on, rather than asking them to push save and load, you could consistently save the data.

Hope that gives you a good understanding of how you can do it.

Recommended reading:

http://community.bistudio.com/wiki/6thSense.eu:EG

http://community.bistudio.com/wiki/publicVariable

http://community.bistudio.com/wiki/compile

Edited by Rommel

Share this post


Link to post
Share on other sites

Please note that call compile code is performance demanding and setvariable is preffered instead:

call compile format ["%1_saveVar = %2; publicVariable '%1_saveVar'; ", _uid, [_cash,_pos,_rank]];

to be replaced with

missionnamespace setvariable [format ["%1_saveVar",_uid],[_cash,_pos,_rank],true];

or

missionnamespace setvariable [str _uid + "_saveVar",[_cash,_pos,_rank],true];

Share this post


Link to post
Share on other sites

Thanks for the help!

Though, say I wanted to reset all stats, how would I do this?

---------- Post added at 02:33 PM ---------- Previous post was at 02:25 PM ----------

Could I create a gameLogic called 'server' and set the variables in that space? then to clean delete the gameLogic and replace?

---------- Post added at 02:48 PM ---------- Previous post was at 02:33 PM ----------

Also, does this save on server shutdown?

Share this post


Link to post
Share on other sites

@Gaia

I've allready replaced allmost all call compile formats in Domination with missionNamespace setVariable some time ago, the new versions use it allready (found out about it somehow by accident and indeed missionNamespace setVariable is much faster, 4-5 times, than call compile format).

Though missionNamespace setVariable ["bla",somevalue, true] didn't work.

Means I couldn't broadcast those global vars over the network with setVariable. Got an error, can't remember which one. publicVariable was fine.

Has it changed or have I made just a stupid mistake ?

Now we only need access to the local script namespace :p

Xeno

Share this post


Link to post
Share on other sites

Aren't dynamic variable names something of the past, something you'd use when you don't have access to more elegant solutions like arrays or hashes?

Share this post


Link to post
Share on other sites

Can't you save to a text file or sql server?

Cause i don't think the variables will save on server shutdown.

Share this post


Link to post
Share on other sites
Can't you save to a text file or sql server?

Cause i don't think the variables will save on server shutdown.

If you host from ingame server (so non dedicated) you have access to the default arma2 save/load options afaik, no experience there though.

Access to write to files / sql is something only available by extension dll's.

Share this post


Link to post
Share on other sites
Aren't dynamic variable names something of the past, something you'd use when you don't have access to more elegant solutions like arrays or hashes?

I don't want to hijack this thread from its original topic, but since Gaia brought up the call compile format issues, I wanted to get some input.

I try to avoid call compile format whenever I can, but, I currently have one script that has to create multiple game logics, public variables, and execute additional script instances. I use call compile format heavily to do this. Here is an abbreviated example (modified for simplicity):

What I am currently doing:

// Initialize an array to extract data from.

_array = 
[
    ["A", [12857.9,9872.9,0]],
    ["B", [2256.56,5257.14,0]],
];

// Use call compile format to create logics, PVs, and execute script instances.

{
call compile format 
["

                  ""Logic"" createUnit [ %2, group, ""MY_logic_%1 = this;""];

                  MY_variable_%1 = 1;

                  publicVariable ""MY_variable_%1"";

                  [""%1""] execVM ""MY_script.sqf"";

", (_x select 0), (_x select 1)];

} forEach _array; 

Should I be doing this (or something else instead)?

// Initialize an array to extract data from.

_array = 
[
    [MY_variable_A, [12857.9,9872.9,0], "MY_logic_A = this;", "MY_variable_A"],
    [MY_variable_B, [2256.56,5257.14,0], "MY_logic_B = this;", "MY_variable_B"],
];

// Create logics, PVs, and execute script instances.

{

    "Logic" createUnit [(_x select 1), group, (_x select 2)];

    (_x select 0)  = 1;

    publicVariable (_x select 3);

    ["(_x select 0)"] execVM "MY_script.sqf";


} forEach _array;

I have tried variations of the latter before, but I seemd to get errors from uninitialized variables or other such problems. Was I doing it wrong or are there other factors in play?

Share this post


Link to post
Share on other sites
I don't want to hijack this thread from its original topic, but since Gaia brought up the call compile format issues, I wanted to get some input.

I try to avoid call compile format whenever I can, but, I currently have one script that has to create multiple game logics, public variables, and execute additional script instances. I use call compile format heavily to do this. Here is an abbreviated example (modified for simplicity):

What I am currently doing:

...

I have tried variations of the latter before, but I seemd to get errors from uninitialized variables or other such problems. Was I doing it wrong or are there other factors in play?

In the example you're using reserved variable 'group', though maybe that's just in the example. :)

The correction would be:

// Initialize an array to extract data from.

_array = 
[
["A", [12857.9,9872.9,0]],
["B", [2256.56,5257.14,0]]
];

// Create logics, PVs, and execute script instances.
{	
"Logic" createUnit [(_x select 1), group, format["MY_logic_%1 = this", _x select 0]];
 _var = format["MY_variable_%1", _x select 0];
missionNameSpace setVariable [_var, 1];
publicVariable _var;

[_var] execVM "MY_script.sqf"; // or _var should be  _x select 0  ?
} forEach _array;

Unsure about the need for the publicVariable there btw. (at least in this example it makes not much sense)

Still, another example would be to: MY_logic_%1 = [this, 1];

However, what I was aiming at is that there are different ways to approach accessing values, than to store them in dynamic variables.

For instance by using arrays, or hashes if you need a better index than integer based.

But there's more to it, like the inits could be made "myArray set [count myArray, this]", or could be handled inside (XEH) missionConfig or config eventhandlers, just to name a few.

You can store the (unique) name/reference of the object also on the object itself with setVariable, as opposed to assigning a global variable to it.

Still, I suppose there are situations where it is more optimal or logical to use dynamic variables.

In MP there's also the consideration about every publicVariable's value at the moment of JIP player joining, is synchronized to him.

So even if you have publicVariables that contain just objNull, and are of no value anymore to the new player, they will be synced.

By limiting the amount of pv's, aswell as for instance maintaining an array and cleaning it up (as opposed to 100's of (now possibly useless) pv's), depending on what type of thing you're doing, you could probably save here especially on longer running games.

A simple hash example:

_keys = ["A", "B"];
_values = [_obj1, _obj2];

_object = _values select (_keys find "B"); // fetch
_idx = count _keys; _keys set [_idx, "C"]; _values set [_idx, _obj3]; // set

(Which you could also reverse)

Real implementation: http://dev-heaven.net/docs/cba/files/hashes/fnc_hashCreate-sqf.html (etc)

Edited by Sickboy

Share this post


Link to post
Share on other sites

Thanks SB!

I realize you were focusing on the topic of setting/accessing array data but I saw an opportunity ;) BTW, group was just for the example, I was using an actual group name. The errors or parts not working were the parts that would now use missionNameSpace setVariable. Thanks again! and sorry for the hijack all...

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×