Monday, October 14, 2013

iOS achievements wouldn't work

Oddly enough although I was trying hard to give out my achievements for the new game, they simply didn't appear to update. Yet I was getting the callback to hit and it said there was no error. How is that possible?  (I use the Marmalade SDK and the EDK for the GameCenter functionality).

I couldn't understand how this was happening so I decided that I needed to find more information.. time to debug.

As I run the game remotely on the iPad with no debugger connected I came up with my standard debug collation methods. This includes coloring the screen to various colors to tell me what is going on. Then I added some debug prints to the screen to tell me which function was the last one entered. Following that by another string of information of values used within that last function entered.

Oddly the printout and coloration was correct. For example:
The color was...
Green.. which meant success on the callback.
The last function entered was...
void cGameCenter::ReportAchievement(const char *_name, int _percentage, int _index)
The function information was...
name == "HB_A01"
percentage == 609
index == 0

Now as it happens that information is mostly correct, only one piece of it stands out in a bad way. It is impossible to have 609 percent of course. So I figured this was the issue. So I quickly found the problem..yeah, I had the divide the wrong way around, so that was easy enough.

So I tried once again after my percentage fix.

This time the information was correct. Yet the achievement didn't show up at all on Gamecenter. Most odd indeed. As all this information was correct I had to look for another culprit. As it happens the test app supplied with Marmalade asks for string input and uses that input to send to the achievement. I figured I should try this same method as it had worked in my previous game.

// test setup
const char* tmp = s3eOSReadStringUTF8("Enter achievement name:");
strcpy(name, tmp);
const char* valueStr = s3eOSReadStringUTF8("Percent Complete:",S3E_OSREADSTRING_FLAG_NUMBER);
_percentage = atoi(valueStr);
sprintf (gAchieveDebugStr, "name=%s, %%=%d, index=%d\n", name, _percentage, _index);
s3eIOSGameCenterReportAchievement(name, _percentage, ReportAchievementCallback);

 And I plugged in the same information into these strings that the function report told me I had entered earlier, but didn't work. Amazingly the achievement worked out great.. It Worked! What the heck? I couldn't understand what I was witness too. It should not have worked.

So this got me to thinking on why or how my real code didn't work. Well after much debate and reading of my code I figured it out.

The answer was the name string. I was sending in a
const char name[256] = "HB_A01";

And that didn't work. For some reason the string had to be on the stack, in the case that eventually worked for me, I simply copied my string into the local one declared inside the report function.

That worked... So after all my effort all I really needed was to put the name in a local variable.... GAH! there was no mention of this anywhere, in the help forums or the help docs.

Still I got it in the end which is what matters,

Da Voodoochief

No comments:

Post a Comment