Game Development Community

Creating a file that hold info on character?

by David J Weaver · in Torque Game Engine · 01/08/2002 (4:56 am) · 40 replies

OK Ill admit im not perfect with C++ in fact i rather am a NooB at it but for a mod im working on i would like to have a file that stores a characters position, score, etc... any ideas?
Page «Previous 1 2
#1
01/08/2002 (6:00 am)
This one looks fun.

Is it for multiplayer? Meaning, will you need to save stats on more than one person, or just one?


Dark
#2
01/08/2002 (11:55 am)
Yes it is multiplayer and to be brutally honest its also for a RPG using T2
#3
01/08/2002 (5:24 pm)
I don't have a lot of time, so this will be brief.

To set your player's stats you would use:

$NameStats::Whatever = Whatever;


If your name was Dark, and you wanted to set his strength to 100 you would do:

$DarkStats::Strength = "100";


When you save it you would use this function:

function GameConnection::saveStats(%client)
{
	%name = %client.name;
	%file = "./stats/" @ %name @ ".cs";
	%exp = "$" @ %name @ "Stats::*";
	export(%exp, %file, False);
}

Call the function with %client.saveStats();


Then you execute the file. You'll have to make a new directory called stats for the files to be saved in.

Sorry I can't explain it in more detail, just don't have time :\


Dark
#4
01/08/2002 (9:18 pm)
The problem with that is, what's stopping the player from opening the file and editing it to boost his position? Come on people, didn't you learn anything from Diablo 1? :)
#5
01/09/2002 (4:40 am)
Hmm this is great! but now how would i get it to save the players position, and when he logs back in teleport him directly to that point. saving pos would be something like %posx,%posy, Awwwww heck i dont know
#6
01/09/2002 (4:45 am)
To make the world do this every 5 mins would it look like this?

schedule(0, 500000)
{
%client.saveStats();
}
?
Errr like this..
schedule(500000, 0, "%client.saveStats();");
return;
#7
01/09/2002 (12:27 pm)
Wow, does that block of code really work chris?! I didnt have time to try it out, but it looks VERY useful for creating a save file.

And who cares if the player can just edit it? It takes more effort than most people will bother with, and you cant really prevent hacking of files anyway (just make it harder). If you need something to be secure (a MMORPG character file), then it shouldnt be stored on a users computer, but on a server. And if it isnt essential, why prevent a player from having a little fun with it? :)
#8
01/09/2002 (12:51 pm)
LOL the whole point is to keep the file on the server so no the player canott edit it..
#9
01/09/2002 (1:53 pm)
or if you need to keep the file clientside.

1. File is encrypted clientside.
2. on client connect, server retrieves file from client
decrypts file and uses serverside decrypted version
of file.
3. on client disconnect, updated version of file is
encrypted severside a set back to client for offline
storage

Possible problems with such an implementation are:

A. speed of encrypt/decrypt
B. maintaining key list, ect for serverside decryption

If such an system could be implemented, you could create games that use non-centralized servers [like most multiplayer FPS systems] that also allow players to maintain character data regardless of the server they use.

HAVOC
#10
01/09/2002 (3:51 pm)
it would be nice if some one would write a tutorial on this...
I have been looking into saving basic character stats into a MySQL database (that's what i'm using for the username and password for logins) but I don't know if that'll work or not.
#11
01/09/2002 (6:37 pm)
ok this is from a person on a diff forum. his name is BadShot so give him credit

Well, here's some examples on how to do it. Call GetPlayerStats(%client); from gameConnection::onConnect to get all the players stats from a file when they connect. In gameConnection::onDrop, call SavePlayerStats(%client); to save thier stats to a file when they leave. Thier file will be saved in the filename userdata/userGUID where GUID is supposedly the unique ident number of the client.


function GetPlayerStats(%client)
{
%filename = "userdata/user" @ %client.guid;
if (isFile(%filename))
{
%file = new File Object()
if (openFileForRead(%filename))
{
%file.readLine(); //First line lost to dump, ignore it.
%client.level = %file.readLine();
%client.experience = %file.readLine();
%client.strength = %file.readLine();
%file.close();
}
%file.delete();
}
else
CreatePlayerStats(%client);
}

function CreatePlayerStats(%client)
{
%client.level = 1;
%client.experience = 0;
%client.strength = 0;
SavePlayerStats(%client);
}

function SavePlayerStats(%client)
{
%filename = "userdata/user" @ %client.guid;
export('', %filename, False); //This is how I create and clean
new MessageVector(TempVector);
TempVector.dump(%filename);
TempVector.delete(); //Files so they can be written to fresh.

%file = new FileObject();
if ( %file.openForAppend( %filename ) )
{
%file.writeLine(%client.level);
%file.writeLine(%client.experience);
%file.writeLine(%client.strength);
%file.close();
}
%file.delete();
}

function ModifyExperience(%client, %amount)
{
%levelup = getnextLevelUp(%client);
%client.experience += %amount;
if (%client.experience > %levelup)
{
%client.level++;
bottomPrint(%client, "Level Up! Now at level %1", %client.level );
}
else
bottomPrint(%client, "Experience Gained: %1; Total Experience: %2; Next Level Up: %3", %amount, %client.experience, %levelup );
}

function getNextLevelUP(%client)
{
%level = %client.level;
if (%level == 1)
return 100;
else if (%level == 2)
return 400;
else if (%level == 3)
return 1000;
}
#12
01/10/2002 (3:55 pm)
The code I posted is server-side. So only the server has access to it. If you want to save the client's position then you would do:


// To make it easier here's a function to SET a stat.
function GameConnection::setStat(%client, %stat, %val)
{
	%name = %client.name;
	eval("$" @ %name @ "Stats::" @ %stat @ " = \"" @ %val @ "\";");
}

// To make it easier here's a function to GET a stat.
function GameConnection::getStat(%client, %stat)
{
	%name = %client.name;
	eval("%stat = $" @ %name @ "Stats::" @ %stat @ ";");
	return %stat;
}

// to save the position:
%client.setStat("Position", %client.player.getTransform());
// to get the position (and put the player there):
%client.player.setTransform(%client.getStat("Position"));

This is probably the best way to do it. All you have to do is save the stats when the player exits, and exec teh stat file when the player joins. You should make a login and password thing too unless you want other people to login as someone else.


Dark
#13
01/10/2002 (7:44 pm)
Chris, perhaps you can give us more detailed instructions on how to incorporate this into our games...
... perhaps a tutorial? =)

- ian wheat
#14
01/11/2002 (9:32 am)
ok, this is what I did (without success)
I added
%client.onClientLeaveGame();
at the beginning of the setStat and saveStat functions. both of which are in common/server/clientConnection.cs
however it doesn't create my stats file when I leave nor does it load my stats and position (I have the getStats function in clientConenction.cs so that's not the problem =)

any ideas as to why it's not working?
#15
01/11/2002 (7:01 pm)
[jeapordy theme]
=)
i'd really like to know more about how this works and to get some ideas on something similiar for usernames and passwords for logging into the server.

thanks
#16
01/11/2002 (7:15 pm)
ok about the user names the tut that i posted above uses the GUID witch is tracked to each person. and all you have to do is turn of aliases becouse T2 wont have 2 people using the same "Real" name. And i seem to be getting a sintax error on line 119 of "SERVER.cs" (thats where gameconection::onconnect is) this is where i put my functions well anyway the line 119 reads:
%file = new File Object()
Now im thinking this mught be a reall stupid thing but should it be
%file = new File Object(); ?
or
%file = new FileObject();?
#17
01/12/2002 (7:08 pm)
I think it's without spacing
#18
01/13/2002 (7:38 am)
David, it's without a space, and do you have a semi-colon after it?
#19
01/13/2002 (7:52 am)
If you add %client.onClientLeaveGame() at the beginning of the two functions, all it will do is call %client.onClientLeaveGame(). That won't do much.

Instead you would add %client.saveStats() at the top of onClientLeaveGame:

function GameConnection::onClientLeaveGame(%client)
{
	%client.saveStats();

	// ... code

It won't save anything unless you have something set to save. And you need to make sure you have a stats directory (you'll probably have to change the path in GameConnection::saveStats() ).

When the client enters the game you'll need to load the stats:

// Loading function:
function GameConnection::loadStats(%client)
{
	%name = %client.name;
	%file = "./stats/" @ %name @ ".cs"; // you should change this path
	exec(%file);
}

GameConnection::onClientEnterGame(%client)
{
	%client.loadStats();
	// Set something to test with:
	%client.setStat("TestStat", "TEST!!!");
	// ... blah...

It will set a stat, and when you leave the game it should save it as long as you included all of the functions from my above posts (and if the stats path is right). Test it, see if the file is created.


Dark
#20
01/13/2002 (7:56 am)
David, it would be:

// 60,000 = 60 seconds. 60 seconds * 5 = 5 min.
%client.statSched = %client.schedule(60000 * 5, "saveStatsSched");

// function to keep it repeating.
function GameConnection::saveStatsSched(%client)
{
	// with functions like this you should add
	// a few checks to keep it from repeating forever

	// make sure there is a client.
	if(!%client)
		return;

	// cancel any old schedules
	if(%client.statSched)
		cancel(%client.statSched);

	%client.saveStats();
	%client.statSched = %client.schedule(60000 * 5, "saveStatsSched");
}

*Edit: Oh, and that tutorial you posted, I think it only works in T2. If I remember right, guid is the WON ID, and Torque had everything that delt with WON ripped out. So, if you're using T2, then it would work really well. But if you're using torque, then you'll have to do it with a username/password.


Dark
Page «Previous 1 2