Sign In Register

How can we help you today?

Start a new topic
Answered

Finally Published, Receiving Null Reference Exceptions From AccountDetailsRequest (ScriptData)

I'm most likely missing something simple here (yet again), but haven't discovered just what that simple thing is, so I thought I'd ask here.


I've just Published the first Snapshot of my game to the Live Servers via the Configurator. The Snapshot itself is a healthy green color on the screen now, and at the top of the screen, I see that both Preview and Live servers have "No Issues". Everything looks great, however I'm unable to log in from the Unity Editor any longer, for some reason.


In the Unity Editor itself, I have unchecked Preview Build in the GameSparks settings window, so it should be connecting to the Live servers. I do, in fact, receive the GS: Available message in the Unity Console, and I receive basic Facebook account information when using my Token for authorization. The problem seems to stem from my AccountDetailsRequest, which is looking for variables I've been storing in ScriptData. I assume that, because the player is brand new, that these values simply haven't been set, yet I'm not receiving NULL as a response, but instead get a Null Reference Exception that prevents the code from even executing... I hope that makes sense.


In short, I wish to retrieve ScriptData values for a New Player who may not have these values stored yet. How do I go about setting up Default values for such an instance, so that New Players can start the game with the correct initial values? This was all working fine on the Preview server, but for some reason, the information or functionality didn't carry over when I Published to the Live Servers.


As always, any help is most certainly appreciated. I've been working frantically to get this game up before Halloween, finally have a mostly stable build, and can't seem to get it Published properly. If there's any additional information I can provide, please don't hesitate to ask. Thanks!


Best Answer

Hi Kenneth,


Yes defaultValues was just a name I used for the example,it could be anything you’d like, playerStats, defaultStats etc... The code above wouldn't work if you had authenticated first then tried to link the account to Facebook with a FacebookConnectRequest, so if you load the Test Harness and do a FacebookConnectRequest with a valid Token, the player will be identified as new and the scriptData values set. Keep an eye on your externalAuthentication system collection as if you’re testing this any token used by you or another test account will be found in there and the player won’t be recognized as new.


Just to clarify, placing the code in the AuthenticationResponse covers all social authentication methods and having it in the RegistrationResponse covers playing registering for GameSparks with username and password. So with it in both this will cover all new players no matter what authentication method is used.


So a slight tweak on the above code to make it more relevant to what you’re trying to do. In your Authentication/Registration responses you could have the following.



//check if the player is new
var newPlayer = Spark.getData().newPlayer

if(newPlayer === true){

Spark.getPlayer().setScriptData("playerStats", {
"Lives": 0
 
});

var playerStats = Spark.getPlayer().getScriptData("playerStats");
Spark.setScriptData("playerStats", playerStats);
}

//or if it's a returning player, load the scriptData values
else{
var values = Spark.getPlayer().getScriptData("playerStats");

Spark.setScriptData("playerStats", values);

} 

    


We can also create events to set and retrieve this data. Create an event called “getScriptData” and place this in the Cloud Code for it.


 

var values = Spark.getPlayer().getScriptData("playerStats");
Spark.setScriptData("playerStats", values);

 


Running this event will return our playerStats data stored in scriptData. You could customise this further by passing in a specific scriptData value but for the nowit's just getting the playerStats values.


We can also create an event called setScriptData and give if a lives value like below.



Now place this in the Cloud Code for this event and run it. You'll see the new value set.

  

//value passed in through event
var Lives = Spark.getData().Lives;

Spark.getPlayer().setScriptData("playerStats", {
"Lives": Lives
});

//get the updated stats
var values = Spark.getPlayer().getScriptData("playerStats");
Spark.setScriptData("playerStats", values);

  


Hope this helps, can you let us know what method you have currently working on the client side to achieve this ? It might help narrow down what is causing the issue. 


Thanks,

Liam


Hi Kenneth,


So what you can do here is perform a simple check in the Authetntication/RegistrationResponse Cloud Code Events to see if a player is new, and if they are, add some default scriptData values for them. The code below should help you.


 

//check to see if this is a new player
var newPlayer = Spark.getData().newPlayer

  if(newPlayer === true){

  Spark.getPlayer().setScriptData("defaultValues",  {
   "name": "value",
   "name1": "value1"
    });
  }

 



Thanks,

Liam

Okay, was able to confirm that all ScriptData from my AccountDetailsRequest/Response is NULL. At least now I know where the issue lies for certain. While I'm guessing there's a better way to handle it, since it worked as it was on the Preview server, I'm still hoping someone can tell me how to handle this properly. In the meantime, however, I've achieved a sloppy workaround by detecting when ScriptData is Null, then running code that pushes the required ScriptData values onto GS, then running the initial "LoadPlayer" code a second time once the ScriptData values are no longer Null. Seems a bit recursive, but at least it's working for the moment.

 

Awesome, I'll give that a shot :) Thanks for your help, Liam!

 

Unfortunately, Liam's solution did not solve the issue. I'm still receiving NullReferenceException errors when trying to retrieve "lives" from ScriptData.

Per Liam's instructions, I attempted to put the following code into my "Responses: Authentication Response" Cloud Code:
//check to see if this is a new player
var newPlayer = Spark.getData().newPlayer
if(newPlayer == true){
  Spark.getPlayer().setScriptData("defaultValues",  {
   "lives": 5,
   "gameState": 0
    });
  }

 Having failed there, I tried to make the example look a bit more like the entries I have in my "Events" Cloud Code (skipping the "gameState" & only storing "lives"):


 

//check to see if this is a new player
var newPlayer = Spark.getData().newPlayer
if(newPlayer === true){
   var lives = Spark.getData().lives;
   Spark.getPlayer().setScriptData("lives", lives);
   Spark.setScriptData("lives", Spark.getPlayer().getScriptData("lives"));
  }

 

Both attempts failed with the same NullReferenceException error, which happens when the Unity Code attempts to retrieve the stored value for "lives" from AccountDetails / ScriptData.

I'll keep fiddling about, but any other suggestions or advice would be greatly appreciated as I am in a hurry to get this thing working in a live environment (and am really not sure why it worked fine in the Preview environment at all if these alterations are necessary).
Alright, still having no luck & my own earlier workaround seems to have issues all it's own, so it's a non-starter as well. Would the fact that I'm using Facebook to connect / authenticate be part of the reason Liam's code example isn't working for me? Also, his code includes "defaultValues"; is that part of the GS code, or an arbitrary designation used for the example? What I want to do is set a series of default ScriptData variables if a user does not already exist on the system, then retrieve & implement those new values. I'm in a big time crunch at the moment & would certainly love any assistance. Thanks!

 

Also a bit confusing... Should the cloud code example above have been placed in the AuthenticationResponse, RegistrationResponse, or both (keeping in mind that users are authenticating with Facebook).

 

Feeling a bit foolish now, but hopefully what occurred to me fixes things. I just realized that I likely don't have Default Values set for these entries in the Events I've created. I presume that filling those in would give me the correct values & not null entries? Off to test the theory...


 

Ah well, that idea didn't come to anything, which also makes me wonder why there are spaces to store default values for these entries if they're not used when no other values are presented, but I digress... I tried several different ways to attack the problem from the Cloud Code side with absolutely no luck in adding and/or altering "lives" to a player's ScriptData. I've given up and gone back to a retooled version of my earlier workaround, which is less than ideal, but far better than nothing. At least now new players can log into the game, and once they do, the default variables are set in place via game-side code, hopefully preventing further login issues.

 

Answer

Hi Kenneth,


Yes defaultValues was just a name I used for the example,it could be anything you’d like, playerStats, defaultStats etc... The code above wouldn't work if you had authenticated first then tried to link the account to Facebook with a FacebookConnectRequest, so if you load the Test Harness and do a FacebookConnectRequest with a valid Token, the player will be identified as new and the scriptData values set. Keep an eye on your externalAuthentication system collection as if you’re testing this any token used by you or another test account will be found in there and the player won’t be recognized as new.


Just to clarify, placing the code in the AuthenticationResponse covers all social authentication methods and having it in the RegistrationResponse covers playing registering for GameSparks with username and password. So with it in both this will cover all new players no matter what authentication method is used.


So a slight tweak on the above code to make it more relevant to what you’re trying to do. In your Authentication/Registration responses you could have the following.



//check if the player is new
var newPlayer = Spark.getData().newPlayer

if(newPlayer === true){

Spark.getPlayer().setScriptData("playerStats", {
"Lives": 0
 
});

var playerStats = Spark.getPlayer().getScriptData("playerStats");
Spark.setScriptData("playerStats", playerStats);
}

//or if it's a returning player, load the scriptData values
else{
var values = Spark.getPlayer().getScriptData("playerStats");

Spark.setScriptData("playerStats", values);

} 

    


We can also create events to set and retrieve this data. Create an event called “getScriptData” and place this in the Cloud Code for it.


 

var values = Spark.getPlayer().getScriptData("playerStats");
Spark.setScriptData("playerStats", values);

 


Running this event will return our playerStats data stored in scriptData. You could customise this further by passing in a specific scriptData value but for the nowit's just getting the playerStats values.


We can also create an event called setScriptData and give if a lives value like below.



Now place this in the Cloud Code for this event and run it. You'll see the new value set.

  

//value passed in through event
var Lives = Spark.getData().Lives;

Spark.getPlayer().setScriptData("playerStats", {
"Lives": Lives
});

//get the updated stats
var values = Spark.getPlayer().getScriptData("playerStats");
Spark.setScriptData("playerStats", values);

  


Hope this helps, can you let us know what method you have currently working on the client side to achieve this ? It might help narrow down what is causing the issue. 


Thanks,

Liam


1 person likes this
Login to post a comment