Alright, enough of the boring dev-ops things. I needed to get it out of the way first because all that setup was a pre-requisite for the changes I’ll talk about today. The dev-ops features were already used in Rejuvenation 13.5. On the other hand these improvements are brand new in Reborn 19.5. Rejuvenation and Desolation will of course get them as well when they make their next releases.
That said, some of these features would not have been possible without all the dev-ops work.
JoiPlay
One thing we noticed when Rejuvenation 13.5 came out was that quite a few people tried to play on Android using JoiPlay. This was on my radar for a while, but I didn’t know there were so many people who wanted to play on their phone so it didn’t seem important. Well, I clearly underestimated the demand. Several times a day someone asked on either Rejuv’s or JoiPlay’s Discord about how to make it work. I reached out to the person who prepared the fixing patch who is quite knowledgeable regarding JoiPlay and got a lot of useful info about how I can make the games run better on JoiPlay and how to set up default controls. Because of this, the next major releases of all three games will come out with an experimental JoiPlay version, set up with good default controls and a few other tweaks.
For instance, JoiPlay has a feature where it can optimize the tilesets to be smaller to fix some problems. I took the script they’re using, added it into eevee (also fixed three minor bugs I found in the script) and made our workflows automatically prepare these optimized tilesets when building a release. This involved some more technicalities such as building a Docker image for eevee where I had to compile a library which has been unmaintained for 11 years but let’s skip these dev-ops details.
I also tried to set up good default controls while using JoiPlay with a gamepad. Here I’m not actually sure if and how well it works because JoiPlay can only recognize around half of the buttons of my Dual Sense. With a different gamepad it might work better but I can’t test it myself. Feedback will be appreciated when this comes out.
Improved controls
The nice thing about the new mkxp-z setup is that it’s now much easier for us to update it to a newer version and to make occasional custom tweaks when needed. For instance I wanted to tweak the default controls because it always bugged me that the Previous Page and Next Page (for pokedex, bag etc.) were only bound to Q and W but not to Page Up and Page Down by default. These defaults are baked in mkxp-z’s source code. Yes, players can add them through the F1 menu but I wanted to improve the defaults. Also not all things can be changed through the F1 menu because for instance the F12 soft reset is an internal function of mkxp-z which you can’t rebind. This meant there was no way to soft reset while using a gamepad except for some clunky external programs where you would make a gamepad button trigger F12. I tweaked our mkxp-z fork so that a gamepad guide button triggers soft-reset. Then I went through the default controls for both keyboard and gamepad, discussed it with the team a little and changed a few default keybinds to make more sense. Keyboard only got small changes while the gamepad controls were tweaked quite a bit.
Also after some research I found out that I can actually detect the strength of the press on a gamepad L2 and R2 buttons. This is a bit of an experiment but I made turbo speed dynamic depending how strong you hold L2. This might be a subject to change depending on player feedback but we can adjust it quite easily. There is another button to make turbo permanent without holding anything if you prefer that.
During the game intro there is this screen with the default controls, right? Except it was a bit outdated because it was an image which was difficult to edit. And there was no such screen for gamepad controls. So I scrapped that and made a new screen which is up to date and actually generated by code so it’s easy to edit later. Then a second one for gamepads. And you can access them any time, not just during the game intro. There are a few conditions in there to account for game differences because Reborn has rotating tile puzzles while the other two don't.
Old screen from Rejuv (quite a few keys are incorrect here):
New screens:
(note: small mistake there, first line should be C / Enter / Space instead)
One new thing you can notice among keyboard controls is that you can now quickly go through long menus such as pokedex or debug menus using Ctrl+Q/W (or R2+L1/R1 on gamepad) to skip 10 pages at once.
Another nice change is that some minigames such as rotation puzzles and mining have their special actions like tile rotation or mining tool switch bound to several buttons at once so that you don’t need to think too hard about which button to use.
Sorry for those blacked out parts. Those are some new features Lucent implemented recently. They’ll be revealed in another post!
Built-in updater
Reborn e19 came with an updater (shout out to Aie who wrote this) which you could use to get patches. It did its job well but had some issues such as mac support. Later on when Desolation 6 was about to come out I whipped up my own updater called gogoat. (It’s written in Golang so why not continue the Pokemon naming convention, right?) After some tweaks, this worked on mac as well by the time Rejuvenation 13.5 entered testing. However the problem was that even this would be clunky on Android even if I could compile it to run there. If we were to make a release for JoiPlay I wanted the patches to be easily available there as well. So back to the drawing board.
The JoiPlay community member I mentioned earlier came up with an idea to download and apply a patch from a preload script. This was a cool proof of concept, but if we can make the game update itself, it should work that way on all platforms. It sounds very cool and user-friendly so I wanted to see if it was feasible.
To achieve this I basically needed two things: To download a patch and to unzip it, meaning an HTTP client and a zip library. An HTTP client is like a web browser for programs. It makes a request to a server and gets a response back– in our case, the patch zip. Sounds pretty easy, but it turned out to be around 100 times more complicated than it has any right to be. Why? Because the Ruby instance which mkxp-z and JoiPlay are running internally is severely restricted. Neither an HTTP client nor an unzipping library is available in mkxp-z. Well, technically, mkxp-z has HTTPLite, but you can’t really use that for file downloads. So I reached out to the mkxp-z community and, after some trial and error, we managed to get Ruby’s standard library working in mkxp-z on all three platforms. This contains an HTTP client. The rubyzip gem is written purely in ruby so we could just copy its source code and get it working as well. However, this didn’t support HTTPS. (a security layer for web browsing that's very important.) After a while, and some more help from the mkxp-z maintainer, I managed to patch it to make openssl available, and HTTPS was working correctly. It didn’t have root certificates, but I can get those elsewhere. (These are needed for openssl to decide if the server can be trusted.) So, in the next release you might see directories called stdlib and gems, two new dlls for openssl and crypto and a cacert file. All of that is purely for the built-in updater to work. But, even if it’s quite a few extra files, it’s only around 15 MBs total so it's not a big deal.
Alright, now that mkxp-z is done, let’s get back to JoiPlay. While there is no way to get Ruby’s entire standard library running on JoiPlay, it actually comes with an additional method called HTTPLite.download built-in. So it should be easier to download the patch there, right? Wrong. For one, while it does make HTTPS requests, I suspect it doesn’t actually check whether the certificate is valid. However, I can neither verify that nor do anything about it. At least it works, except for one important detail. In some cases (patreon-only builds) we also need to send an additional authorization header to the server with an access password. The download method does have a headers argument, but it’s broken and the headers are not actually sent. So I had to implement some server-side band-aid to accept the authorization in the url instead of a header. As for unzipping it, while the rubyzip gem doesn’t fully work on JoiPlay because some dependencies are missing and impossible to add, the important part– unzipping– does actually work, after a few tweaks in the code to suppress unrelated errors.
Finally, after all of this, the new built-in updater seems to work correctly on all four platforms.
JoiPlay still had several nasty issues during the beta - optimized tilesets were not updating meaning the game essentially never got any map updates. Then a new JoiPlay built completely broke loading of Ruby libraries. I fixed that and a week later it broke again. Luckily, we had a JoiPlay player in the beta (ty reispher!) who helped me with testing all of it. This is where Ame’s quote at the top came from. I really really hope this won’t fall apart due to some unforeseen and unfixable problem. Fingers crossed!
To clarify, this updater is intended only for bugfix patches as it cannot update the Game.exe itself or its equivalents on other platforms. Updating from 19.5.0-rc.0 community release to 19.5.0 stable release will still require manual installation. Same for updating to 19.6.0 or 20.0.0 later on.
Favorite Items
For a long time, I didn’t like the fact that the first bag pocket is used for way too many items, some of which are mostly useless, while others are often the best in the game. I often had trouble finding the useful ones among the rest.
On the other hand, the X-Items pocket only had a very few items. It felt like they didn't even deserve their own pocket. Most challenge runners don’t even use these items to begin with, making the pocket utterly useless for some.
So, in this update, X-Items are moved into the Medicine pocket. The Battle Items pocket has been repurposed for a new Favorite Items pocket. You now have the option to mark any item in any pocket as Favorite which will make it show up in the Favorite Items pocket in addition to its normal location.
Discord integration
Another project I was working on was Discord integration. Discord has a feature called “Rich Presence”. A game can use this to tell Discord some details of what you’re doing in the game and have the details shown as your status. With this Discord can show which area of Reborn you’re currently exploring or which trainer you’re fighting.
As usual, we had some complications while setting this up. Aie did all the hard work around what the game will actually report. My part was making sure the integration works on all platforms where Discord’s SDK is available. I cooperated with rainefall, the author of the extension which sits between our scripts and Discord’s SDK. Our scripts are written in Ruby programming language and this extension is a Ruby gem (library) written in the C programming language. Compiling this extension for Windows, Linux and MacOS in a way that actually worked required some adjustments for each platform. Admittedly, rainefall was the one making the breakthrough in all three cases as I know next to nothing about C. Still, I did plenty of work on testing it, setting up the automated compilation and researching possible causes for the issues we saw. For Windows, it actually needs to be done as part of the mkxp-z compilation pipeline or at least using mkxp-z’s fork of Ruby. Linux required some special flags for the C compiler. MacOS was, as usual, the most problematic because not only did we have to make sure it works on both AMD and ARM processors, but the compiler somehow insisted on linking some required libraries using an absolute path rather than relative, which makes no sense. Still no clue if there is a way to tell the compiler to not do that but after more research I found a tool capable of fixing the link.
It was quite a relief when we actually had a setup working for all three desktop platforms. So, Reborn 19.5 will come with this feature included. There is an option to disable it of course. The leaders of the Rejuvenation and Desolation teams also seemed interested so there is a good chance for this to eventually drop in those games as well.
Hopefully you’ll enjoy the improvements! We still have quite a bit more to show you so keep an eye on this blog for more posts!
- 21
- 3
Recommended Comments
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.