Welcome to the sponsor-exclusive content for the Ren'Py Patreon. Sponsors like you ensure this page exists. Thank you.

_images/2021-04.jpg

Ren’Py Developer Update - April 2021 link

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.

Developer Update link

3D Stage link

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.

Swing Transition link

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")

Mouse Displayables link

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.

Adjust Attributes link

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 Work link

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.

Adjust Attribute Example link

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!