Using Game Center Add-on makes physics fail?

So my code works fine, and at one part I use the function collide(contact). But when I uncomment this line to make Game Center work

//Uncomment the following line if you’d like to use the basic GameCenter addon:

//[self.viewController registerAddon:[GameCenterAddon sharedInstance]];

whenever a collision happens I get the error attempt to index local ‘contact’ ( a nil value ).
I have tested it multiple times. If I go back and comment the line out, the code works fine. Can anyone confirm this, or knows how to fix it?
edit: seems now like a lot of the more expensive parts of my program make it crash when using the Haddon.

Could you please ensure you are using the latest Codea Addons from

https://github.com/TwoLivesLeft/Codea-Addons

(These will be included in the next update to Codea)

@Simeon those are the ones I am using. By ‘included’ do you mean included at export?

@Simeon I think I might be misusing. Is there a walkthrough for the game center addon I can use?

Oh sorry @jrohanian, this actually could be due to the incorrect header file included with exported projects.

Please replace your luaconf.h file with the one located here:

http://codea.io/lib/luaconf.h

@Simeon no, still doesn’t work. Do I need to make any changes to the CodeaAddon.h/.m files, or changes to the appDelegate.h/.mm files before using game center (besides uncommenting the line in AppDelegate.mm) ?

@jrohanian odd, I recall debugging this same issue with another user. Do both 32 and 64 bit builds fail?

@Simeon, yes, 32 and 64 bit have identical errors.

Hi, the problem is with the function luaL_openlib.

Here are my files:

.h

//
//  GameCenterAddon.h
//
//  Basic GameCenter integration Codea Addon
//   supports leaderboards, achievements
//
//  Created by Simeon on 12/10/2014.
//  Copyright (c) 2014 Two Lives Left. All rights reserved.
//

/*
 
 This addon implements the following Lua API:
 -------------------------------------------
 
 -- Check if GameCenter is enabled
 if gamecenter_enabled() then
 
 -- Submit to default leaderboard
 gamecenter_submitScore( 1234 )
 
 -- Submit to specific leaderboard
 gamecenter_submitScore( 1234, “LeaderboardID” )
 
 end
 
 -- Show default GameCenter leaderboard (pauses Codea)
 gamecenter_showLeaderboard()
 
 -- Show specific GameCenter leaderboard (pauses Codea)
 gamecenter_showLeaderboard(“LeaderboardID”)
 
 -- Show achievements (pauses Codea)
 gamecenter_showAchievements()
 
 -- Submit an achievement with a percent complete amount (0.0 - 100.0)
 gamecenter_submitAchievement( “AchievementID”, percent )
 
 -- Submit a score for a specific leaderboard
 gamecenter_submitScore( 1234, “LeaderboardID” )
 
 */

#import <Foundation/Foundation.h>

#import "CodeaAddon.h"

@interface GameCenterAddon : CodeaAddon

+ (instancetype) sharedInstance;

@property (nonatomic, assign) BOOL gameCenterEnabled;
@property (nonatomic, strong) NSString *defaultLeaderboard;

@end

and .m

//
//  GameCenterAddon.m
//
//  Basic GameCenter integration Codea Addon
//   supports leaderboards, achievements
//
//  Created by Simeon on 12/10/2014.
//  Copyright (c) 2014 Two Lives Left. All rights reserved.
//

#import "GameCenterAddon.h"

#import <GameKit/GameKit.h>

#import "StandaloneCodeaViewController.h"

#import "lua.h"
#import "lauxlib.h"

#define GAMECENTER_LIB_NAME "gamecenter"

#pragma mark - Lua Functions

static int gamecenter_enabled(struct lua_State* L);

static int gamecenter_showLeaderboards(struct lua_State* L);
static int gamecenter_showAchievements(struct lua_State* L);

static int gamecenter_submitScore(struct lua_State* L);
static int gamecenter_submitAchievement(struct lua_State* L);

#pragma mark - Lua Function Mappings

/*[[static const luaL_Reg gamecenterLibs[] =
{
    {"enabled", gamecenter_enabled},
    {"showLeaderboards", gamecenter_showLeaderboards},
    {"showAchievements", gamecenter_showAchievements},
    {"submitScore",      gamecenter_submitScore},
    {"submitAchievement",gamecenter_submitAchievement},
    {NULL, NULL}
};*/

#pragma mark - Game Center Addon

@interface GameCenterAddon ()<GKGameCenterControllerDelegate>

@end

@implementation GameCenterAddon

#pragma mark - Singleton

+ (instancetype) sharedInstance
{
    static id _sharedObject = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedObject = [[self alloc] init];
    });
    return _sharedObject;
}

#pragma mark - Game Center Helper Methods

- (void) authenticateLocalPlayerWithCodeaController:(StandaloneCodeaViewController *)codeaController
{
    __weak __typeof(&*self)weakSelf = self;
    
    //Create the authentication handler which captures the Codea View Controller
    GKLocalPlayer *player = [GKLocalPlayer localPlayer];
    
    player.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
        
        if( viewController != nil )
        {
            //Game Center wants us to present something
            
            //Pause the Codea game
            codeaController.paused = YES;
            
            //Present the controller
            [codeaController presentViewController:viewController animated:YES completion:nil];
        }
        else
        {
            //The player signed in, or game center was disabled
            
            //Resume Codea game
            codeaController.paused = NO;
            
            //Game center is enabled if the player authenticated
            weakSelf.gameCenterEnabled = [GKLocalPlayer localPlayer].authenticated;
            
            if( weakSelf.gameCenterEnabled )
            {
                //Get the default leaderboard
                [[GKLocalPlayer localPlayer] loadDefaultLeaderboardIdentifierWithCompletionHandler:^(NSString *leaderboardIdentifier, NSError *error) {
                    
                    weakSelf.defaultLeaderboard = leaderboardIdentifier;
                }];
            }
        }
        
    };
}

- (void) showGameCenterWithConfigurationBlock:(void(^)(GKGameCenterViewController *gvc))config
{
    GKGameCenterViewController *gcController = [[GKGameCenterViewController alloc] init];
    
    //Pause Codea Runtime
    StandaloneCodeaViewController *currentCodea = self.codeaController;
    currentCodea.paused = YES;
    
    if( config )
    {
        config(gcController);
    }
    
    //Present game center leaderboards
    gcController.gameCenterDelegate = self;
    [currentCodea presentViewController:gcController animated:YES completion:nil];
}

- (void) submitScore:(NSInteger)score leaderboard:(NSString *)leaderboard
{
    GKScore *localScore = [[GKScore alloc] initWithLeaderboardIdentifier:leaderboard];
    
    localScore.value = score;
    localScore.leaderboardIdentifier = leaderboard ?: self.defaultLeaderboard;
    
    [GKScore reportScores:@[localScore] withCompletionHandler:^(NSError *error) {
        //Do nothing yet
    }];
}

- (void) submitAchievement:(NSString *)achievement percent:(double)percent
{   
    GKAchievement *localAchievement = [[GKAchievement alloc] initWithIdentifier:achievement];
    localAchievement.showsCompletionBanner = YES;
    localAchievement.percentComplete = percent;
    
    [GKAchievement reportAchievements:@[localAchievement] withCompletionHandler:^(NSError *error) {
        //Do nothing yet
    }];
}

- (void) showLeaderboardWithID:(NSString *)leaderboardID
{
    __weak __typeof(&*self)weakSelf = self;
    
    leaderboardID = leaderboardID ?: self.defaultLeaderboard;
    
    [self showGameCenterWithConfigurationBlock:^(GKGameCenterViewController *gvc) {
        gvc.viewState = GKGameCenterViewControllerStateLeaderboards;
        gvc.leaderboardIdentifier = weakSelf.defaultLeaderboard;
    }];
}

- (void) showAchievements
{
    [self showGameCenterWithConfigurationBlock:^(GKGameCenterViewController *gvc) {
        gvc.viewState = GKGameCenterViewControllerStateAchievements;
    }];
}

#pragma mark - Codea Addon Protocol Implementation

- (void) codea:(StandaloneCodeaViewController*)codeaController didCreateLuaState:(struct lua_State*)L
{
    //Authenticate the local player, pausing the runtime if necessary
    [self authenticateLocalPlayerWithCodeaController:codeaController];
    
    //Register Game Center functions with Lua
    lua_register(L, "gamecenter_enabled", gamecenter_enabled);
    lua_register(L, "gamecenter_showLeaderboards", gamecenter_showLeaderboards);
    lua_register(L, "gamecenter_showAchievements", gamecenter_showAchievements);
    lua_register(L, "gamecenter_submitScore", gamecenter_submitScore);
    lua_register(L, "gamecenter_submitAchievement", gamecenter_submitAchievement);
    //luaL_openlib(L, GAMECENTER_LIB_NAME, gamecenterLibs, 0);
}

#pragma mark - Game Center View Controller Delegate

- (void) gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController
{
    [gameCenterViewController.presentingViewController dismissViewControllerAnimated:YES completion:^{
        
        //Unpause Codea Runtime
        self.codeaController.paused = NO;
        
    }];
}

#pragma mark - Lua Function Implementations

static int gamecenter_enabled(struct lua_State* L)
{
    lua_pushboolean(L, [GameCenterAddon sharedInstance].gameCenterEnabled);
    
    return 0;
}

static int gamecenter_showLeaderboards(struct lua_State* L)
{
    NSString *leaderboardID = nil;
    
    int n = lua_gettop(L);
    
    //Get the leaderboard ID
    if( n > 0 )
    {
        leaderboardID = @(luaL_checkstring(L, 1));
    }
    
    //All Lua functions call outside of main thread
    // we need to handle any UI on main thread
    dispatch_async(dispatch_get_main_queue(), ^{
        
        //If leaderboard is nil, default leaderboard will be used
        [[GameCenterAddon sharedInstance] showLeaderboardWithID:leaderboardID];
        
    });
    
    return 0;
}

static int gamecenter_showAchievements(struct lua_State* L)
{
    //All Lua functions call outside of main thread
    // we need to handle any UI on main thread
    dispatch_async(dispatch_get_main_queue(), ^{
        
        //If leaderboard is nil, default leaderboard will be used
        [[GameCenterAddon sharedInstance] showAchievements];
        
    });
    
    return 0;
}

static int gamecenter_submitScore(struct lua_State* L)
{
    int n = lua_gettop(L);
    
    double score = 0;
    NSString *leaderboardID = nil;
    
    if( n > 0 )
    {
        score = atof(lua_tostring(L, 1));
    }
    
    if( n > 1 )
    {
        //Custom leaderboard specified
        leaderboardID = @(luaL_checkstring(L, 2));
    }
    
    [[GameCenterAddon sharedInstance] submitScore:score leaderboard:leaderboardID];
    
    return 0;
}

static int gamecenter_submitAchievement(struct lua_State* L)
{
    int n = lua_gettop(L);
    
    if( n >= 2 )
    {
        NSString *achievementID = @(luaL_checkstring(L, 1));
        double percent = atof(lua_tostring(L, 2));
        //lua_Number percent = luaL_checknumber(L, 2);
        
        [[GameCenterAddon sharedInstance] submitAchievement:achievementID percent:percent];
    }
    
    return 0;
}

@end

It changes the implementation by registering each function individually and not part of a gamecenter table, so gamecenter.submitScore becomes gamecenter_submitScore and so on.

:slight_smile: working. thank you @JakAttak @Simeon

@JakAttak the bug has now been fixed in the Codea Addon repo (https://github.com/TwoLivesLeft/Codea-Addons). I was registering the gamecenter table incorrectly, the update still registers the same API (i.e., within a table called gamecenter)

@Simeon, @JakAttak, I’m using Xcode 7.1 beta and iOS 9.1 and I’m having a error Expected identifier or '('. How can be this fixed?