Game Development Community

Configuring For Android

by Claude Rains · in Torque 2D Beginner · 09/24/2014 (11:08 pm) · 15 replies

I already made a simple yet entertaining little game, and it works fine on Windows, but I want to release on android too and there's a couple of problems I'm running into.

I can use the default android project to compile just fine, per the instructions in the Android Development Guide, but then the name of the app is "Torque2D" and the package name is com.garagegames.torque2d. Obviously I don't want a package name that conflicts with anyone else's, or other projects I might make, so I tried changing it. I know changing the app name is as simple as changing the label in strings.xml. It's the package name however that's confusing me. When I change all references to com.garagegames.torque2d to com.edfgames.missilecommander (my desired package name) including the src folder structure (com/garagegames/torque2d) the game no longer runs on my tablet. Am I only supposed to change it in AndroidManifest.xml and leave all other references to com.garagegames.torque2d intact? Is there something else I'm supposed to do in addition that I'm neglecting? Forgive me, I'm quite new to android.

The second problem I'm having is with prefs. Currently I export video prefs and the high score pref to a "preferences.cs" in the root directory from the root main.cs onExit command. This allows the game to track a high score and also opens up video options to power users (I didn't bother with a video options menu in-game and I didn't bother to hide the high score because cheaters gonna cheat). This apparently doesn't work on android however, as the score is not retained between sessions. Is there a specific way I'm supposed to handle prefs on android?

I'd appreciate any help I can get, the sooner I resolve these issues the sooner I can push out my game.

About the author

Recent Threads


#1
09/25/2014 (5:33 am)
The only things I change are app_name within Strings.xml the package within Android_Manifest.xml and the ic_launcher images.
#2
09/25/2014 (11:10 am)
Interesting, I've been experimenting on android as well and run into the prefs problem. Hope to see a sollution presented here as the only other related thread has no replies and isn't clear.
#3
09/25/2014 (1:05 pm)
Alright, it runs now, thanks practicing01. However my prefs problem has gotten worse.

For the video options, and originally for the the high score, I exported the prefs using a command like this one:

export("$pref::Video::*","preferences.cs", false );

and I'd load them using this command just after the default preferences were loaded:

if ( isFile("preferences.cs") )
exec( "preferences.cs" );

That didn't work, so I tried this command for the high score pref, part of which I saw in another thread:

export("$pref::Game::*", getUserDataDirectory() @ "/MissileCommander/preferences.cs", false );

which I then load with

if ( isFile(getUserDataDirectory() @ "/MissileCommander/preferences.cs") )
exec( getUserDataDirectory() @ "/MissileCommander/preferences.cs" );

On windows this works fine, and lets me hide the high score file while still leaving the video options exposed in the game's folder. However on Android, this causes the game to fail to load past the splash screen after I've played it once, until I clear the cache. There was one point where it did load before I cleared the cache, but the high score still was not retained. Is there a specific command I'm supposed to use when dealing with Android to export and load prefs?
#4
09/25/2014 (7:23 pm)
I tried getPrefsPath() instead of getUserDataDirectory() and the result was the same. It crashes after the splash the second time I try to play and almost every time after, but the one time it does start up all the way the score is gone. Is the android port of T2D simply unable to save files anywhere in any form?
#5
09/26/2014 (3:07 am)
Are you able to write out a TAML file in Android and read it back in?

As an option, you could use a ScriptObject and store any high score or preference data in dynamic fields on it. Then simply save it out and read it back in via TAML.
#6
09/26/2014 (11:28 am)
Well it doesn't crash anymore but it still isn't retaining the high score. I use this in AppCore's main.cs to initially load the score if it exists and create it if it does not:

if ( isFile( getUserDataDirectory() @ "/MissileCommander/HighScore.taml" ) )
$HighScore = TamlRead( getUserDataDirectory() @ "/MissileCommander/HighScore.taml" );
else
$HighScore = new ScriptObject(){ val = 0; };

$Pref::Game::HighScore = $HighScore.val;

Then I've tried using this, both in the root main.cs' onExit function and then in my own waveEnd function that gets called earlier, both work on PC but neither work on android:

$HighScore.val = $Pref::Game::HighScore;
TamlWrite( $HighScore, getUserDataDirectory() @ "/MissileCommander/HighScore.taml" );

On the PC no errors come up in the console and the file is created fine. On android I can't tell if either is happening because the console doesn't work and my tablet isn't rooted.
#7
09/29/2014 (7:53 pm)
So, nothing? As I said before I'm curious as well what the procedure is for saving on android. Has this been documented anywhere or tested by anyone? Has anyone actually made or successfully ported a Torque game to android?

I have two devices I can test on if it'll help.
#8
09/30/2014 (9:31 am)
Nobody in the Android community knows how to save on Android devices?

The question I have is this: does Android use /home/<username> folders like Linux? If so, it may expect apps to save settings and whatnot here and here only. Just a shot in the dark, I don't work on Android - but I have spent a lot of time working in Linux over the last year and a half....
#9
09/30/2014 (11:21 am)
Perhaps someone in the IRC channel knows how it's supposed to work.

irc.maxgaming.net#garagegames

Looking through some of the platform code for Android, I see there are a few TorqueScript functions for the console - enableWinConsole(true/false); and enableDebugOutput(true/false);

Maybe someone with an Android device can try those out to see if they can access the console that way.
#10
09/30/2014 (5:27 pm)
getUserDataDirectory returns the android cache directory. You only have a few directories you are allowed to write in so you will want to use this when writing out files to android. Try debugging or putting in print statements into Taml::read and Taml::write and make this is not corrupting the path. Just do a Con::printf("Taml::write - %s", mFilePathBuffer); after that code to see if the path is still pointing where it should.

// Expand the file-name into the file-path buffer.
    Con::expandPath( mFilePathBuffer, sizeof(mFilePathBuffer), pFilename );

Torque console log btw prints to Logcat so you can see the console log while running via logcat tab in eclipse.
#11
10/25/2014 (5:35 pm)
Using Taml throws errors both when trying to read and write on android (I don't have the exact ones since I read them on my phone using CatLog and didn't bother to export the log, but it was basically that it couldn't find the file it was trying to open for writing and that it couldn't read taml data from the file it found, both of which were the same file in the same place), but I don't see why these functions would even be tested or used on android since they're generally of no value outside of development. The export and exec functions don't throw errors at all, but the score still isn't being loaded.

At least I learned from the TAML errors that getUserDataDirectory returns a cache directory that is associated with the app, rather than a general user directory, when used on the android platform, so I don't need my saving function to create a folder for the file like it does on Windows. I just need to know what function will actually save a file. openFileForWrite() perhaps? It's the only other function I know of for creating a file. I guess I'll try it and see what happens.
#12
11/03/2014 (10:12 pm)
Ok, I can verify that using the fileobject system and OpenForWrite() does write a file containing the data I specify (I actually checked the file with a rooted File browser). However when the file is read using OpenForRead() it seems to pull gibberish. I'm using %file.readline() without an end of file loop so I'm gonna try adding one to see if that works, but I suspect the problem lies in how the file i/o functions are translated into android functions, and I don't know enough about programming or Android to fix that if that's the case.
#13
11/04/2014 (4:25 pm)
I can confirm Claude's findings. On PC, OpenForWrite and OpenForRead work fine, saving and then retrieving the data I write to a text file. On Android, OpenForWrite works to create the text file, but OpenForRead gives me gibberish, as echo'd to Logcat. I suspect the same as Claude that the problem is how the android code handles requests for reading data, but I have no programming experience and don't know where to look or what to look for.
#14
11/13/2014 (11:34 pm)
I discussed it with a user named "az" on the irc, and after guiding me through some debugging he agreed this is likely a problem with the i/o functions as implemented on android. I submitted a new bug report on the github: https://github.com/GarageGames/Torque2D/issues/242
Hopefully more qualified people than me will be able to get to the bottom of this.
#15
01/23/2015 (12:07 pm)
Hi all,
found the bug, took me some time to nail it down ;)

The bug is in AndroidFileio.cpp File::Status File::read.

If the handle is not NULL it checks if the size is 0 and return. Size is always 0 when I open a File for read and the given parameter of the function is named _size. _size is needed when the handle is NULL, changing _size to size ends with a crash loading content.


Long story in short words:
After:

if (handle != NULL)
{

I added:

size = _size;

And Bingo the file will be read.