B4i Library GameCenter

iGameCenter library provides access to Apple's Game Center services. Currently only the leaderboard (high scores) feature is implemented.

SS-2017-11-05_17.48.23.png


This service requires some configuration:
1. You must use an explicit app id (without wildcards).
2. Must use a development certificate and provision profile during development.
3. Add this line:
B4X:
#DeviceCapabilities: gamekit
4. An app record must be available in iTunes Connect.
5. Create a leaderboard:

SS-2017-11-05_17.42.38.png


6. Enable Game Center in the app version page:

SS-2017-11-05_17.43.28.png


The code itself is quite simple. You should initialize the GKGameCenter object when the program starts.
The AuthenticationStateChanged event will be raised.
If ShouldShowDialog is True then you need to call Game.ShowDialog.

The AuthenticationStateChanged can be raised in other cases as well so assume that it will be raised and the state will change.

Once authenticated you can submit the current user scores and you can get the top scores.
See the attached example (make sure to change the board id as needed).

See code in post #8 for showing the built-in leaderboard dialog.

Update:

Need to add to main module:
B4X:
#Entitlement: <key>com.apple.developer.game-center</key><true/>
 

Attachments

  • GameCenterExample.zip
    111.3 KB · Views: 19
  • iGameCenter.zip
    60.7 KB · Views: 15
Last edited:

ilan

Expert
Licensed User
Longtime User
hi erel, i have a small problem. there is a part of your code that wont compile.

B4X:
            For Each score As GKScore In Scores
                CustomListView1.AddTextItem($"Player: ${score.Player.Alias}
                Score: ${score.Value}
                Date: $DateTime{score.Date}"$, "")
            Next

if i comment it i can compile.

after i compile in debug mode i add those lines and click save then hit refresh and it works.
after i clean the project and try to compile again i get the error that it cannot compile

this is really weird :confused:

i comment those lines in debug mode, i add those lines manually and it works but then when i clean the project and compile again it doesn't compile

i also use it like this:

B4X:
            For Each s As GKScore In Scores
                Log(s.Player.Alias)
            Next

but it won't compile if the project was cleaned.

i include the logs in a text file because its too long to add it to this post.

i need to mention again that if i compile after i comment those lines and then add them manually while my app runs in the foreground and click save i am able to receive the GKScore values. only if i clean the project or compile it in release mode it won't compile.


regards, ilan
 

Attachments

  • log1.txt
    52.7 KB · Views: 3

ilan

Expert
Licensed User
Longtime User
hi again, i have a small question, please.
i see in all games that use gamecenter that they have the same view to show the hi score list.
i assume that it is a build in feature (dialog) of gamecenter. does b4i GameCenter support that dialog or will it support it in the future?

thank you

download.jpg

EDIT: i think its the game center view controller
https://developer.apple.com/documentation/gamekit/gkgamecenterviewcontroller
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Add this code:
B4X:
Sub ShowLeaderboard(Page As Page, BoardId As String)
   Dim vc As NativeObject
   vc = vc.Initialize("GKGameCenterViewController").RunMethod("new", Null)
   vc.SetField("leaderboardCategory", BoardId)
   vc.SetField("viewState", 0) '0 = leadboards
   Dim del As NativeObject
   del = del.Initialize("B4IGameCenterViewControllerDelegate").RunMethod("new", Null)
   vc.SetField("gameCenterDelegate", del)
   Dim no As NativeObject = Page1
   no.RunMethod("presentViewController:animated:completion:", Array(vc, True, Null))
End Sub

#if OBJC
@end
@interface B4IGameCenterViewControllerDelegate :NSObject<GKGameCenterControllerDelegate>
@end
@implementation B4IGameCenterViewControllerDelegate
- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController {
   [gameCenterViewController dismissViewControllerAnimated:YES completion:nil];
}

#End If
 

ilan

Expert
Licensed User
Longtime User
Hi Erel, lib is working great. i have implemented in my game. You can see it in action in the first post here:
https://www.b4x.com/android/forum/threads/space-defender-ultimate-ispritekit.85566/

i just have one problem. i was stupid enough to create the game with a wildcard app id and wildcard app id's do not support game center. :(
so i have created a new app in the store and uploaded the build to that non-wildcard app id. i doubt that Apple will approve it since the same game already exists but if they do, I will unpublish the first one and keep the non-wildcard app.

So for everyone that read this post DO NOT PUBLISH YOUR APPS WITH A WILDCARD APP ID if you plan to use Gamecenter or Notifications.
And even if not i don't see any advantage of a wildcard id then a non-wildcard id. so better use non-wildcard id and keep the possibility of adding services to your app in the future!

EDIT: ok that was quick o_O after few hours my non wildcard game was approved. if you want to try iGameCenter you in action you can do it here: https://itunes.apple.com/us/app/space-defender-ultimate/id1308056330?l=iw&ls=1&mt=8
 
Last edited:

ilan

Expert
Licensed User
Longtime User
You didn't need to create a new app. Just upload a new build signed with the new provision profile.

you were right erel, i have uploaded a new build with new certification and provisions file and it was approved.
its weird that both games were approved within few hours.
i have unpublished the second build and now the first is again active and has iGamecenter in it.

thank you very much and sorry for losing your hi-score :D (you are no longer in 1st place :))
 

sorex

Expert
Licensed User
Longtime User
I am using my own leaderboard system that works with a generated code that can be used on multiple devices.
You can even use it on a mixture of android/ios devices to keep your scores in sync.

Yesterday the apple boys were nagging that I use a code to share data between devices.
They probably think I'm enabling payed features without using their in-app stuff so they're losing their cut.

While they scheduled a phonecall with me to discuss this I'm thinking it's maybe time to use their leaderboard system instead
and drop the idea of the OS independent global leaderboard that didn't rely on google play service (problem for some eastern countries) & gamecenter.

But I see these problems with the current B4i implementation and their leaderboard in general.

- my own leaderboard/ranking blends into the game lets call it theming. from what I see from @ilan's screenshot this is just a fixed top 7 page that pops up?
can we make our own and just pull in the data like position, score, name of the top 3, 10 ?

- when I submit scores I pull the rank and the score to reach to move up in the ranking. not sure if I can do this with gamecenter?

- my ranking page shows the top 3 scores and under that a list of your score and the 9 scores above you (or some above and under you if you're in the top 10).
can you pull a list like that from gamecenter?

- I filter out scores that haven't been updated for months (uninstalls?) if they suddenly play again they are back in place. I guess I can forget about this with game center.
It's rather useless to keep 10000 scores with only 500 playing.


or can I abuse the login feature of gamecenter and keep using my own system and replace the code with an encrypted version of the email used for gamecenter login?
 
Last edited:

sorex

Expert
Licensed User
Longtime User
I followed the turorial and got the app working.

But when I entered a nick name and submitted it the app crashed.

When I now start the app is gives "welcome nickname" and then crashes aswell.

This appears in the logs...

B4X:
Application_Start
Application_Active
Authenticated!
Error occurred on line: 58 (Main)
+[B4IObjectWrapper raiseEventFromDifferentThreadWithExplicitSender::::]: unrecognized selector sent to class 0x9774c
Stack Trace: (
  CoreFoundation       <redacted> + 150
  libobjc.A.dylib      objc_exception_throw + 38
  CoreFoundation       <redacted> + 0
  CoreFoundation       <redacted> + 700
  CoreFoundation       _CF_forwarding_prep_0 + 24
  B4i Game             __31-[B4IGameCenter RequestScores:]_block_invoke + 442
  GameCenterFoundation <redacted> + 12
  libdispatch.dylib    <redacted> + 10
  libdispatch.dylib    <redacted> + 22
  libdispatch.dylib    <redacted> + 1524
 CoreFoundation       <redacted> + 8
 CoreFoundation       <redacted> + 1574
 CoreFoundation       CFRunLoopRunSpecific + 520
 CoreFoundation       CFRunLoopRunInMode + 108
 GraphicsServices     GSEventRunModal + 160
 UIKit                UIApplicationMain + 144
 B4i Game             main + 106
 libdyld.dylib        <redacted> + 2
)
SignalHandler 6

Edit: I had to change this line to my own leaderboard ID > Dim sf As Object = Game.RequestScores("main")
Edit2: now the score submit crashed even when changing the boardid to my own
Edit3: now it always crashes :)
 
Last edited:

sorex

Expert
Licensed User
Longtime User
The issue above was solved by an update on the remote builder servers.
 
Top