The latest posts in full-text for feed readers.
The PlayJam GameStick community server software got another feature: Purchases. You are now able to buy games (instead of having all of them available for free) and in-game products like levels and powerups.
Your wallet has an infinite amount of money, so you don't risk going broke :)
All games - even already installed ones - have to be bought now. After buying, the game download starts automatically.
The purchase dialog is a web view, displaying a HTML page delivered by the server. I had no idea how it looked like - there were no screenshots to find with my Google-Fu. In the end I found a video of Lee Chapman demoing the Gamestick, and near the end he buys Riptide.
I took screenshots, resized and warped them until they had the correct aspect ratio and size. Then I re-built the layout in HTML and CSS that a 2013 browser understands.
There was no documentation about the purchase requests and responses. The requests were easy to document since I could see them in the server logs, but the responses were hard: Some of them are handled in the Java library, while others are passed to the Marmalade UI and parsed there. The important things like "success, download now" were of course in the compiled C code, and I was forced to use Ghidra to make a bit sense of it.
The magic words are:
{
"body": {
"success": true,
"message": null,
"action": "CLOSEPAYMENT"
}
}
Implementing purchases fixed a long-standing bug: The "uninstalled apps" view in the settings crashed, probably the Marmalade interface was never meant to handle 188 games. Now only the purchased games are listed there - without crashing.
A number of games have in-game products: "Top Gear: Stunt School" allows to buy nuts, dollars and permits. In "Pacman Tournaments" you can buy tokens (3500 for 99.99USD!), "Rise of Glory" lets you spend money on airplane packs and in Prince of Persia you can buy coins (1000 for 1.99, 100000 for 99.99$).
Of course we did not have backups and I had to decompile the game apk files to find the product IDs that they used. Products had to be registered at the server, and the game only asks the server which products are available.
More often than not, decompiling did not work because the game was made with Unity or some other engine, and I miss the tools to unpack those files. In this cases I let the server return all products ids from 1 to 1000, with prices from 0.01€ to 10.00€, and could immediately see which products were used. This did of course only work on some games; others crashed when they received more than 15 products.
OUYA games were much easier in this regard: They send all supported product keys to the server, making it a breeze to quickly add products for unsupported games. Although, easier only after I broke their DRM :)
At one point I was finished and had only find products for the last game, Repulze. Then I saw that - instead of sending integer number product IDs, just as all other games do - this game sends string keys like com.pixelbite.repulze.iap.toolkit_pack1! I had to modify the database, parts of the purchase API and the game data schema to support that :(
But now this feature is really complete, and you can purchase things in the following games:
In 2024-09 we had 163 of 188 games archived. Thanks to GameStick fans Kazdan, Krzysiu, Ryo and TheMartinMess22 we have 170 now, a whopping 90.4%!
Newly rescued games:
Published on 2025-06-25 in gamestick
A collection of links regarding the history of the PlayJam GameStick microconsole.
Age | Date | Event |
---|---|---|
2013-01-02 | Kickstarter funding campaign started | |
1 month | 2013-02-01 | Kickstarter funding campaign ended, 5691 supporters, 647.658$ |
10 months | 2013-10-24 | First Review at golem.de |
11 months | 2013-11-20 | German backers receive Gamesticks: GameStick ist da! |
1y 5m | 2014-05-08 | Last firmware update 0.9.2071 |
1y 5m | 2014-05-31 | Kickstarter docks were shipped |
1y 8m | 2014-08-15 | Inventory sell-off begins: GameStick for 19.99$ |
3 years | 2016-01-05 | PlayJam says GameStick will be running in the forseeable future |
3y 2m | 2016-03-09 | Last Facebook post by PlayJam |
4 years | 2017-01-09 | Official server shutdown |
Date | Category | Event |
---|---|---|
2012-12-10 | PlayJam | First PlayJam tweet: We are live with our pre-launch campaign. Follow us! Visit http://GameStick.tv or like us on http://facebook.com/GameStickNews |
2013-01-02 | Kickstarter | Kickstarter funding campaign started |
2013-01-03 | Kickstarter | Update #1: GameStick Day 1 - Wow. |
2013-01-09 | Kickstarter | Update #4: 320.000$ reached: Stretch Goals Announced! |
2013-01-11 | Kickstarter | Update #6: Stretch goal 1 reached: Stretch #1 Reached! |
2013-01-18 | Kickstarter | Update #8: 400.000$ reached: You spoke and we listened.. |
2013-01-30 | Kickstarter | Update #13: Miracast support: Working with Miracast |
2013-02-01 | Kickstarter | Kickstarter funding campaign ended, 5691 supporters, 647.658$: Wow! What a result! Incredible! Blown Away! |
2013-03-19 | Kickstarter | Update #17: Developer unit in production: Dev Kits, Partnerships and Further Updates |
2013-04-19 | Kickstarter | Update #23: GameStick DEV kit Unboxing Video |
2013-05-27 | Kickstarter | Update #29: GameStick Features on the BBC. |
2013-06-13 | Kickstarter | Update #34: Companion app: Demo showing PlayJam's Companion App working the GameStick UI |
2013-10-23 | Kickstarter | Update #45: Shipping stalled: Shipping update. |
2013-10-24 | Review | Golem.de: Playjams Gamestick im Test: Die Android-Konsole für zwischendurch |
2013-10-30 | Review | Eurogamer: GameStick review: Stick it. |
2013-11-05 | Review | Techradar: PlayJam GameStick review: The latest Android console doesn't get the formula right |
2013-11-07 | Kickstarter | Update #46: Sticks are shipping, Dock shipping delayed: Update - Feedback. |
2013-11-11 | Review | Engadget: GameStick review: Android console gaming still awaits its king |
2013-11-11 | Store | 45 games available: Engadget review |
2013-11-15 | Store | Over 50 games available: GameStick: Aktuelle Spieleliste |
2013-11-20 | Kickstarter | Germans backers receive Gamesticks: GameStick ist da! Die Verpackung… |
2013-12-04 | GameStick | Firmware update 0.9.2049: (source) |
2013-12-12 | GameStick | Firmware update 0.9.2049 report: GameStick Software-Update 0.9.2049 |
2014-01-19 | Store | 68 games available (source) |
2014-02-03 | GameStick | Firmware update 0.9.2058: (source) |
2014-02-06 | Kickstarter | E-Mail: Docks are still not shipping: Dear Backers, Let me start by apologizing for the lack of news and or updates on the GameStick project over recent months - in particular on the status of the docks.[...] |
2014-04-04 | Kickstarter | Last Kickstarter page update #47: Dock situation: Update. (archived copy) |
2014-05-01 | Store | 84 games available (source) |
2014-05-08 | GameStick | Firmware update 0.9.2071 (source) |
2014-05-21 | Kickstarter | E-Mail to Backers: Dock will be shipped next week Update: GameStick Dock |
2014-05-30 | Store | 90 games available (source) |
2014-05-31 | Kickstarter | TopFree got its kickstarter dock: GameStick Dock im Praxistest |
2014-07-12 | Review | Telegraph PlayJam article, 35000 units at GameStop: Get ready for TV gaming to move up a gear |
2014-08-15 | Sell-off | Price at GameStop: GameStick 19.99$ (source) |
2014-08-21 | Sell-off | Price at GameStop: Dock 15$ (source) |
2014-09-01 | Sell-off | Price at GameStop.com: GameStick 19.99$ (GameStick für $19.99, source 2) |
2014-09-18 | Sell-off | PlayJam sells off inventory on ebay Gamestick Sell off? |
2014-09-23 | GameStick | Custom Firmware CFW 1.4 (source) |
2014-12-05 | Sell-off | Price in GameStop store: GameStick 17$, Dock 5$ (source) |
2015-01-05 | Sell-off | Price at Gamestop: Controller 9$ (source) |
2015-10-20 | PlayJam | GameStick website redirects to flareplay.com, only zone.gamestick.tv still available: Neue PlayJam-Konsole FlarePlay und kostenlose AGameAWeek Collection für GameStick |
2015-11-23 | PlayJam | Playjam Titan prototype device sent to shanti: PlayJam Titan, (Gen 2 Gamestick?) |
2016-01-05 | PlayJam | PlayJam says GameStick will be running in the forseeable future: Tweet |
2016-02-26 | PlayJam | Last Tweet by @PlayJam |
2016-03-09 | PlayJam | Last Facebook post by PlayJam |
2016-05-15 | Store | 177 games available (source) |
2016-10-09 | Store | Game download not possible since months: GameStick ist „tot“ |
2017-01-09 | PlayJam | Server shutdown (taken from topfree screenshot) |
2017-01-11 | Store | Topfree blog post about server shutdown with screenshot of Gamestick homepage: GameStick: Das offizielle Ende |
2017-01-12 | Store | 177 games available (source) |
2017-11-09 | Store |
Shutdown: "Store closed earlier this year":
Comment:
No - they closed the store earlier in the year. As far as I know you can't download anything from the GameStick servers any more. |
Published on 2025-04-11 in gamestick
2013 PlayJam GameStick devices have a all-around rubber coating, and the controllers have a rubberized bottom. After 11 years, the coating's chemicals dissolved, leaving a sticky mess that sticks to your fingers when touching it.
It is possible to get rid of the coating by rubbing it off with Isopropanol (Isopropyl alcohol), an old sock and a pair of surgical gloves.
The rubber coating was mentioned in the 2013-07-11 Kickstarter Update #36: The Golden Sample:
- Put a rubberized coating on the bottom of the controller. This gives the finish a really nice quality feel.
- Used a rubber coating on the GameStick so that it did not scratch when inserted in to the controller. It really looks and feels fantastic as a result.
Published on 2024-12-31 in gamestick, hardware
The PlayJam GameStick had native support for using mobile phones as game controllers via its Companion app. Youtube still has a the official demo video showing it' usage.
When starting the app, it would show the GameStick and you could connect to it. Then the GameStick would deliver a branded controller skin to the app, which then displayed a custom controller interface for the game (or the standard one if the game had no own).
While looking through the files of a GameStick backup, I found some of the cached files in the /data/com.playjam.ca.service/files/ directory: .bundle and .meta files. The .bundle files are just Zip archives that contain an XML configuration file, background, button and stick images.
I took the time and built some little scripts to convert the XML configuration file via XSLT into a SVG image, and a script to embed the bitmap image files into the svg file. They can be found in the companion-app repository on Codeberg.
Published on 2024-12-15 in gamestick
My PlayJam GameStick replacement server is now able to deliver firmware updates to the GameSticks: Version 2049 to 2058, and 2058 to 2071.
The GameStick server was shut down in 2017, long before we tried to preserve the system. We thus could not download firmware images from the server, but GameStick Fans member Ryo found the firmware files for 2058 and 2071 somewhere on the internet and collected them for us.
Joe, a new GameStick Fan who joined in 2024-11, found the firmware image for 2049 on his stick.
Those full firmware images are ~180 MiB large and fully reset your GameStick - all settings and games are wiped. They can't be used for automatic updates.
After I manged to build a firmware update that enables the Android debug bridge, Ryo found an official firmware update on one of his GameSticks in 2023: Update-2058-to-2071.img. It was located in the /cache/ folder and only 3.2 MiB large.
Another stick contained Update-2049-to-2058.img (9.9 MiB).
Those .img files are small downloads and keep all the settings and games as they are - the right ones for automatic updates.
The initial request to check for firmware updates is pretty standard: A HTTP POST request to http://update.gamestickservices.net/check.php (actually 2 different domains and one hard-coded IP address), which returns a JSON structure that tells the stick if a firmware update is available, the textual changelog and if the stick must install it ("forced update") - and of course the download URL.
By reading the decompiled OOBE code, I figured out that the download URL gets modified and URL parameters are appended:
The firmware update is split into parts (chunks) of 100 kiB, and each chunk is "encrypted" by XORing it with the magic number 0x5b, and the binary SHA1 sum is put before the data itself.
My guess is that the developers did that to prevent people installing their own updates - a measure that was already defied in 2014-03, known as the lukepanic hack method. That hack supposedly (I don't have the files) opens a web server and delivers a custom firmware update :)
My server now contains a script that takes a firmware update, splits it into chunks, encrypts and signs them - so that the download files can be delivered statically.
All firmware images and updates known to us have been uploaded to the Internet Archive: 0.9.2049, 0.9.2059 and 0.9.2071.
Next we'd really like to have a developer firmware, and also know that there was a 0.9.2079 version we do not possess yet. Let's hope we'll find more sticks with cached firmware files on them.
Published on 2024-12-03 in gamestick
I've been continuing work on the Playjam GameStick replacement server and managed to implement two features: Achievements and leaderboards.
Achievements are things you reached in a game, e.g. jumping onto 3 enemies without touching the ground in Bloo Kid 1, a "Triple hit".
Whenever a player unlocks an achievement, the game sends that information to the server - a simple set-complete API call with the ID of the achievement and the session ID of the user. The server then has to store it in a database, and return it when requested.
Achievements can be requested in several locations:
Each of those locations had its own API call. Implementing the first and the last were easy, but the per-game achievement overview in the GameStick UI was pretty hard - the JSON structure was not parsed by the low-level GameStick database interface, but was handed off unparsed to the Marmalade-based UI, which parsed it and then crashed.
Guessing the property name for the achievement list yielded no results. Since the Marmalade SDk compiled code into C, it is pretty hard to decompile.
Fortunately, I found a Ghidra plugin for Marmalade, and after fixing a bug I could load the Console.s3e file into Ghidra. After some looking I found the property name for the achievement list: gameList.
All achievements were unfortunately registered at the server, and we have no backups of them. This means the games have to be decompiled and inspected to find out which achievements exists, what their title and description is. The achievements on the server also had images, which are lost forever.
Currently the game metadata repository has achievement information for Bloo Kid, Boulder Dash, Prince of Persia and ShaqDown.
Unlike the OUYA, the GameStick had native support for high score lists (but only one per game).
After implementing achievements, leaderboards were quickly done - the only API calls required for all games I know are saving the current score, and fetching the top 50 scores.
A couple of games provide high score lists: FallingBird, FourColorTaxi, GridLock, Magnetoid and Prince of Persia.
Stop the birds unfortunately fails to show the leaderboard for yet unknown reasons.
Published on 2024-10-30 in gamestick
This week the GameStick Fans community reached a milestone: Of the 188 games that were once available for the PlayJam GameStick, 163 have been archived and only 25 remain missing. That's 86.7%; a huge success for the project that started in 2024-04.
The lack of a GameStick community meant that nobody had backed up the available games before PlayJam announced the micro console's death in 2017.
After collecting cache files from GameSticks, 37 games could be downloaded from their AWS S3 URLs without authentication.
Another way to get the games is to contact the developers, but we had only limited success in getting answers to our e-mails, let alone .apk that the developers often did not have anymore.
Extracting installed games from existing GameSticks was the third option to get the game .apk files into our hands. It took a while and quite some effort until we were able to copy files off GameSticks - the devices were locked down and allowed neither file access nor sideloading.
The following people helped by copying games off their GameSticks or contacting developers to get .apks directly from them:
We do not yet have the .apk files for the following GameStick games:
# | Game name | Developer |
---|---|---|
1 | Animalz: Super Squad | InvaderGames |
2 | Baa Baa Bomber | RatJar Games |
3 | Beast Boxing Turbo | GoodHustle |
4 | Canabalt HD | Kittehface Software |
5 | CR Footy | Sacred Duck Games |
6 | Crumble Zone | Rebel Twins |
7 | CUBISTIC | Pytebyte |
8 | Dead Rushing | Dancing Cat Development |
9 | Dr. Bulbaceous Puzzle Solver | Wetgenes |
10 | EDGE | Mobigame |
11 | Finger Hoola+ | Plantpot |
12 | Furfur and Nublo | DevilishGames |
13 | Fuz Rush | Jet Stone Studios |
14 | Groundskeeper 2 | OrangePixel |
15 | Nimble Quest | Nimblebit |
16 | Orborun | Tiny Lab Productions |
17 | Pix'N Love Rush | Advanced Mobile Applications |
18 | RED | Knife Media |
19 | Sci-Fighters | Headup Games |
20 | ShaqDown | One Spear |
21 | SpaceCat | Platty Soft |
22 | Space Grunts | OrangePixel |
23 | Space Vermin | GameDisciples |
24 | Usagi Yojimbo | Happy Giant |
25 | Wasteland Bar Fight | Kybernesis |
If you have a GameStick with one or more of this games - follow the apk rescue instructions, or ask for help in chat.
The following games have been backed up and archived in the GameStick library at the Internet Archive.
Recent gameplay videos can be found on Wayne’s Gaming Den "PlayJam GameStick" playlist
Published on 2024-09-08 in gamestick
I'm on the quest to make PlayJam GameStick micro consoles usable again. Building a replacement server is underway, and collecting game information is nearly finished - but not much progress has been made obtaining the actual .apk files.
37 apks could be downloaded from the PlayJam Amazon AWS S3 bucket, but the rest of them are not accessible although we know the URLs. They are probably only accessible with a temporary access token that the GameStick server once generated.
We contacted a number of developers and asked for the apks, but most don't have them anymore - they are lost. Some developers don't even remember having programmed for the GameStick :) And many don't react on e-mails.
The last resort is to get the .apk files off the GameSticks that have them installed. PlayJam wanted to prevent that, so they locked the GameStick down, preventing access to the Android settings, disabling the adb daemon and even removing the functionality to sideload games (which was available in early firmwares).
Simply starting the Android settings or adbd via the advanced launcher TOFU plugin did not work. I needed to find a way to inspect the GameStick and run applications on them to see what worked. Because adb access was not available, I decided to build my own telnet server that would run as TOFU plugin on the GameStick.
I found a nice Python 2 socket server example and used that as base to build my own server that I could connect to with a telnet client. Development was easy because I could run the server locally. Only at the end I built a TOFU plugin that simply started the telnet server script.
One thing I learned was that the shell (my server) needs to take care of storing the current working directory, and also needs to implement change directory commands - those cannot be delegated to the system. After 2.5 hours I had a telnet server that ran on the GameStick, and I could finally inspect the file system and run programs:
cweiske:~/dev/gamestick/sync/tofu-plugin> telnet gamestick 5023
Trying 192.168.3.41...
Connected to gamestick.
Escape character is '^]'.
/> ls
acct
backup
boot
cache
[...]
/> whoami
u0_a40
/> am start -n com.android.settings/.Settings
[Errno 13] Permission denied
Now I could try to open the Android settings (which still fails) and start adbd - it turned out that running programs on the GameStick is only possible as root:
$ telnet gamestick 5023
Trying 192.168.3.41...
Connected to gamestick.
Escape character is '^]'.
/> su -c start adbd
/> quit
Connection closed by foreign host.
cweiske:~/dev/gamestick/sync/tofu-plugin> adb connect gamestick
already connected to gamestick:5555
cweiske:~/dev/gamestick/sync/tofu-plugin> adb shell
root@android:/ # pwd
/
root@android:/ # ls /data
GameStick
GameStickCache
The result of this endeavour are two TOFU plugins:
Update 2023-06: An adbd-enabling firmware image is available at codeberg.org/gamestick-fans/firmware-adb-enabler/ - see GameStick: Black screen after OOBE.
Published on 2023-05-07 in gamestick
Work on my own server for the abandoned PlayJam GameStick micro console continued, and two weeks ago I deemed it good enough to make it public for others to test.
To make sure everything works fine I removed the GameStick host name entries from my local DNS server, factory reset the GameStick and started the initial setup. It all worked fine as expected, but after completing setup the screen went black and stayed that way. Only notifications that a Gamepad was connected/disconnected or the internet connection was established were shown in the bottom right corner. The GameStick did not react to gamepad nor keyboard input.
Since had reinstalled the 2071 firmware as part of my test, I had no access to adb - for that I had to install and start the TOFU media player, install and run my "start adb" plugin. None of this was an option since the main UI ("Console") did not load.
Flashing firmware 2058 gave the same black screen that 2071 showed.
I suspected something to be off with my API and changed the connect API responses to known-to-work versions from git history of the playjam gamestick API code, but that did not help. Minimizing them did not help either.
Next I tried to replace the profile API with a version that I used when I got it working for the first time, but that did also not help.
I also suspected the session IDs to have invalid characters, but changing them did not yield any results. The black screen stayed.
Another thing that the official connect API responses had were UI translation strings, so I integrated them - but no avail.
The first three days of poking in the dark were over.
During development I had collected a number of server responses that were cached on different GameSticks (Toast, Cataphoresis, Ryo, Kazdan, Lee Chapman). I let my server return those files, but the screen still stayed black.
Since I knew that the UI did not show the latest data when they were downloaded from the server, I had to boot the GameStick once to the black screen, wait for it to download all API data, and rebooted again to see if the new data made any difference.
Nothing.
I also replaced the small .jpg profile images with original large .png files.
From previous experiments I knew that OOBE in firmware 2071 did not show the profile image, while 2058 does. So I tried to find out what changed between those two firmware versions: 2058 used the custom JSON handler, while 2071 had completely switched to a Gson to parse and hydrate the API responses.
There were no differences to find in the parsed properties. Day 4 over.
My main problem was that I did not have error logs because the PlayJam developers had disabled adbd on the GameStick. My next idea was to install all the GameStick .apk files inside the Android emulator and see the error in its logs.
Fortunately I could configure a 4.1 Android system for the emulator, start it and install all com.playjam.* apk files that were part of the 2071 firmware. I could start OOBE, but it would hang in the 5th step, the activation. Logs said that it could not obtain the hardware ID which is needed in requests to the API server.
I dived deep into the decompiled code, found out how the GameStick loads its hardware ID, built an Android app that provides a system service that starts on boot and sends out the com.playjam.SYSTEM_INFO intent with a fake hardware ID and firmware version information.
I learned the hard way that building an app with only a service and without any user interface will never be marked as "activated", and thus its services will never be started by the Android system. So I had to build a dummy UI activity that started the service once.
In the end, my service worked and the GameStick apks could fetch the correct API from the server, and OOBE finished.
The Console UI had some errors because certain files and folders were missing in the /data user partition. I copied them over from the firmware image, and the GameStick intro video played!
Unfortunately the UI crashed while the spinner was rotating, because playing a sound did not work in the emulator:
W/AudioPolicyManagerBase( 654): getOutput() could not find output for stream 3, samplingRate 0,format 0, channels 3, flags 0 E/AudioTrack-Java( 2246): [ android.media.AudioTrack ] getMinBufferSize(): error querying hardware W/dalvikvm( 2246): JNI WARNING: JNI method called with exception pending W/dalvikvm( 2246): in Lcom/ideaworks3d/marmalade/LoaderThread;.runOnOSTickNative:()V (GetObjectClass) W/dalvikvm( 2246): Pending exception is: I/dalvikvm( 2246): java.lang.NullPointerException: I/dalvikvm( 2246): at com.ideaworks3d.marmalade.SoundPlayer.start(SoundPlayer.java:75) I/dalvikvm( 2246): at com.ideaworks3d.marmalade.LoaderThread.soundStart(LoaderThread.java:856)
But this was a kind of success: The intro video was not visible on my real factory-reset GameStick.
Day 6 over.
So my GameStick stays completely black but the emulator shows the intro video: I needed to get back to real hardware. One thing I had not yet tried was CFW 1.4, the Custom FirmWare by shanti (GameStickers.net: [ROM] CFW v1.3 - Updated 1.4 is out :D, archived version). It hopefully has adbd enabled, which would give me logs.
I flashed it onto the GameStick, and it booted into a standard Android user interface (the whole point of the firmware was to get an usable Android without any restrictions). Then I installed all the com.playjam.*.apk files and populated /data as I had when using the emulator.
The results were good: OOBE worked, intro video plays, the spinner is visible and then the normal UI starts and is usable - only game images did not load.
But while it was nice that I got the official UI working on custom firmware, I did not find out why the official firmware stayed black.
Day 7 was gone.
When inspecting the CFW 1.4 files I noticed /system/build.prop which contained three additional lines:
persist.service.adb.enable=1 persist.service.debuggable=1 persist.sys.usb.config=mass_storage,adb
If the official firmware had this, I'd get proper error logs and could see the error messages.
I learned that the GameStick firmware .img files are standard Android OTA .zip files and not some custom format.
I also learned that firmware files need to be signed, so I used the standard java method for signing:
$ signapk -a 4 --min-sdk-version 16 --disable-v2 certs/certificate.pem certs/key.pk8 image.tmp.zip image.signed.img
.. but when trying to flash that image I got:
Verifying update package...
Installation aborted.
I tried different parameter combinations (align/noalign, v1/v2) but all failed.
Then I read all 28 pages of the archived CFW thread on gamestickers.net and found someone who asked how the image was signed. shanti had answered:
here is the program I used: "Sign-em! 2.0"
http://forum.xda-developers.com/showthread.php?t=1966007
I got the linux version and found it used signapk.jar. After finding that I saw that it used some internal old Sun Java class sun.misc.BASE64Encoder that was not available anymore in any recent OpenJDK :(
Android system recovery normally only installs firmware images
that have been signed by one of a number of white-listed keys.
The GameStick's recovery seems to allow all properly signed images,
regardless which signing key was used.
This is the reason the CFW was possible at all
- on OUYA, custom firmwares could only be installed when using a
custom bootloader,
but not with the stock recovery that requires firmwares to be signed
by a key that only OUYA possessed.
Then I found the next XDA thread post that linked to HemanthJabalpuri/signapk which contained MinSignApk 1.0 that ran on current Java versions!
I signed my firmware image with MinSignApk, and could flash it!
Update 2023-06: An adbd-enabling firmware image is available at codeberg.org/gamestick-fans/firmware-adb-enabler/
Now that I had flashed my custom firmware 2071+adb I finally saw the errors:
I/ActivityManager( 3509): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 pkg=com.playjam.gamestick.console cmp=com.playjam.gamestick.console/.Main u=0} from pid 3754 D/GameStick( 4262): **************************************** D/GameStick( 4262): Failed to create download directory
The directory existed, so I removed it:
$ adb shell rmdir /data/data/com.playjam.consoledev/files/Downloads
Next boot, the GameStick would create the directory, and the following it would complain again. So this was not the problem.
I/ActivityManager( 4479): Displayed com.playjam.gamestick.console/.Main: +313ms (total +1s416ms) W/System.err( 4628): java.io.EOFException W/System.err( 4628): at libcore.io.Streams.readAsciiLine(Streams.java:203)
The firmware update check needs to return its JSON on a single line, otherwise parsing would fail. I modified the server.
D/PlayjamKeyboard( 3685): Starting for type : 0/0 I/marmalade( 4262): PJException error has occurred : 62 c:/_work/dev/marmalade_main/menu_head/src/PNGFile.cpp OpenTextureFile open png Error : empty file name
This finally looked like the real problem. I removed all game information from the API in case the game images were the culprit, as well as the profile images. Still the same error.
Day 8 was over.
The next day I tried more image related changes:
While booting the GameStick I came across a very special error:
W/DatabaseService:ConnectDownloader( 3794): Failed to duplicate connect data for console : /data/GameStick/ConsoleResources/315f7b66-fae7-4ab3-9d46-bf41942694b6.json => /data/GameStickCache/reg_server_response.json
Reading through the source code led to me understanding that process:
The last step failed because downloading fresh data (500 kiB!) was faster than parsing cached data.
This could only happen on my local setup: GameStick's WiFi reception is so bad that I could not use my normal access points. Instead I enable an access point on my laptop whenever I do GameStick development, and the GameStick only needs to transmit data some 30cm to my laptop. Since the API server is running on the same machine, data transmission is much faster than usual, leading to that race condition.
This problem was fixed with a sleep(2) call to slow down the API.
The GameStick still gave the OpenTextureFile error with no hint about the file it tried to read.
I tried my luck, built a 2058 firmware with adbd and did get a more verbose error:
I/marmalade( 5452): PJException error has occurred : 97 c:/_work/dev/marmalade_main/menu_head/src/PNGFile.cpp OpenTextureFile open png Error : Cannot open file raw:///data/GameStickCache/Assets/textures/placeholder3.png
That was very strange. I knew that the firmware image contains nearly 1000 files in the /data folder, and confirmed that this particular file also exists in both 2058 and 2071 firmware files.
It turned out that /data/GameStickCache/Assets/ was completely missing on my device, as well as /data/GameStickCache/Resources/. What the heck?
Now I remembered that when flashing firmware via system recovery, I always do two steps to get a nice clean system:
But the GameStick firmware installation process already populates the user data partition /data/! Wiping user data after installation removes all the asset files that are needed by the console user interface, leaving a broken system.
Now it also made sense that I did not see this problems on the emulator and the CFW setup: I knew those files were missing and had manually copied them from the firmware update into /data.
Day 9 had finally brought relief.
The key takaway is that the PlayJam developers did not follow standard Android conventions and put necessary system data onto the user partition.
When flashing a GameStick, always wipe user data first, and then flash the firmware .img file. Never the other way round.
Published on 2023-06-19 in bigsuck, gamestick
My replacement server for the PlayJam GameStick micro console is ready for semi-public testing. It allows you to finish the initial setup (OOBE), list all the games, and download + play 130 of them.
It's not complete yet: We know of games that cannot be controlled properly because button mappings are missing, and achievements are not yet stored on the server. Firmware updates are not distributed. Probably many other issues are waiting to be found.
It is semi-public because GameStick devices have to be white-listed by me.
When your GameStick is stuck in the initial setup, attach a keyboard. On the language selection screen, type "hardware" and your GameStick's hardware ID will be shown in the top left corner.
Send that hardware ID by mail to me via cweiske+gamestick@cweiske.de or join the GameStick Fans Discord chat server and contact me there.
If the hardware ID does not appear, continue until WiFi setup and complete it. The GameStick will contact my server automatically and I can read the ID from the logs. Open ip.cweiske.de in your browser and send me that IP address, so I can correlate IP and hardware ID.
The GameStick setup in screenshots:
The Gamestick OOBE lets you select the language, setup WiFi and shows a verification code:
Then you need to continue in your browser: Enter a name, select a profile image and choose the age rating for games.
When you finish setup in the browser, the GameStick will show your "Gamer tag" (name) and the profile image (only on firmware 2058, non on 2071):
Afterwards the boot video will play and you'll the the main user interface that you can use to download + play games:
Games names beginning with !!
indicate that they cannot be downloaded.
We currently have .apk files for 131 of the 188 games.
Published on 2023-06-19 in gamestick