Welcome to the sponsor-exclusive content for the Ren'Py Patreon. Sponsors like you ensure this page exists. Thank you.
Welcome to the April developer update. This was the month where a lot of the potential of the Ren’Py 7.4 series has finally been realized, with some new features that are coming in Ren’Py 7.4.5. In this month’s article, I’ll talk about some of these new features, like the 3D Stage, and do a deep dive into a new callback I think has a lot of potential.
Perhaps the biggest new feature in 7.4.5 is the debut of the 3D Stage system. This is a set of new features in Ren’Py that allows a creator to position sprites and backgrounds in three-dimensional space. Ren’Py will then use the GPU’s 3D rendering hardware to produce perspective-correct effects.
This is similar in intent to the existing 3D Camera system, but works differently internally. The big improvement with the 3D stage is that Ren’Py is laying out the sprites in three-dimensional space, which allows for perspective effects that couldn’t be accomplished with two-dimensional positioning, rotation, and scaling.
For example, with the 3D Stage it is possible to build a three-dimensional room, where the parallax effect affects portions of the floor closer to the camera differently than portions that are farther away. A future release (probably the next one) will add support for 3D modeled backgrounds, something the 3D Stage anticipates.
For all of the power it gives, the 3D Stage proved to be fairly simple. It adds four new transform properties to Ren’Py.
Right now, I’m in the process of writing documentation for the 3D Stage that will go into Ren’Py proper. The good news is that it looks like the interface will be fairly simple, with four new style properties.
The Swing() transition, that you saw a preview of a few months ago, is now
part of Ren’Py. The swing transition swings the image around the vertical
or horizontal axis. You’ll be able to use it with:
scene bg whitehouse
show eileen happy
with Swing(1.0)
There are several options now - you can swing around the X or Y axes, and can swing in forward and reverse directions. It’s also possible to specify the background image that is shown in places where the swing isn’t visible:
scene bg washington
show eileen vhappy
with Swing(1.0, vertical=True, reverse=True, background="stars.png")
Another area of work was the mouse cursor. Ren’Py 7.4 moved to using the hardware mouse cursor for most rendering. This is the right choice for most applications, as GPUs render the hardware mouse cursor with little buffering, meaning that it’s going to be very responsive to the mouse.
With that being said, hardware mouse cursor sizes can be limited. Windows guarantees a 32x32 cursor, and while 64x64 seems to be safe, anything larger than that may run into problems.
Since I had some feedback from projects that used large cursors, I’ve re-implemented a version of the pre-7.4 system, with some improvements. It’s now possible to delegate drawing the mouse to a displayable. Ren’Py comes with a built-in implementation of such a displayable, MouseDisplayable. This allows any displayable to be used as a mouse cursor.
There’s also a new callback, config.adjust_attributes, that is a lot more
powerful than it might first appear. It takes a tuple containing
an image name and attributes. For example, ('eileen', 'happy'), and
can return different attributes, like ('eileen', 'happy_eyes', 'happy_mouth', 'happy_feet').
This should interact well with LayeredImage, as it makes it possible to have a single attribute that sets attributes that are part of multiple groups. This becomes very flexible as Ren’Py will store the adjusted attributes, which means that those attributes persist through changes.
I’ve put together an example of how to use this, below.
Other than that, I’ve been focusing on places where Ren’Py 7.4.4 was having platform problems. iOS builds have been fixed, as has starting on Android when the player switches away during start. On macOS, Steam support has been fixed, and the app has been restructured so that it can be notarized by Apple.
Apart from that, I’m well into the Ren’Py 7.4.5 release process. I expect a prerelease to come out in the next day or so.
To show an example of config.adjust_attributes, I’ve written a sample
callback. To include it, first place this into the aliase.rpy file (or any
other rpy file):
init -100 python:
class Aliases(object):
"""
Expands attributes into other attributes.
"""
def __init__(self, **aliases):
# A map from an attribute name to a tuple of
# attributes it expands to.
self.aliases = { }
for k, v in aliases.items():
self.aliases[k] = tuple(v.split())
def __call__(self, name):
rv = [ name[0] ]
for i in name[1:]:
if i.startswith("-"):
prefix = "-"
i = i[1:]
else:
prefix = ""
for attr in self.aliases.get(i, ( i, )):
rv.append(prefix + attr)
return tuple(rv)
You’ll then want to set up your aliases, using something like:
define config.adjust_attributes['eileen'] = Aliases(
happy="eyes_happy mouth_happy",
concerned="eyes_concerned mouth_concerned",
)
Where each keyword argument maps an attribute to a space-separated string giving the attributes it expands to. If this is given, then:
show eileen happy
becomes equivalent to:
show eileen eyes_happy mouth_happy
That’s all for this month. As always, thank you for your support!