Open Feint Tutorial
by Eyal Erez · in iTorque 2D · 10/25/2009 (1:04 pm) · 95 replies
So after receiving help from so many people on how to set up Open Feint, I figure I�ll make a beginners guide and place all of the different bits together in one thread. I�d like to thank Kevin Ryan , Ronny Bangsund , Sven Bergström , Craig Fortune and John Sear for their help. they did all the work and for most of it, I just copy and paste :) Hope I didn�t forget anyone.
So the first steps are getting the open feint sdk integrated.
Follow these steps http://help.openfeint.com/faqs/guides-2/integrating-the-openfeint-sdk
Step #7. go to you project dir and open iTGB_Prefix.pch and add the prefix.
now build and you will probably get an error. open iPhoneMemory.mm and change the to that:
in platform.h you need to change extern void* FN_CDECL operator new(dsize_t size, void* ptr); to that:
Now here's my TGBAppDelegate.mm without the productId and secret which you should replace with yours. please note that I placed the console functions here where ideally they should be placed in consoleFunctions.mm
I've also add the following line to TGBAppDelegate.h
The isOpenFeint function is used in iPhoneMain.mm to stop the mainLoop from running when openFeint window is open. Here's the hack :
For the Achievements you will need to add them on your dashboard and add the achievements.h to you project as well as offline support if you like.
This should be it, unless I forgot anything.
Please help me improve it with your insights.
So the first steps are getting the open feint sdk integrated.
Follow these steps http://help.openfeint.com/faqs/guides-2/integrating-the-openfeint-sdk
Step #7. go to you project dir and open iTGB_Prefix.pch and add the prefix.
#ifdef __OBJC__ #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> #import "OpenFeintPrefix.pch" #endif
now build and you will probably get an error. open iPhoneMemory.mm and change the to that:
#ifndef TORQUE_DISABLE_MEMORY_MANAGER
void* FN_CDECL operator new(dsize_t dt, void* ptr)
{
return (ptr);
}
#else
#include "new"
#endifin platform.h you need to change extern void* FN_CDECL operator new(dsize_t size, void* ptr); to that:
#ifndef TORQUE_DISABLE_MEMORY_MANAGER extern void* FN_CDECL operator new(dsize_t size, void* ptr); #else #include <new> #endifnow you should be able to build with no errors.
Now here's my TGBAppDelegate.mm without the productId and secret which you should replace with yours. please note that I placed the console functions here where ideally they should be placed in consoleFunctions.mm
#import "TGBAppDelegate.h"
#include "platform/platformInput.h"
extern void _iPhoneRunTorqueMain( id appID, UIView *Window, UIApplication *app );
extern void _iPhoneGameInnerLoop();
extern void _iPhoneGameResignActive();
extern void _iPhoneGameBecomeActive();
extern void _iPhoneGameWillTerminate();
extern void _iPhoneGameChangeOrientation();
#define OPEN_FEINT
#ifdef OPEN_FEINT
#import "OpenFeint.h"
#import "OFHighScoreService.h"
#import "OFHighScore.h"
#import "OFAchievementService.h"
#import "OFAchievement.h"
#import "OpenFeint+Dashboard.h"
#import "Achievements.h"
#endif
@implementation TGBAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
_iPhoneRunTorqueMain( self, window, application );
// http://www.garagegames.com/community/forums/viewthread/98361/3#comments
NSString *productKey = @"Your_key";
NSString *secret = @"your_secret";
NSString *displayName = @"your_game";
NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight], OpenFeintSettingDashboardOrientation,
[NSNumber numberWithBool:YES], OpenFeintSettingDisableChat,
nil
];
[OpenFeint initializeWithProductKey:productKey
andSecret:secret
andDisplayName:displayName
andSettings:settings
andDelegates:nil];
}
bool OpenFeintIsOn = false;
- (void)applicationWillResignActive:(UIApplication *)application {
_iPhoneGameResignActive();
[OpenFeint applicationWillResignActive];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
_iPhoneGameBecomeActive();
[OpenFeint applicationDidBecomeActive];
}
- (void)applicationWillTerminate:(UIApplication *)application {
_iPhoneGameWillTerminate();
}
- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation{
_iPhoneGameChangeOrientation();
}
- (void) runMainLoop {
_iPhoneGameInnerLoop();
}
- (void)dealloc {
[window release];
[super dealloc];
}
- (void) dashboardWillAppear
{
OpenFeintIsOn = true;
}
- (void) dashboardWillDisappear
{
OpenFeintIsOn = false;
}
void launchOpenFeintDashboard(S32 dashboardType)
{
if (dashboardType == 0)
[OpenFeint launchDashboard];
else if (dashboardType == 1)
[OpenFeint launchDashboardWithAchievementsPage];
else if (dashboardType == 100)
{
NSString *leaderboardId = @"37873"; // Beginner
[OpenFeint launchDashboardWithHighscorePage:leaderboardId];
}
else if (dashboardType == 101)
{
NSString *leaderboardId = @"37883"; // Advanced
[OpenFeint launchDashboardWithHighscorePage:leaderboardId];
}
else if (dashboardType == 102)
{
NSString *leaderboardId = @"56223"; // Expret
[OpenFeint launchDashboardWithHighscorePage:leaderboardId];
}
}
void submitOfScore(S32 score, S32 leaderboardNum)
{
NSString *leaderboardId = @"37873";
if (leaderboardNum == 1) leaderboardId = @"37883" ;
else if (leaderboardNum == 2) leaderboardId = @"56223" ;
[OFHighScoreService setHighScore:score
forLeaderboard:leaderboardId
onSuccess:OFDelegate()
onFailure:OFDelegate()];
}
void awardOfAchievement(S32 awardedNum)
{
if (awardedNum == 1)
[OFAchievementService unlockAchievement:LIGHT_SPEED];
else if (awardedNum == 2)
[OFAchievementService unlockAchievement:STARGAZER];
else if (awardedNum == 3)
[OFAchievementService unlockAchievement:COMBO_KING];
else if (awardedNum == 4)
[OFAchievementService unlockAchievement:BRONZE_MEDAL];
else if (awardedNum == 5)
[OFAchievementService unlockAchievement:SILVER_MEDAL];
else if (awardedNum == 6)
[OFAchievementService unlockAchievement:GOLD_MEDAL];
else if (awardedNum == 7)
[OFAchievementService unlockAchievement:SPACESHIP_DESTROYER];
}
ConsoleFunction(launchOpenFeintDashboard, void, 2, 2, "launchOpenFeintDashboard(leaderboardNum) "
"launches the open feint dashboard")
{
argc;
launchOpenFeintDashboard( dAtoi(argv[1]) );
}
ConsoleFunction(submitOfScore, void, 3, 3, "sumbitScore(score) "
"awards the passed achievement")
{
argc;
submitOfScore( dAtoi(argv[1]),dAtoi(argv[2]) );
}
ConsoleFunction(awardOfAchievement, void, 2, 2, "awardOfAchievement(awardNum) "
"awards the passed achievement")
{
argc;
awardOfAchievement( dAtoi(argv[1]) );
}
bool isOpenFeint()
{
return OpenFeintIsOn;
}
@endI've also add the following line to TGBAppDelegate.h
bool isOpenFeint(void);
The isOpenFeint function is used in iPhoneMain.mm to stop the mainLoop from running when openFeint window is open. Here's the hack :
void _iPhoneGameInnerLoop()
{
if(Game->isRunning()){
S32 start = Platform::getRealMilliseconds();
if( isOpenFeint() == false)
{
Game->mainLoop();
}
S32 time = sgTimeManagerProcessInterval - (start - gLastStart);
gLastStart = start;
iPhoneRunEventLoopTimer(time);
}
else
{
Game->mainShutdown();
}
}For the Achievements you will need to add them on your dashboard and add the achievements.h to you project as well as offline support if you like.
This should be it, unless I forgot anything.
Please help me improve it with your insights.
#2
I guess only challenges are missing, if you want to implement those. Oh, and one typo - Search for "elefate" ;)
10/25/2009 (5:01 pm)
Excellent :)I guess only challenges are missing, if you want to implement those. Oh, and one typo - Search for "elefate" ;)
#3
Btw, near the top you wrote: "So the first steps are getting the scoreloop sdk integrated"
10/25/2009 (6:06 pm)
Nice one Eyal. Good to see my tutorial has helped spur on some similar ones. Can't comment on how well this work as obviously I use Scoreloop and not Openfeint, but Openfeint appears to work in a very similar fashion. :)Btw, near the top you wrote: "So the first steps are getting the scoreloop sdk integrated"
#4
Craig, your tutorial was a great introduction for implementing anything non-torque. I learned a lot from it.
Ronny, I actually do want to use challenges so I'm sure you'll here from me next week. I also want to change to custom welcome openFeint screen so that I don't need to load these two full screen png's that takes almost 600k .
10/25/2009 (10:14 pm)
oops. I've edited the errors :)Craig, your tutorial was a great introduction for implementing anything non-torque. I learned a lot from it.
Ronny, I actually do want to use challenges so I'm sure you'll here from me next week. I also want to change to custom welcome openFeint screen so that I don't need to load these two full screen png's that takes almost 600k .
#5
10/26/2009 (12:03 am)
Yeah, I'll be on IRC - just check European time :)
#7
Also, you should be able to edit those png's Eyal. Nice tutorial
10/26/2009 (1:17 am)
Why not :) I think it can lead to some good collections of tips for engine users that we can collect for a megawiki of helpful information.Also, you should be able to edit those png's Eyal. Nice tutorial
#8
10/26/2009 (7:14 am)
If there are plenty of iPhone peeps on IRC nowadays I think I'll start using it a lot more, currently I only nip on now and then. Sadly I remember the days when it used to be packed full of people, seems quite quiet nowadays in comparison.
#9
It depends on what time of the day you enter if you'll see many, because they do exactly the same thing - nip in and out again because everybody else is doing it, but at different times!
It sometimes picks up 10 AM Vegas time (the GG community's GMT), sometimes nearer the end of the work day (3 PM+). Fridays are busier than Saturdays, and Sundays are sometimes entirely dead.
10/26/2009 (9:18 am)
Like I said to Eyal, IRC is something you have to live and breathe to really benefit ;)It depends on what time of the day you enter if you'll see many, because they do exactly the same thing - nip in and out again because everybody else is doing it, but at different times!
It sometimes picks up 10 AM Vegas time (the GG community's GMT), sometimes nearer the end of the work day (3 PM+). Fridays are busier than Saturdays, and Sundays are sometimes entirely dead.
#10
Agreed with Ronny. A lot of these tips popping up have been in discussion for weeks in the IRC. :)
11/03/2009 (4:15 pm)
Great tutorial! Just got OF plugged in.Agreed with Ronny. A lot of these tips popping up have been in discussion for weeks in the IRC. :)
#11
12/03/2009 (1:35 pm)
So once you have it installed, how do you use it? All through Objective-C? Are there functions visible to torquescript? How do you tell it what high scores to save and what not?
#12
12/03/2009 (1:48 pm)
You use the console functions to do that. this way you can do everything from script.
#13
launchOpenFeintDashboard
submitOfScore
awardOfAchievement
is that all of them? What is I want to get and display a high score though script? Do I need a new console function for that?
I have a lot of questions so please bear with me. If I'm asking too much, please let me know.
Tell me if I understand this correctly. With launchOpenFeintDashboard you're passing it a number from script, then it chooses the correct string to use in its function, right? Could I just pass it a string from script? I have 20 levels in my game. So do I need 20 different leaderboards? I guess that goes for the other functions as well.
Right now I have a system that saves locally, but it's a little more complex than just a score. It is based on time and number of moves. The lower the moves the better, if the moves are tied then the lower time is better. IS it possible with open feint to do the same thing, storing 2 fields for your score, moves and time?
oh also, I followed the directions to a t and I'm getting an error when I compile saying " 'isOpenFeint' was not declared in this scope" reffering to it being used in _iPhoneGameInnerLoop()
*edit, I fixed the error by adding bool isOpenFeint(void); at the top of iphonemain.mm. I don't know if that was the correct way to fix it though.
sorry for so many questions, I'm a bit lost and not sure if I should continue to pursue it. I'd love to have it in my game, but I'm afraid of screwing things up in the process.
12/09/2009 (12:25 am)
ok, sorry to keep asking more, but know nothing about editing source code. I don't know objective-c or C++. in fact, i don't even know if that's C++ or objective-c. I'm only familiar with torquescript. Will I be getting in over my head? It looks like there's 3 console functions right?launchOpenFeintDashboard
submitOfScore
awardOfAchievement
is that all of them? What is I want to get and display a high score though script? Do I need a new console function for that?
I have a lot of questions so please bear with me. If I'm asking too much, please let me know.
Tell me if I understand this correctly. With launchOpenFeintDashboard you're passing it a number from script, then it chooses the correct string to use in its function, right? Could I just pass it a string from script? I have 20 levels in my game. So do I need 20 different leaderboards? I guess that goes for the other functions as well.
Right now I have a system that saves locally, but it's a little more complex than just a score. It is based on time and number of moves. The lower the moves the better, if the moves are tied then the lower time is better. IS it possible with open feint to do the same thing, storing 2 fields for your score, moves and time?
oh also, I followed the directions to a t and I'm getting an error when I compile saying " 'isOpenFeint' was not declared in this scope" reffering to it being used in _iPhoneGameInnerLoop()
*edit, I fixed the error by adding bool isOpenFeint(void); at the top of iphonemain.mm. I don't know if that was the correct way to fix it though.
sorry for so many questions, I'm a bit lost and not sure if I should continue to pursue it. I'd love to have it in my game, but I'm afraid of screwing things up in the process.
#14
Apple have this, among other things, on Obj-C:
developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Introd...
12/09/2009 (8:50 am)
I suggest reading the free book Thinking in C++ by Bruce Eckel so you can recognise that language.Apple have this, among other things, on Obj-C:
developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Introd...
#15
You create these leaderboards on openFeint dashboard and you will call them by their id (OF generates the id for you)
I don't think you can have a leaderboard based on two different scores so you may need to change that on your hand. However there is a way to sort the leaderboard based on time. I'm sure it's somewhere on their docs/website.
12/09/2009 (11:22 am)
launchOpenFeintDashboard will open the dashboard withe the leaderboard you picked (since you mentioned you'l have 20)You create these leaderboards on openFeint dashboard and you will call them by their id (OF generates the id for you)
I don't think you can have a leaderboard based on two different scores so you may need to change that on your hand. However there is a way to sort the leaderboard based on time. I'm sure it's somewhere on their docs/website.
#16
1. I changed my functions to work like this
will that work correctly? I figured that way I could pass stuff like the leaderboard ID and achievement through script instead of hard coding it in the source. I figure I can now reuse that in other games without having to change the source again.
2. For offline leaderboards, I downloaded my openfeint_offline_config.xml from open feint. It says to include that in my project. Where do I put it, under the open feint main directory? Do I need to include it in any code at all like how you imported the achievements.h?
Thanks for your patients..
Oh, btw. I found out from the OF forum that there is a way to do the scoring system I want....kind of.
help.openfeint.com/discussions/questions/646-multiple-score-fields
but I think I'll just rewrite it to calculate a score based on there time and move count and use that on the leaderboard
12/09/2009 (5:46 pm)
Ok, I think I'm starting to understand this a bit better. I just have 2 more questions.1. I changed my functions to work like this
void launchOpenFeintDashboard(const char* leaderboardId)
{
if (leaderboardId == "0")
[OpenFeint launchDashboard];
else
{
NSString *leaderboard = [[NSString alloc] initWithUTF8String:leaderboardId];
[OpenFeint launchDashboardWithHighscorePage:leaderboard];
}
}
void submitOfScore(S32 score, const char* leaderboardId)
{
NSString *leaderboard = [[NSString alloc] initWithUTF8String:leaderboardId];
[OFHighScoreService setHighScore:score
forLeaderboard:leaderboard
onSuccess:OFDelegate()
onFailure:OFDelegate()];
}
void awardOfAchievement(const char* award)
{
NSString *achievement = [[NSString alloc] initWithUTF8String:award];
[OFAchievementService unlockAchievement:achievement];
}
ConsoleFunction(launchOpenFeintDashboard, void, 2, 2, "launchOpenFeintDashboard(leaderboardNum) "
"launches the open feint dashboard")
{
argc;
launchOpenFeintDashboard(argv[1]);
}
ConsoleFunction(submitOfScore, void, 3, 3, "sumbitScore(score) "
"awards the passed achievement")
{
argc;
submitOfScore( dAtoi(argv[1]),argv[2]);
}
ConsoleFunction(awardOfAchievement, void, 2, 2, "awardOfAchievement(awardNum) "
"awards the passed achievement")
{
argc;
awardOfAchievement(argv[1]);
}will that work correctly? I figured that way I could pass stuff like the leaderboard ID and achievement through script instead of hard coding it in the source. I figure I can now reuse that in other games without having to change the source again.
2. For offline leaderboards, I downloaded my openfeint_offline_config.xml from open feint. It says to include that in my project. Where do I put it, under the open feint main directory? Do I need to include it in any code at all like how you imported the achievements.h?
Thanks for your patients..
Oh, btw. I found out from the OF forum that there is a way to do the scoring system I want....kind of.
help.openfeint.com/discussions/questions/646-multiple-score-fields
but I think I'll just rewrite it to calculate a score based on there time and move count and use that on the leaderboard
#17
12/10/2009 (12:57 pm)
Yes, without testing it I think it should work. it's a good idea to pass the string from the script so you don't have to change the code. the offline xml , you can just copy to your openFeint dir in the tree structure of xCode. I don't think you need to include it.
#18
Now, Any idea on how to get the users local high score for a given leaderboard? I want to be able to display it next to the level name on the level select screen.
12/12/2009 (2:42 am)
Cool. I tested it and it works well. Also I just added the xml file to the open feint directory and it worked as well. Now, Any idea on how to get the users local high score for a given leaderboard? I want to be able to display it next to the level name on the level select screen.
#19
TGBAppDelegate.mm
'OpenfeintsettingdisableChat' was not declared in this scope
'LIGHT_SPEED' was not declared in this scope
'STARGAZER' was not declared in this scope
'COMBO_KING' was not declared in this scope
'BRONZE_MEDAL' was not declared in this scope
...
have I missed something with the tutorial ?
01/19/2010 (12:12 pm)
hey, can you help me with such errors I got:TGBAppDelegate.mm
'OpenfeintsettingdisableChat' was not declared in this scope
'LIGHT_SPEED' was not declared in this scope
'STARGAZER' was not declared in this scope
'COMBO_KING' was not declared in this scope
'BRONZE_MEDAL' was not declared in this scope
...
have I missed something with the tutorial ?
#20
As for the others problems it's because you're using the achievement names used in the tutorial. You need to change them to the achievement names for your game. If you don't have any then remove them.
01/19/2010 (12:48 pm)
OpenfeintsettingdisableChat had been removed since OF 2.4. Instead use OpenFeintSettingDisableUserGeneratedContent. As for the others problems it's because you're using the achievement names used in the tutorial. You need to change them to the achievement names for your game. If you don't have any then remove them.
Employee Michael Perry
ZombieShortbus