Building community in purely single player games
by Craig Fortune · 07/22/2008 (2:48 pm) · 8 comments
Building community is an important way to get people playing, and keep playing, your game. I was thinking about a way to create this sort of community for some games I'm working on and after playing a few little flash games scattered all around the net I realized I was playing them again and again, just to get myself up the leader boards a little bit.
I like to call these "One more go" games, meaning that no matter how many attempts you have, you always want that one extra turn to try and improve your ranking on the scoreboards. A prime example is this game: [url=http://www.miniclip.com/games/monkey-kick-off/en/ ]Monkey Kick Off[/url] I always find myself trying to get a better score as the minutes continually slide off the clock on the wall at an alarming rate. As an aside, my best is actually 5037 not as shown in the image - Yes I have seen the amazing vistas of Monkey Village and beyond! :D
Taking away the uber-simplistic (yet very fun I find) game play dynamics why does this game have any relevance to building community? Pretty simply really, it has a leader board. That's it. Community doesn't have to mean chat rooms and forums and communication etc, it can be as simple as putting them in contact with other player's scores and letting them "compete" against one another.
This picture has nothing to do with this .plan, its just that otherwise its a picture-less .plan... :)
It's a character called "Dave" from a little game I'm making with a mate. Anyway...
So why the rambling?
Off the back off this "research" (That's my word for procrastination, try it for size on your bosses) I decided to implement my own online scoreboard and have TGB send the information gathered (scores + names) up to said scoreboard. I'm no database and website guy so I actually searched around for a bit on GG and elsewhere for the know-how to go about doing this. Turns out, it so damn simple that anyone whose head doesn't make a rattling noise when they nod should be able to do it. The following is a step-by-step guide to setting up your own scoreboard. It's a collection of the information I found in tutorials and on the GG forums, so I'm not claiming it's all mine by any stretch of the imagination.
If you don't understand some of the terms etc being used here then you'll find a wealth of information on the net. Google is your friend, it is frequently mine. This is a real "bare bones" implementation and shouldn't be considered a final usable thing.
I will be putting this on TDN also; it's just here so that people who might be interested are more likely to see it.
Step 1:
You'll be storing the information in an SQL database, so if you haven't got access to one readily then I suggest you sign up here (its free hosting, so you have nothing to lose :D): http://www.000webhost.com/
Step 2:
Setup a SQL database using their control panel systems. You'll want to have a table setup with the following fields:
The id setups up a unique identifier for each row entered. The name... that's obvious. The score, again obvious. The dateSubmitted field is used to store when you actually upload the score, it'll fill itself in with the current time that the database considers it to be.
Step 3:
Save the following code into a .php file (I suggest something like "scores.php" for the sake of simplicity) and upload it to your webspace. Make sure you have PHP enabled obviously.
The code above does the following:
Then...
To summarize, when you load up this page it'll connect to your database and grab the data and then display it. Simple huh?
Step 4:
Now for the page which handles uploading...
This page again connects to the database but this time there are a few important differences. You'll see we are using $_GET to grab the values of the name and score variables passed to the page. We later check that these actually exist and then INSERT into the database the information like thus:
If we got the data we wanted (name and score) we echo back:
You'll see why in the next step ;)
Step 5:
Now we need Torque (in this case TGB) to actually send the data over to the scoreUpload page.
Not exactly rocket science is it? There are prettier ways to do this, but why bother when you're just trying to show a bare bones concept? Not being a web guy I wasn't really sure if I should be using GET or POST throughout all of this. GET works with the PHP stuff nicely. I like GET. :)
First we setup our servername we want to connect to and the relevant path if necessary. The %path part is the page and then %script contains the PHP gubbins to pass the variables values to the page.
Then we create a HTTPObject with
and finally do a Get command using it. This is the bit that actually sends data to the host.
Step 6:
Some more script stuff. So we can actually handle if we don't connect, include this:
Remember earlier with the "replyData" line? Well now we're going to do something with it. The following code will check each line that comes back to us from the server after our GET command. We check if the opening word of the line is "replyData" and if so we actually pay some attention to it. We know that we're going to get something to act upon here regarding our attempted upload of our score, so lets popup a messagebox showing the result. We check the second word and if it is "No" we know the data wasn't accepted for some reason. We don't have to bother checking for the rest of the line... in fact we don't need to send it at all to be honest but it was handy for me while testing.
Step 7:
Go in game and open the console and type something like
Everything should work ok and you should get a message box popup telling you that you have uploaded your score!
Conclusion:
As you can see that really wasn't too taxing at all. I literally had to learn how to use PHP and SQL Databases while doing that and still it only took me an hour or two start to finish. Admittedly it'd take me like 15 minutes now but ho'hum :)
Hopefully this will open up the opportunity for many people who were a bit unsure how to go about storing player data online to get some really cool little additions in their games.
Future changes:
Obviously security needs to be added here, as you can just go straight to your page in a browser and merrily add scores ad infinitum. :) A nice solution would be to have user accounts etc, but that is obviously beyond the scope of this short tutorial.
Having a web-based score table viewable in TGB would be neat, and super simple. I'll likely get that on TDN also.
Thanks for reading, hope it helps!
edit: general typos etc, the usual ;)
I like to call these "One more go" games, meaning that no matter how many attempts you have, you always want that one extra turn to try and improve your ranking on the scoreboards. A prime example is this game: [url=http://www.miniclip.com/games/monkey-kick-off/en/ ]Monkey Kick Off[/url] I always find myself trying to get a better score as the minutes continually slide off the clock on the wall at an alarming rate. As an aside, my best is actually 5037 not as shown in the image - Yes I have seen the amazing vistas of Monkey Village and beyond! :D
Taking away the uber-simplistic (yet very fun I find) game play dynamics why does this game have any relevance to building community? Pretty simply really, it has a leader board. That's it. Community doesn't have to mean chat rooms and forums and communication etc, it can be as simple as putting them in contact with other player's scores and letting them "compete" against one another.
This picture has nothing to do with this .plan, its just that otherwise its a picture-less .plan... :)
So why the rambling?
Off the back off this "research" (That's my word for procrastination, try it for size on your bosses) I decided to implement my own online scoreboard and have TGB send the information gathered (scores + names) up to said scoreboard. I'm no database and website guy so I actually searched around for a bit on GG and elsewhere for the know-how to go about doing this. Turns out, it so damn simple that anyone whose head doesn't make a rattling noise when they nod should be able to do it. The following is a step-by-step guide to setting up your own scoreboard. It's a collection of the information I found in tutorials and on the GG forums, so I'm not claiming it's all mine by any stretch of the imagination.
If you don't understand some of the terms etc being used here then you'll find a wealth of information on the net. Google is your friend, it is frequently mine. This is a real "bare bones" implementation and shouldn't be considered a final usable thing.
I will be putting this on TDN also; it's just here so that people who might be interested are more likely to see it.
Step 1:
You'll be storing the information in an SQL database, so if you haven't got access to one readily then I suggest you sign up here (its free hosting, so you have nothing to lose :D): http://www.000webhost.com/
Step 2:
Setup a SQL database using their control panel systems. You'll want to have a table setup with the following fields:
id - set it be a smallint type and to auto increment and be the primary key name - set it to be a varchar of a size that is big enough to contain the longest name you expect score - set it to something relevant to your scoring system, for testing I have it as a mediumint dateSubmitted - set it to be a timestamp type and current_timestamp
The id setups up a unique identifier for each row entered. The name... that's obvious. The score, again obvious. The dateSubmitted field is used to store when you actually upload the score, it'll fill itself in with the current time that the database considers it to be.
Step 3:
Save the following code into a .php file (I suggest something like "scores.php" for the sake of simplicity) and upload it to your webspace. Make sure you have PHP enabled obviously.
<html>
<head>
<title>Title</title>
</head>
<body>
<?
$service = "your_hostname_here";
$username = "your_username_here";
$password = "your_password_here";
$database = "your_databasename_here";
mysql_connect($service, $username, $password);
@mysql_select_db($database) or die( "Unable to select database");
$query = "SELECT * FROM your_table_here ORDER BY score DESC";
$result = mysql_query($query);
$num = mysql_numrows($result);
?>
<table>
<tr class="header"><td>Position</td><td>Name</td><td>Score</td><td>Date Submitted</td></tr>
<?
$loopindex = 0;
while ($loopindex < $num)
{
$thisname = mysql_result($result, $loopindex, "name");
$thisscore = mysql_result($result, $loopindex, "score");
$thisdate = mysql_result($result, $loopindex, "datesubmitted");
$thispos = $loopindex+1;
echo ("<tr><td align=left><p>$thispos</p></td>
<td align=center><p>$thisname</p></td>
<td align=center><p>$thisscore</p></td>
<td align=center><p>$thisdate</p></td></tr>\n");
$loopindex++;
}
?>
</table>
</body>
</html>The code above does the following:
Attempts to connect to a SQL database. Selects everything in the table you specify Orders the rows by descending score
Then...
Starts to create a table Loops through each row of the data you grabbed from the database and fills in the cells of a table with it Closes table, body and html tags.
To summarize, when you load up this page it'll connect to your database and grab the data and then display it. Simple huh?
Step 4:
Now for the page which handles uploading...
<?
$name = $_GET['name'];
$score = $_GET['score'];
$service = "your_hostname_here";
$username = "your_username_here";
$password = "your_password_here";
$database = "your_databasename_here";
mysql_connect($service, $username, $password);
@mysql_select_db($database) or die( "Unable to select database");
if($name)
{
if($score > 0)
{
$query="INSERT INTO your_table_here VALUES ('null', '$name', '$score', CURRENT_TIMESTAMP)";
$result=mysql_query($query);
echo("replyData Score submitted! Name: $name, Score: $score");
}
}
else
{
echo("replyData No score was submitted");
}
?>This page again connects to the database but this time there are a few important differences. You'll see we are using $_GET to grab the values of the name and score variables passed to the page. We later check that these actually exist and then INSERT into the database the information like thus:
$query="INSERT INTO your_table_here VALUES ('null', '$name', '$score', CURRENT_TIMESTAMP)";
$result=mysql_query($query);If we got the data we wanted (name and score) we echo back:
"replyData Score submitted! Name: $name, Score: $score"and if not:
"replyData No score was submitted"
You'll see why in the next step ;)
Step 5:
Now we need Torque (in this case TGB) to actually send the data over to the scoreUpload page.
function scoreTest(%name, %score)
{
%server = "_hostnamehere_:80";
%path = "/uploadScore.php";
%script = "name=" @ %name @ "&score=" @ %score;
%httpObj = new HTTPObject(scoreUploadHTTPObj);
%httpObj.Get(%server, %path, %script);
}Not exactly rocket science is it? There are prettier ways to do this, but why bother when you're just trying to show a bare bones concept? Not being a web guy I wasn't really sure if I should be using GET or POST throughout all of this. GET works with the PHP stuff nicely. I like GET. :)
First we setup our servername we want to connect to and the relevant path if necessary. The %path part is the page and then %script contains the PHP gubbins to pass the variables values to the page.
Then we create a HTTPObject with
%httpObj = new HTTPObject(scoreUploadHTTPObj);
and finally do a Get command using it. This is the bit that actually sends data to the host.
%httpObj.Get(%server, %path, %script);
Step 6:
Some more script stuff. So we can actually handle if we don't connect, include this:
function scoreUploadHTTPObj::onConnectFailed(%this)
{
echo("Connection Failed");
}Remember earlier with the "replyData" line? Well now we're going to do something with it. The following code will check each line that comes back to us from the server after our GET command. We check if the opening word of the line is "replyData" and if so we actually pay some attention to it. We know that we're going to get something to act upon here regarding our attempted upload of our score, so lets popup a messagebox showing the result. We check the second word and if it is "No" we know the data wasn't accepted for some reason. We don't have to bother checking for the rest of the line... in fact we don't need to send it at all to be honest but it was handy for me while testing.
function scoreUploadHTTPObj::onLine(%this, %line)
{
if(getWord(%line, 0) $= "replyData")
{
if(getWord(%line, 1) $= "No")
MessageBoxOK("DID NOT UPLOAD SCORE", "Your score has not been uploaded. (Rejected)", "");
else
MessageBoxOK("UPLOADED SCORE", "Your score has been uploaded!", "");
}
}Step 7:
Go in game and open the console and type something like
scoreTest("name_here", "score_here");Everything should work ok and you should get a message box popup telling you that you have uploaded your score!
Conclusion:
As you can see that really wasn't too taxing at all. I literally had to learn how to use PHP and SQL Databases while doing that and still it only took me an hour or two start to finish. Admittedly it'd take me like 15 minutes now but ho'hum :)
Hopefully this will open up the opportunity for many people who were a bit unsure how to go about storing player data online to get some really cool little additions in their games.
Future changes:
Obviously security needs to be added here, as you can just go straight to your page in a browser and merrily add scores ad infinitum. :) A nice solution would be to have user accounts etc, but that is obviously beyond the scope of this short tutorial.
Having a web-based score table viewable in TGB would be neat, and super simple. I'll likely get that on TDN also.
Thanks for reading, hope it helps!
edit: general typos etc, the usual ;)
About the author
Recent Blogs
• Reflection, Part 4• Reflection, Part 3
• Reflection, Part 2
• Reflection, Part 1
• iPhones and Productivity
#2
I'm not a webguy as I stated above, but I do believe that addSlashes is done automatically on all things like POST/GET etc data. A very good point to raise though as it has serious implications! :)
AddSlashes docs entry
07/22/2008 (3:52 pm)
James,I'm not a webguy as I stated above, but I do believe that addSlashes is done automatically on all things like POST/GET etc data. A very good point to raise though as it has serious implications! :)
AddSlashes docs entry
#3
I'd recommend reading in sql connection information and passwords from a protected file on the web server as there have been more than a few PHP vulnerabilities that cause the server to dump the source of your *.php's. Don't put anything in your .php's that you wouldn't want displayed in a main index.html.
I'd also recommend a code, system, and architecture review from someone with a decent amount of skill... an owned high scores table will wreck any community you've worked hard to build...
07/23/2008 (12:00 am)
And don't just add slashes, validate the data (and no not on the client, on the server). for a score field, the only allowed characters should be "0-9". Player names should only allow "a-z, A-Z, 0-9". etc.. etc..I'd recommend reading in sql connection information and passwords from a protected file on the web server as there have been more than a few PHP vulnerabilities that cause the server to dump the source of your *.php's. Don't put anything in your .php's that you wouldn't want displayed in a main index.html.
I'd also recommend a code, system, and architecture review from someone with a decent amount of skill... an owned high scores table will wreck any community you've worked hard to build...
#4
All good points, but beyond the scope of this little tutorial :P Its not feature complete (in fact I stated quite the opposite). I'm more trying to show what can be done rather than how to do it (The actual code I'm using has additional security and checks in place already)
edit: wording sounded "off"
07/23/2008 (6:04 am)
Brian,All good points, but beyond the scope of this little tutorial :P Its not feature complete (in fact I stated quite the opposite). I'm more trying to show what can be done rather than how to do it (The actual code I'm using has additional security and checks in place already)
edit: wording sounded "off"
#5
07/24/2008 (9:32 am)
Wow, thanks! And just when I needed it!
#6
07/24/2008 (3:23 pm)
No problem Dan. Glad it helped someone :)
#7
08/11/2008 (8:21 am)
hmmm... good article...
#8
10/18/2008 (6:52 pm)
Great stuff, I was just looking for this and you saved me a great deal of time. Cheers. 
Torque Owner James Mintram
Whenever inserting data into a database escape the data you are inserting otherwise it will be very easy for someone to exploit!
In PHP the function is AddSlashes I believe.
James Mintram