Saving Games Online

Now that our Mac version is finally running smoothly on Unity we’re going to create a version that runs in a web player. The main hurdle we’re facing is saving games (a few hundred thousand plus) online. We’re currently planning on a php/MySql solution of some kind.

But I’m sure we’re not the first team to start saving games online. Could anyone share with us any any advice they’ve gleaned along the way–before we cause ourselves too much pain :wink: ?

Thanks!

You want CookieCutter.

Ah, an excellent idea–thank you. However, each of our “games” often represent an entire school with 18 classrooms encompassing 500 students sitting down at random workstations. We also need to aggregate all their performance data into a central admin report. So unfortunately we’re probably locked into a more robust solution than cookies.

We’re considering switching our game file format to saving lots of little ordered pair data points using GET. Or preferably we’d like to find a way to encode and upload our current entire “saved game” file–perhaps using a POST function. We’re also considering using Amazon’s S3 service for file storage/retrieval.

But by the time we got that far we realized that we surely couldn’t be the first team trying to save games online, so we’re hoping we can avoid inventing the wheel.

MySQL should be able to handle a few hundred thousand records comfortably. Given the usage scenario, you will need to let the users log on with a textual username and password to access their data, and perhaps store a few other personal details (like e-mail address, performance data) and, of course, the save game data.

You could use a session-based connection with the server if you have lots of users switching machines at random. You could construct the web player so as to force the user to log on each session, rather than “remembering” the last user - you could still use cookies under this scheme. From experience, I would say it is easier to implement a session-based server app using Ruby/Rails rather than PHP, since Rails has excellent built-in support for sessions. However, you may, of course, prefer PHP from the point of view of existing knowledge, more hosting options, etc.

I can’t see any reference to the POST method in the Unity WWW class docs, although I suppose it’s possibly a 2.0 feature (?) However, I think you could use Application.ExternalCall to call some AJAX code in the embedding web page and transfer data that way. You could use (browser) JavaScript to send an XMLHttpRequest to your server (with as much data as you like) and then store it in an “invisible” HTML construct in the page. Then, you could have another JS function to retrieve that data using the DOM. Call these JS functions from your web player and you have an inelegant but usable communication channel. I believe passing binary data via XMLHttpRequest is problematic, so you might need to encode your save games in base 64 before transfer. (HEALTH WARNING: I’ve never tried this technique for transferring data, but it seems reasonable!)

Save game performance might be an issue - you may get many hits in quick succession if, say, a teacher suddenly tells a class to save and log off when the school bell rings. You can probably improve the speed of the database somewhat if you separate out the “cold” fields from the save data and put them in their own table. Again, Rails makes this very straightforward to manage. Both Rails and PHP are basically “shared nothing” systems, so they will scale straightforwardly if you need to add extra servers to cope with demand (and the scaling-up should be transparent to the client web player).

You should also protect against SQL injection and other possible server attacks. There is a very handy “top ten” of common attacks and countermeasures at the OWASP Project website.

Your user performance data should be quite easy to generate from the saved games and, of course, the obvious way to publish it is via a website. Again, Rails will make it very easy to have an admin page for each school, accessible via a log-on, but it’s also perfectly possible with PHP.

I’ll post again if I think of anything else…

Brilliant–thank you!

You could easily store everything inside a MySQL database. You can do thousands and thousands of records as long as you put proper indexes on your ID columns. One of our corporate training projects is a training game that logs every answer. We have over a million records and all queries are still on the order of milliseconds. Most popular forums end up with millions of records, too, without much trouble.

If performance does become an issue you can separate the game save data from the table that describes it. So instead of columns like this in one table:

saveid date … savedata

You have two tables:

saveid date … savedata_id
savedata_id savedata

This will prevent MySQL from seeking over huge chunks of data if you get a key failure on a query.

We haven’t done anything specifically in Unity, yet, but generally you just serialize all of your information and get it over to PHP somehow. GET has character limits so POST is your best option, as you mentioned (I don’t think it’s supported in 1.6.x via the built-in WWW class though). You may be able to use the .NET classes to POST; I’m not sure if it’s sandboxed in the web player or not.

If users will be jumping around machines a lot you could have them log in via the backend PHP logic and then pass their session ID to Unity’s side of things. Any data that Unity sends in would just include whatever is identifying them. There’s a thread around here somewhere with some techniques for passing information into Unity. There isn’t a defined way–as there is in Flash with FlashVars–but there are some techniques that work.

Hello,

I am curious to know if you were able to save your data and implement measures to protect against SQL injection and other possible server attacks such as the “top ten” common attacks mentioned by OWASP? Any infomraion would be very much appreciated.

I am curious also. I’ve been trying to use wwwForm to POST data but there seems to be a 1000 field cap. I’ve no idea how to send POST data other than using wwwForm so now I’m stuck as to how to save my data online.