Saving scores for IOS and connecting to game center
by Josiah Reeves · in Torque 2D Beginner · 05/15/2014 (2:04 am) · 10 replies
I am having trouble finding a good method for saving scores on iOS. Here is the way i initially had it setup which works fine running on OSX but when running it on the iphone causes the game to crash.
Here is the code i was using:
%topscorefile = new FileObject();
%topscorefile.OpenForWrite("./score/score.txt");
%topscorefile.writeline (Game.bestScore);
%topscorefile.close();
The error I get is:
Fatal: (.../engine/source/io/fileStream.cc @ 319) FileStream::_write: the stream isn't open
Fatal: (.../engine/source/io/fileStream.cc @ 324) FileStream::_write: file stream lacks capability
So what is the best way to save a score locally for when a phone isn't connected to game center?
And my next question would be about game center integration. I understand the game center setup but what i am unsure of is how I can get the score directly from torque and send save to game center.
Here is the code i was using:
%topscorefile = new FileObject();
%topscorefile.OpenForWrite("./score/score.txt");
%topscorefile.writeline (Game.bestScore);
%topscorefile.close();
The error I get is:
Fatal: (.../engine/source/io/fileStream.cc @ 319) FileStream::_write: the stream isn't open
Fatal: (.../engine/source/io/fileStream.cc @ 324) FileStream::_write: file stream lacks capability
So what is the best way to save a score locally for when a phone isn't connected to game center?
And my next question would be about game center integration. I understand the game center setup but what i am unsure of is how I can get the score directly from torque and send save to game center.
About the author
Stereo Compositor for Legend 3D
#2
Taml::writeFile() - Could not open filename '/private/var/mobile/Applications/.../.../Game.app/modules/Game/1/score/score.taml' for write.
Is there a certain location i should be saving to maybe?
05/15/2014 (11:20 pm)
Unfortunately I encounter the same problem. When running this on the iPhone the file can't be written to.Taml::writeFile() - Could not open filename '/private/var/mobile/Applications/.../.../Game.app/modules/Game/1/score/score.taml' for write.
Is there a certain location i should be saving to maybe?
#3
05/21/2014 (3:49 pm)
On the iPhone you need to deal with the sandbox. The appropriate location for iPhone is "~/Documents" for long-term storage (there is a temp space as well). Don't hardcode this directly but you can get this through the getUserDataDirectory() method. See Doc page. Once you have that append your file name for your data.
#4
Taml::writeFile() - Could not open filename '/var/mobile/Applications/.../score.taml' for write.
Taml::read() - Could not open filename '/var/mobile/Applications/.../score.taml' for read.
TamlRead() - Could not read object from file '/var/mobile/Applications/.../score.taml'.
Perhaps i'm doing something wrong with my code? Here is basically what I'm doing. Again this works when running on OSX.
05/26/2014 (6:48 pm)
Thank you for the help! I got it working correctly when i run it on my computer but when running it on my iphone it still gives me an error.Taml::writeFile() - Could not open filename '/var/mobile/Applications/.../score.taml' for write.
Taml::read() - Could not open filename '/var/mobile/Applications/.../score.taml' for read.
TamlRead() - Could not read object from file '/var/mobile/Applications/.../score.taml'.
Perhaps i'm doing something wrong with my code? Here is basically what I'm doing. Again this works when running on OSX.
$savePath = expandPath(getUserHomeDirectory()@"/score.taml"); %scorefile = TamlRead($savePath); TamlWrite(%topscorefile, $savePath);
#5
05/26/2014 (11:07 pm)
Never mind. I see what i was doing wrong. I was using home instead of data directory. It's working perfectly now thank you! Now how would i get this into game center? Is there a way i can pass it directly to game center when the player dies instead of moving through a file?
#6
To see more Game Center functionality, open engine/source/platformiOS/GameCenter.mm.
05/27/2014 (6:16 am)
@Josiah - You want to call a series of functions in script:// Iniitialization %isAvailable = isGameCenterAvailable(); if (%isAvailable()) initGameCenter(); // Example code. Use your code instead of this to get score %score = 10; // Example code. The score category should be specific to your game %category = "Game High Score"; // Submit the score submitScore(%score, %category);
To see more Game Center functionality, open engine/source/platformiOS/GameCenter.mm.
#7
modules/Game/1/main.cs (6): Unable to find function isGameCenterAvailable
modules/Game/1/main.cs (10): Unable to find function initGameCenter
After doing some searches for initGameCenter() i came across an old forum post which said you needed to add
When i do this I get a lot of warnings and errors which can be resolved for the most part by turning off ARC in the build settings. This solves the errors but nearly all of the code relating to Game Center is deprecated. It's possible though that i just have the wrong version maybe?
05/27/2014 (11:43 pm)
Thank you Michael for the help. I added the code in and it looks like it can't find it or something. I get this errormodules/Game/1/main.cs (6): Unable to find function isGameCenterAvailable
modules/Game/1/main.cs (10): Unable to find function initGameCenter
After doing some searches for initGameCenter() i came across an old forum post which said you needed to add
#define TORQUE_ALLOW_GAMEKITabove
#ifdef TORQUE_ALLOW_GAMEKIT
When i do this I get a lot of warnings and errors which can be resolved for the most part by turning off ARC in the build settings. This solves the errors but nearly all of the code relating to Game Center is deprecated. It's possible though that i just have the wrong version maybe?
#8
05/28/2014 (5:13 am)
Sounds like all the code needs to be updated then. The Game Center portion of iOS hasn't been touched in a long time, so I'm not surprised. If you could, please post an issue on the T2D MIT GitHub page so it can be tracked as a known issue.
#9
Solution #2:
If you do not wish to convert the code to ARC (e.g. you are not writing a new application, but are maintaining an old one / or you imported so much code that moving to ARC is not worth it) you can disable ARC.
Disabling ARC for selected files To disable ARC, you can use the -fno-objc-arc compiler flag for specific files. Select the target and go to Build Phases -> Compile Sources. Edit the Compiler
Flags and add -fno-objc-arc.
Disabling ARC for the project
Source:How to disable Xcode4.2 Automatic Reference Counting
Click on you project, in the left hand organizer.
Select your target, in the next column over.
Select the Build Settings tab at the top.
Scroll down to "Objective-C Automatic Reference Counting" (it may be listed as
"CLANG_ENABLE_OBJC_ARC" under the User-Defined settings group), and set it to NO.
09/01/2014 (3:13 pm)
Worked for me. From StackOverflow.com stackoverflow.com/questions/15844097/how-can-i-fix-this-error-arc-forbids-explic...Solution #2:
If you do not wish to convert the code to ARC (e.g. you are not writing a new application, but are maintaining an old one / or you imported so much code that moving to ARC is not worth it) you can disable ARC.
Disabling ARC for selected files To disable ARC, you can use the -fno-objc-arc compiler flag for specific files. Select the target and go to Build Phases -> Compile Sources. Edit the Compiler
Flags and add -fno-objc-arc.
Disabling ARC for the project
Source:How to disable Xcode4.2 Automatic Reference Counting
Click on you project, in the left hand organizer.
Select your target, in the next column over.
Select the Build Settings tab at the top.
Scroll down to "Objective-C Automatic Reference Counting" (it may be listed as
"CLANG_ENABLE_OBJC_ARC" under the User-Defined settings group), and set it to NO.
#10
09/01/2014 (4:02 pm)
Another issue is Game Center Sandbox getting screwy with its login. Described here stackoverflow.com/questions/5682715/game-not-recognized-in-game-center along with things to do to fix it. Just spent two hours beating my head on that.
Associate Mike Lilligreen
Retired T2Der
// Save the top score as a dynamic field on a ScriptObject %file = new ScriptObject(); %file.topScore = Game.bestScore; // Write it out TamlWrite(%file, "./score/ScoreObject.taml"); // Read it in %score = TamlRead("./score/ScoreObject.taml"); Game.bestScore = %score.topScore;