Another Game and Facebook Woes (er… Tutorial)


Guillotine Image

Who Cut the Deck - A Facebook card game.

First, I’ll cut to the chase and announce the alpha release of a card game I’ve been working on called Who Cut The Deck.

The idea for the game  was born of a necessity.  A friend of mine is leaving town, but we regularly get together to play cards or board games.  We considered the idea of using some kind of Skype arrangement to handle the games, but a basic problem exists for any game which uses cards… we can’t network the arrangement of shuffling.  So, I decided to make a network card shuffler.

It’s expanded, as these things do.  And the goal for me has now become to as closely match as possible the feel of being in the same room sitting around a table playing these games.  Thus it’s in 3d, it has physics simulation, and hopefully at some point I can get sound and video achieve the verisimilitude.

Finally, I’ll admit the point wasn’t to use a standard deck, but some of the more interesting card and board games that are out there.  Of course, these won’t be released as I’m keeping them for our personal use, but I may approach the copyright owners at some point and see if something can be arranged.  Until then, I hope people outside our group of friends will enjoy playing any game possible with a normal deck of cards.  There are, after all, quite a few of them.

Now, to maintain some of the technical quality of this site, I’ll talk about some of the trials and tribulations of integrating Facebook and Unity.  It’s not as bad as trying to network from scratch (the worst possible programming hell you’ll ever face, thank you Unity/Raknet for taking that out of my hands), but it’s not as easy as you might expect from some of the tutorials around the web.

One thing is that Facebook has very recently changed the API.  You can still use existing methods, but they are probably going to be deprecated.  I continue to use them (specifically the original PHP api) myself, because I just wanted to get it working, but it’s good to know where things break down.

I won’t list them here because it’s easy enough to search the web for “Unity3d Facebook Tutorial”, but a good one I used to setup is here.  As of this writing, it is not yet complete.  I’ll expand on it a little bit here.

The last entry ends with a query to the image FQL.  This is a nice start, but one of the most important things you’ll run into is that using PHP you’ll need to do a large portion of your queries on the front end.  This is because PHP processes on the server, but Unity runs on the client.  Now, you can also setup some PHP helpers callable from Unity using it’s WWW class, but none of these can use authorization directly.  I believe it is possible to establish the authorization with Unity in the initial load and pass this into unity to forward back to these helper queries, but I haven’t made that work yet.

In the meantime, you can only get basic information available without access to the login (in my case I query name and profile image).  The following code is how I pull out the name and image you see when you first load up the game.

<?php
$user_id = $_REQUEST["id"];
require_once 'facebook-platform/php/facebook.php';
$apikey = XXXXXX;
$secret = YYYYYY;
$facebook = new Facebook ($apikey, $secret);
$info = $facebook->api_client->users_getInfo ($user_id, array ('first_name'));
$query = "SELECT pic_big FROM profile WHERE id = $user_id;";
$result = $facebook->api_client->fql_query($query);
print $info[0]['first_name'].",".$result[0]["pic_big"];
?>

The Unity code that accesses this is:

var url = correctURL+"getFBProfile.php?id="+userId;
var www = new WWW (url);
yield www;
var data = www.data.Split(","[0]);
playerName = data[0];
if (imageCache.Contains(userId)) {
  playerImage = imageCache[userId];
} else {
  www  = new WWW (data[1]);
  yield www;
  playerImage = www.texture;
  imageCache.Add (userId, playerImage);
}

Finally, the note I need to explain is how to get the userId into Unity. Following the tutorial above, you’ll see how to get to that point. To get it into Unity is not nearly as trivial as I expected it would be. First you don’t know when unity is loaded from the webpage so you can’t call it immediately, instead you need some javascript function in the webpage that calls back into unity. I have:

<script type="text/javascript">
function initializeUnity () {
  GetUnity().SendMessage("Main Menu", "SetGameType", "Facebook");
  GetUnity().SendMessage("Main Menu", "SetUserId", <? print "\"$user_id\"" ?>);
  GetUnity().SendMessage("Main Menu", "SetFriends", <? print "\"$friends\"" ?>);
  GetUnity().SendMessage("Main Menu", "InitializationComplete", "");
};
</script>

That final InitializationComplete is the most important missing piece from documentation I could find.  It sets a variable “loaded” to true inside Unity so that I can do the following before doing anything else using userId.

Application.ExternalCall ("initializeUnity", "");
while (!loaded)
  yield WaitForSeconds(0.1);

This is because those calls in the webpage are Message and those will be passed asynchronously (for all intents and purposes) to your javascript. So you need to wait until they all come through before assuming they have completed.

However, by this point in your application you’ll have everything you need (and if you ever pass through authorization keys that’ll also work beyond this point…) to proceed as expected.  Good luck.

One of these days I’ll talk about latency issues with Unity’s master server from the states.  And why it’s probably much better to keep it somewhere close to your users :)

In the meantime, let me know if you try Who Cut the Deck and feel free to offer suggestions or bugs in the comments.

  1. #1 by Mike Stramba on December 28, 2010 - 8:17 PM

    Hi,

    I found out about your game at http://forum.unity3d.com/threads/48497-Facebook-card-game

    I launched it from my Facebook account, the main screen loads, I press the “Start a New Game” button, but nothing happens.

    My unity web player is whatever version was installed with Unity 3.1.0f4

    Mike

(will not be published)
*

Switch to our mobile site