Lua Brigde - Custom Leaderboard?

The below implementations was replaced by Native Extension. Please scroll down to see recent updates.

Code example for Game Center extension :

https://github.com/vinhvd/defoldgamecenter


Hello,

I’ve tried to build a custom leaderboard for game center :

1. Authenticate :
1.1 Lua :
> local f = assert(package.loadlib(“libgamecenter_authenticate.dylib”, “exec”))
> f()

1.2 Object C :

> #define EXPORT __attribute__((visibility("default")))

> NSString *const PresentAuthenticationViewController = @"present_authentication_view_controller";

>         EXPORT
>          int exec(lua_State *L) {
>     
>         GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
>         localPlayer.authenticateHandler  =
>         ^(NSViewController  *viewController, NSError *error) {
>             if (error) {
>                 printf("Game Center : authenticate error : %s",
>                        [[[error userInfo] description] UTF8String]);
>             }
>         
>             if(viewController != nil) {
>                 [[NSNotificationCenter defaultCenter]
>                  postNotificationName:PresentAuthenticationViewController
>                  object:nil];
>             } else if([GKLocalPlayer localPlayer].isAuthenticated) {
>                 printf("Game Center : authenticate : OK");
>             }
>         };
>     
>     return 0;
>}

2. Load Scores :

2.1 Lua :

local f = assert(package.loadlib(“libgamecenter_load_scores.dylib”, “exec”))
f()

2.2 Object C :
>#define EXPORT attribute((visibility(“default”)))

>#define kLeaderboardID @"highscore"

> EXPORT
> int exec(lua_State *L) {
>     
>     GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
>     if (leaderboardRequest != nil)
>     {
>         leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
>         leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllTime;
>         leaderboardRequest.identifier = kLeaderboardID;
>         leaderboardRequest.range = NSMakeRange(1,100);
>         [leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
>             if (error != nil)
>             {
>                 printf("Game Center : load score error : %s",
>                        [[[error userInfo] description] UTF8String]);
>                 NSLog(@"Game Center : load score error : %@:", [[error userInfo] description]);
>             }
>             if (scores != nil)
>             {
>                 GKScore* myScore = leaderboardRequest.localPlayerScore;
>                 
>                 NSLog(@"Me: %@: %d", myScore.player.alias, (int)myScore.value);
>                 printf("Me: %s", [myScore.player.alias UTF8String]);
>                 
>                 
>                 for (GKScore* score in scores)
>                 {
>                     NSLog(@"Player %@: %d", score.player.alias, (int)score.value);
>                 }
>                 
>             }
>         }];
>     }
>     return 0;
> }

3 Report Score :

3.1 Lua :

 >  local f = assert(package.loadlib("libgamecenter_report_score.dylib", "exec"))
>     f()

3.2 Object C :

 >EXPORT
> int exec(lua_State *L) {
>    GKScore* highScore = [[GKScore alloc] initWithLeaderboardIdentifier:kLeaderboardID];
>         highScore.value = (int64_t)64;
>         [GKScore reportScores:@[highScore] withCompletionHandler:^(NSError *error) {
>             if (error) {
>                 NSLog(@"Game Centre : report score : %@", error);
>                 printf("Game Center : report score : %s",
>                        [[[error userInfo] description] UTF8String]);
>             }
>         }];
>     return 0;
> }

Result :

#1 Authenticate : work perfectly

Not login yet

Logged in already

#2 Load Scores :

Me and all players are enable to load in Object C codes

#3 Report Score :

It is able to store hard code score to Game Center .

Question :

As Lua standard, it is able to pass value from Lua to C and return value from C to Lua ( L is Lua state)

For example : In lua, I want to pass a score value to C as : f(1000)
then I can get the value in C to report score as :

  >   if(lua_isnumber(L, 1)) {
>         int score = lua_tonumber(L, 1);
>     }

and I can load the score from C to lua as : lua_pushnumber(L, score);

However , when pass and return the values , the game halts .

Is it possible to pass and return values in embedded Lua of Defold like the above ?

> lua_CFunction
> typedef int (*lua_CFunction) (lua_State *L);
> static int foo (lua_State *L) {
>        int n = lua_gettop(L);    /* number of arguments */
>        lua_Number sum = 0;
>        int i;
>        for (i = 1; i <= n; i++) {
>          if (!lua_isnumber(L, i)) {
>            lua_pushstring(L, "incorrect argument");
>            lua_error(L);
>          }
>          sum += lua_tonumber(L, i);
>        }
>        lua_pushnumber(L, sum/n);        /* first result */
>        lua_pushnumber(L, sum);         /* second result */
>        return 2;                   /* number of results */
>      }

Thanks,
-RG1

10 Likes

Wow, I wasn’t even aware that you could do something like this! Interesting…

2 Likes

In theory, I believe there’s always a door in any tools/frameworks to do some specified tasks. Although, I’m not clear about Apple Game Center roadmap, I’d like to build a leaderboard for my simple games as Facebook has some disadvantages except a “Saga” game which supplied a lot of levels which players are willing to give “publish_actions” and “user_friend” permission to push their score and get their friends. Nowadays, people are aware of public share of game. FB leaderboard and achievement might not suitable for simple game.

In the lua_CFunction, it’s able to get Lua State , but I got strange number when invoking lua_gettop(L) instead of number of args. That’s the only issue to support Leaderboard using the implementation.

I hope to achieve it while waiting for Defold official support on LeaderBoard. If not , I still get some great experiences.

Correction: “I wasn’t even aware that you could do something like this in Defold

I thought perhaps we had modified the package loader or something, but apparently not.

There is also a lot of fun stuff you can do with LuaJITs FFI (Foreign Function Interface): http://luajit.org/ext_ffi_tutorial.html

The thing with all of this is that it’s often very platform specific stuff. Which may be fine depending on the use-case.

2 Likes

No need to correct the previous message as I see what you mean (positive). The LuaJITs is interested
stuff to play. Thanks for your sharing.

One more question : I saw that The FFI library is built into LuaJIT by default, but look like it is not able to load the library in Defold as the loader was modified (Only accept a *.lua file for “require”). Navigate more the link I get https://luapower.com/objc#local-objc-requireobjc , it is quite easier to “bridge” with Object C but it doesn’t support to load also. How to load FFI or objc lib in Defold if possible ?

Thanks,
-RG

1 Like

Perhaps, I should correct some points :

Apple Game Center roadmap : I meant Apple roadmap, whether Apple continue to pay attention on Game Center for upcoming iOS and mac OS release.

Defold official support for Game Center : no timeline so far, I’ve tried some approach to make a workaround solution.

Facebook vs Game Center : The point mentioned my vision about social feature for simple game. A simple game might not enough to attract player to give “user_friends” permission to build a leaderboard/achievement and “publish_action” to update their score.

Game Activity : Nowadays, people (players) are aware of share their game activities to public. A private virtual place where all are interested in games should be better.

Coming late in this thread, but did you manage to make this work? I’d really like to implement a leaderboard =)

2 Likes

@Gozock : For some reason, I’ve not got the chance to follow up the resolution. In the meanwhile , you might invest on a mBaas (e.g. BackendLess) with/without FB to build the LeaderBoard via REST API. That is my current solution for up-comming games also.

I will back when the Editor 2 is available.

-RG.

2 Likes

Are you sure that it will work on iOS?
As I know Apple did not support dynamic linking due to security concerns.

I’m almost 100% sure this will not work on iOS since it will not be able to find libgamecenter_authenticate.dylib. How would you even bundle it with the .ipa?

iOS 8 lifted this restriction I’m pretty sure… someone needs to test!

You can modify the ipa, and then resign. The ipa is an archive, inside of it is an app package which can be opened like a folder with right click.

I don’t know if it would actually work as I’ve never tried this specifically.

Yeah, you can probably unzip, add and resign the ipa, but all of the io.* functions and most certainly also package.loadlib() works on the filesystem of the device, not on whatever files that might exist inside the IPA itself (that is why there is a sys.load_resource() function).

Maybe read it from internal data, and in that case just include the file in game.properties list, and then copy it into a folder which the loadlib can then read from? As long as it’s included with the game bundle and not downloaded remotely it should be ok?

I found out that you can load FFI without using require :smiley:

local ffi = package.preload.ffi()
4 Likes

I’ve not got the chance to follow up the custom leaderboard using .loadlib function. Yes, it is platform specified. I implemented this feature for the very special situation and it doesn’t support independent platform. I’m not sure it is enable for me to reach the final solution using this implementation.

As my investigation, we should use PlayFab API to implement a leaderboard for independent platform solution. There’s no solution to integrate with Game Center and Google Play service for Leaderboard so far.

1 Like

Thank you for the info. It’s unfortunate but yes, I also believe that PlayFab is a good way to go.

Now that we have native extensions it’s probably a lot better to create a native extension for Game Center. And one for Google Play Games.

Yeah, I see. Thanks for your updates.

To my previous comment , “There’s no solution to integrate with Game Center and Google Play service for Leaderboard so far.” I posted it when I missed the chance to see how implement Object C code in native extension. Up to know, I got some concepts to write an extension for Game Center, and Google Play Game service later on.

1 Like