Welcome to the sponsor-exclusive content for the Ren'Py Patreon. Sponsors like you ensure this page exists. Thank you.
Welcome back to yet another Ren’Py developer update. September was a month of working on fixes and improvements while working on Ren’Py 7.4.9. So far, there have been three pre-releases, and my hope is to get the new version out soon.
This month had a continued focus on Android, though the direction of that focus was changed a bit. While last month was very much about getting Ren’Py working with Android App Bundles and Play Asset Delivery, this month is more about improving the Android build process.
This mostly took the form of polishing the portions of the build process that are implemented in the Ren’Py launcher. For example, I had feedback from one of the testers that made it clear that they were confused when it came to selecting APKs and Bundles. Changing it from regular buttons to checkboxes eliminated that confusion.
Another change was making it possible to list the Android devices connected to your computer, and disconnect a device that had connected already. These are just a bunch of little things that hopefully add up to a better Android build process.
A second thing I did was to make it possible for a game to request permissions
from Android. The new build.android_permissions variable and
renpy.check_permission() and renpy.request_permission functions
let you ask the operating system for permissions that Ren’Py normally doesn’t
need. Similarly, I’ve documented that Pyjnius,
a library that lets you access Android APIs from Ren’Py, is something that is supported
as part of Ren’Py.
Finally, there have been a few device compatibility fixes. One of the big ones was that save thumbnails were showing up as black on some devices. That’s an issue that I believe I’ve finally solved.
iOS also got some work this month. There, the main problem was that the iOS project that’s produced required you to make a number of changes to have it work properly. It would also contain files that weren’t necessary, and build configurations that aren’t used.
I spent a day auditing the produced project, removing these unnecessary files, and making sure that everything that can has a sensible default. While you’ll still need to make some changes, like setting the project identifier and your developer account, it should now be less work to create an iOS project.
Another thing I spent my time on this month was Transforms. There are a couple
of things I worked on. The first was improving the way the perspective
transform property interacts with regular transform properties, which
wasn’t something I had considered when first implementing it.
What I decided is this:
xpos, ypos, zpos, and rotate
move the camera around. Note that this generally has the opposite effect on
the scene the camera is looking at - moving the camera to the right moves
the scene to the left, rotating the camera clockwise rotates the scene counterclockwise,
and so on.The other focus on transitions was on reliability, especially in the case of changing data. Some of the changes in 7.4.8 could cause problems if the data was changed before an ATL Transform could be shown. 7.4.9 should capture data the same way older versions of Ren’Py did.
Finally, there were some reports of Ren’Py having texture glitches after a window was resized. This would manifest as an image being completely wrong - instead of a button background, you might have a word or picture show up.
This was traced back to a problem in memory management. Ren’Py primarily uses something called reference counting to manage memory. The idea is that every object that is created in the game keeps track of the number of objects that refer to it. When no object refers to it, Python (and hence Ren’Py) can release that object and reclaim the memory and other uses.
A problem is if we have two objects that refer to each other:
python:
a = object()
b = object()
# Each object has one reference, through the variables.
a.friend = b
b.friend = a
# Each object has two references, one through the object and one
# through the other object's field
del a
del b
# After del deletes the two variables, each of the objects still has one
# reference to it.
When this happens, the reference counter can’t release the memory. Python’s garbage collector will have to run to release it, at some time in the future. That can slow the game down (very slightly), but more importantly, it delays the release.
What I found was that a small reference cycle could cause a texture to be released after it should be replaced. That lead to the replacement getting removed too, which showed up as a visible glitch, usually for a short amount of time.
Kind of a long explanation, but it was a really small problem that took me down a rabbit hole - it took about eight hours to figure it out. And the result is that games will be slightly better - so it’s worth it.
Next month, I’m hoping to get the Ren’Py 7.4.9 out the door. There’s likely to be a 7.4.10 after all - there’s a pull request to improve the performance of persistent data on very large games, so we’ll be looking at that.
What I’m thinking of is keeping 7.4.x alive for small features and fixes as I work on Ren’Py 8, which will support Python 3. We’ll see how things go.
Lastly, I thought I’d post an example I wrote last month. A question came up on twitter about using the high-contrast text, which places a black background under the text, as a normal part of a game. As the high-contrast mode changes a lot of things about how text is rendered, I didn’t think it was a good idea.
Instead, I put together a screen that can replace the normal say screen, that displays text inside a frame with a black background. Here’s the screen:
screen cap(who, what):
frame:
style "empty" # The empty style resets the frame to no background, margins, or padding.
background "#000" # Set the background to black.
padding (5, 5) # Add a bit of padding.
xalign 0.5 # Center the text.
yalign 1.0 yoffset -30 # Place it near the bottom of the screen.
text what:
id "what" # Ren'Py needs this for a say screen to work.
pos (0, 0) # This screen needs the text to be positioned at (0, 0)
layout "subtitle" # Subtitle layout tries to make all lines even.
text_align 0.5 # Center the text within the text block.
size 30 # Set the text size.
The easiest way to use it is with a character that has a screen parameter:
define caption = Character(None, screen="cap")
caption "Orbiting Earth in the spaceship, I saw how beautiful our planet is. People, let us preserve and increase this beauty, not destroy it!" (screen="cap", what_size=30)
As always, thank you for your support.