Unity: Kongregate API Package not connecting

19 posts

Flag Post

Hey all,

So I have been trying to integrate the Kongregate API into my game for a little while now but when I test the game after uploading it to kongregate, my debug message tells me it is not connected.
What am I doing wrong?

Here’s my info;
-I am using the Kongregate API Package that was posted on the Unity Blog.(http://blogs.unity3d.com/2010/12/29/kongregate-unity-game-contest/)
-I only attempt to submit my stats in the final scene, the score screen.
-In that scene I have placed an object that is called Kongregate and it has the Kongregate.cs script attached to it.
-And I have a Camera object in that same scene that has a few function calls to the Kongregate.cs script, including the functions for submitting stats, checking the connection, and checking the user’s Kongregate ID.
-I have also set up a test scene with the Kongregate.cs and KongregateTest.cs scripts(the ones included in the package) to see if I am missing something but that also says it is not connected when I publish it as a single scene.

Please help
Thanks!

 
Flag Post

Did you ever solve this problem? I am having the same issue :(

 
Flag Post

Hi all,

We had the same problem, the Unity package didn’t connect to Kong API, so we modified the script like this

In the Start method, we changed all the Application.ExternEval call for this one

		Application.ExternalEval(@"
			// Extern the JS Kongregate API

			if(typeof(kongregateUnitySupport) != 'undefined')
			{
  				kongregateUnitySupport.initAPI('Kongregate', 'OnKongregateAPILoaded');
  			};
			 
			function isGuest()
			{
				return kongregate.services.isGuest();
			}

			function getUsername()
			{
				return kongregate.services.getUsername();
			}

			function getUserId()
			{
				return kongregate.services.getUserId();
			}

			function showSignInBox()
			{
				if(kongregate.services.isGuest())
  					kongregate.services.showSignInBox();
			}
		
			function submitStat(statName, value)
			{
				kongregate.stats.submit(statName, value);
			}

			function getUserItems()
			{
				kongregate.mtx.requestUserItemList(null, onUserItems);
			}

			function onUserItems(result)
			{
				if (result.success)
				{
					var items = '';
					for (var i = 0; i < result.data.length; i++)
					{
						items += result.data[i].identifier;
						if (i < result.data.length - 1)
							items += ',';
					}
					SendUnityMessage('SetUserItems', items);
				}
			}

			function purchaseItem(item)
			{
				kongregate.mtx.purchaseItems([item], onPurchaseResult);
				SendUnityMessage('LogMessage', 'purchase sent....');				
			}

			function onPurchaseResult(result)
			{
				if (result.success)
				{
					SendUnityMessage('LogMessage', 'purchase complete...');
					getUserItems();
				}
			}

			// Utility function to send data back to Unity
			function SendUnityMessage(functionName, message)
			{
				var unity = GetUnity();
				unity.SendMessage('Kongregate', functionName, message);
			}

			function Log(message)
			{
				unity.SendMessage('Kongregate', 'LogMessage', message);
			}
		");

And added this method at the end of the file

	void OnKongregateAPILoaded(string userInfo)
	{
		Debug.Log("API Loaded");
		
		string[] userParams = userInfo.Split('|');
		int userID = int.Parse(userParams[0]);
		string name = userParams[1];
		string gameAuthToek = userParams[2];
		
		jsAPILoaded = true;
		SetUserId(userParams[0]);
		SetUsername(name);
		SetIsGuest(false);
	}

The rest of the script is the same.

I hope this could be useful for you :)

 
Flag Post

The last method (OnKongregateAPILoaded) has a little bug, and should be like this to handle guest:

void OnKongregateAPILoaded(string userInfo)
	{
		Debug.Log("API Loaded");
		jsAPILoaded = true;
	}
 
Flag Post

Well, I don’t know how you did it but it WORKED! Thank you so much for helping me (us?) out with this.

Now I have Kongregate API integration ticked off my TODO list :)

You ROCK!

 
Flag Post

Hi again! After testing a bit, I realized that the script did not work at all, because it did not manage well the guest users and the change of guest user to logged user, so I was coding a little more and here is the last script

using UnityEngine;
using System.Collections;


public class Kongregate : MonoBehaviour 
{	
	// Public API (Static Members)
	static public bool isConnected
	{
		get { return instance.jsAPILoaded; }
	}
	
	static bool _isGuest = false;
	static public bool isGuest
	{
		get 
		{
			instance.CallJSFunction("isGuest()", "SetIsGuest"); 
			return _isGuest; 
		}
	}
	
	static string _username = "";
	static public string username
	{
		get
		{ 
			instance.CallJSFunction("getUsername()", "SetUsername");
			return _username;
		}
	}
	
	static string _userId = "0";
	static public string userId
	{
		get 
		{ 
			instance.CallJSFunction("getUserId()", "SetUserId"); 
			return _userId;
		}
	}
	
	static string _items = "";
	static public string[] items
	{
		get
		{
			instance.CallJSFunction("getUserItems()");
			if (string.IsNullOrEmpty(_items))
				return new string[0];
			else
				return _items.Split(',');
		}
	}
	
	static public void ShowSignIn()
	{
		instance.CallJSFunction("showSignInBox()");
	}
	
	static public void SubmitStat(string statistic, int value)
	{
		instance.CallJSFunction(string.Format("submitStat('{0}', {1})", statistic, value));
	}
	
	static public void PurchaseItem(string item)
	{
		Debug.Log("Attempting purchase of " + item);
		instance.CallJSFunction(string.Format("purchaseItem('{0}')", item));
	}
	
	static Kongregate _instance = null;
	static Kongregate instance
	{
		get
		{
			if (!_instance)
				new GameObject("Kongregate", typeof(Kongregate));
				
			return _instance;
		}
	}
	
	// Instance Members	
	bool jsAPILoaded;
	string jsReturnValue;
	
	void Awake()
	{
		// Only allow one instance of the API bridge
		if (_instance)
		{
			Debug.Log("Destroying GO");
			Destroy(gameObject);
		}
		
		Debug.Log("Awake kongregate");
		_instance = this;
	}
	
	void Start() 
	{
		Debug.Log("Trying to load Kongregate API");
		Application.ExternalEval(@"
			// Extern the JS Kongregate API

			function isGuest()
			{
				return kongregate.services.isGuest();
			}

			function getUsername()
			{
				var name = kongregate.services.getUsername();
				return name;
			}

			function getUserId()
			{
				return kongregate.services.getUserId();
			}

			function showSignInBox()
			{
				if(kongregate.services.isGuest())
  					kongregate.services.showSignInBox();
			}
		
			function submitStat(statName, value)
			{
				kongregate.stats.submit(statName, value);
			}

			function getUserItems()
			{
				kongregate.mtx.requestUserItemList(null, onUserItems);
			}

			function onUserItems(result)
			{
				if (result.success)
				{
					var items = '';
					for (var i = 0; i < result.data.length; i++)
					{
						items += result.data[i].identifier;
						if (i < result.data.length - 1)
							items += ',';
					}
					SendUnityMessage('SetUserItems', items);
				}
			}

			function purchaseItem(item)
			{
				kongregate.mtx.purchaseItems([item], onPurchaseResult);
				SendUnityMessage('LogMessage', 'purchase sent....');				
			}

			function onPurchaseResult(result)
			{
				if (result.success)
				{
					SendUnityMessage('LogMessage', 'purchase complete...');
					getUserItems();
				}
			}

			// Utility function to send data back to Unity
			function SendUnityMessage(functionName, message)
			{
				Log('Calling to: ' + functionName);
				var unity = kongregateUnitySupport.getUnityObject();
				unity.SendMessage('Kongregate', functionName, message);
			}

			function Log(message)
			{
				var unity = kongregateUnitySupport.getUnityObject();
				unity.SendMessage('Kongregate', 'LogMessage', message);
			}

			if(typeof(kongregateUnitySupport) != 'undefined')
			{
  				kongregateUnitySupport.initAPI('Kongregate', 'OnKongregateAPILoaded');
  			};
		");
		  
//		Application.ExternalCall("SendUnityMessage", "OnLoaded", "Message to myself");
//		Application.ExternalCall("loadAPI");

		DontDestroyOnLoad(gameObject);
	}
	
	public void LogMessage(string message)
	{
		Debug.Log(message);
	}
	
	void OnLoaded(string error)
	{
		if (string.IsNullOrEmpty(error))
		{
			jsAPILoaded = true;
			Debug.Log("Connected");
		}
		else
			Debug.LogError(error);
	}
	
	public void SetIsGuest(object returnValue)
	{
		if (bool.TryParse(returnValue.ToString(), out _isGuest))
		{
			// Request username again if guest
			if (_isGuest)
				_username = "";
		}
	}
	
	public void SetUsername(object returnValue)
	{
		_username = returnValue.ToString();
	}
	
	void SetUserId(object returnValue)
	{
		_userId = returnValue.ToString();
	}
	
	void SetUserItems(object returnValue)
	{
		_items = returnValue.ToString();
	}
	
	void CallJSFunction(string functionCall)
	{
		CallJSFunction(functionCall, null);
	}
		
	void CallJSFunction(string functionCall, string callback)
	{
		if (jsAPILoaded)
		{
			if (string.IsNullOrEmpty(callback))
			{
				Application.ExternalEval(functionCall);
			}
			else
			{
				Application.ExternalEval(string.Format(@"
					var value = {0};
					SendUnityMessage('{1}', String(value));
				", functionCall, callback));
			}
		}
	}
	
	void OnKongregateAPILoaded(string userInfo)
	{
		Debug.Log("API Loaded");
		jsAPILoaded = true;

		string[] userParams = userInfo.Split('|');
		int userID = int.Parse(userParams[0]);
		string userName = userParams[1];
		string gameAuthToek = userParams[2];
		
		if (userID == 0)
		{
			SetIsGuest(true);
		}
		else
		{
			SetUserId(userParams[0]);
			SetUsername(userName);
			SetIsGuest(false);
		}
	}
}

As I know, the main problem with the Unity binding was the way it is loading Kongregate and the way it is getting the UnityObject in “SendUnityMessage” method. It also does not manage well the properties, because if a change is made (user logs in, for example), the data is not refreshed.

So what I am doing here is this:

  1. Connect to Kongregate the way it is showed in the Kongregate API (http://www.kongregate.com/developer_center/docs/using-the-api-with-unity3d)
  2. Get the UnityObject to communicate with Unity through KongregateUnitySupport instead of using “GetUnity” function
  3. Username, UserID and IsGuest are not cached, so they are calculated each time they are required (using the Kongregate API)

PsychicParrot, thx for your comment :)

 
Flag Post

Thank you very much, after a day of WTF, I copied in your changes and it all works.

 
Flag Post

Any tips on implementing the Kongregate API with Javascript?

 
Flag Post

I’ve tried to use some code similar to the ones on the documentation but it is not working…
@

var isKongregate = false;
var userId = 0;
var username = “Guest”;
var gameAuthToken = "";

function Start(){

LoadAPI();
playerName = username;
PlayerPrefs.SetString(“PlayerName”,playerName);
}

function LoadAPI(){

// Begin the API loading process if it is available
Application.ExternalEval(
“if(typeof(kongregateUnitySupport) != ‘undefined’){” +
" kongregateUnitySupport.initAPI(‘FBRacer’, ‘OnKongregateAPILoaded’);" +
“};”
);
}

function OnKongregateAPILoaded(userInfoString){
// We now know we’re on Kongregate
isKongregate = true;

// Split the user info up into tokens var params = userInfoString.Split(“|”0); userId = parseInt(params0); username = params1; username = username.ToString(); gameAuthToken = params2;

}
@

 
Flag Post

Thanks CrazyBitsStu…

Your code got me up and running!

 
Flag Post

@gregtedder: It’s CrazyBitsStudios. Kongregate just cuts it off

Anyway, gonna see if his script solves my problems. For some reason, the api on the Unity website doesn’t work. at all. ever. Can’t even detect if user is guest or logged in. Just says I’m Guest. Fingers crossed CrazyBitsStudio has solved my problems once and for all :) Just have to transfer a few very large files before I can find out…

 
Flag Post

You’re aware that his last reply was like 10 months ago, right?

 
Flag Post

whoops! No I did not. Thanks for pointing that out.

EDIT: In case anyone knows: is there a particular reason I get an ‘unidentified webpage error’ when my game tries to submit score in IE?

EDIT 2: Just found out maybe highscores aren’t my fault. So far, it seems none of the Unity games can detect that I’m logged in (I tried Carpal Clicker, Sanctioned Renegades, and Carbon Combat). I’m using Firefox, although I did try it in IE (saving highscore produces unidentified error)

 
Flag Post

i’m trying to get it working for three days… no success (((

 
Flag Post

Has anyone managed to solve this? I’ve got my game uploaded as a preview and getUsername() returns “Guest”!

 
Flag Post

This version of code works fine for me !

 
Flag Post

if using an iframe, how can I notify the unityobject that a message is coming back from kongregate? As of now, I’m using the IFrame template provided by kongregate. It uses the embed function of the Kongregate API to inject my IFrame page inside. But once the message is sent, how would you hook into the response from within the embedded unity page?

 
Flag Post

I’m not sure if this will work but I added this at the bottom of

if (typeof(kongregateUnitySuppor) != ‘undefined’)
{…};

kongregate.service.addEventListener(‘login’, function()
{
var services = kongregate.services;
var params=[services.getUserId(), services.getUsername(), services.getGameAuthToken()].join(‘|’);
unity.SendMessage(‘Kongregate’, OnKongregateUserSignedIn’, params);
}

Then added a function…

public void OnKongregateUserSignedIn(string userInfoString)
{
string[] data = userInfoString.Split(“|”0);
int userID = int.Parse(data0);
string userName = data1;
string gameAuthToken = data2;

SetUserId(userID);
SetUsername(userName);
SetIsGuest(false);

//TODO: This is where I sync the guest data to the logged in user data
}

According to the random stuff I had to scavenge around here, the function should be called whenever a user logs in his account. I haven’t tested this yet. I am still working on this whole thing now.

 
Flag Post

Ok ppl I myself have spent a good chunk of my day searching for the answer to this Unity problem myself and in the end… the only thing that worked for me was to change the name of the object I attach the Kongregate API script. It should be named “MyUnityObject”.

The Coding I used :

//object must be named “MyUnityObject”/

var isKongregate = false;
var userId = 0;
static var username = “Guest”;
var gameAuthToken = "";

function Awake(){
// This game object needs to survive multiple levels
DontDestroyOnLoad (this);
// Begin the API loading process if it is available
Application.ExternalEval(
“if(typeof(kongregateUnitySupport) != ‘undefined’){” +
" kongregateUnitySupport.initAPI(‘MyUnityObject’, ‘OnKongregateAPILoaded’);" +
“};”
);

}

function OnKongregateAPILoaded(userInfoString){
// We now know we’re on Kongregate
isKongregate = true;
Debug.Log(“ON KONG”);
// Split the user info up into tokens
var params = userInfoString.Split(“|”0);
userId = parseInt(params0);
username = params1;
gameAuthToken = params2;
}

// Called when the Kongregate user signs in, parse the tokenized user-info string that we

// generate below using Javascript.
function OnKongregateUserSignedIn(userInfoString){
var params = userInfoString.Split(“|”0);
userId = parseInt(params0);
username = params1;
gameAuthToken = params2;
}

// Register a sign in handler to let us know if the user signs in to Kongregate. Notice how we are using the
// Javascript API along with Application.ExternalEval, and then calling back into our app using SendMessage.
// We deliver the new user information as a simple pipe-delimited string, which we can easily parse using String.Split.
Application.ExternalEval(
“kongregate.services.addEventListener(‘login’, function(){” +
" var services = kongregate.services;" +
" var params=[services.getUserId(), services.getUsername(), services.getGameAuthToken()].join(‘|’);" +
" kongregateUnitySupport.getUnityObject().SendMessage(‘MyUnityObject’, ‘OnKongregateUserSignedIn’, params);" +
“});”
);

//Original code By : Mushizo on Kongregate. Edited by : Maskill