Distributing Your Next Game

So you just finished working on your latest project and it’s time to let others play it. If you’re like me you’d probably like to know some things about your game after you’ve released it. Personally I’m most interested in tracking how many people downloaded each of my games. It’s fun to check in now and again and see that more people have tried my game out, and it’s also helpful in figuring out what’s popular and what’s not.

In addition to tracking statistics it’s also important to have some sort of platform to distribute your games. It’d be especially nice if you could write something once and then continue to leverage it for future games. That’s exactly what I’ve set out to do with this code.

The goal of this project is straightforward. First, provide an easy way to add and maintain my list of projects. Second, lay down a foundation to track and gather data about who downloads my games.

Easy distribution

Alright, the first page of this simple application displays all of the available games to download. It reads in all of the JNLP files in the current directory and presents them as a list. In the future you can add a new game by simply uploading its JNLP file to the directory. Likewise it’s easy to remove a game by simply removing its JNLP file from the directory. To keep things simply I haven’t styled the page at all — feel free to update the script with any styles that suits you. Let’s take a look at list.php

<?php
/**
 * List each JNLP file.
 *
 * @author Alexander Schearer <aschearer@gmail.com>
 */

$files = new DirectoryIterator(".");
$games = array();

/* Escape and record each game name. */
foreach ($files as $file) {
    if (substr($file, -5) == ".jnlp") {
        $game = explode(".", $file);
        $games[] = htmlentities($game[0]);
    }
}
?>
<html>
    <head>
        <title>List of Available Games</title>
    </head>
    <body>
        <h1>List of Available Games</h1>
        <ul>
<?
foreach ($games as $game) {
?>
            <li><a href="serve.php?game=<? echo $game; ?>"><? echo $game; ?></a></li>
<?
}
?>
        </ul>
    </body>
</html>

list.php is incredibly simple. All it does is iterate over the list of files in the current directory and for any file ending in .jnlp it sets the name aside. That’s it!

Sitting beside list.php is a .htaccess file. The purpose of this file is to hide any files which we don’t want the user to see. This includes the JNLP files which we will be serving ourselves and the counter file which will track downloads. Here’s how it works:

<Files *.jnlp>
    Order deny,allow
    deny from all
</Files>

<Files *.csv>
    Order deny,allow
    deny from all
</Files>

The first section hides the JNLP files. The second hides any comma delimited files. In case it wasn’t clear that’s the file which will track the information about our games.

Now that you understand how we present the games to the user let’s look at the last file (I told you this was simple). serve.php is a script which sends the game’s JNLP file to the user. Of course, before it does that it makes a note of it.

<?php
/**
 * Serve and record the requested JNLP file.
 *
 * @author Alexander Schearer <aschearer@gmail.com>
 */

$game = @$_GET['game'];

/* Check that the JNLP exists, 404 if it doesn't. */
if (!isset($game) || !file_exists($game . ".jnlp")) {
    header("HTTP/1.0 404 Not Found");
    display404();
    exit;
}

/* Increment the counter for the game. */
$handle = f open("counter.csv", "r");
$lines = array();
$found = false;

/* Search for the game in the existing rows. */
while (($line = fgetcsv($handle, 100, ",")) !== FALSE) {
    if ($line[0] == $game) {
        $line[1] += 1;
        $line[2] = date('r');
        $found = true;
    }
    $lines[] = $line;
}
/* If it wasn't found then add a new row for it. */
if (!$found) {
    $lines[] = array($game, 1, date('r'));
}
/* Clear the file and write the rows back to it. */
$handle = f open("counter.csv", "w+");

foreach ($lines as $line) {
    fputcsv($handle, $line); 
}

/* Send the JNLP to the client. */
header('Content-type: application/x-java-jnlp-file');
header('Content-disposition: attachment; filename="' . $game . '.jnlp"');
echo file_get_contents($game . ".jnlp");

/**
 * Display some 404 text to the user.
 */
function display404() {
?>
<html>
    <head>
        <title>404 Not Found</title>
    </head>
    <body>
    <h1>404 Not Found</h1>
    <p>The requested game was not found.</p>
    </body>
</html> 
<?php
}
?>

So what’s important here? First off, notice that we record the statistics to counter.csv. This comma delimited file contains a row for each game. Currently it collects the number of times the game was downloaded as well as the last time a download happened. You can view the results in any text editor or even in Excel if you’re so inclined.

If the requested game doesn’t exist then the script exits with a 404 error. Like before I haven’t styled the response at all so please do if straight HTML bothers you. This is just a polite way to let the user know he’s in the wrong place.

Finally, due to some technical errors I was forced to write fopen as f open please make sure to fix this or else your script won’t run!

Conclusion

That’s that. I think this is a very simple but effective way to maintain your growing list of games. I’ve already been using something like this for my games for the last few months and have really appreciated being able to track interst in my games. Let me know if you find it useful, too.

Finally, here’s a list of cool and easy things you could do to extend this platform:

  1. Add a database and track more information.
  2. Add a web interface for the tracked information (read graphs).
  3. Add a service which works like list.php but returns XML. (Say to paste into your blog’s sidebar.)

Related Posts

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>