Game Development Community

A Brief Scoreloop Integration Tutorial

by Craig Fortune · in iTorque 2D · 10/18/2009 (12:57 pm) · 43 replies

Quite a few people seem to be struggling with integrating Scoreloop in to their projects, which is a shame as it is a great little system. Here is a quick little tutorial on how to do it. This is barebones and simply gets you “on your feet” with working with Scoreloop.

DISCLAIMER: This was very quickly typed up (had to strip some of my own bits out) so I have probably missed some bits etc, if you spot them please let me know so I can update these instructions for other people. Thanks. (Also, you'll probably see some weird/odd comments - ignore those, this is just ripped out from my working build for my game :D)

First off, I’m assuming you have followed the instructions as part of the Scoreloop download , if not, go do those steps first!

TGBAppDelegate.h needs to be changed, first up is to add the include - I have my Scooreloop directory inside my XCode_iPhone directory alongside my project file)
#import <Scoreloop/Scoreloop.h>

the @interface part needs the protocols it abides to changing too, like thus:
@interface TGBAppDelegate : NSObject <UIApplicationDelegate, SLClientDelegate>

Also, in the @interface part add the following to add the score loop client object in.
id<SLClient> scoreloopClient;

and add a property below like thus:
@property (nonatomic, retain) id<SLClient> scoreloopClient;

Now in TGBAppDelegate.mm make the following changes and additions:

Add scoreloopClient to our synthesize list
@synthesize window, scoreloopClient;

In - (void)applicationDidFinishLaunching:(UIApplication *)application

Add the following two lines: (these are features in Scoreloop, read the docs for more info)
[scoreloopClient setFeature:kSLFeatureTeaserStrategy enabled: NO];
[scoreloopClient setFeature:kSLFeatureAutorotateInterface enabled: YES];

- (id) init
Should be changed to look like the following: (this setups up scoreloop - NOTE THE BITS YOU NEED TO CHANGE!)
- (id) init
{
	self = [super init]; 
	if (self != nil) 
	{ 
		// Create the scoreloop client. 
		// The init method of the Application Delegate is 
		// the recommended place 
		scoreloopClient = SLClientCreateWithGameAndDelegate( 
							@"    GAME ID FROM SCORELOOP GOES HERE!!!!!   ",  
							@"    SECRET FROM SCORELOOP GOES HERE!!!!!    ",   
							self); 
	}	
	return self;
}

Add the following: (The Con::executef stuff is because I like to handle changes with Scoreloop status in script – they are just global script functions – always handy to have callbacks etc :D)
- (BOOL) application:(UIApplication *)application handleOpenURL:(NSURL *)url 
{ 
	// let Scoreloop know that another app started the game. 
	// If Scoreloop can't handle the URL, it will return NO 
	// This is important to implement as this enables starting 
	// challenges from other applications 
	return [scoreloopClient handleOpenURL:url]; 
}
- (void) scoreloopDidShow:(id<SLClient>) aClient
{
	// Scoreloop UI Active and showing
	Con::executef(1, "onScoreloopDidShow");
}

- (void) userDidFinishScoreloop:(id<SLClient>) aClient usingContext:(NSDictionary*) aContext
{
	// User successfully finished with Scoreloop UI
	// WITH CHALLENGE
	Con::executef(2, "onUserDidFinishScoreloop", "");
}

- (void) userDidCancelScoreloop:(id<SLClient>) aClient
{
	// User unsuccessfully finished with Scoreloop UI
	// NO CHALLENGE
	Con::executef(1, "onUserDidCancelScoreloop");
}

- (BOOL)client:(id) aClient shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
	return YES;
}

Now create ScoreloopHandling.h inside the same folder as TGBAppDelegate with the following code:
//
//  ScoreLoopHandling.h
//  Torque2D
//
//  Created by Craig Fortune on 07/08/2009.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#ifndef SCORELOOPHANDLING_INCLUDED
#define SCORELOOPHANDLING_INCLUDED

namespace ScoreLoopHandling
{
	void submitScore(int score);
	void showScoreLoop();
}

#endif

Here is the matching .mm file…
#include "platformiPhone/ScoreLoopHandling.h"
#import <Scoreloop/Scoreloop.h>

void ScoreLoopHandling::submitScore(int score)
{
	id<SLClient> scoreloopClient = [(id)[UIApplication sharedApplication].delegate scoreloopClient];

	NSNumber* scoreResult;
	scoreResult = [NSNumber numberWithInt: score];
									
	// for advanced game play (levels...) you can pass a context 
	NSDictionary* context = nil; 
	
	[scoreloopClient gameDidEndWithScoreResult: scoreResult usingContext: context];
}

void ScoreLoopHandling::showScoreLoop()
{
	id<SLClient> scoreloopClient = [(id)[UIApplication sharedApplication].delegate scoreloopClient];	
	[scoreloopClient show: kSLTabOverview];
}

The above files are your glue between your scoreloop and your game, lets add the consolemethods to actually utilize them now. In ConsoleFunctions.cc add the following right at the bottom.

ConsoleFunctionGroupBegin(Scoreloop, "Functions for dealing with Scoreloop");

ConsoleFunction( endGameWithScore, void, 2, 2, "")
{
	argc; argv;
	
	int score = dAtoi(argv[1]);
	ScoreLoopHandling::submitScore(score);
}

ConsoleFunction( showScoreLoopGUI, void, 1, 1, "")
{
	ScoreLoopHandling::showScoreLoop();
}

ConsoleFunctionGroupEnd(Scoreloop);

You need to add this to the top of ConsoleFunctions.cc too...

#include "platformiPhone/ScoreLoopHandling.h"

You can now call the functions from script. For instance you could have a button that calls showScoreLoopGUI(); to load up scoreloop, or when it is game over you can call endGameWithScore(%playerScore);
Page «Previous 1 2 3 Last »
#1
10/18/2009 (3:59 pm)
Thanks! Great tutorial!

Hm, when I try to compile project I get this "Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/g++-4.2 failed with exit code 1"
#2
10/18/2009 (4:18 pm)
Will need more info than that to assist you :/

Anything else in your build log?
#3
10/18/2009 (6:01 pm)
Might be wrong SDK?
#4
10/18/2009 (6:34 pm)
Possibly, tried compile for device?
#5
10/18/2009 (6:37 pm)
Craig, you rock! many many thanks.
Got it to work in 30min :)
I am using GCC4.0 SDK3.0 iTGB1.3 and targeting 2.2.1 so I didn't have any problems.
Now I just need to hook it up using the console functions.
This tutorial should be pinned since I bet a lot of people will want to use it.
#6
10/18/2009 (7:26 pm)
@Eyal: Glad it worked for you. This should hopefully give people a nice simple "base example" for how to include other "non torque" things into their games.

I just added the following to as I forgot before:
Quote:
Just remembered, you need to add this to ConsoleFunctions.cc too

#include "platformiPhone/ScoreLoopHandling.h"
#7
10/18/2009 (7:35 pm)
yes, maybe now that I've learned something I can go back and try to integrate greystripe again. I failed miserably on that one too :)
#8
10/18/2009 (8:53 pm)
Just had a quick look at Greystripe and it seems pretty straight forward to integrate actually. If anything it is maybe slightly easier as you just kick start a background thread by calling GSInit() in the applicationDidFinishLaunching delegate. (Rather than your app needing a ref to Scoreloop)

The example console functions + scoreloophandling files I provided are a good starting point for exposing the displayad functions in Greystripe.

I might even give it a shot tomorrow and post my experience :)
#9
10/18/2009 (8:57 pm)
Craig, have you used context at all?
My game has 3 levels of difficulty so I was wondering how do you pass context into submitScore() ?
#10
10/18/2009 (9:02 pm)
Not yet, on my list of things to do at some point actually. Will post up changes when I've done it
#11
10/19/2009 (8:14 am)
I have solved previos error, but now I have new 11 errors -
/Users/FLy/Desktop/iTGB_SL/engine/compilers/Xcode_iPhone/../../source/platformiPhone/TGBAppDelegate.h:12: error: cannot find protocol declaration for 'SLClientDelegate'

 /Users/FLy/Desktop/iTGB_SL/engine/compilers/Xcode_iPhone/../../source/platformiPhone/TGBAppDelegate.h:14: error: cannot find protocol declaration for 'SLClient'

/Users/FLy/Desktop/iTGB_SL/engine/compilers/Xcode_iPhone/../../source/platformiPhone/TGBAppDelegate.mm:19: error: no declaration of property 'window' found in the interface

/Users/FLy/Desktop/iTGB_SL/engine/compilers/Xcode_iPhone/../../source/platformiPhone/TGBAppDelegate.mm:23: error: 'kSLFeatureTeaserStrategy' was not declared in this scope

/Users/FLy/Desktop/iTGB_SL/engine/compilers/Xcode_iPhone/../../source/platformiPhone/TGBAppDelegate.mm:24: error: 'kSLFeatureAutorotateInterface' was not declared in this scope

/Users/FLy/Desktop/iTGB_SL/engine/compilers/Xcode_iPhone/../../source/platformiPhone/TGBAppDelegate.mm:66: error: 'SLClientCreateWithGameAndDelegate' was not declared in this scope

/Users/FLy/Desktop/iTGB_SL/engine/compilers/Xcode_iPhone/../../source/platformiPhone/TGBAppDelegate.mm:77: error: invalid conversion from 'objc_object*' to 'BOOL'

/Users/FLy/Desktop/iTGB_SL/engine/compilers/Xcode_iPhone/../../source/platformiPhone/TGBAppDelegate.mm:79: error: cannot find protocol declaration for 'SLClient'
#12
10/19/2009 (9:41 am)
Eyal Erez, Greystripe is much easier than this to implement, I've just submitted a game with it in.

One thing you should remember is that you have to stop all rendering while the greystripe advert is being shown, I just did this by creating an if() statement around the main game loop which would stop all background things from happening while the advert is loading and being displayed.

It required a bit of script changing so that no levels loaded while it was being shown but if you've done any programming before its nothing you shouldn't be able to do.

Good post by the way Craig, this will help lots of people and I'll keep it somewhere for when we create a game with Scoreloop!
#13
10/19/2009 (1:37 pm)
@Komar: add the following to the top of TGBAppDelegate.h
#import <Scoreloop/Scoreloop.h>

Adjust this (if necessary) to point to the location of the scoreloop sdk on your mac.
#14
10/19/2009 (1:43 pm)
@John: The if statement you mention I assume just keeps hold of a bool you set when displaying an advert right? A neat and straight forward little way of handling that situation, heh - even if it just feel a bit nasty :)
#15
10/19/2009 (2:38 pm)
So I've got the levels to work. it may not be the correct way of doing it, but it works.
in scoreloopHandeling.mm
void ScoreLoopHandling::submitScoreLevel(int score, int myLevel)  
{  
    id<SLClient> scoreloopClient = [(id)[UIApplication sharedApplication].delegate scoreloopClient];  
	
    NSNumber* scoreResult;  
    scoreResult = [NSNumber numberWithInt: score];  
	
    NSNumber* levelResult;  
    levelResult = [NSNumber numberWithInt: myLevel];  
	
	
	// for advanced game play (levels...) you can pass a context   
    //NSDictionary* context = nil;   
	//NSDictionary* context = nil;   
	
    BOOL ui = [scoreloopClient gameDidEndWithScoreResult: scoreResult atLevel: levelResult];  
	
    if(ui)  
        NSLog(@"stuff supposed to show");  
    else  
        NSLog(@"stuff NOT supposed to show");  
}

modified scoreloopHandeling.h
namespace ScoreLoopHandling  
{  
    void submitScore(int score);  
    void submitScoreLevel(int score, int myLevel);  
    void showScoreLoop();  
}

added function to consoleFunctions.cc
ConsoleFunction( endGameWithScoreLevel, void, 3, 3, "")  
{  
    argc; argv;  
	
    int score = dAtoi(argv[1]);  
    int myLevel = dAtoi(argv[2]);  
    ScoreLoopHandling::submitScoreLevel(score,myLevel);  
}

Then you need to add a file called SLScoreFormatter.strings to your project. example can be find at SLDemo dir.
In my case all I needed to add to this file is:
"1" = "Beginner";
"2" = "Advanced";
"3" = "Expert";
but there are many options for different formatting.
#16
10/19/2009 (4:06 pm)
Thanks, now it run, but then I receive - "program received signal sigabrt"
#17
10/19/2009 (4:11 pm)
Komar, you really need to supply more information. Errors with no context are very hard to diagnose.
#18
10/19/2009 (4:29 pm)
Thats only this error I have. Debugger said - "program received signal sigabrt" and nothing more. And when I am trying to launch my game on device - it shuting down after 2-4 seconds.
#19
10/19/2009 (4:39 pm)
Komar, I actually had similar crash after 2-4 seconds when I first integrated it.
For me the problem was that I didn't set my GAME ID and SECRET in appDelegate.

scoreloopClient = SLClientCreateWithGameAndDelegate(   
                            @"    GAME ID FROM SCORELOOP GOES HERE!!!!!   ",    
                            @"    SECRET FROM SCORELOOP GOES HERE!!!!!    ",     
                            self);
#20
10/19/2009 (4:45 pm)
BTW. I found out that if you was actually supposed to use Mode and not Level since I want a separate high score board for each difficulty.
So the I've added another function to scoreloopHandling.mm
void ScoreLoopHandling::submitScoreMode(int score, int myMode)  
{  
    id<SLClient> scoreloopClient = [(id)[UIApplication sharedApplication].delegate scoreloopClient];  
	
    NSNumber* scoreResult;  
    scoreResult = [NSNumber numberWithInt: score];  
	
    // for advanced game play (levels...) you can pass a context   
    NSDictionary* context = [NSDictionary dictionaryWithObjectsAndKeys: 
							 [NSNumber numberWithInteger:myMode], kSLContextKeyMode, nil] ;

	
    BOOL ui = [scoreloopClient gameDidEndWithScoreResult: scoreResult usingContext: context];  
	
    if(ui)  
        NSLog(@"stuff supposed to show");  
    else  
        NSLog(@"stuff NOT supposed to show");  
}
Page «Previous 1 2 3 Last »