Full Changelog — Ren'Py Documentation

# Full Changelog

## 7.4.0

### Model-Based Renderer

This release includes a new model-based renderer, the component of Ren'Py that is responsible for drawing text and images to the user's display, supplementing (with the intent of eventually replacing) the original OpenGL renderer added in Ren'Py 6.10. This renderer takes better advantage of the hardware present in modern GPUS (both dedicated graphics cards and GPUs integrated into processors) to improve performance and increase capability. This renderer supports desktop computers that support either OpenGL 2.2 or DirectX 9.0c or 11, and mobile devices and embedded systems that support OpenGL ES 3.

The biggest change in the model-based renderer is that Ren'Py is no longer limited to drawing rectangular images in a 2-dimensional plane. Instead, Ren'Py has been converted to use meshes made up of triangles in a three-dimensional space. While existing rectangular sprites are displayed in the same way, this opens up Ren'Py to non-rectangular meshes, and eventually full three dimensional geometry.

In addition to mesh geometry, model-based renderering supports shaders, both shaders included with Ren'Py, and shaders specified by creators as part of their game. Shaders are small programs that run on the GPU, that can process geometry and pixel data, to allow for all sorts of graphical effects.

The model-based renderer implements a new fast texture loading system, which moves an expensive part of texture loading, alpha premultiplication, from the CPU to the GPU.

The model-based renderer also creates mipmaps for each texture that is loaded into the GPU. A mipmap is a series of smaller versions of the texture, stored on the GPU. By creating and utilizing mipmaps, Ren'Py is now able to shrink images below 50% of the original size, without the appearance of the aliasing artifacts. This is especially relevant when assets meant for 4K monitors are used on 1080P and smaller displays.

For this release, the Model-Based Renderer is opt in, with that opt-in controlled by the `config.gl2` variable. As we gain more experience with it, it is indended to be come the default Ren'Py renderer.

### Live2D

One of the features enabled by the model-based renderer is support for displaying sprites made in Live2D. Ren'Py requires you to download Live2D Cubism separately, as you'll need to execute a contract with Live2D, Inc. before distributing a game that uses their technology.

Ren'Py supports the display of Live2D models, complete with the ability to change expression and to queue up one or more motions. This is integrated into Ren'Py's image attribute system. Ren'Py also supports fading from one motion to another when an attribute changes.

### Matrixcolor and Blur

The model-based renderer enables new functionality in transforms, such as matrixcolor and blur.

Transforms (including ATL Transforms) now support a new `matrixcolor` property, which either a matrix or an object that creates a matrix that changes in time, and uses it to recolor everything that is a child of the transform.

While previous versions of Ren'Py supported the `im.MatrixColor()` image manipulator, the new property is much improved. The image manipulator would often take a large fraction of a second, making it too slow for real-time use, and was limited to single images. The new transform property is fast enough that it can be changed every frame if necessary, and can be applied to any displayable. It's now possible to apply a Transform using matrixcolor to a layer, to recolor the entire layer - making it possible to push your game into sepia or black-and-white without needing a separate set of images.

There are a few difference between the image manipulator and the the transform property versions of matrixcolor, as the new version uses 4x4 matrices and premultiplied alpha color, so the new property can't use the same matrices. Instead, there are number of new ColorMatrix objects that need to be used.

Transforms also support a new `blur` property, which blurs the child of the displayable by the given number of pixels.

### Python 2/Python 3 Compatibility Mode

While Ren'Py is not yet supported on Python 3, this release of Ren'Py includes several features to allow you to begin writing scripts that will work on both Python 2 and Python 3.

First, Ren'Py now uses future to provide standard library compatibility. It's now possible to import modules using their Python 3 names, when a renaming has occured.

When a .rpyc file begins with the new `rpy python 3`, the file is compiled in a Python 3 compatibility mode. The two changes this causes are:

- Ren'Py will compile the file in a mode that attempts to emulate Python 3 semantics, including the change to division. In Python 3, `1/2` is equal to .5, and not 0. Since this changes the type of the expression, this can change the position of displayables. `1//2` keeps the original semantics.
- Ren'Py will change the behavior of dict so that the `items`, `keys`, and `values` methods return views, rather than lists, when called directly from that .rpy file. These match the Python 3 semantics for these methods, but need to be explicitly turned into a list before being saved or participating in rollback.

### Upgraded Libraries and Platform Support

For Ren'Py 7.4, the build system was redone, replacing the multiple build systems needed to build Ren'Py with a single build platform that handles every platform except for webasm. The change in build system also involved updating all of the libraries that Ren'Py uses to newer versions.

As a result of this, the list of platforms that Ren'Py offically supports has changed slightly. Here's the latest list of what is supported:

Platform | CPU | Note
--- | --- | ---
Linux | x86_64 | Raised minimum version to Ubuntu 16.04
Linux | i686 | Raised minimum version to Ubuntu 16.04
Linux | i686 | Raised minimum version to Ubuntu 16.04
Linux | armv7l | Intended to support Raspberry Pi, uses Raspian Buster
Windows | x86_64 | A new port to 64-bit Windows Vista and later.
Windows | i686 | Raised minimum version to Windows Vista.
macOS | x86_64 | macOS 10.6+ (All 64-bit macOS versions.)
Android | armv7a | Android 4.4 KitKat
Android | arm64 | Android 5.0 Lollipop
Android | x86_64 | Android 5.0 Lollipop
iOS | arm64 | All 64-bit iOS devices, iOS 11.0+
iOS | x86_64 | The 64-bit iOS simulator, iOS 11.0+
Web | webasm | Modern web browsers

The biggest new platform that Ren'Py supports is the 64-bit Windows platform, which means that Ren'Py is available in 64-bits on all major desktop and mobile platforms. The new `renpy.bits` variable can be used to determine if Ren'Py is running on a 32 or 64-bit platform, if necessary. (For example, to set `config.image_cache_size_mb` appropriately.)

The one platform that loses support in this release is 32-bit (armv7l) iOS devices. These devices are no longer supported by Apple, and do not support the level of OpenGL ES that Ren'Py requires.

### Web

Ren'Py now runs significantly faster in the browser, thanks to new compilation techniques.

A game built for the web platform can now download image and audio files from the web server as the game is played. The download begins when the image or sound is predicted. This can reduce the initial time it takes before the game begins running, as well as memory usage.

When running inside a web browser on a touch-screen device, Ren'Py will display a touch-based keyboard, to compensate for web browsers having difficulty displaying keyboard entry for wasm-based games.

The splash screen displayed while loading can use the WebP format, including animated WebP.

More Python modules are provided, making the Python environment closer to native Ren'Py ports.

Support for iOS browsers was improved.

### Steam

It is now possible to install Steam support from the Ren'Py launcher, by choosing "preferences", "Install libraries", "Install Steam Support".

The new `config.steam_appid` variable automatically creates the steam_appid.txt file for you. This needs to be set by a `define` statement, or in a python early block.

### Translations

The Simplified Chinese, Japanese, and Korean translations have been updated, and now use a unified font.

There is a new Simplified Chinese translation of the tutorial game, courtesy of Neoteus.

### Depreciations and Removals

As described above, Ren'Py no longer support Windows XP.

As described above, Ren'Py no longer supports 32-bit iOS devices.

The choice of downloading the Editra text editor has been removed from Ren'Py. Editra hadn't been updated in over 5 years, and the website it was originally distributed from has disappeared.

While not completely removed, the software renderer has been simplified and removed as an option for gameplay. Its purposes is now limited to informing players about issues that prevent display of graphics with a GPU-based renderer.

### Miscellaneous

Support for controllers has been improved. Repeat is now supported on controllers, and the libraries that Ren'Py uses have been compiled to support many of the more popular game controllers.

Ren'Py now uses software playback of movies on Android and iOS devices, meaning the same files can be used on all platforms that support video playback.

Defining a mouse cursor using `config.mouse` now uses SDL2's color cursor API, which generally results in hardware acceleration and reduced mouse movement lag.

The `define` statement can now be used to set a key in a dictionary.

    # Ren'Py was started in 2004.
    define age["eileen"] = 2020 - 2004

The `define` statement can take += and |=, to apply the appropriate update operators.

    define config.keymap['dismiss'] = [ 'K_KP_PLUS' ]

    # This assumes endings is a set.
    define endings |= { "best" }

It is now possible to specify a relative audio channel whenever an audio is file is played, using the new `volume` clause to `play` and `queue`.

The new `fit` property of transforms provides for different ways of making an image fit size with a different aspect ratio. For example, it can be scaled to be contained fully within the given size, or to make sure that it completely covers the given size.

The `xpan` and `ypan` transform properties no longer double the size of the displayable they are applied to, making them easier to combine with positioning transform properties.

The `renpy.input()` function can now take regular expressions when determining what is and is not allowed.

Grids now take `margin` style properties, that is applied outside the grid, and inside a containing viewport.

Ren'Py support an {alt} text tag, that causes the text to be spoken during self-voicing, but not displayed. It also supports a {noalt} text tag that does the opposite.

The launcher window can now be resized if necessary. A button has been added to the launcher preferences to restore the default size.

The new `build.mac_info_plist` variable makes it easier to customize the mac app.

The requests library, is bundled with Ren'Py, making accessing the web much easier.

Pressing PAUSE on your keyboard brings the player to the game menu, finally giving that key a function.

## 7.3.5

### Fixes

On desktop platforms, the presplash screen has been reworked so that it will not cause the window to become nonresponsive if clicked.

The iOS port has been updated to include modules that have been newly added to Ren'Py, allowing the compilation of iOS apps.

### Other Changes

The `audio` directory, which automatically defines names in the audio namespace, has been made visible in the launcher, and is added to newly-createrd projects.

The new `config.exception_handler` callback allows an application to replace Ren'Py's exception handling system in its entirety.

## 7.3.4

### Fixes

This release fixes major graphics glitches that were introduced in 7.3.3.

- On Windows, textures would fail to be reloaded when switching from fullscreen to windowed mode or vice-versa. This would cause the wrong texture to be displayed.
- On all platforms, graphical glitches could occur when `Flatten()` was used.

### Other Changes

Dynamic images can now include "[prefix_]" everywhere, and especially when `add` has been used to add a dynamic image to buttons, drags, and similar focusable objects.

Creator-defined screen language statements may now take `if` statements as children.

The drag and drop system has been improved to better interact with updated screens.

## 7.3.3

### Audio

Ren'Py now supports an `audio` directory, which automatically defines names in the audio namespace. This makes it possible to have a file named `game/audio/overture.ogg`, and play it using:

    play music overture

The new `AudioData()` class allows you to provide compressed audio data to Ren'Py, either generated programatically or taken from a source other than a file. To support this, the Python wave and sunau modules are now packaged with Ren'Py.

An issue with enabling the mixing of mono sound files has been fixed. This issue caused many WAV files not to play. (We still don't recommend the use of WAV files.)

### Platforms

Ren'Py is now distributed as a signed and notarized binary on the Mac. As this process takes a very long time to accomplish, the ability to sign macOS binaries has been removed from Ren'Py itself, in favor of external scripts that take care of the signing and notarization process.

The minimum version supported by the Android port has been lowered to Android 19 (Android 4.4 KitKat).

The web port of Ren'Py has seen a number of changes:

- Screen variants are now detected and set.
- Fullscreen support has been improved, though the user may need to click to enable fullscren.
- Leaving the web page is detected, so persistent data may be saved.
- 'game.zip' can now be renamed. 'DEFAULT_GAME_FILENAME' in index.html controls this.
- Portable HTTP requests (native+renpyweb): see https://github.com/renpy/renpyweb/blob/master/utils/asyncrequest.rpy
- Enable networking in Python web port for testing WebSockets, transparently available through the Python 'socket' module
- HTTP Cache-Control allows for smoother game updates.
- The pygame.draw module is now included, allowing Canvas support.
- WebGL compatibility has been improved.

### Other Changes

During profiling conducted for the GL Rewrite project, it became clear that the switch to framebuffer objects in 7.3.0 was the cause of certain performance regressions. By changing how FBOs are used, Ren'Py performance has been improved.

The `renpy.input()` function can now be given the name of a screen that is used to prompt the user for input.

The creation of list, dicts, and sets inside of screen language is now analyzed correctly. This will allow more displayables to be analyzed as constant, improving screen performance.

The notify screen is now hidden on rollback.

The NVL mode screen indicates that it shows the window, which prevents problems when `window show` is in effect.

When a `Call()` with from_current set to true occurs during a multi-part statement (like a menu with dialogue), control is restored to the first part of that multi-part statement (thus causing the dialouge to be displayed).

More functions now use a tag's default layer.

The `renpy.is_init_phase()` function has been added.

Automatic voice now works for dialogue that is part of a menu statement.

Support for GLES1 has been dropped. (It hadn't been used for years.)

The `SelectedIf()` and `SensitiveIf()` actions can now take other actions as arguments.

Many BarValues now take a force_step argument, which forces changes to the bar to be rounded to the nearest step value.

`Frame()` now allows the tile argument to be the string "integer", which tiles the contents of the frame an integer number of times.

`Character()` now allows the name argument to be a function or callable object when dynamic is true.

### Translations

The Korean and Spanish translations have been updated.

## 7.3.2

### Fixes

Fix a regression in the platform variables, caused by the previous release.

### Translations

Update the spanish translation.

## 7.3.1

### Changes

Descriptive text (text that is intended to be show when self-voicing is enabled, so that scenes can be described to the vision impared) has been updated. Descriptive text is now accessed using the `alt` character (the old `sv` character has been retained as an alias.) It's also now possible to display descriptive text using a custom character, rather than the narrator.

Ren'Py now always initializes the media playback system, so that a movie can be played even if no audio will be played.

The default property of most displayables, which is used to choose a displayable to be focused by default, has been renamed to default_focus so that it does not conflict with the `default` statement. It also now takes an integer, with the displayable with the highest focus number getting focus.

The `Flatten()` displayable now passes positions from the child.

Seeded random number generators created with renpy.random.Random now support rollback.

When emulating Android or iOS, the platform variables (like renpy.android, renpy.ios, renpy.windows, and renpy.mobile) are set properly.

Renpyweb now stores the date and time that a save file was created.

### Fixes

This release fixes a fairly major issue that could cause screens that interpolate text to not update, or update improperly.

This release properly runs the image prediction routine from the image prediction thread.

A problem with the {clear} text tag has been fixed.

The `config.end_game_transition`, which was not working properly in most circumstances, has been fixed.

### Translations

The Russian, Korean, and Spanish translations were updated.

## 7.3.0

### Renpyweb

Courtesy of Sylvain Beucler, Ren'Py now can generate distributions for the the HTML5 web platforms, capable of running on modern web browsers that support the Web Assembly standard. This is intended for small games and demonstrations of larger games, as right now the implementation downloads the full game to the web browser before running any of it.

Web support is marked as beta, as there are cases where problem with the web platform (most notably, a lack of threading) cause problems such as sound glitches if an image takes too long to load. As a result, it is possible to have a Ren'Py game that works well on all other platforms, but not in the web browser. As web browsers themselves improve, we will improve our implementation and eventually remove the beta tag.

Building a web distribution can be done from the new "Web" button on the Ren'Py launcher. The launcher now includes a small web server, that can be used to launch the game in a creator's web browser for test purposes.

### Creator-Defined Statements

Ren'Py's creator-defined statements, and the Lexer objects that are used by them, have been extended to improve the functionality in many ways. With respect to the Lexer:

- It is now possible to ask the Lexer object to parse a single line as a Ren'Py statement, or all the lines remaining in the block as Ren'Py statements.
- It is now possible to ask the lexer to catch errors, so as to limit the scope of errors to a part of a creator-defined statement rather than the whole statement.

The `renpy.register_statement()` function has new arguments to enable new functionality.

- Statement prediction can be controlled by the predict_all and predict_next arguments, which predict all possible next statements or take a function that determines what will run next, respectively.
- The new post_execute argument lets one specify an execute function that is run as the next statement - the one after the creator-defined statement. This allows a pattern where a statement runs, executes the block inside it, and then runs something after the block to clean it up. (For example, an event that serves as a label, and then jumps back to a dispatcher when it is done.)
- The new post_label argument lets one specify a function to supply the a label that goes after the creator-defined statement, which can function like the `from` clause to the call statement.

Ren'Py now stores the result of parsing a creator-defined statement in the .rpyc files. While this allows for more complex syntax and faster startup, it means that it may be necessary to force a recompile if you change a creator-defined statement's parse function

### Screen Language Improvements

It is now possible to supply an `as` clause to a screen language displayable. This is especially useful with drags, as it lets the screen capture the drag object and call methods on it as necessary.

The `on` statement can now take a list of events.

A screen now takes a sensitive property, which determines if it is possible to interact with the screen at all.

Ren'Py will now produce an error when a non-constant property follows a Python statement, inside screen language. (This was very rare, and almost always a mistake.)

### Text Improvements

Ren'Py now includes support for self-closing custom text tags, which are custom text tags that do not require as closing text tag.

Ren'Py now supports three new flags that can be applied when formatting text:

- "[varname!u]" forces the text to upper-case.
- "[varname!l]" forces the text to lower-case.
- "[varname!c]" forces the first letter of the text to upper-case, capitalizing it.

### Android and iOS Improvements

Ren'Py now uses Framebuffer Objects on any device that claims to support it. As a result `focus_mask` now works on Android and iOS.

Ren'Py now produces 64-bit arm binaries for Android. These will be required by the Google Play store later this year.

Text input on Android was rewritten again, to fix problems where the user was unable to advance. Completion was eliminated, as it was the source of the problems. While languages that require input methods will need a larger rewrite to function, Ren'Py should now properly handle all direct input keyboards.

### Translations

The Ren'Py launcher and sample project have been translated into Turkish by Arda Güler.

The Ren'Py tutorial game has been translated into Spanish by Moshibit.

French, Japanese, Korean, Russian and Spanish translations have been updated for this release.

### Other Improvements

The `side` displayable now renders its children in the order they are provided in the control string.

The `say` statement, `menu` statement, and `renpy.call_screen` statements now tak a _mode argument, which specifies the mode Ren'Py goes into when these statements occur.

The `renpy.show_screen()` and `renpy.call_screen()` functions now take a zorder argument.

Ren'Py will now play a mono sound file with the same volume as a stereo sound file, rather than sending half the energy to each ear.

The new `config.load_failed_label` specifies a label that is jumped to when a load fails because Ren'Py can no longer find the current statement. This makes it possible to a game to implement its own recovery mechanism.

The new `config.notify` variable makes it possible to intercept the notification system and do your own thing.

The interface of `config.say_attribute_transition_callback` has been changed in an incompatible way, to allow sets of old and new tags to be given.

`Action` and `BarValue` now support a get_tooltip method, which allows the object to supply a default tooltip.

### Fixes

A problem that could cause Ren'Py to drop certain characters, especially accent markers in Arabic, has been fixed.

The filename of the internal copy of OpenDyslexic has been changed so as not to cause problems with copies distributed with games.

## 7.2.2

Ren'Py now supports a new Accessibility menu, which can be accessed by pressing the "a" key. This menu, which is intended to be used by players, let's the player override the game font, change the scaling and spacing of text, and enable self-voicing.

Ren'Py will now allow files in the public game directory (/mnt/sdcard/Android/package/files/game) to override those included with the game proper. This has been listed as a feature in 7.2.0, but didn't work right.

Ren'Py will now include temporary image attributes in the say statements generated as part of the translation process.

When uploading to itch.io, Ren'Py now downloads butler itself. This means there is no longer a dependence on the location or structure of the Itch app, as there was before.

The bar values `DictValue()`, `FieldValue()`, `VariableValue()`, and `ScreenVariableValue()` all take a new action parameter, which gives an action that is performed each time the value changes.

The rollback system has been optimized to reduce the amount of garbage that needs to be collected.

## 7.2.1

### iOS Improvements

Ren'Py will now set the version field for the iOS application when generating a project.

Ren'Py will now look for the files ios-icon.png and ios-launchimage.png, and use them to generate the icon and launch image in the sizes required for iOS.

### Other Improvements

The `renpy.in_rollback()` function returns True when in the rollback that occurs immediately after a load. This makes it possible to use:

    python:
        if not renpy.in_rollback():
            renpy.run(ShowMenu('save'))

To display a save menu during an initial playthough, but not during loading or rollback.

`config.say_attribute_transition_callback` now exists, making it possible to select the transition to use on a per-say-statement basis.

The new `RENPY_SEARCHPATH` environment variable makes it possible to override `config.searchpath` on launch.

### Fixes

Ren'Py has been audited to make sure that the semantics of == and != match, whenever == was redefined.

There was a fix to problems that might occur when a transform is added to a screen using the `add` statement.

The way `extend` processes arguments was changed to ensure that newer arguments take priority over arguments given to the statement being extended.

Ren'Py now properly considers the scope when comparing dynamic images for equality. This fixes an issue that prevented some dynamic images from updating when part of a screen.

A crash when `config.save_dump` is true on macOS has been fixed.

A crash when `config.profile` is true has been fixed.

Ren'Py now explicitly asks for text (as opposed to email, password, phone number etc) input on Android when the keyboard is displayed.

An issue has been fixed that prevented roll-forward from working through a menu statement.

Fixes a bug that prevents roll-forward through a menu.

## 7.2.0

### Menu Arguments

Ren'Py now has support for menu arguments. Arguments can be passed to a choice menu as a whole, or to the individual choices within the menu, using the syntax:

    menu ("jfk", screen="airport"):

        "Chicago, IL" (200):
            jump chicago_trip

        "Dallas, TX" (150, sale=True):
            jump dallas_trip

        "Hot Springs, AR" (300) if secret_unlocked:
            jump hot_springs_trip

Menu arguments passed to the menu itself become arguments to the screen, except the screen argument which selects the screen, and the nvl argument, which - if present - selects the NVL-mode menu. The arguments to the choices become arguments to the items passed to the menu screen.

### Temporary Say Attributes

Ren'Py now supports temporary say attributes. Just like regular say attributes, these are included as part of the say statement. However, these temporary say attributes are reverted once the dialogue has finished. For example, in the script:

    show eileen happy

    e "I'm happy."

    e @ vhappy "I'm really happy!"

    e "I'm still happy."

In the first line and last line of dialogues, Eileen is using her happy emotion. The vhappy emotion is shown before the second line of dialogue, and replaced with the previous emotion (happy in this case), before it.

### Text

There have been a number of text changes that affect text when a window is scaled to a non-default size:

- The text is now aligned on its baseline, rather than at the top of the text. This is relevant when an absolute outline offset is used.
- It is now possible to choose how the outline scales when the window is scaled. This is done with the `outline_scaling` style property.

When positioning a Text object, the `yanchor` property can be renpy.BASELINE. When it is, the anchor is set to the baseline of the first line of the text.

### Statements

The new `window auto show` and `window auto hide` statements allow automatic dialogue window management to continue while showing or hiding the dialogue window.

The `show screen` and `hide screen` statements now take a with clause, that works the same way it does with `show` and `hide`.

The screen language `use` statement now can take an `expression` clause, that makes it take an expression rather than a literal screen name. This allows a variable to be used when selecting the screen that is included. See Use for more details.

### Changes

The new `renpy.is_skipping()` function reports if Ren'Py is currently skipping.

The input displayable now takes a new copypaste property, which when true allows copying with ctrl+C and pasting with ctrl+V. This is enabled in the console and launcher.

`Preference("display", "window")()` now avoids creating a window bigger than the screen, and will be selected if the current window size is the maximum window size, if the size selected with `gui.init()` is bigger than the maximum window size.

Creator defined statements now have a few more lexer methods available, making it possible to to parse arguments, image name components, labels, and delimited python.

The `renpy.force_autosave()` function takes a new argument, that causes the autosave to block until it completes.

The ctc screen now takes a number of new parameters, if required.

The new `im.Blur()` image manipulator can blur an image. Thanks to Mal Graty for contributing it.

LayeredImage groups now support a `multiple` property, which allows multiple attributes in the same group to be displayed at the same time. This is useful because it allows the auto-definition function of a group to be applied to non-conflicting images.

Ren'Py will remain fullscreen when the mouse changes desktops, and will avoid shrinking a maximized window during a reload.

The `config.allow_duplicate_labels` variable can be defined or set in an init python block to allow duplicate labels to be defined in a game.

The `Movie()` displayable can now be told not to loop, and displays the associated static image when it stops looping. It also can take an image that is displayed before the movie proper starts.

### Android Changes

The downloading of the Android SDK has been updated to fix a change in the provided tools that prevented things from downloading.

An explicit action is now given to the keyboard, to make sure the enter key works.

Ren'Py now uses the Amazon payment APIs when sideloaded onto a device made by Amazon, allowing their payment system to be tested on a dual-store APK.

Ren'Py will now allow files in the public game directory (/mnt/sdcard/Android/package/files/game) to override those included with the game proper.

### Fixes

A bug preventing Ren'Py from displaying zero or negative-width characters (such as certain diacritics) has been fixed.

An issue that prevented Ren'Py from updating a displayable that was added to a screen with transform properties has been fixed.

The order of drags within a drag group is now preserved when an interaction restart occurs.

Size-changing properties like `xysize` now apply to a Drag and not the space it can move around in.

A bug that could cause a transparent, black, or gray line to appear on the bottom line of a screen during a dissolve has been fixed.

A regression in support for imagefonts has been fixed.

Creating a new file from the navigation menu of the launcher now works.

Menu sets now work again.

Ren'Py will no longer crash if an incomparable type is given to `Function()` and other actions.

A case where rolling forward would fail is now fixed.

A problem that prevented the Steam overlay from showing up on macOS was fixed.

## 7.1.3

This was a quick re-release of 7.1.2 in order to fix a single bug, which was that a test change had been left in causing `config.default_language` to be set on initial startup.

## 7.1.2

### Improvements

Ren'Py's screen language now support the inclusion of anonymous ATL transforms. It's now possible to write:

    screen hello_title():
        text "Hello.":
            at transform:
                align (0.5, 0.5) alpha 0.0
                linear 0.5 alpha 1.0

The new `SetLocalVariable()` and `ToggleLocalVariable()` actions make it possible to set variables inside used screens.

The new `config.menu_include_disabled` variable determines if menus should include entries disabled by an if clause.

Shift-keybindings (like Shift+I and Shift+R) now work in the Android emulation mode.

Ren'Py now better reports errors in text tags that require a value but are not given one.

The new `_version` variable indicates the version of the game itself that was used when a new game is first created. This only stores the version at game creation - after that, it's up to the creator to keep it updated.

The `Movie()` displayable now supports a new mode the color data and alpha mask data are placed side-by-side in the same file. This prevents issues where a main and mask movie could go out of sync.

The `FilePageNext()` and `FilePagePrevious()` functions now take arguments that control if the they can bring the player to the auto or quick save pages.

The new `config.skip_sounds` variables determines if Ren'Py will skip non-looping audio files that are played while Ren'Py is skipping.

### Translations

Ren'Py now has the ability to automatically detect the locale of the user's system, and use it to set the language. Please see `config.enable_language_autodetect` and the Translation documentation for how this works.

The French, German, Korean, Russian, and Simplifed Chinese translations have been updated.

### Fixes

A Windows-specific bug that caused RTL (the support for languages like Arabic and Hebrew) to corrupt the second half of text strings has been fixed. This should prevent garbage characters from being displayed when rendering those languages.

Ren'Py will now report an error if a game accesses an image that does not exist, but has as a prefix an image that does exist. Before this change, if `eileen happy` exists and `eileen happy unknown` was shown, the additional attribute would be ignored.

Lint has been improved to deal with images that take attributes that are not in the image name, like layered images.

Ren'Py generates choice menu images that are suitable for use on the phone.

### Android Fixes

As Ren'Py's new Android support only worked well on a 64-bit version of Java 8, we make that 64-bit requirement explicit.

## 7.1.1

### History Fix

This release fixes an issue with Ren'Py's history screen. The problem occurred when a line of dialogue contained a quoted square bracket, so something like:

    "I [[think] I'm having a problem."

When this occurs, the string "I [think] I'm having a problem." is added to the history. Ren'Py would then display that in history, substitute the `think` variable, and crash.

This is fixed by adding `substitute False` to the history screen. This is done to new projects, but for existing ones you'll need to make the fix yourself. Here's the new history screen:

    screen history():

        tag menu

        ## Avoid predicting this screen, as it can be very large.
        predict False

        use game_menu(_("History"), scroll=("vpgrid" if gui.history_height else "viewport"), yinitial=1.0):

            style_prefix "history"

            for h in _history_list:

                window:

                    ## This lays things out properly if history_height is None.
                    has fixed:
                        yfit True

                    if h.who:

                        label h.who:
                            style "history_name"
                            substitute False

                            ## Take the color of the who text from the Character, if set.
                            if "color" in h.who_args:
                                text_color h.who_args["color"]

                    $ what = renpy.filter_text_tags(h.what, allow=gui.history_allow_tags)
                    text what substitute False

            if not _history_list:
                label _("The dialogue history is empty.")

The new lines are the ones with `substitute False` on them. You'll want to make this change to your history screen to prevent his problem from happening.

### Android Improvements

Ren'Py now sets the amount of memory used by the Android build tool to the Google-set default of 1536 megabytes. To change this, edit rapt/project/gradle.properties. To make sure you're capable of building larger games, please make sure your computer has a 64-bit version of Java 8.

Ren'Py explicitly tells Android to pass the Enter key to an input.

Ren'Py now crops and sizes the icon correctly for versions of Android below Android 8 (Oreo).

Ren'Py gives a different numeric version number to the x86_64 apk. This will allow both x86_64 and armeabi-v7a builds to be uploaded to Google Play and other stores, rather than having to first created one build and then the other, manually changing the version numbers between.

### Other Improvements

Ren'Py now handles the (lack of) drawing of zero width characters itself, preventing such characters from appearing as squares in text if the font does not support the zero width character.

Ren'Py supports the use of non-breaking space and zero-width non-breaking space characters to prevent images in text from being wrapped.

Ren'Py supports the a new "nestled-close" value for the ctc_position parameter of `Character()`. This value prevents there from being a break between the click-to-continue indicator and the other lines.

Drags (in drag-and-drop) now support alternate clicks. (Right clicks on desktop and long-clicks on touch platforms.)

### Fixes

The `SetVariable()` and `ToggleVariable()` functions have been extended to accept namespaces and fields. So it's now possible to have actions like `SetVariable("hero.strength", hero.strength + 1)` or `ToggleVariable("persistent.alternate_perspective")`.

Automatic management of the dialogue window (as enabled by the `window auto` statement) now considers if an in-game menu has a dialogue or caption associated with it, and handles that appropriately.

The source code to the embedded version of fribidi that Ren'Py is expected to build with is now included in the -source archive.

There have been a number of fixes to the voice sustain preference to make it work better with history and the voice replay action.

## 7.1

### Android

This release sees a major rewrite of Ren'Py's support for Android to modernize it. This is required so Ren'Py games can be uploaded to the Google Play store. Some of these changes may require you to update a game's files. Most notably, the format of icons has changed, so the icons will need to be redone.

The minimum version of Android that Ren'Py will run on has been raised to Android 19 (aka 4.4 KitKat), while it targets Android 28 (aka 9 Pie).

The x86_64 architecture has been added, while x86 has been dropped. (Some x86 devices may be able to run the arm platform version through binary translation layers.)

### Monologue Mode

It's now possible to write multiple blocks of dialogue or narration at once, using triple-quoted strings. For example:

    e """
    This is one block of dialogue.

    And this is a second block.
    """

will create two blocks of dialogue. See Monologue Mode for more info.

There is also a new {clear} text tag that works with monologue. When the {clear} tag is part of a line by itself, it is the equivalent of the `nvl clear` statement. See NVL Monlologue Mode for more about this.

### Say-With-Attribute Change

There has been a change to the way a say-with-attributes is handled when there is not an image with the tag displaying. Previously, Ren'Py would use the attributes given in the most recent say-with-attributes statement to selected the side image to show.

Now, Ren'Py will use the provided attributes and existing attributes to resolve the side image. This makes a say-with-attributes that occurs when an image is not showing work the same way as when it is. When the attributes do not select a single side image, Ren'Py will select the image with all of the given attributes, and the most possible of the existing attributes.

The rationale for this change is to help with side images that are defined as layered images, where providing only the attributes that change makes sense.

### Updater Changes

The updater for Ren'Py itself now asks you to select the update channel each time you go to update. The purpose of this is to make it clear which channel you're updating to each time you update, so you don't accidentally update to a prerelease or nightly version after a release comes out.

As part of this, you might see the Prerelease channel missing for some updates. That's normal – unlike in previous versions, the channel only appears when there are prereleases available.

### Translations

The Ren'Py launcher, template game, and The Question have been translated into the Latin script of Malay by Muhammad Nur Hidayat Yasuyoshi.

The Korean translation has been significantly updated.

It is now possible to translate the strings used by RAPT into non-English languages.

### Other

Ren'Py can now automatically save the game upon quit, in a reliable fashion. (As compared to the previous autosave, which could fail or be cycled out.) This is controlled by the `_quit_slot` variable.

File actions (like `FileSave()`, `FileLoad()`, and `FileAction()`) can now take a slot=True argument. When this is given, the action loads a named slot, without involving the page.

The developer menu (accessed through Shift+D) can now display a screen that shows the attributes associated with displayed and hidden images.

Added `renpy.transform_text()`, a function to transform text without touching text tags or interpolation.

Buttons created using the `make_buttons` method of a Gallery object now inherit from the empty style, and not button. This prevents properties from the button style from causing problems.

The code to finish displaying text is now called from the event method, as if the mouse button was clicked. This helps prevent interaction ends when menus are up.

Displayable prefixes are supported when evaluating auto images in imagebuttons and image maps.

A bug that caused an error in an NVL-mode statement if the next statement was an NVL-mode statement with an undefined character name has been fixed.

When two ATL transforms are nested, the state from both is propagated, not just the outermost.

Ren'Py now updates dynamic images that are used in windows, bars, and frames. (And derived displayables, like buttons and imagemaps.)

An issue that caused Ren'Py to consume 100% of a core when modal True was given has been fixed.

Ren'Py now includes a copy of fribidi, rather than requiring an OS-installed version.

The new `box_wrap_spacing` allows control of the spacing between rows or columns introduced by `box_wrap`.

The `adjust_spacing` style property can now take "horizontal" and "vertical" as values, causing text spacing to be adjusted in only the specified direction.

LayerdImageProxy can now take an interpolated string.

The new `config.context_callback` is called when starting the game or entering a new context, like a menu context. It can be used to stop voice or sounds from playing when entering that context.

The `Drag()` displayable (and the screen language equivalent, `drag`) have grown a new activated property. This is callback that is called when the user first clicks the mouse on a drag. (Before it starts moving.)

## 7.0

Ren'Py 7.0 marks the completion of over a decade of development since Ren'Py 6 that brought features like ATL, Screen Language, OpenGL and DirectX acceleration, support for the Android and iOS platforms, Translation, Accessibility, and so much more.

For releases between 6.0 and 7.0, see the other entries in this changelog, and the older changelog on the Ren'Py website. The rest of this entry contains the differences between 7.0 and 6.99.14.3.

### Layered Images

A layered image is a new way of defining images for use in Ren'Py. It's intended to be used with a sprite that has been created in Photoshop or some other program as a series of layers. The layered image system can use the attributes the image was displayed with and Python conditions to determine what layers to display.

Layered images are intended to be a replacement for the use of `Composite()` and `ConditionSwitch()` to define layered images. It includes a language that makes defining such images simpler, and Ren'Py can generate portions of the definitions from appropriately named files. It also integrates better with the rest of Ren'Py, as attributes can be predicted in ways that a ConditionSwitch cannot, and layered images work with the interactive director.

### Dict Transitions

Dict Transitions makes it possible to use the with statement and certain other functions to apply transitions to one or more layers. Ren'Py will not pause for these transitions to occur. Dict transitions make it possible – and even convenient – to have a transition apply to the sprites alone while dialogue is being displayed.

### Changes

The old tutorial and old templates are no longer included with Ren'Py. They can still be used with new version of Ren'Py if copied into this or later versions.

The new `Scroll()` action makes it possible to have buttons that change the position of a viewport or the value of a bar.

The `Dissolve()`, `ImageDissolve()`, and `AlphaDissolve()` transitions now respect the alpha channels of their source displayables, as if given the `alpha=True` argument. As omitting the alpha channel is no longer an optimization, this change allows the same transitions to be used in more places.

Automatic image definitions now take place at init level 0, rather than an init level of greater than 999. This allows `renpy.has_image()` to be used in `init` blocks.

The interactive director now has a button that allows you to choose if it is displayed at the top or the bottom of the screen.

The screen language for statement now takes an index clause:

    for i index i.name in party:
        ...

When provided, it should return a unique value that can map information like button and transform state to the object it originates from.

There is now alternate ruby text, allowing two kinds of ruby text to be displayed at once (such as a translation and pronunciation guide).

The new displayable prefix system make it possible to define your own displayables that can be accessed using strings, the same way that images, image files, and solids have a string form.

Ren'Py now supports creating .zip files that have single files (such as .rpa files) that are larger than 2GB. As this requires the use of the Zip64 standard, unpacking such files may not be supported on some platforms, most notably Windows XP.

The new `renpy.get_hidden_tags()` function returns the set of tags that have attributes but or otherwise hidden, while the `renpy.get_showing_tags()` function can return a list of tags in sorted order.

Showing a movie sprite a second time will now replay the movie from the start, for consistency with ATL and other animations.

The documentation has received an editing pass, courtesy of Craig P. Donson.

### Translations

The Ren'Py tutorial and The Question now have French translations, thanks to Alexandre Tranchant.

The Japanese and Russian translations have been updated.

### Fixes

This fixes a regression that prevented screens from handling the hide or replaced events when the screen was not being shown. (This might be the case when the player is skipping through the game.)

An issue that caused the interactive director to be translated into Russian when the default (English) language was being used has been fixed.

The `Composite()`, `Crop()` and `Tile()` displayables are now actually available under their new names.

An issue that could cause Ren'Py to roll back to an incorrect place when accessing the console has been fixed. This could cause the console to display incorrect data, while in the console itself.

## 6.99.14.3

### Changes

The `AlphaMask()` displayable now places its mask inside the child displayable, in the same way that AlphaDissolve always has. This allows the mask to be created using ATL or other transforms.

Several obsolete image manipulators have been deprecated, and removed from the documentation. These are image manipulators that have been completely replaced by `Transform()`.

Several functions have been renamed, to remove a pointless Live prefix.

- LiveComposite is now `Composite()`
- LiveCrop is now `Crop()`
- LiveTile is now `Tile()`

The old names have been retained as compatibility alias.

### Fixes

This release fixes an issue where children of for statements in screens would not get their data propagated through screen update cycles. This manifested in complicated ways, such as transitions repeating and slow text refusing to work.

This release displays the newest save slot in the selected color, as intended. This applies to newly created games, older projects can update by adding to the bottom of gui.rpy:

    define gui.slot_button_text_selected_idle_color = gui.selected_color
    define gui.slot_button_text_selected_hover_color = gui.hover_color

A problem introduced in 6.99.14.2 with the the default statement not working after a rollback has been fixed. This should only ever have affected games that were updated after a save was first created.

## 6.99.14.2

### Features and Changes

The Atom text editor is now supported in Ren'Py. When it is selected, Ren'Py will download Atom, and will create a new profile with the language-renpy, renpy-dark-syntax, and renpy-light-syntax Atom plugins installed, along with a few default setting to make Ren'Py programming easier.

It is now possible to supply a baseline to image-based fonts.

When a screen in the default gui scrolls, the pageup and pagedown keys will now work to scroll it. (This only works with newly-created projects.)

The `Movie()` displayable now takes a play_callback argument, which specifies a function that is called to play a movie. This function can do things like queue up a transition movie before queuing the usual loop, making for smooth transitions.

The new `renpy.get_say_image_tag()` function makes it possible to retrieve the name of the speaking character.

ATL interpolation can now interpolate from a transform with multiple lines in it, provided none of the lines takes time to complete.

Adding the from statement to a call no longer changes the translation identifier. (Which is also used by the automatic voice code.) Since this would be a breaking change, Ren'Py also computes the old-style translation identifier and uses that if it exists.

The _choose_attributes method is called when only a single displayable can be located. This supports the AttributeImage beta (https://github.com/renpy/ai).

The new `gui.button_image_extension` variable allows button images to be .webps without changing Ren'Py itself.

### Self-Voicing

Ren'Py's self-voicing mode, which provides accessibility for blind users, has been improved:

- Selected buttons say the word "selected" after them.
- Bars say the world "bar" after them.
- Some actions have had their self-voicing information changed to better reflect how the action is used in the new GUI.
- Alt text built into Ren'Py can be translated.

While this can change some of the self-voicing output, the changes should not affect any translations that already exist.

### Fixes

An issue where a save or auto-save could rarely cause data corruption in the non-saved game has been fixed.

Python hide statements are now run in a Python function context, which makes certain constructs (like generator expressions) compile and run correctly.

Global labels now behave as described in the documentation, even when indented.

A regression with custom mouse cursors that could cause the mouse to jump around wildly has been fixed.

An issue with side images persisting after a menu was shown has been fixed.

Ren'Py no longer stores the state of displayables that are not being shown in a screen that has been replaced. (This was an issue when the first screen is re-show, and the displayables took their old state.)

The show and replace events are now always delivered to a transform in a screen. While this behavior was always intended and could occur whenever a screen was shown, previously caching could prevent some show events from being delivered.

Characters that require the alt key can be typed. (The alt key is necessary to type particular characters in European languages.)

When the Android build system fails to rename a file or directory, it will retry for 60 seconds before giving up. This is an attempt to work around antivirus software breaking Windows semantics.

## 6.99.14.1

### Image Prediction and Caching

Ren'Py now searches for the bounding box of non-transparent pixels when converting an image into a texture. When the `config.optimize_texture_bounds` variable is true (as it is by default), only the non-transparent pixels are stored in the image cache. This can massively reduce the in-memory size of certain images, such as images that correspond to mostly-transparent layers.

The `config.cache_surfaces` variable is now False by default. This halves the amount of memory required for the image cache, but may slow down multiple image manipulators applied to the same image.

The size of the image cache is now controlled by the `config.image_cache_size_mb` variable, which defaults to 300 megabytes. With the new default settings, each pixel inside the images non-transparent bounding box takes up 4 bytes of memory.

The result of these three changes is that images take up less memory in cache, meaning Ren'Py can store far more predicted images.

Ren'Py now refuses to call functions that read from disk (such as `renpy.image_size()`) when predicting images and screens, rather than risking these slow calls leading to drops in framerate.

The `ConditionSwitch()` and `ShowingSwitch()` displayables have a new predict_all parameter. When True, this causes all displayables to be predicted, not just the currently selected one. This could be used to have Ren'Py preload all emotions of a sprite.

The `renpy.start_predict()` and `renpy.stop_predict()` functions now take wildcard patterns. For example:

    $ renpy.start_predict("eileen *")

Starts predicting all images beginning with the tag eileen, while:

    $ renpy.start_predict("* beach*")

matches all images that include a beach attribute.

The F4 key now displays the image load log.

### Other Improvements

Transforms now have a new `maxsize` property, which scales images down until they fit into a bounding box.

The Python expression cache is kept when Ren'Py is reloaded, providing a slight increase in performance compared to unmarshalling it on each reload.

The traceback.txt and errors.txt files now include a date at the bottom, making it easier to determine if a file is stale.

The new `renpy.list_images()` function returns a list of all the images that have been defined.

Drag displayables now take the mouse_drop property. When true, this causes the location of the mouse pointer to be used to select a drag to drop on, rather than the drag with the maximum overlap.

The Spanish translation has been updated.

### Other Fixes

Fixes a bug where the ATL "on hide" clause didn't work.

Release the GIL when waiting for a screen flip, making tasks that run in background threads (music playback, image preloading, autosave, etc.) run much faster.

## Ren'Py 6.99.14

### Performance

Quite a bit of work has been done to improve performance, both absolute performance and apparent framerate stability.

When connected to a device with AC power, Ren'Py will attempt to draw the screen at a constant framerate. When the device is on battery, several frame will be drawn before reverting to the 5fps framerate, to ensure updates to the screen are pushed through display buffering.

Ren'Py has a number of options that control display performance, accessed through the Shift+G menu. In addition to the GL performance change described above, this allows the player to lock the framerate and accept tearing when a frame is late. A player on a slow machine might choose to prefer 30fps to an unstable framerate. If the developer expects many players will be on slow devices, a default can be chosen with:

    default preferences.gl_framerate = 30

When a frame takes too long to render (say, because an unpredicted image has to be loaded from disk), Ren'Py will attempt to use the time the frame was presented as the base time for transitions and displayables. Effectively, this means that if Ren'Py has to skip frames, it'll skip them before the first frame in a sequence, rather than between the first and second frame.

Ren'Py itself triggers garbage collection immediately after a frame is drawn, if enough objects have been created. Outside of this collection, the number of objects required to trigger the garbage collector has been raised. The thresholds are high enough that collection should not be required if the game does not create circular object references. (That is, objects that refer to each other in a loop.) Ren'Py has been changed to eliminate common sources of circular object references.

For most games, Ren'Py managed garbage collection should reduce or even eliminate frame drops caused by the garbage collector. However, it is possible to revert to the previous tuning by setting `config.manage_gc` to False.

By default, Ren'Py will remove transient screens (like say and choice) and displayables without triggering on "hide" event handlers. The process of checking for such handlers was relatively expensive, while the use of those handlers is rare. This change can be reverted by setting `config.zap_transients` to False.

Ren'Py will now cache compiled Python expressions the first time it encounters them, rather than compiling an expression each time it is encountered. This speeds up the overused ConditionSwitch displayable, along with other parts of Ren'Py. Because of this change, a game will open slowly the first time it's run under Ren'Py 6.99.14, as all of the expressions need to be compiled.

This release both increases the speed of maintaining the information required by rollback, and does so less often. This may be visible to players by Ren'Py now allowing them to roll back farther than before.

There have also been many other performance improvements that will only be visible by the increased speed. This release just includes the first round of performance improvements, while a new performance profiling framework included will allow Ren'Py developers to further improve things.

### Multiple Character Dialogue

Ren'Py now includes a system that allows multiple characters to speak dialogue at the same time. It's accessed by giving the multiple argument to consecutive say statements. For example:

    e "Ren'Py now supports multiple character dialogue." (multiple=2)
    l "About time! I've been wanting this for years!" (multiple=2)

As there is more than one way to show dialogue from multiple characters (side-by-side? top-and-bottom? one or two textboxes?), Ren'Py doesn't include support for this out of the box yet. Please see the Multiple Character Dialogue section of the documentation for the styles you'll need to define.

### GUI Preferences

Ren'Py supports a new GUI preference system that replaces the old style preference system, as it allows preferences to apply to variables in the new GUI that can be referenced from multiple styles.

This makes it possible to write:

    define gui.text_font = gui.preference("font", "DejaVuSans.ttf")

To access the preference, and:

    vbox:
        style_prefix "radio"
        label _("Font")
        textbutton _("DejaVu") action gui.SetPreference("font", "DejaVuSans.ttf")
        textbutton _("Dyslexic") action gui.SetPreference("font", "OpenDyslexic-Regular.otf")

to set it. See the section on GUI Preferences for more details.

### Tooltips

A new tooltip system has been added to Ren'Py, to replaced the one that already existed. While in the previous system, one had to write:

    default tt = Tooltip("No button selected.")

    textbutton "One.":
        action Return(1)
        hovered tt.Action("The loneliest number.")

    text tt.value

It's now possible to write:

    textbutton "One.":
        action Return(1)
        tooltip "The loneliest number."

    text GetTooltip()

This is intended to save boilerplate and make screens more readable. For more information, see the Tooltips section.

### Changes

SSL and TLS support has been added to all platforms. This allows Ren'Py games to make requests to secure web servers, perhaps in conjunction with a Python library such as requests. This support is only included in built distributions if imported at init time.

The new `im.Data()` image manipulator creates an image from compressed binary data, as might be downloaded from a web server.

The `config.loadable_callback` lets scripts inform Ren'Py about additional loadable files.

Ren'Py will attempt to diagnose problems with pickling objects during a save, and report an object that caused a pickling problem. (This is best-effort, but tends to catch common problems.)

When a viewport is given scrollbars, Ren'Py will now offer its child a large amount of space in the given direction. This prevents problems with displayables drawn at or below the visible area of a viewport.

Ren'Py now resolves the ambiguity between the `xpos` and `xalign` style properties in favor of xpos, and similarly for other cases where both more and less specific style properties are given to the same style.

Custom statements now take a label function that can return a custom label for the statement. This allows the custom statements to be jumped to or called.

The new config.gl_clear_color variable allows a creator to set the color of the letterboxes and pillarboxes used when the screen is not filled.

Drag displayables (part of the drag and drop system) now support a bottom method, that can be used to lower the drag to the bottom of its drg group.

The `config.cache_surfaces` variable, added in the last release, has been documented. Setting this variable to False can reduce Ren'Py's memory consumption, at the cost of of slowing down images used by multiple image manipulators. (Which should be a rare case in modern Ren'Py.)

Variable and field munging (which change the name of a variable that begins with __ to a file-specific value) now work inside string substitutions.

Viewports and vpgrids now support the pagekeys property, which allows one to use the pageup and pagedown keys to scroll the viewport. The arrowkeys property is now documented.

RAPT now compiles Java code using a source and target version of 1.6, which allows it to be built on modern JDKs.

### Fixes

An issue where screens could display incorrectly when compiled at different times has been fixed. This could only show up under certain circumstances.

- The project has screens in multiple files.
- The files were compiled at different times. (This can never be the case for a released game, since all files are recompiled at the same time when building distributions.)

After upgrading to this release, the problem can be fixed by pressing "Force Recompile" in the launcher. This can be done for any game in development, but isn't necessary for released games.

There have been several improvements to the interactive director, allowing it to work in more circumstances.

A race condition that could cause Ren'Py to lock up (causing a blank screen to be displayed) on Android and iOS has been fixed. This was introduced in 6.99.13.

In 6.99.13, a race condition caused Ren'Py to infrequently skip movie playback entirely.

Ren'Py now supports the AltGr key.

Ren'Py now limits the amount of console output it logs, to prevent print statements from consuming memory if the console is never displayed.

## Ren'Py 6.99.13

### Tutorial and The Question

This release includes updated versions of the Tutorial game and "The Question", the example game that's bundled with Ren'Py.

The Tutorial game has been largely rewritten, and is now structured as a pair lectures, the first covering the creation of a basic visual novel in Ren'Py, and the second covering in-depth topics needed to create more advanced games. The Tutorial has also lost content that is less relevant to modern Ren'Py, focusing in on the features that are the best practice to use in new games.

The Tutorial now has over 250 examples, that can now be copied out of the tutorial and into your own projects.

"The Question" has been rewritten with a new script by Lore, one that is more appropriate for educational use than the original. It's also been updated with new background, and to demonstrate best practices when writing Ren'Py scripts.

Both games have been modernized with high-definition widescreen graphics and use of the new default Ren'Py GUI.

Right now, the old tutorial is still distributed with Ren'Py, and is used if when a translation is present for the old tutorial but not the new tutorial.

### Interactive Director

Ren'Py now ships with an built in interactive director tool. This tool makes it possible to add the scene, show, hide, with, play, queue, stop, and voice statements to Ren'Py from inside an under-development visual novel, without having to change to a text editor and reload the project. The interactive director can be accessed by pressing the D key (without Shift) inside an unreleased game.

The interactive director had been distributed outside of Ren'Py, with a license that made it free for noncommercial use. It's now part of Ren'Py, and has the same license as the rest of Ren'Py, which allows for both commercial and noncommercial use.

### New GUI

A few changes have been made to the new GUI. Buttons have been brightened and their text shrunk. Bars have been reduced in height somewhat. The intent is to provide more room in menus, especially for game-specific preferences on the preferences screen.

For newly-generated games, it is now possible to customize the location and look of the namebox (the frame containing a character's name) on a character by character basis. This is done by giving properties prefixed with namebox to the Character. For example, the namebox_background property changes the background of a namebox.

### Raspberry Pi

Ren'Py now comes with experimental support for the Raspberry Pi platform.

The Raspberry Pi port is similar to the Android and iOS ports, both in its limitations and how it's meant to run games rather than develop them. As with all platforms, creators developing for the Raspberry Pi need to account for the resources available to them and design their games accordingly.

That being said, The Question and the new Tutorial both run on a Raspberry Pi 3 computer costing $35.

### Hyperlinks

Hyperlinks created with the `{a}` text tag now support jumping and calling labels. A tag of the form `{a=jump:label}` jumps to the label, while one of the form `{a=call:label}` ends the current statement and calls a label. There are also `{a=show:screen}` and `{a=showmenu:screen}`, which show screens in-game and in a menu context, respectively.

The new `config.hyperlink_protocol` variable determines the default protocol for a hyperlink that has none. For example, if it's "jump", then `{a=mylabel}` is equivalent to `{a=jump:mylabel}`.

The new `config.hyperlink_handlers` variable is a dictionary mapping protocols to functions, which can be used to add creator-defined protocol handlers.

The size of a hyperlink is now inherited from the size of the enclosing text. This makes hyperlinks work within text of a non-default size.

### Say with Arguments

The Ren'Py say statement now supports being passed arguments, which are placed in parenthesis after the text to be spoken. For example:

    e "Hey!" (what_size=36, what_color="#ffeeee")

These arguments are first passed to config.say_argument_callback, and then are passed to the character. The default implemention (in `Character()`) creates a new character with the passed arguments, and uses that to display the text.

One place this is handy is with jump hyperlinks and the new advance argument to Character, which prevents text from being advanced directly. It's now possible to write:

    e "Would you like to go {a=jump:living_room}west{/a} or {a=jump:kitchen}north{/a}?" (advance=False)

Which pauses execution until the player clicks on a hyperlink.

### Translations

The launcher and default project have been translated into French, courtesy of Alexandre Tranchant.

The launcher and default project have been translated into Brazilian Portugese, courtesy of MrStalker.

The Indonesian and Simplified Chinese translations have been updated.

### Other

The new `config.preload_fonts` variable can take a list of TrueType or opentype font files to preload at Ren'Py stop. This prevents Ren'Py from pausing animations when opening a new font.

Ren'Py now opens audio files in a second thread of execution. This prevents animations from pausing when an audio file is played or loops from slow or busy disks.

The new `renpy.get_attributes()` function can be called to retrieve the attributes associated with an image tag on a layer.

When a file named projects.txt is present in the projects directory, it is expected to contain a list of full paths to directories, one per line. Those paths are treated as projects and displayed in the launcher.

There is a new `Call()` action, that terminates the current statement and calls a label. The Call action and the `renpy.call()` function take a new from_current parameter, which causes them to return to the start of the current statement, which could be used (very carefully) to call an aside before returning to the main story.

The preference variables have been given their own page in the documentation, one that clarifies it's better to use the default statement to directly set the default value of a preference variable.

The "steam" package has been renamed to "market", reflecting that it will work just as well with other markets.

In ATL, interpolation statement with a warper now last one frame. This means that the `pause 0` statement now completes after one frame, rather than instantaneously, allowing for single-frame animations. Please do not use this to include subliminal messages in your game.

The show later at statement now persists transform state, much like other statements that involve a transform. This shouldn't change much, but opens the possibility of layer transforms that involve randomness.

The {nw} text tag now waits for voice and self-voicing to complete before allowing text to advance.

The grid and vpgrid displayables now support the `xspacing` and `yspacing` style properties, which set the spacing in the horizontal and vertical directions independently.

The `config.character_id_prefixes` variables contains a list of prefixes that are used by a Character to style displayables. Similar to what, who, and window, if "logo" is in this variable, properties like logo_xpos and logo_background will cause the logo and background properties to be set on the displayable with id "logo".

Ren'Py now supports the Python print function. Output printed with the print function will go to the log.txt file and the Ren'Py console, which can be accessed by typing Shift+O.

It is now possible to customize what happens when the Ignore button is clicked on the exception reporting screen. This is done using the `_ignore_action` variable, which can be set to a Jump action that might clean up after the player and start a turn again.

The Ren'Py set type now inherits from the Python set type, rather than the obsolete sets.Set type. Set literals are now properly wrapped so that the set participates in rollback.

The list of NVL-mode text blocks is cleared when the language is changed. This prevents Ren'Py from showing a mix of text languages, so of which may be nonsense in the current font.

The "text speed" and "auto-forward time" `Preference()` values now take a range argument, allowing the creator to specify a range.

The new `renpy.filter_text_tags()` function can be used to filter text tags in a string. It's used to remove text tags in the history screen of the default GUI.

In screen language, a block given to a use statement can now contain a has statement.

When set to "auto", the `config.developer` variable is set to True or False during the init phase. Previously, it was always true during the init phase, and would only change once init is over.

When a position property is supplied to a viewport or vpgrid with vertical, horizontal, or both kinds of scrollbars, the position property is passed to the side container that holds the viewport and scrollbars. This makes it possible to position viewports and vpgrids using the same syntax as other displayables.

Itch.io support has been improved. A problem that prevented uploading to itch.io from Windows has been fixed. The table of channels to upload to has been updated, and now takes advantage of butlers's new support for uploading Linux bz2 and Android apk files.

Creator-defined statements can run a function at init time, in addition to the function run when the statement executes normally. Creator-defined statements can take a block of Ren'Py script that is parsed and can be jumped to.

The time it takes to parse Ren'Py scripts has been dramatically reduced.

A missing _menu variable could cause Ren'Py's init phase error handling to not report a relevant error. This has been fixed.

The PlayCharacterVoice action can now mark a button as selected while the character voice is playing.

The new `renpy.add_python_directory()` function provides a way to add subdirectories of the game directory to the Python path.

The Ren'Py documentation has been edited to remove the use of the word "code", and replace it with less cryptic terminology.

It is now possible to support Ren'Py via Patreon. A link to a page with sponsor information is in the launcher by default. It can be hidden in the launcher preferences.

## Ren'Py 6.99.12.4

### Console

The Ren'Py console has been updated to match the neutral Ren'Py style, and to add a number of new features:

- The console is now available during exception handling. (As always, it accesses the global scope.)
- The console history is kept as part of persistent data.
- Watched variables are stored as part of save files, which means that the watch is restored when the game is (automatically or manually) reloaded.

### Other

A regression (bug) introduced in version 6.99.4 that prevented the default input screen (and hence renpy.input) from working has been fixed.

A memory alignment issue that could result in a SIGBUS crash on ARM-based Android devices when playing video has been fixed.

Hide and replace animations are removed from Ren'Py when a rollback or load occurs. This prevents hide animations from playing when a displayable has not been showing.

Auto-forward mode is disabled when self-voicing is enabled, to prevent the game from automatically advancing and making self-voicing information obsolete.

When running with Steam support enabled, Ren'Py will query the Steam overlay and redraw the screen when Steam asks for an update. (This should increase the FPS of the Steam overlay.)

Fadeouts now span looping audio by default. Previously, a fadeout would come to a stop at the end of an audio track.

Right-to-left (Arabic and Hebrew) language support has been enabled on the iOS platform.

A bug in render clipping has been fixed. This generally manifested as 1-pixel overlaps or open spaces when drawing frames and bars.

The Arabic, Indonesian, and Russian language translations have been updated.

## Ren'Py 6.99.12.3

### GUI

It is now possible to systematically customize the look of different kinds of text in Ren'Py. For example, one can now choose different sizes for name, dialogue, interface, label and prompt text.

All text properties are now available through the gui system. For example, gui.text_outlines can be used to make text outlined by default, while gui.name_text_bold can be used to make character names bold.

To allow for the above two changes, some of the gui variable names have been renamed in a more systematic manner. For example, gui.default_font has been renamed gui.text_font, while gui.name_font has become gui.name_text_font.

It is now possible to outline gui text using variables like gui.text_outlines and gui.interface_text_outlines.

Due to the design of the new GUI, the changes described in this section will only take effect when a new game is created, or a game's GUI is updated.

### Translations

The Russian translation has been updated and modernized, thanks to Ria-kon and Project Gardares.

The Italian translation has been updated and modernized, thanks to Gas.

### Other

A crash on video playback on Android and iOS has been fixed.

The default encoding for non-Unicode strings in Ren'Py has been changed to the filesystem encoding. This should address a series of encoding issues that have occured on non-ascii systems since 6.99.12.

Ren'Py will no longer search for system-installed fonts when in developer mode.

In some cases, Ren'Py duplicates displayables to ensure that displayable state is not aliased. (For example, a transform is duplicated when it is show, so that when it is shown a second time it will not retain its state.) This copying has been optimized so it only occurs when necessary.

The `config.replace_text` callback now runs even if no custom text tags have been defined.

An issue where text could be clipped when it was not necessary has been fixed.

Viewports are now draggable when other focusable things are on the screen.

This release adds more functions to support the Interactive Director, and basic support for attribute images.

## Ren'Py 6.99.12

### Macintosh Support

This release includes a number of changes to support macOS Sierra. These include:

- The Macintosh application produced by Ren'Py is now read-only by default. Save files will be placed in a system-global directory, while screenshots will be written to the Desktop.
- The organization of the Mac application has been changed to allow the application to be code-signed.
- When run on a Macintosh with Xcode installed and the `build.mac_identity` variable set properly, Ren'Py will use the codesign tool to sign the package before archiving it.
- When run on a Macintosh, Ren'Py will create a .dmg file containing the application. When Xcode is installed and `build.mac_identity` is set, the package will be signed.

The result of this is that, when a creator has a Macintosh computer and a (free) Developer ID Application certificate, it is possible to create distribute downloadable Ren'Py games that satisfy Gatekeeper and Gatekeeper Path Randomization.

Since it is no longer possible to make a single distribution that runs on all desktop platforms, the all (Windows, Mac, and Linux) package type has been removed. It's been replace with a pc package type that supports Windows and Linux, and the existing mac type that supports macOS. (There is a new steam package type to help with app store bundles, but that's not recommended for distribution to end users, since it won't work with macOS Sierra.)

The launcher has been modified so it can launch games created using older versions of Ren'Py, even under Sierra. This can be done by placing the game inside the Ren'Py directory, starting Ren'Py, choosing the game in the launcher, and choosing "Launch Project".

### Translation Changes

Support generating projects in non-English languages has been improved. When a new project is created, it includes translations of the interface strings into the project's language, allowing the translation of text presented to the player by Ren'Py.

There is now a single place for translating Ren'Py – translating the launcher also now translates the comments of a generated game. The process of translating Ren'Py (the launcher and the GUI) is now documented on the Translating Ren'py page. This page also suggests a logical order in which strings should be translated.

Functions have been added for selecting an alternate font, changing defines (such a text size), and copying files into a generated project, based on the translation.

Translate python blocks are now executed before regular style statements (translate style statements are executed after both). This change was intended for and documented 6.99.11, but the implementation was flawed, so a corrected implementation is used now.

### Python Changes

Ren'Py will now compile Python code as if:

    from __future__ import absolute_imports, print_function, unicode_literals

was true. If compilation fails, it will then re-compile the code without these settings. This is intended to allow new code to be written that will be compatible with a future Python 3-based Ren'Py.

This should have minimal impact to existing code. The one case where it could be a problem is if a character string is used to encode binary data, in which case a binary string (b"string") should be explictly used.

### Other Changes and Fixes

Dynamic images are now copied before a transition occurs. This makes it possible to use dynamic variables and the with statement together, to transition from one value of the variable to another.

Ren'Py now supports the WEBP image format.

This version of Ren'Py includes fixes to support the interactive director tool.

The iOS app store is queried for the price of available in-app purchases when the game starts. This allows the price of such purchases to be presented without the game blocking.

The dialog window that is presented when accessing the iOS app store can now be translated.

It is now possible to pass positional arguments to a game menu screen via ShowMenu.

An issue introduced in 6.99.11 that could cause ATL Transforms to repeat has been fixed.

A regression with first_fit that caused it to not work has been rectified.

An issue that cause ongoing sound playback to skip while a new sound sample was loaded has been eliminated.

Support for the itch.io butler tool on Windows has been fixed.

Hiding the interface no longer stops voice playback.

The new `DisableAllInputValues()` action can disable input values all at once.

The mousewheel property of viewports and vpgrids supports a new value, "change". When this value is given, the viewport only consumes mouse events when the event would change the viewport. The motivating use of this is a history window that dismisses when it reaches the bottom.

Namespaces may now contain dots in their names.

The new `QueueEvent()` action queues a key binding event when activated. This can be used to activate many bindings, including the new 'dismiss_unfocused' binding, which dismisses the current dialogue even if it is not focused.

## Ren'Py 6.99.11

### New In-Game GUI

Ren'Py ships with a new default GUI. This system, used in-game to customize the main menu, game menu, and in-game screens, replaces the old themes and screens.rpy system with a new system that's intended to be an improvement for every creator:

- For new creators, the new GUI is intended to look attractive (if generic) out of the box. It is adaptable to a choice of sizes, and supports games with light and dark backgrounds.
- Intermediate creators will be able to more easily customize the new GUI, without having to to work with screens and styles directly. It's now possible to completely re-theme the GUI by changing variables in the `gui` namespace, and editing template images.
- Advanced creators will be able to replace the new gui entirely, either piece by piece or wholesale. The new gui infrastructure resets all styles to sensible defaults, making it easier to apply customization.

There is also a gui customization guide, consisting of over 5,000 words of documentation and code, and 40 images, that explains how to change the look of the GUI.

In addition, the new GUI adds support for a number of new features. These features are generally implemented in a way that custom GUIs can take advantage of. Highlights include:

- The GUI defaults to supporting 16:9 widescreen resolutions.
- The new GUI is intended to support PCs and mobile devices in landscape mode. Where appropriate, it conforms to iOS and Android interface guidelines.
- The new GUI includes native support for a history or readback screen.
- The new GUI includes support for assigning names to file pages, allowing a certain amount of organization to be applied to files.
- The NVL and choice screens are now given lists of objects as parameters, instead of tuples. (The objects also function as tuples, for compatibility with old code.)
- The yesno_prompt screen has been renamed to confirm.
- Ren'Py supports the use of a ctc screen to display the click-to-continue indicator.

### Improved Platform Support

There have been a number of fixes to Ren'Py's support for various platforms.

Windows HighDPI mode is detected properly when displaying the presplash.

Android The Android build system has undergone a rewrite, adding support for x86, while retaining and modernizing support for ARM devices. RAPT now included many dependencies, fixing Android build problems.

Ren'Py now supports immersive mode on Android's 4.4+. Immersive mode hides the system UI, including the navigation bar, allowing Ren'Py to take up the entire screen.

Chrome OS Ren'Py now support ChromeOS by running the Android APKs via the Android Runtime for Chrome tool.

### Style Prefix Support

Ren'Py now supports the use of a prefix_ substitution with style properties. Where previously, one was required to write:

    style button:
        insensitive_background "insensitive_button.png"
        idle_background "idle_button.png"
        hover_background "hover_button.png"
        selected_idle_background "selected_idle_button.png"
        selected_hover_background "selected_hover_button.png"

one can now write:

    style button:
        background "[prefix_]button.png"

This searches through prefixes in a manner similar to the way styles do. When looking for a selected_idle_background, Ren'Py will search for selected_idle_background.png, idle_background.png, and background.png

### Style Properties

Windows and buttons can take the `padding` and `margin` style properties. These properties can take a tuple that gives the margin and padding on all four sides.

The new `base_bar` style property sets the left and right (or top and bottom) bars to the same value. It can be to set the background of a slider or scrollbar the uses a thumb image.

The `xfit` and `yfit` style properties can be given to the fixed screen language statement and `Fixed()` displayable. When a fit property is true, the fixed shrinks in the given axis to fit all child displayables.

Buttons and Windows now fully respect the `xmaximum` and `ymaximum` style properties.

There is now a `offset` style property, which sets the `xoffset` and `yoffset` properties to the first and second components of a tuple.

### Translate and Style Statement Order Changes

The `config.defer_styles` variable has been added to determine if style execution should be deferred, as described below. If config.defer_styles is true when style evaluation would have occurred, that style is put on a deferred list. The `gui.init()` function called by the new GUI sets this variable to true.

To facilitate translations customizing the fonts of the new GUI, the order of execution of `translate python`, `style` and `translate style` statements has been changed. When the game starts (after all statements have run), or when the language changes, the following steps occur.

1. The `gui` named store is cleaned to its state at the end if init. (This is the store that all variables defined with gui.`name` live in.)
2. All `translate` language `python` statements are run, where language is the current language.
3. All deferred `style` statements are run.
4. All `translate` language `style` statement are run, where language is the current language. (If not None.)
5. The callbacks in `config.change_language_callbacks` are called.

Ren'Py can be made to return to the old behavior (in which only `translate` language `style`, `translate` language `python`, and callbacks are executed) by setting `config.new_translate_order` to False.

### Local Labels

Ren'Py now supports labels scoped to inside another label. It's possible to write:

    label day1:

        menu:
            "Should I sleep in?"

            "Yes":
                jump .afternoon

            "No":
                jump .morning

    label .morning:

        "It's the morning."

    label .afternoon:

        "It's the afternoon."

In this code, the .morning and .afternoon labels can be jumped to directly from code that is immediately after the day1 label, or by jumping to day1.morning or day1.afternoon from other code.

### Transforms

Transforms now support `xtile` and `ytile` transform properties. These properties allow the underlying displayable to be tiled multiple times.

Transforms now support `xpan` and `ypan` transform properties. These properties take an angle (between 0 and 360 degrees, but angles outside that are clamped to that range). The angle is used to pan the image horizontally or vertically by that amount. This makes it possible to simulate a 360 degree panoramic image.

### Translations

When generating a new project, all of the strings in the new game are translated using translations taken from the launcher project.

A Vietnamese translation of the launcher and tutorial have been added to Ren'Py. Thanks to Thuong Nguyen Huu for contributing it.

A Indonesian translation of the launcher and default project has been added to Ren'Py. Thanks to Pratomo Asta Nugraha for contributing it.

Ren'Py can now automatically generate a piglatin translation for test purposes.

### Other

The new nvl_narrator character can be used to as the narrator while in NVL-mode.

The define statement can be used to define variables that are also Ren'Py keywords. For example, "define menu = nvl_menu" now works.

A `Frame()` can now be given a `Borders()` object, that encapsulates the borders of a Frame into a single object. Borders objects also have a padding field that can be passed into the new `padding` style property.

Buttons, textbuttons, imagebuttons, and hotspots now take selected and sensitive properties that directly control if the button is selected or sensitive.

Buttons, textbuttons, imagebuttons, and hotspots take keysym and alternate_keysym bindings, that make it possible to assign keys to the buttons. When the given key is pressed, the action or alternate action is run.

Ren'Py now supports extracting string translations from one project and applying them to another project. The translations can also be applied in reverse order, turning an English -> Russian interface translation into a Russian -> English translation.

Viewports and vpgrids now support an arrowkeys property, that makes the viewport scrollable using arrow keys and a controller d-pad.

Viewports and vpgrids now support horizontal scrolling via the mouse wheel, by setting their mousewheel parameter to "horizontal".

InputValues now take a returnable property, that causes their value to be returned when enter is pressed.

Ren'Py support a `renpy.get_refresh_rate()` function, which returns the referesh rate of the primary screen. This allows games using nearest neighbor mode to move at a whole-pixel rate – just like a Commodore 64 did.

Ren'Py can now automatically upload your game to itch.io, if `build.itch_project` is set.

The `config.after_load_callbacks` can be given callback functions to run once a load has been completed.

The `config.tts_voice` variable has been added, to allow for a platform-specific choice of text-to-speech voice to use.

`config.quit_action` now defaults to `Quit()`, which will display the quit prompt over the in-game interface.

The `config.afm_voice_delay` has been added, and allows a pause to occur after the voice finishes in auto-forward mode, before advancing the text.

The new "video sprites" `Preference()` makes it possible to disable video sprites (and use fallback images) on hardware too slow to support them.

The progress indicator now can be accessed using the F2 key, in addition to the Shift+Alt+P binding. The latter binding has been fixed to work reliably on PC platforms.

## Ren'Py 6.99.10

### Fixes

This release contains multiple fixes to regressions that affected some, but not all, players and creators. Upgrading from Ren'Py 6.99.9 is strongly recommended.

- Problems opening a DirectInput gamepad or joystick in exclusive mode could prevent Ren'Py from starting.
- A failure to preload a library prevented Ren'Py from starting on some Android devices.

### Translation

This release features a new Greek translation of the launcher, contributed by George Economidis.

### Other Changes

The input widget now accepts input values Input values allow an input to directly update a variable, field, or dict, and also make it possible to have multiple inputs displayed at the same time.

The new `key_event` style property controls when events are passed to the children of a button. This may need to be set to true when a button controls the focus of an input value.

The new vpgrid widget combines aspects of a viewport and a grid with more efficient rendering. Given the requirement that all elements of the grid are the same size, only elements that are visible to the player will be rendered.

The `yesno_prompt` screen has been renamed to `confirm`, with the old name being retained as an alias when a confirm screen is not present.

A screen named `help` will now be used by the `Help()` action if it exists.

The `audio` channel has been changed to play only one sound at a time while skipping through the game, to prevent a cacophony of sound while the player skips.

The new init offset statement makes it possible to apply a priority offset to statements that run at init time, including `init`, `init python`, `define`, `default`, `style`, and `transform`.

The default init priority of `image` statements has been changed from 990 to 500, so that larger offsets can be used with init offset without sending their init priority out of the range -999 to 999.

The style_group ui property has been renamed to style_prefix, to make its function more apparent. (The old name still works, for compatibility with older code.) A new style_suffix ui property has been added, allowing the same screen code to be reused with multiple style prefixes.

The style_prefix ui property may now be applied to transcluded blocks.

The new `GamepadExists()` function and `GamepadCalibrate()` action expose gamepad detection and calibration to screen language.

The time required to take a screenshot has been reduced by decreasing the compression level used.

The Android SDK downloaded by Ren'Py has been updated to r24.4.1.

## Ren'Py 6.99.9

Ren'Py's audio and movie playback support has been completely rewritten, allowing for the addition of many features that would not have been possible without this rewrite. These include:

- Partial playback of audio files, using a concise notation. This allows the creator to specify start and end points, and a loop point at which playback continues on the second and later iterations. A similar notation can be used to queue silence.
- A new default channel named `audio` has been added. Unlike the `sound` channel, the audio channel supports playing back multiple audio files simultaneously (limited by system performance).
- The new `PauseAudio()` action can pause and unpause audio playback as required.
- The new `renpy.music.get_pos()` and `renpy.music.get_duration()` functions return the curent playback position and total duration of an audio channel, respectively. `AudioPositionValue()` can be used to display these as the value of an animated bar.
- Movie playback now supports playing multiple movies at the same time, provided all movies share the same framreate, and limited by system performance.
- Movies now loop seamlessly at the end of playback.
- Ren'Py now supports movie sprites, which are sprites backed by two movies, one containing color information and the other containing the alpha channel. Movie sprites are a superior alternative to animated gifs, as modern movie formats provided greater color depth and far superior compression. Movie sprites are supported on all platforms, including mobile platforms, subject to system performance.
- Movies are no longer required to contain an audio track for synchonization.
- It is now possible to play back a movie file on an audio channel, in which case only the audio track is played.

The `play` and `queue` statements now evaluate filename expressions in the audio namespace, which makes it possible to alias a short name to an audio file.

The default audio sample rate has been increased to 48 kilohertz, which should produce a slight increase in audio quality.

Audio and movie playback support now uses ffmpeg 3.0, and support for the VP9 video and Opus audio codecs has been added to the default distributions. The Opus codec can automatically adjust to speech and music, and should be considered by all creators.

### Bug Fixes

A bug has been fixed that caused fullscreen windows to be displayed at the wrong side on the Microsoft Windows platform when system-wide DPI scaling is enabled.

The Drag.snap animation has been fixed.

### Other

The new `config.speaking_attribute` variable can be used to automatically apply an attribute to an image when a character starts speaking, and to remove that attribute when the

Say statements with image attributes now respect `config.tag_layer`.

This release includes experimental support for having an Android package be converted into a Chrome application using the ARC welder tool.

Unarchived directories are now a documented format that can be used when building packages.

Edgescrolling stops when the mouse leaves a viewport.

It is now possible to translate the prompts that occur when self-voicing is enabled. A self-voicing debug mode can be accessed by typing Shift+Alt+D.

The `Preference()` action can now adjust the volume of non-standard mixers.

There is now a new {alpha} text tag, which can control the alpha channel of text on a character-by-character basis.

Images that are included using the {image} text tag are now aligned using the usual placement rules. (That is, ypos, yoffset, and yanchor now work if given when defining the image.)

The `EndReplay()` action now takes a confirm argument, which asks the player if they want to end the replay.

The new `renpy.run()` function provides a documented way to run an action or list of actions.

The sharpness of vertically-oriented text has been improved.

The `adjust_spacing` style property is now avialable through screen language.

The confirm argument of the `Quit()` action now defaults to None, which prompts the player to confirm a quit if and only if the player is not at the main menu.

A new "rollback side" `Preference()` allows Ren'Py to roll back when the user touches a side of the screen. By default, this is the left side on mobile platforms, and disabled on the dektop.

The `config.developer` now defaults to "auto". When set to auto, config.developer will be true during development, and false once the game is being distributed.

## Ren'Py 6.99.8

### Tags, Layers, and Transforms

The new `config.tag_layer` variable makes it possible to specify the default layer used by an image on a per image tag basis. This makes it possible to place an image on its own layer without having to use onlayer. The new `config.default_tag_layer` variable specifies the default layer for unknown tags.

The new `renpy.add_layer()` function provides as way to add a new layer above or below the existing layers, if and only if the layer does not already exist.

The new `config.tag_transform` variable makes it possible to specify a default transform (or list of transforms) to use when a transform is not provided as part of a show or scene statement.

The new `config.tag_zorder` makes it possible to specify a default zorder that's used for a tag when no other zorder is used.

### Easing Functions

Thanks to Nyaatrap, Ren'Py now supports Robert Penner's easing functions in ATL. These functions speed up and slow down interpolations (and in some cases, can cause interpolations to overshoot their targets), in order to provide more pleasing and natural motion.

The new easing functions are documented in the Warpers section.

### Side Images

New-style side image functionality (using images with the side tag) has been overhauled. It's now possible to apply an ATL transform, and hence a transition, whenever the side image changes. Different transforms can be used in the case where the character changes and the case where it stays the same.

See the Side Images section for complete documentation.

### PushMove Transitions

A new type of transition - `PushMove()` - has been added to Ren'Py, along with the `pushright` (or pushleft, pushtop, pushbottom)

### Other

Fixed a major bug where Ren'Py would put an extra space at the end of each text block. This could change the layout of text (and hence other portions of the interface.) The fix reverts the change that added the space, causing it to be smaller than in 6.99.7 (but the same size as 6.99.6 and before.)

Ren'Py now supports HighDPI ("retina") displays on the Windows platform, displaying text at the native screen resolution.

Ren'Py properly maximizes on most desktop platforms. (Everything Windows 7 and below, which have a start orb that can overlap the Ren'Py window.)

Added the `renpy.is_start_interact()`, which can be called in a per_interact method to determine if this is the first pass through an interaction (as opposed to a restarted interaction).

The new `renpy.maximum_framerate()` function increases the framerate Ren'Py draws at for a given period of time. Ren'Py's Steam support uses this to ensure the Steam overlay animates smoothly.

It's now possible to use the `config.default_music_volume`, `config.default_sfx_volume`, and `config.default_voice_volume` variables to set the default values of the various mixers.

The new `config.overlay_screens` variable takes a list of screens that are displayed whenever a pre-screens overlay would be displayed, and hidden otherwise. This makes it easy to have a screen as a permanent part of the in-game interface, even if the game can be entered from multiple places (like a Replay).

Ren'Py now clears focus (causing unhover events to trigger) when the mouse leaves the game window.

The hbox and vbox displayables now support the `xminimum` and `yminimum` style properties (and hence, `xsize`, `ysize`, `xysize`, and `area` properties.)

The new `PlayCharacterVoice()` action makes it possible to play a sample of a character's voice at that character's voice volume level.

The Extract Dialogue screen now includes a number of additional options.

The Traditional Chinese translation has been updated.

## Ren'Py 6.99.7

### Dynamic Images

Dynamic images have been added to Ren'Py. It's now possible to write code like:

    image eileen happy = "eileen [outfit] happy"

This code creates a displayable that interpolates the value of the `output` variable at least once per interaction. The interpolated string is then used to find another displayable to use.

Dynamic images can be used anywhere a displayable is expected, and the string can be an string that resolves to a displayable. One possible use might be to replace boring and repetitive condition switches in dress-up games with code like:

    image eileen dressup = LiveComposite(
        (300, 600),
        (0, 0), "eileen_base.png",
        (0, 0), "eileen_top_[top].png",
        (0, 0), "eileen_bottom_[bottom].png",
        (0, 0), "eileen_accessory_[accessory].png",
        )

Dynamic image can be used in a screen language add statement:

    for item in inventory:
        add "store_[item].png"

When so used, the variables are looked up in both the screen and global scopes.

### Define Improvements

The define statement can now be used to define config and persistent variables. The code:

    define config.screen_width = 1280
    define config.screen_height = 720

Now works as expected. Persistent variables work in an idiosyncratic way, as the code:

    define persistent.unlocked_endings = [ ]

Will only set the unlocked_endings variable if it has not already been set.

### Android/iOS

The android SELECT key – present on remote controls – is now supported for advancing text and selecting buttons, bars, etc. This means most TV-based android consoles should be supported.

Direct support for the OUYA console has been dropped. The console should still be supported as a general TV-based android console.

The new `config.save_on_mobile_background` and `config.quit_on_mobile_background` make it possible to adopt various strategies to deal with an Android or iOS app losing focus.

To help apps comply with an Apple policy on the purchase of money cheats, consumable in-app purchases have been added for iOS only.

### Other

Unknown gamepads can be calibrated from the Shift+G menu.

The new `config.replace_text` callback makes it possible to replace text with other text. For example, one can replace multiple dashes with en-dash or em-dash characters.

If a screen named `skip_indicator` is present, it will be displayed instead of the default skip indicator.

In the launcher, pressing F5 will launch the current project.

Skipping is now disabled when leaving a Replay.

Creator-defined statements can now return statements to be predicted.

The Finnish and Traditional Chinese translations have been updated.

The new `adjust_spacing` style property has been added. It controls if the spacing of drawable-resolution text is adjusted to match the spacing of viewable-resolution text. Setting this to False can prevent kerning from changing after extend, but requires the GUI be designed to adjust to the changing text size. To prevent obvious artifacts, this is set to False for input text.

The following bugs have been fixed:

- A problem with script backups when the user has a non-ASCII username.
- If a screen was predicted with multiple arguments, that screen would only be predicted once for the purpose of image prediction.
- On Mac OS X, if the Ren'Py window was covered or offscreen, VSYNC would fail and CPU usage would rise to 100%. (Ren'Py now detects failed VSYNC and limits its own framerate.)
- Subsurfacing a clipped surface would not work, manifesting in incorrect rendering of scrollbars in several of the default themes.
- It was hard to pick a theme in the launcher.
- When a window was scaled, hyperlinks would react to the mouse in incorrect positions.
- Window show now used narrator to render the empty window. It also had problems with characters defined in the character namespace.
- Newlines surrounding certain text tags would not be rendered.
- Underlines could have small spaces in them when the window was scaled.
- Problems with the software renderer on various hardware.
- A problem where lint would not recognize an image name with reordered attributes in the scene statement.
- A crash when merging achievements from multiple instances of a game.
- Having multiple text blocks, all with at least one hyperlink, could cause hyperlinks to be higlighted incorrectly.
- Various documentation problems.

## Ren'Py 6.99.6

### HighDPI/Retina

Support for HighDPI/Retina displays has been added to Ren'Py. This support is automatically used when running on iOS or Mac OS X systems that have a retina display.

On all platforms, Ren'Py now renders text at the display resolution, rather than the resolution the game was set to. The result is that text remains sharp even when upscaled significantly. Creators should be aware that due to variability in character size and kerning, this can cause changes in text layout and word wrap as the window is scaled.

To get the greatest benefit from these changes, the included copy of DejaVuSans has been updated to version 2.35, and the DejaVuSans-Bold font has been added. The bold font will automatically be used when a bold version of DejaVuSans.ttf is requested.

### Gamepad

Ren'Py now uses the SDL2 controller API to support gamepads. This API provides a standardized mapping of controller buttons to something similar to an Xbox controller.

### Backups

Ren'Py will now automatically back up .rpy files that are part of changed games. These backups will be placed in the same system-specific location that save files are placed.

### Other Improvements

A new `achievement.sync()` function and `achievement.Sync` action have been added to Ren'Py. These synchronize achivements between local storage and other backends, such as Steam.

A major bug in scanning archive files has been fixed. This bug often manifested as an archived images/ directory not being scanned some, but potentially not all, of the time. We strongly recommend upgrading from 6.99.5 if your game uses and archives the images/ directory.

If a file is not found in the game directory, Ren'Py will search the images/ directory for that file. This behavior is controlled by the `config.search_path` variable.

Screens now take the style_group property, which was previously only allowed on displayable statements.

Screen language statements now take arguments and properties properties, which allows statement to be passed a list of additional positional arguments and a dict of additional properties, respectively.

The new `Color` class allows conversion between color spaces and other color-theory operations.

Ren'Py now supports a game/python-packages directory, which can be used with pure-python packages installed via pip. See the new First and Third-Party Python Modules and Packages documentation for more details.

Renios now supports compiling for 32-bit simulators (for the iPhone 4 and 5).

The Korean and Russian translations have been improved.

A pause will now automatically end when auto-forward mode is enabled.

## Ren'Py 6.99.5

### Startup

Much work has been done to reduce Ren'Py's startup time, especially on mobile platforms such as Android and iOS. This was largely accomplished by caching the results of transforms, analyses, and code compilation so less work is done when the game is unchanged. To take full advantage of this, perform a 'Full Recompile' of your project from the front screen of the Ren'Py launcher.

The desktop presplash code has been rewritten to use pygame_sdl2, and is now also faster.

A new `config.minimum_presplash_time` has been added. This ensures that the desktop presplash, android presplash, and iOS launchscreen are displayed for at least a certain amount of time, making them more useful for branding purposes.

As part of this work, script_version.rpy and script_version.rpyc will no longer be added to packages. Instead, script_version.txt will be added. (This ensures that the script does not change as part of packaging.) In addition, bytecode.rpyb has been moved to the game/cache directory, where addditional cache files now join it.

### iOS

There have been a number of improvements to renios, some necessary to get Ren'Py games accepted on the Apple App Store. Nightly builds of 6.99.5 have been used to get multiple games accepted.

Renios has been upgraded to use SDL 2.0.4 rc1. This improves compatibility with iOS 8, and makes it possible to keep the launchscreen displayed until Ren'Py fully starts. As a result, support for the ios-presplash image is no longer necessary, and has been dropped.

### Other Improvements

A Simplified Chinese translation of the template game has been added, and the Korean and Arabic translations have been updated.

ATL has had an update event added. This event is called in rare (but possible) cases when a screen is re-created from scratch, such as after a load or when styles or translations are changed.

`SetMute()` and `ToggleMute()` actions have been added, along with a new "all mute" `Preferences()` that mutes all mixers.

Font hinting is now controllable using the `hinting` style property.

The `config.nearest_neighbor` variable configures Ren'Py to draw all images using nearest-neighbor interpolation by default, helping ensure that pixel art stays sharp when scaled up.

The new `renpy.predicting()` function returns true if Ren'Py is running a screen for prediction purposes.

The new `renpy.return_statement()` function is a Python equivalent to the Ren'Py return statement.

The new `_dismiss_pause` and `_skipping` variables make it possible to control pauses and skipping on a line-by-line basis.

Canvas objects (returned by the Render.canvas() method) now have a get_surface() method that returns a pygame_sdl2 Surface that is in a format that can be used by Ren'Py. This surface can be manipulated by Pygame drawing operations.

The new `_get_voice_info()` function returns an object that contains information about the voicing associated with the currently-running say statement.

## Ren'Py 6.99.4

The Ren'Py script language now includes a new default statement. This statement sets a variable to a value a default value at game start or load, if a default statement has not set the value of the variable in the current game. This makes it possible to initialize saved variables near the relevant code, rather than all at once at label start.

Lint will now warn if a `define` or `default` statement redefines a Ren'Py or Python built-in name.

The screen language use statement now takes a block, which can be transcluded into a screen using the `transclude` statement. This makes it possible to use statements to "wrap" a block of screen language code.

The screen language also supports creator-defined statements, which are transformed into use statements. These make it possible to extend the screen language syntax.

The new Render.place() is available for use in creator-defined displayables. This method renders a displayable, then applies Ren'Py's layout algorthing to place that displayable within a containing rectangle.

Ren'Py now logs errors importing the steam module to log.txt.

Ren'Py now logs the duration of various parts of the init process to log.txt.

On mobile, Ren'Py will wait until the start of the first interaction before creating the main window. This prevents a black screen from being displayed for some time as Ren'Py starts.

There are a number of improvements to iOS support, to support passing Apple's package verification process.

The launcher now includes a button to retrieve logcat information from an Android device.

The launcher now checks that the version of rapt and renios match the version of Ren'Py proper.

### Fixes

Fixed a performance problem caused by failing to release the Global Interpreter Lock while waiting for event input. This could cause problems running various background threads, like the image preloader and autosave.

Ensured that screens are only analyzed once as the game starts. Previously, screens could be analyzed multiple times as the styles and languages were set, leading to excessive startup times, especially on mobile platforms.

The volume curve has been changed to be more correct and perceptually accurate. The previous curve had serveral problems, most notably that is sharply jumped from 0 to 10%. This may require players to adjust their volume settings.

The gallery slideshow timer now repeats through multiple images.

Text blits are now expanded to include an outline on a descender on the bottom row of text.

Drags outside of a draggroup can now be snapped into place.

The Gallery now properly advances through locked and unlocked images. Previously, this advancing was reversed, so next_unlocked would advance through locked and unlocked images.

Text accounts for the size of outlines when allocating textures, preventing the bottom line of outlines from being cut off.

Position information (xpos, ypos, etc.) are now passed from an inner transform to an outer transform during as single frame. Previously, this information would lag by a single frame, which could lead to nested transforms lagging or failing to complete.

## Ren'Py 6.99.3

Removed debugging code that could cause problems by writing an unnecessary zipfile.txt file.

## Ren'Py 6.99.2

Ren'Py now supports an images directory underneath the game directory. Images found inside this directory – or in subdirectories of this directory – will be automatically defined as images in Ren'Py. This will likely render the use of the image statement obsolete in simple games.

The new `AlphaMask()` displayable allows one displayable to be masked by the alpha channel of another.

The android and iOS emulators now emulate the onscreen keyboard.

The achievement API has been changed somewhat, but only with respect for progress functions. (Which were broken in the previous releases.)

Actions that care about the current screen (like SetScreenVariable) now work when used with the hovered and unhovered properties.

The updater has improved. If an incremental download fails, Ren'Py will try downloading the complete file before giving up.

When building for Android, Ren'Py will copy the apk files in to the dists directory used by the desktop platforms.

Added the `RestartStatement()` action.

Added the `renpy.reset_physical_size()` and `ui.screen_id()` functions.

Allowed the screen language key statement to take the activate_sound style property. This makes it easier to play a sound when a key is pressed.

Documented `ui.interact()`.

Updated the Simplified Chinese and Korean translations, and the Italian template.

## Ren'Py 6.99.1

Added the `renpy.load_image()`, `renpy.load_surface()`, and `renpy.get_showing_tags()` functions.

## Ren'Py 6.99

### SDL2

Ren'Py is now based on Pygame_SDL2, a reimplementation of the Pygame API based on the SDL2 library. One of the largest changes in Ren'Py's history, switching to SDL2 lays the groundwork for many improvements, in this and future releases.

### iOS Support

Ren'Py now supports the iOS platform. To develop for iOS, you will need a Macintosh computer, Xcode, and a paid membership in the iOS developer program. (An iPad or iPhone to test with is highly recommended.)

Ren'Py's iOS support includes the ability to create Xcode projects, and to update those projects with the latest version of a Ren'Py game. Xcode can be used to change project settings, and to create debug and release builds.

The iOS port supports iOS 7 and higher. Almost all of Ren'Py is supported, with the exception being that video playback is limited to fullscreen video in formats the iOS device supports.

For now, the default set of Ren'Py screens are not particularly compatible with iOS. You will need to customize your game to make it touch friendly and compliant with Apple's guidelines before submitting it to the iOS app store.

Please see the iOS documentation for more information and a copyright notice you must include as part of your app description on iOS.

### Android Support

Android support has been rewritten, and is now based in SDL2. This release brings Android support to parity with desktop platforms. Improvements include:

- Support for rotating the screen to match the user's preferred orientation.
- Improved in-app purchase support, with the ability to retrieve prices and create a single .apk that supports the Google and Amazon stores.
- Android audio playback is now based on the same code that's used on the desktop and iOS platforms. This enables support for features like panning and fading volume. It also means the same sound files can be used on Android, iOS, and desktop platforms.
- Keyboard input is now supported on Android.
- Languages requiring bidirectional text (like Arabic and Hebrew) are supported on Android.

A number of issues with Android support have been fixed, including one that prevented Ren'Py from unzipping the android SDK automatically when the path to the Ren'Py install was too long.

Please see the Android documentation for more information and a copyright notice that should be included as part of your app description.

### Steam

Ren'Py now ships with Python bindings for the steam API. These bindings are built as part of the Ren'Py build process, which means they will be maintained alongside Ren'Py going forwards.

For an explanation of how to use the Steam API, please contact the Ren'Py developers directly. The bindings make available:

- Initialization.
- User statistics and achievements.
- Retrieving other apps by the same developer that have been installed.
- DLC support.
- The in-game overlay, including the ability to launch a purchase flow.
- Session tickets.

The steam bindings will be integrated with Ren'Py as appropriate. For now, this integration consists of binding the steam achievement system to the new Ren'Py achievement API.

### Distribution Improvements

The launcher now has the ability to add from clauses to call statements, automatically turning:

    call dayplanner

into:

    call dayplanner from __call_dayplanner

From clauses, which are really labels, help Ren'Py to find the return site to use when a game is changed. This should help fix problem with games that may change greatly between releases.

When asked to package a game that is more than about 2GB in size, Ren'Py will produce a ZIP64-format archive. These archives may be less compatible that smaller zip files.

### Languages and Translations

There is now a Russian translation of the tutorial game, and a Finnish translation of the launcher.

Ren'Py supports input methods (IMEs) on platforms where SDL2 makes that support available. (All platforms except for Linux.) Input methods make it possible to input complex non-ASCII text, such as Chinese, Japanese, and Korean.

### Clipboard Voicing

Ren'Py now supports clipboard voicing, which is accessed by Shift+C.

Clipboard voicing is a form of self-voicing that works by copying the text to the clipboard, where a screenreader program is likely to read it using settings preferred by the player.

### Custom Text Tags

Ren'Py snow supports a new form of custom text tags.

Custom text tags are applied after the text has been tokenized into tags and text. This makes it easier to write a custom text tag that manipulates text or applies multiple existing text tags to text.

The previously-existing form of custom text tag has been renamed to style text tag, and is still supported.

### Other Improvements

A high-level achievement API has been added to Ren'Py.

Ren'Py now includes support for recognizing touch gestures on Android and iOS.

It is possible to hide the editing buttons in the launcher, so they can't be used to open an absurd number of editor windows.

The developer can choose if strings should be empty when generating translations.

Three new set manipulation actions `AddToSet()`, `RemoveFromSet()`, and `ToggleSetMembership()` manipulate sets and lists-as-sets. (Such as inventory lists.)

Drags (as in, drag-and-drop) now supports the `focus_mask` style property.

The complexity of the style system has been reduced, decreasing memory usage and startup time.

The new `renpy.suspend_rollback()` suspends the recording of rollback checkpoints, while still allowing rollback to occur.

The RENPY_GL_CHECK_ERRORS controlls the logging of OpenGL/ANGLE function calls and errors.

A completion progress indicator can be toggled by typing Shift+Alt+P or swiping up-down-left-right-left-right.

As of this release, dictionary and set comprehensions are wrapped to support rollback.

## Ren'Py 6.18.3

This release adds the showif statement to screen language. The showif statement shows and hides its children based on a condition. When its children are ATL transforms, showif delivers ATL events to manage the show and hide process.

Ren'Py's image prediction mechanism now models the return stack, and can predict images through a call and return pair. Previously, a call followed by a return would block image prediction.

Ren'Py now predicts that the start label will be called from the main menu. This will help to avoid unpredicted image loads at the very start of a game.

The ATL on statement now can take a comma-separated list of event names.

The new `updater.UpdateVersion()` function contacts an update server and determines if an update is available.

The new `renpy.invoke_in_thread()` function runs a function in a background thread, and restarts the interaction when that thread finishes.

While in self-voicing mode, the {w} and {p} tags are ignored.

The Traditional Chinese and Russian translations have been updated.

### Bug Fixes

Fixed a regression that could cause hiding transforms to skip time.

Fixed a bug that would cause the screen language if statement to show children from blocks with a false condition, if those child blocks were run during prediction.

Fixed an issue where SetScreenVariable and ToggleScreenVariable were declared as pure functions, but weren't. They now have been reimplemented as pure functions.

Fixed an issue where a grab could fail to transfer between interactions, leaving Ren'Py unresponsive.

## Ren'Py 6.18.2

The define statement can now take a store name, and the say statement will search the `character` store before searching the default store. This means that if one uses:

    define character.e = Character("Eileen")

Say statements like:

    e "Hello, world."

will continue to work, even though `e` has been freed up for other purposes.

The default image cache size (set in `config.image_cache_size`) has been increased from 8 to 16 screens worth of images.

When set to True, the new `crop_relative` transform property tells a Transform to interpret float components of its `crop` property relative to the width or height of its transformed child, as appropriate. For example, (0.5, 0.0, 0.5, 1.0) will cropout the lower-right quadrant of the child.

When set to false, the new `keyboard_focus` style property hides buttons, bars, and imagemap hotspots from the keyboard focus mechanism.

The Mousearea screen language statement now respects the `focus_mask` style property, making it possible to have non-rectangular mouseareas.

Ren'Py now includes functions that can be used to profile the memory consumption of a game, including the memory consumption of Ren'Py itself. These functions are `renpy.profile_memory()` and `renpy.diff_memory()`. The new `renpy.profile_rollback()` lets one more specifically see the memory consumption of the internal rollback log.

When self-voicing mode is enabled, Ren'Py displays a notification that explains how to disable self-voicing mode.

This release fixes a subtle bug caused by incorrect analysis of for loops in screen language screens, when the iteration variable is a constant. (For example, when the iteration variable is `define`ed somewhere else in the game.)

This release adds Traditional Chinese translations of the launcher and template game, contributed by Civalin.

## Ren'Py 6.18.1

This release includes a new `Placeholder()` displayable, which can be used to display placeholder characters. Placeholders are now used when displaying images that are not defined.

The new `sv` Character-like object can be used when self-voicing is enabled to display (and hence speak) descriptive text.

ATL transforms in screens now begin executing when first shown. Previously, ATL transforms began executing when the screen containing the ATL transform was first shown, which meant that if the transform changed over the course of screen display, a portion of the new transform would be skipped.

This release includes a German template contributed by NoJoker.

## Ren'Py 6.18

### Screen Language Improvements

This release includes a new implementation of screen language that has the potential to be much faster than the original implementation of screen language. Where the original screen language evaluated screens from scratch at the start of each interaction, this new implementation can incrementally reuse large portions of a screen between interactions. Please see the new Screen Language Optimization documentation for information on how to maximize screen language performance.

Of special note is that screens now perform better when defined with a parameter list. Screens that do not expect parameters should be defined with an empty parameter list.

To support improved optimization, when the screen language use statement calls a screen with a parameter list, only variables in that parameter list are updated. (This is a change in previously-undocumented behavior.)

Screens now support passing properties to a displayable from within an if statement, provided the if statement is the first thing inside the displayable. For example:

    text "Eileen":
         if eileen_mad:
             color "#fcc"
         else:
             color "#cfc"

now works.

As there is now a larger benefit from predicting screens, screen prediction has been improved in several ways:

- By default, Ren'Py will now use the arguments supplied to a screen in the `show screen` and `call screen` statements to predict the screen. This is potentially dangers, as it means that if either statement has side effects, those side effects will occur as part of screen prediction. To mitigate this problem, both statements now take a `nopredict` clause that prevents screen prediction.
- Ren'Py will now attempt to predict images inside if clauses that would not be taken, and will ignore errors that occur during statement prediction.
- A pair of functions, `renpy.start_predict_screen()` and `renpy.stop_predict_screen()` allows for manual prediction of time images that will be used by screens, including parameterized screens.

Ren'Py now supports profiling of screens, via the `renpy.profile_screen()` function.

Ren'Py has been changed to make a copy of the screens being displayed before a transition occurs. This makes it possible to use a transition to show screen updates. For example, one could increase the value displayed by a bar, and then use the dissolve transition to dissolve in the new segment of bar.

### Image Prediction

Ren'Py now has a supported mechanism for manually predicting images in cases where automatic image prediction fails. This mechanism consists of two functions: `renpy.start_predict()` starts prediction of images, while `renpy.stop_predict()` stops prediction.

### Accessibility

Ren'Py now includes support for self-voicing, a mode in which Ren'Py will read on-screen text to vision impaired players. To activate self-voicing, press the `v` key. For more information, please read the self-voicing documentation.

The new `alt` style property allows one to supply alternative text that allows Ren'Py to voice imagemap components and buttons with incomplete names.

The Ren'Py launcher now includes a large-text mode that can be accessed from the preferences page. This mode increases text size and contrast.

### Android In-App Purchasing

This version of Ren'Py includes a high-level interface that supports in-app purchasing on the Android platform. This interface currently support Google Play and the Amazon App Store.

### Pixel Art

Ren'Py supports nearest-neighbor filtering of images. This ensures that screen pixels correspond to a single texture pixel, which is the scaling mode preferred for use with pixel art. Nearest-neighbor mode is enabled with the new `nearest` transform property.

The new `config.adjust_view_size()` callback makes it possible to set the size of the Ren'Py viewport to something other than the size of the window (or screen, in fullscreen mode). For example, a game can use this callback to limit its viewport size to integer multiples of its native size.

### Voice Improvements

Voice volume is now adjustable on a per-character basis, using the voice_tag argument to `Character()` and the new `VoiceVolume()` value.

Using the new `config.emphasize_audio_channels` variable, Ren'Py can emphasize audio on some channels. This is doen by lowering the volume of non-emphasized channels when a emphasized channel is playing, and returning the volumes to normal when no emphasized chanels are playing. By setting this variable to `[ 'voice' ]`, the voice channel can be emphasized over music and other sounds,

### OS X Bug Workaround

To workaround a bug in Mac OS X 10.9, Ren'Py will now always open on the the primary monitor of a Macintosh.

### Other

With some limitations, non-ASCII characters can now be used as character names. Since Python code does not allow non-ASCII identifiers, such character names must be defined by the define statement, and used outside Python code.

The auto property of imagebuttons and imagemaps now can take image names as well as image filenames.

The new `renpy.image_exists()` function returns true if an image has been defined.

Gallery navigation can now be customized by customizing the `gallery_nav` screen.

The new `renpy.count_dialogue_blocks()` and `renpy.count_seen_dialogue_blocks()` return the total number of dialogue blocks and the number of dialogue blocks that have been seen by the current user in any game. With some caveats, these can provide an indication of how much of the game the user has seen.

The `config.autosave_on_choice` variable determines if Ren'Py will autosave on choice, while the `config.autosave_on_quit` variable determines if Ren'Py will autosave when the game is about to end (by quit, return, or loading a save slot).

The new `events` transform property determines if events are passed to a transform's children. This is useful for ATL transforms, when some children should not receive events.

Save dumps (enabled by `config.save_dump`) are performed before the save occurs, making them far more useful for debugging pickling problems.

When show_ arguments are past to an `NVLCharacter()`, the show_ prefix is stripped and those arguments are passed to the `nvl` screen.

### Translations

This release add an Italian translation of the launcher and template game, contributed by Oshi-Shinobu.

This release adds a Portuguese translation of the template game, contributed by Mrstalker.

This release adds a Simplified Chinese translation of the launcher, contributed by Huanxuantian.

## Ren'Py 6.17.7

This release includes a number of Android changes:

- RAPT has been updated to use the latest version of the SDK. Please install the SDK again if you have build problems.
- RAPT no longer includes a copy of Ren'Py. Instead, Ren'Py includes a copy of itself into the built game that RAPT uses. This makes it possible to include fixes to Ren'Py in an Android package.
- A low-level In-App Purchase implementation, contributed by Emmanuel Marty and Winter Wolves. The low-level IAP code supports Google Play and the Amazon App Store. This code is not currently documented, as it will be wrapped in a higher-level implementation.

This release includes a fix to an audio-video sync issue that affected the Windows, Mac OS X, and Linux platforms.

## Ren'Py 6.17.6

This release adds a German translation of the launcher, contributed by Marcel.

This release adds a Korean translation of the launcher and template game, contributed by Baekansi.

This release includes a workaround for an issue that could prevent the launcher from starting on certain Mac OS X computers.

## Ren'Py 6.17.5

### Translations

This release features an Arabic translation of the launcher and template game, contributed by Renoa.

The Japanese and Spanish translations have been updated.

### Changes

The traceback system has been changed to generally report script statements, rather than the functions Ren'Py uses to implement those statements.

The `renpy.pause()` function now only sets a checkpoint (allowing rollback) if the delay time is 0. This prevents rollback from being blocked by short pauses.

The new `renpy.queue_event()` function provides a way to queue Ren'Py events from user-written interface code. (For example, it could be used to listen to commands on a serial port that's connected to a custom controller.)

If set, RENPY_SKIP_MAIN_MENU and RENPY_SKIP_SPLASHSCREEN environment variables cause Ren'Py to skip the main menu and splashscreen, respectively.

The RENPY_TIMEWARP environment variable makes it possible to speedup and slow down time.

An experimental new autoreload system can be accessed by setting `config.autoreload` to True, then pressing Shift+R to toggle automatic reloading.

### Fixes

A regression in 6.17.4 caused a major memory leak on Shift+R. This has been fixed. Several other problems with Shift+R have also been fixed.

An issue preventing transitions from working properly inside a restarted ATL transform has been fixed.

The --warp was documented incorrectly, and had stopped working. It's been repaired, and its documentation has been improved.

## Ren'Py 6.17.4

### Reloading

This release contains a complete rewrite of Shift+R reloading.

The rewrite was necessary to eliminate several major memory leaks that were triggered by reloading.

### Android

Ren'Py has been updated to use the newest (at the time of release) versions of the Android SDK and Ant. This should fix build problems caused by the use of older versions.

Ren'Py now recognizes and supports the Amazon Fire TV device. When a Fire TV is detected, the "firetv" screen variant is selected. To support pushing games to this device, Ren'Py now supports connecting to Android devices via the Remote ADB protocol.

### Other

Fixed a problem that occurred when an interaction containing a MoveTransition was restarted.

Added support for imagemaps that are larger than the screen. This allows an imagemap to be placed inside a viewport.

It is now possible to select the layer used by the say, choice, and nvl choice screen. Please see `config.say_layer`, `config.choice_layer`, and `config.nvl_layer` statements.

The prediction of window and bar images has been improved.

## Ren'Py 6.17

### Styles

The style system, which makes it possible to configure the look of displayables, has been rewritten from scratch. The new code reduces the amount of time it takes to create a new style to a small fraction of the previous time. Since every displayable creates an associated style, this has the potential to lead to a substantial performance improvement.

This release also introduced a new style statement that can be used to define styles, in place of Python code. (Of course, the older form remains fully supported.) Lengthy and redundant code like:

    init python:
        style.quick_button_text.set_parent('default')
        style.quick_button_text.size = 12
        style.quick_button_text.idle_color = "#8888"
        style.quick_button_text.hover_color = "#ccc"

can be replaced with:

    style quick_button_text is default:
        size 12
        idle_color "#8888"
        hover_color "#ccc"

Finally, the style inspector (accessed through Shift+I) has been rewritten.

### Syntax Changes

In addition to the new style statement, there are four other syntax changes:

- The definition of a simple expression has been expanded. Simple expressions (which are used in ATL and the screen language, among other places) now encompass all Python expressions that do not include lambda or the ternary (... if ... else ...) operator.

  This means that code like:

      show logo:
          xpos 800 / 2

  is now legal. Previously, the expression had to be parenthesized.

- The new `show layer` statement allows one to apply a transform or ATL transform to an entire layer, using syntax like:

      show layer master at flip

  or:

      show layer master:
          xalign 0.5 yalign 0.5 rotate 180

- The new `window auto` statement makes it possible for Ren'Py to automatically show and hide the dialogue window. By default, it is shown before `say` statements, and hidden before `scene` statements, but this can be customized.

- The init statement has been extended so it can be combined with other statements. It's now possible to write "init 1 image = ...", "init -2 define name = ..." and so on.

### Translations

This release adds French and Russian template games and translations of the launcher.

### Android

It is no longer necessary to download RAPT (the Ren'Py Android Packaging Tool) separately from Ren'Py. As of this release, RAPT will be downloaded by the Ren'Py launcher when an Android build is requested, and will be updated by the Ren'Py updater.

Buttons may now have an alternate action that is triggered by longpress on Android and right-click on desktop computers.

This release fixes a bug in which Ren'Py would not save persistent data (including preferences) before being terminated by the Android system, and a regression that broke compatibility with some Android 2.3 systems.

### New and Changed Preferences

There are two new preferences accessible through the `Preferences()` function:

- "auto-forward after click" controls if auto-forward mode is stopped by a click.
- "show empty window" determines is if the "window show" and "window auto" statements will cause an empty window to be shown.

Neither of these is exposed as part of the default preferences screen, but both can be added by interested developers.

There is one changed preference:

- "display" now has an "any window" option, which restores a fullscreen Ren'Py to its prior windowed size.

### Other

`ShowMenu()` can now pass arguments to the screen it displays.

The input displayable now takes a pixel_width property, that limits the size of the input field it a certain number of pixels.

The `FileCurrentScreenshot()` function

The new `xsize`, `ysize`, and `xysize` style properties make it possible to directly set the size of a displayable.

The `focus_mask` style property can now take as an argument a callable that returns true when a displayable should be focused. If such a callable can be written, it may be much faster than the current method of determining pixel opacity.

Viewport now respects the xfill and yfill properties. The default viewport style sets these to true. Setting them to False will cause the viewport to shrink to fit its contents when those contents do not fill the entire viewport.

The new `renpy.get_image_bounds()` function retrieves the bounding box of an image that is being displayed, after all Transforms have been applied to it.

The new `renpy.retain_after_load()` can be used to retain data updated by a screen after the game is loaded.

The new `xsize`, `ysize`, and `xysize` style properties make it possible to directly set the size of resizable displayables.

Prediction of images with partial attributes and side images used in dialogue has been improved. Prediction of creator-defined statements now works as documented.

## Ren'Py 6.16.2

This release adds a Spanish translation of the launcher and the template game.

This release adds the new `renpy.get_mouse_pos()` function, which retrieves the mouse position if a mouse is supported.

## Ren'Py 6.16

### Android

Android support has now been integrated into the Ren'Py launcher. While for size reasons RAPT is still a separate download, once RAPT has been placed inside the Ren'Py directory, the launcher will allow you to:

- Install the Android SDK.
- Configure a project as an Android application.
- Build and Install the Android application.

The launcher can now launch Ren'Py in modes that simulate Android phones, tablets, and television-based consoles.

Ren'Py includes support for television-based Android consoles, such as the OUYA. It includes support for detecting the OUYA specifically, and choosing a variant as appropriate.

This release adds some video playback support to the Android port. While limited to full-screen video and codecs that the Android platform supports (which unfortunately have little overlap with desktop Ren'Py), this may be enough to enable cutscene movies.

Ren'Py now includes a new set of screen variants, with "large", "medium", and "small" reflecting the visual size of devices (televisions are considered to be small because they're far away), while "touch", "tv", and "pc" reflect the input devices involved.

Android now supports displaying vertical text.

### Save, Load, and Persistent Improvements

The low-level load/save API has been overhauled. It's now possible to access save slot information directly, instead of having to scan all save slots to find the one you want. New functions include `renpy.list_slots()`, `renpy.newest_slot()`, `renpy.slot_mtime()`, `renpy.slot_json()`, and `renpy.slot_screenshot()`.

At a higher level, there is a new `FileNewest()` function that's true for the newest save slot. `FilePageNext()` and `FilePagePrevious()` now support a wrap argument that causes them to wrap around a defined number of screens.

There is now support for adding arbitrary JSON information to save files. This allows per-save information (like the path you're on in a VN, date and amount of money in a sim, or party composition in an RPG) to be accessed from the save and load screens.

JSON information is created by `config.save_json_callbacks`, and can be accessed through the low-level `renpy.slot_json()` or high-level `FileJson()` functions.

When possible, Ren'Py now stores save files with the game, as well as in a user-global save directory. This means that if a Ren'Py game is placed on a USB drive or shared on a network, the saves will be available on multiple computers. (When save files are available in both places, the newest file wins.)

When a save file on a network share is updated, Ren'Py will automatically rescan the contents of that file, and restart the current interaction. (This will update the save and load screens, making the file available to be loaded.)

Ren'Py will no longer auto-save while at the main menu.

Persistent data is also stored in both locations. When the persistent data is not identical, it will be merged. By default, the most recently updated value for each field will be used. In some cases (for example, a set of endings the player has reached), this is not the correct behavior. The new `renpy.register_persistent()` can be used to register different merge behavior.

### Voice

This release adds support for playing voice without having to fill the script with voice statements. This support consists of two new pieces of functionality:

- The launcher contains a new "Extract Dialogue" function. This extracts the dialogue into a tab-delimited file. Each record includes the character, the dialogue text, the filename and line number, and a unique identifier for that line.
- The `config.auto_voice` variable is used to give a filename pattern that is formatted with the unique identifier. If a file with that filename exists, and no other voice file is being played, that file is used as the voice.

There are also several new voice-related preferences. The "voice sustain" preference determines if voice is sustained through multiple interactions. The "wait for voice" preference determines if auto-forward mode waits for the voice to finish before advancing.

### Image Gallery and Music Room

The image gallery now can display a navigation overlay with next, previous, slide show, and return buttons. The creator can choose if these buttons display the images associated with a single button, or advance between multiple buttons.

The Music Room includes the ability to play a random track, and to determine if the tracks are shuffled, looped, or if play is confined to a single selected track.

### Text Rendering

Ren'Py now renders portions of font characters that leave the character bounding box. This prevents text (especially hinted and anti-aliased text) from being cut off, but may lead to apparent placement problems for fonts with very inaccurate bounding boxes.

### Japanese Language

The Ren'Py launcher has been translated into Japanese. The language used by the launcher can be switched from the preferences screen.

There is now a Japanese language template game, which defaults to a Japanese font and has a translated interface.

Much of the documentation has been translated to Japanese. The Japanese translation can be found at:

> http://ja.renpy.org/doc/html/

### Documentation

The Ren'Py documentation has been improved. The following pages have been added or migrated from the old wiki-based documentation.

- Labels & Control Flow
- Python Statements
- Conditional Statements
- Audio
- Movie
- Persistent Data
- Creator-Defined Statements
- Character Callbacks
- File Access
- Environment Variables
- Reserved Names

Many other documentation pages have been improved and edited.

### Other

The default quick menu now includes rollback and fast skip functionality. (This functionality is contained in the template screens.rpy, and may need to be copied into your game.)

The default yes_no screen now answers no when the user right-clicks. (This functionality is contained in the template screens.rpy, and may need to be copied into your game.)

The fast skipping function now stops when it visits seen text.

The `build.destination` variable can be used to select the directory in which Ren'Py places files when building a distribution.

There is a new NullAction that can be used when one wants a button to be sensitive to hover and unhover, but not performing a useful action on click.

ConditionSwitch is now much faster.

Ren'Py will deal with files with insane timestamps by giving them the current time.

### Bugfixes

This release includes many bugfixes. Some of the more important are:

- A fix to a problem that would cause Ren'Py to restart the display when starting up on Windows. This could cause Ren'Py to spuriously detect a slow video card, and present the user with the appropriate error message.
- A fix to a problem where Ren'Py would fail to display the proper error message when Python code containing non-ASCII characters fails to compile.

## Ren'Py 6.15.6

This release includes improvements for the Android platform:

- Assets are now read exclusively from the APK and expansion file.
- Logs and tracebacks are placed on external storage.
- Saves are placed on external storage, except when saves from older versions of Ren'Py exist.

The GL2 shaders Ren'Py uses have been simplified in the (usual) case where no clipping is occurring. This leads to a noticeable speed improvement on Android, and potentially other platforms as well.

An issue with Drag-and-drop has been fixed. Thanks go to Kinsman for contributing this fixe.

The `Skip()` action now triggers the skip indicator. It also supports a new fast parameter, which causes skipping to the next menu.

This release includes various minor changes to improve compatibility with very old Ren'Py games. (It now runs the Ren'Py 5 demo.)

## Ren'Py 6.15.5

This release adds two new features:

- The GL renderer now supports additive blending. This is enabled using the `additive` transform property in an ATL transform or use of the `Transform()` class. Additive blending will not work if the software renderer is in use, and it's up to creators to deal with that issue.
- The new `Flatten()` displayable combines multiple textures into a single texture. This can be used to prevent incorrect behavior when a displayable containing multiple overlapping textures (like a `LiveComposite()` is shown with an `alpha` between 0 and 1.

It also fixes the following issues:

- Whitespace is now skipped before default arguments, which previously caused parse errors in some cases.
- Ren'Py now sets the unix mode of files and directories in zip and tar files to 644 and 755 as appropriate. Prior versions of Ren'Py used 666 and 777 as the permissions, which lead to a security problem when the file was unpacked by a tool that didn't respect the user's umask. (Info-zip had this problem.)
- Auto-hinting for fonts is now enabled by default. This restores font rendering compatibility with prior releases.
- Ren'Py now builds with and requires the current version of libav. It should also work with current versions of ffmpeg when libav is available.
- The version of SDL distributed with Ren'Py has been patched to prevent multiple windows from showing up in the Window menu when entering and leaving fullscreen mode.

### Ren'Py 6.15.4

This release fixes a compile problem that prevented Ren'Py 6.14.x and Ren'Py 6.15.0-3 from running on most 64-bit Linux systems.

Image prediction has become more fine-grained, and can take place while the screen is animating.

The new `build.exclude_empty_directories` determines if empty directories are include or excluded from the distribution. It defaults to true, previously the default was platform-dependant.

## Ren'Py 6.15

### Translation Framework

Ren'Py now includes a comprehensive translation framework. This framework includes support for using a single language selection to change dialogue, menus and other interface text, images and files, styles and styles.

The dialogue translation support allows lines of dialogue to be split and combined at the translator's discretion. As most Ren'Py statements are allowed inside the new translation blocks, it's possible to use logic (like conditions) to tailor the translations to your language.

The launcher includes a new "Generate Translations" button, which – as part of a sanctioned translation where the full script is present – will generate empty translation files for a new language.

### Improved Japanese Support

Ren'Py 6.15 includes multiple changes to better support the Japanese language.

- The tutorial game has been translated to Japanese, with the language being selectable from the preferences menu.

  The tutorial was translated by Koichi Akabe.

- Support for vertical writing has been added to Ren'Py. Consisting of the `vertical` style property for text, and the new `box_reverse` property on hboxes, this support makes it possible to display dialogue, menus, and other text in a vertical orientation.

  Vertical text support was written by Koichi Akabe.

- The line-breaking algorithm has been updated to match Unicode 6.2. In addition, three new "languages" have been added. The new "japanese-strict", "japanese-normal", and "japanese-loose" languages (based on the line-break options in the CSS3 Text module) allow greater control of how Ren'Py breaks lines with small kana and other special characters.

  Linebreaking can be further tailored using the new `renpy.language_tailor()` function, which can change the linebreaking class of a character.

### Console

The new debug console makes it possible to interactively run Ren'Py script and Python statements, and immediately see the results. The console is available in developer mode or when `config.console` is True, and can be accessed by pressing Shift+O.

The console can be used to:

- Jump to a label.
- Interactively try out Ren'Py script statements.
- Evaluate a Python expression or statement to see the result.
- Trace Python expressions as the game progresses.

The console was originally written by Shiz, C, and delta.

### Screen Parameters

Screens now take named parameters, similar to the way that labels and transforms take named parameters. It's now possible to write:

    screen top_text(s, size=36):
         text s xalign 0.5 size size

and:

    show screen top_text("It works!")

### Replay Gallery

Ren'Py now includes support for replaying scenes. A scene replay can be invoked from anywhere in Ren'Py (for example, from a main menu or game menus screen, even when the game has started). When the replay ends, Ren'Py will return to the location the replay was invoked from, even if that location is in a screen or in Python code. Rollback works inside a replay, but saving and loading is disabled.

The `Replay()` action begins a replay. The `renpy.end_replay()` ends a replay if one is in progress, and is ignored otherwise.

### Voice Improvements

There have been several improvements to the voice playback system. The new `config.voice_filename_format` variable makes it possible to use only part of the filename in a voice statement. The new voice_tag parameter to `Character()`, in conjunction with the `SetVoiceMute()` and `ToggleVoiceMute()` actions, makes it possible to selectively mute particular characters' voices. The new `VoiceReplay()` action makes it possible to replay the current voice.

### Launcher Improvements

There were a few launcher improvements in this release.

- The files pane of the navigation page has a new button that allows the user to create a new script file.
- The launcher can generate translation templates, and can be translated using the translation framework.
- The Ren'Py launcher now has a small amount of support for skins. While the basic layout of the launcher remains fixed, skins allow the background images and colors to be changed. See the skin documentation for more details.

### Macintosh Changes

The Macintosh version of Ren'Py now requires a 64-bit capable processor, and Mac OS X 10.6 or newer.

### Packaging Improvements

The file layout of Ren'Py games has been somewhat altered. With the exception of small launcher programs, all platform-dependent binaries are under the lib/ directory. Ren'Py itself has now been placed in the renpy/ directory. The common/ directory has been moved to renpy/common/, as it's considered an integral part of Ren'Py.

Ren'Py now uses renamed but otherwise unmodified Python binaries on all desktop platforms. (Previously, it used platform-specific binaries.) Portions of the library are shared between the desktop builds.

A running Ren'Py process on Linux will now be named after the game, rather than having python as a name.

### Other Changes

- Viewports now support edge scrolling, which scrolls the viewport when the mouse is within a a configurable distance of the viewport edge.
- Most keyboard keys now automatically repeat. The repeat rate is controlled by `config.key_repeat`.
- Side images can now be used with menus.
- The `config.enter_yesno_transition` and `config.exit_yesno_transition` variables make it possible to define a transition that is run when yes/no prompts appear and disappear, respectively.
- The viewport statement now supports edge scrolling - automatic scrolling when the mouse approaches the sides of the viewport.
- The new `transform_anchor` transform property makes the anchor the point around which a transform is scaled and rotated. (For example, it's now possible to rotate around the bottom-right corner of an image, rather than just its center.)
- The common directory has been moved to renpy/common, as it's part of Ren'Py. The giant 00screens.rpy file has been broken up into a large number of smaller files.
- The new `box_reverse` and `order_reverse` style properties allow the user to control the order in which children of vbox and hboxes are placed and drawn, respectively.
- The xoffset and yoffset transform properties now take floating point numbers, allowing more precise positioning if subpixel is true.
- The `child` style property of buttons is now exposed to the screen language.
- The new `config.enter_yesno_transition` and `config.exit_yesno_transition` variables allow a creator to supply transitions that are used upon entering and exiting yes/no prompts.
- The Python decimal module is now included in the default builds of Ren'Py.

### Bugfixes

Among others, the following bugs were fixed:

- github bug37: A crash with LiveTile when sizes were not integers.
- github bug41: `renpy.loadable()` failed to search for files inside android packages.
- github bug42: The launcher can now run a game that's in a read-only directory.
- github bug45: Ren'Py would fail when the hiding of a screen caused a screen beneath it to be hidden.
- github bug46: A bug that prevented Ren'Py from evicting images from an over-full image cache, that manifested as a runaway memory leak.
- github bug50: Vertical bars would scroll with the left and right arrow keys; and bars would remain grabbed even if they were grabbed while leaving the screen, preventing further input.
- github bug51: The slow_done callback was not called after a rollback.
- github bug56, github bug57: `renpy.loadable()` now works with Android assets.
- github bug60: Fixed a bug that prevented {p} and {w} from working properly when followed immediately by a text tag.
- github bug61: Ren'Py no longer crashes when an end_game_transition is set and a screen uses a variable that is no longer defined when the game restarts.
- github bug65: Multiplying a rollback list by a number now always produces a rollback list.
- Editra should work better on Windows.
- It's now possible to `renpy.call()` a label that doesn't take parameters.
- Fixed an error handling failure when a style used by error handling was not buildable.
- Fixed an error handling failure when a python early block contained a syntax error.

## Ren'Py 6.14

### Ren'Py Launcher Rewrite

The Ren'Py launcher has been rewritten. Some of the improvements are:

- A new visual design by Doomfest of the Dischan visual novel team.

- The launcher now includes direct access to open the script and game directories, and common script files.

- The launcher includes Script Navigation support. Clicking the name of a label, define, transform, screen, or callable will open the editor to the location where that name is defined.

  Script navigation also provides access to individual script files.

- The launcher now supports one-click project building. Instead of using multiple steps to build a project, a single click will now cause the launcher to:

  - Read the build process configuration from the game script.
  - Build the archives needed.
  - Generate the archive and update files.

- The launcher can now use the Ren'Py updater to update Ren'Py, and to download editors.

### Editra & Text Editing

For most users, Ren'Py recommends the use of the Editra editor. We have developed an Editra plugin that communicates with the Ren'Py launcher and supports the editing of Ren'Py script.

While still in beta, Editra is a fast and light editor with good code editing support. Editra also includes a spell-checker that can be enabled, and applies to dialogue and other strings.

If Editra is selected by the user, and it is not installed, Ren'Py will automatically download it.

The jEdit editor remains supported, and is preferred for use with languages (like Chinese, Japanese, and Korean) that Editra doesn't support fully. If selected, Ren'Py will download jEdit automatically.

Ren'Py also supports editing files through system-specific file associations. (This support will not send the cursor to the correct line, however.)

### Ren'Py Web Updater

Ren'Py includes an updater that can update Ren'Py and individual Ren'Py games by downloading changes from a properly-configured web server with a small number of update files uploaded to it.

The updater uses zsync to download the minimal set of changes between the local files on disk and the files stored on the server. A single set of files on the server supports updating from all prior versions of a project.

Ren'Py includes a default updater interface that can be further configured by interested users.

### Transform Changes

This release changes the behavior of transforms to make them more correct and easier to use.

The xzoom and yzoom properties are now applied before, rotation. This means that the shape of the image will remain consistent as the image is rotated. Previously, the image to change shape as it was rotated.

The xzoom and yzoom properties may now be negative, with negative zoom values causing the images to be flipped. The positioning code now takes this into account, and positions a flipped image properly.

Thanks to Edwin for contributing these changes.

### Screen Language, Displayable, and Transition Enhancements

- The Textbutton and Label screen language statements now take properties prefixed with `text\_`. These properties have the text_ prefix stripped, and are then passed to the internal text displayable.
- The Viewport screen language statement now takes a scrollbars parameter. If given, scrollbars that manipulate the viewport are created.
- The Viewport screen language statement now takes xinitial and yinitial parameters. If given, these control the initial positioning of the viewport.
- A screen language block may now contain multiple has statements. Screen language widgets that take single children can now take a has statement.
- The input displayable now supports the use of the left and right arrow keys within the text. (Thanks to Edwin for this feature.)
- `MoveTransition()` has been rewritten. The new version now uses transforms to control the positioning of entering and leaving images, and can interpolate between the locations of moving images.

### Rollback Improvements

- The new `renpy.fix_rollback()` function allows the game to fix choices, even if they are made in rollback mode. The user can roll back and roll forward, but is restricted to making the choices he made the first time through the game.

  Thanks to Edwin for contributing fix_rollback.

- Rolling forward now works through a jump out of a `call screen` statement.

### Video Improvements

Ren'Py's video playback support has been partially rewritten to improve robustness, speed, and framerate stability. These improvements should reduce the number of frame drops Ren'Py performs, and should also prevent Ren'Py from locking up if too many frames are dropped.

Ren'Py now supports the WebM video format.

### Image Load Log

When `config.developer` is true, Ren'Py keeps an internal log of image loads.

This log can be access by showing the _image_load_log screen. This screen displays the name of an image file for a few seconds after that image has been loaded. The name is in white if the image was loaded by the image predictor, and pink if Ren'Py was unable to predict the image.

### File Actions and Functions

Two screen functions have been added, and two screen actions have been changed:

- The new `FileUsedSlots()` function returns a list of used file slots on the current page.
- The new `FileCurrentPage()` function returns the name of the current page.
- The `FileSave()` and `FileAction()` actions have been modified so that if the slot name is None, an unused slot based on the current time is used.

Taken together, these changes make it possible to create a list of save slots where the user is able to add new slots to the list.

### Multiple Store Support

Ren'Py now supports multiple stores – multiple namespaces in which Python code can be run. Variables in these stores are saved, loaded, and rolled-back in the same way that variables in the default store are.

Stores are accessed by supplying an in-clause to a python block. For example:

    init python in stats:

        def reset():
            """
            Code to reset the statistics.
            """

User-created stores are placed into the "store" package, with the default store being the package itself. Names can be imported between packages.:

    init python:
        from store.stats import reset

    init python in stats:
        from store import ToggleField

Note that stores do not affect the order in which init python blocks are run. A name must be defined in a block before the one that imports that name.

### Platform Support and Library Updates

Linux support has been changed.

- The Linux platform supports the x86_64 CPU architecture in addition to the x86 architecture. The Ren'Py shell script will automatically determine the platform it is running on when it is launched.
- The Linux version is now linked against the libraries from the 2009-era Ubuntu 10.04 Lucid. (Previously, Ren'Py had been linked against 2006's Dapper.) Older versions of Linux are no longer supported.

Many libraries that Ren'Py depends on have been updated. Some of the changes that have occurred are:

- Python has been updated to version 2.7.3.
- Pygame has been updated to version 1.9.1.
- GLEW has been updated to version 1.7.0. This may fix OpenGL problems on some Linux systems.
- LibAV has been updated to version 0.7.6, and has been compiled with CPU detection enabled.

### Other Changes

- The `renpy.call()` function allows – with major and important caveats – a call to a Ren'Py label to begin from inside Python code. Such a call immediately terminates the current statement.

- When an action is expected, nested lists of actions can be given. The lists are flattened and the action executed.

- Added the `OpenURL()` action, which opens a URL in a web browser.

- Added the `config.gl_resize` variable, which determines if the user can resize OpenGL windows.

- Ren'Py's handling of command line arguments has been rewritten. Most notably, lint is now invoked with the:

      renpy.sh <gamename> lint

  command. (Which also works with renpy.exe.)

- Ren'Py can now dump information about the game to a json file when starting up. The information dumped can assist other tools in providing launcher-like code navigation.

- The little-used remote control feature has been removed from Ren'Py.

- The `config.gl_resize` variable now controls resizing of a game running in GL mode.

- Documentation fixes (by SleepKirby and others).

- The NVL-Mode tutorial has been ported to Sphinx (by Apricotorange).

- Ren'Py now defaults to reporting errors with sound and music files when config.developer is True.

## Ren'Py 6.13.9

The new RAPT tool makes it far easier to package a Ren'Py game for Android. It can semi-automatically set up an Android build environment on your system, build a package, and install that package on your Android device.

To fix some editor-related problems, backported the 6.14 editor system. This changes how editors are configured. Please see Text Editor Integration for a description of the new system.

The new `config.save_dump` variable causes Ren'Py to write out save_dump.txt each time it saves. This file describes the contents of the save, making it possible to figure out what's causing an overly large save file.

Worked around a bug in Mesa that can cause crashes on certain Linux systems.

Fixed the following bugs in Ren'Py.

- The (default) texwrap layout represents character widths as floating-point numbers. This fixes a bug where non-integer kerning would lead to text overflowing its bounding box.
- Menu choices are logged correctly.
- All file access is now done in Unicode, rather than the system's native encoding. This prevents crashes that occurred when Ren'Py was placed in a directory that had non-ASCII characters in it.
- Fixed focus_mask on the ANGLE renderer.
- Displayables can now have fractional-pixel sizes. This allows a zooming image to remain precisely centered on the screen.
- Fixed a problem where Ren'Py would save unnecessary trees of displayables each time it saved a screen. This would lead to overly large save files and slow save performance.
- Ren'Py would not attempt an alternate rendering method if the texture test failed, leading a "Textures are not rendering properly." exception.
- A crash in Render.fill.

## Ren'Py 6.13.8

Side images can now be limited to showing a single character, or only showing characters that are not on the screen. See `config.side_image_tag` and `config.side_image_only_not_showing`.

Added `config.python_callbacks`, a list of Python functions that are called at the end of each python block.

Ren'Py now tests the video card it is running on for functionality. If it can't draw textured rectangles to the screen, it will proceed to a different renderer.

Old-style string interpolation is now enabled by default, alongside new-style string interpolation.

Ren'Py is now compatible with libpng 1.5. Thanks to James Broadhead for the patch.

Fixed the following bugs:

- A crash when dealing with certain invalid fonts.
- Pausing too long when typing out text.
- Cutting one pixel off a block of text when fractional kerning was used.
- Crashing when the time was set in the far future or past.
- Immediately exiting when rolling forward at the quit prompt.
- Crashing when a non-existing directory is added to the search path. (This prevented Katawa Shoujo from starting in the latest version.)
- Save-file size was overly large due to screens being included in save files.

## Ren'Py 6.13

### Text Rewrite

Text display has been rewritten from scratch. In addition to supporting many new features, the new implementation of Text is much faster at text layout and display, and contains much cleaner code.

Some of the new features that are now supported by the text display system are:

- Interpolation of variables enclosed in square brackets. It's now possible to write code like:

      "You scored [score] out of a possible [max_score] points."

  The new string interpolation takes place on all text that is displayed, rather than just say and menu statements. When used as part of a screen, interpolation has access to screen-local variables.

  PEP 3101-style string formatting is supported, which means that this syntax can be used to display fields and items, as well as variables.

- Kerning support was added, both as the `kerning` style property and the `k` text tag.

- Support for ruby text (also known as furigana), via the `rt` and `rb` text tags, and the `ruby_style` style property.

- The new `space` and `vspace` text tags make it easy to whitespace into the text.

- The new `cps` text tag controls the speed of text display.

- By default, Ren'Py uses the Unicode linebreaking algorithm to find points at which a line can be broken. This algorithm should correctly break lines that contain a mix of western and eastern languages. Since that algorithm is incorrect on some Korean texts, Ren'Py also implements a korean-with-spaces variant, that only breaks runs of Korean text at whitespace. These algorithms can be selected by the `language` style property.

- Ren'Py now uses the Knuth-Plass linebreaking algorithm to choose the points at which it actually splits lines. This algorithm attempts to minimize the unevenness of all lines except the last. Ren'Py also supports a nobreak mode, which allows one to create a Text larger than the screen without it being automatically wrapped. These can be selected using the `layout` style property.

- The new `newline_indent` style property determines if Ren'Py adds indentation after a newline in text.

- The new `line_leading` style property inserts space above a line of text. (Ruby text can be placed into this space.)

- Text can be automatically translated before it is displayed. (This support will be improved in a future major release.)

### DirectX Support

On Windows systems that have the February 2010 DirectX update installed, Ren'Py will use DirectX via the ANGLE adaptation layer, if OpenGL 2.0 or later is not found. The ANGLE layer is used by popular web browsers such as Firefox and Google Chrome. This allows hardware rendering to be used on netbooks, where drivers often support DirectX far better than OpenGL.

At startup, Ren'Py will test the graphics capabilities of the computer it is running on. If the software render is being used, or the game renders at an unacceptably slow speed, Ren'Py will display a warning message to the user. The warning message includes a link to a page on renpy.org that explains how to update the graphics drivers.

This version of Ren'Py will only use the software renderer if both DirectX and OpenGL are incapable of rendering Ren'Py games. Screen-scaling in the software renderer has been replaced by a simpler but slower version.

### Other Changes

- Ren'Py now includes a style preference system. This system allows styles to be changed after the init phase has finished. These changes are saved with the persistent data. Among other things, style preferences allow a game to offer the user the option to change the font, size, and color of dialogue text.

- Support has been added for screen-based image galleries and music rooms. This support consists of a classes that provides actions that make it easy to present the user with graphics and music. The creator is responsible for creating screens that use the supplied actions.

- The default screens.rpy file, used when a new game is created, contains support for a "quick menu". This menu adds buttons to screens that allow the user to quick save, quick load, save, toggle skipping, toggle auto-forward mode, and access the preferences menu.

- Ren'Py includes 5 new themes, and a number of new color schemes.

- Several new actions have been added. The `SelectedIf()` action allows the creator to control if a button is displayed in the selected state. The `SetMixer()` action allows a mixer to be set to a specific value. The `Rollback()` and `RollForward()` actions allow the creator to bind rollback to buttons.

- The behavior of the xfill and yfill style properties was accidentally changed in the 6.12 series. It has been returned to the historical behavior.

- The `Dissolve()` and `ImageDissolve()` transitions now take a time_warp parameter.

- The `Frame()` displayable now allows the user to specify the left, top, right, and bottom borders independently.

- The `caret` style property allows the user to customize the caret of an input widget.

- The `renpy.displayable()` function has been exposed to the user.

- Timers can now take a list of actions, rather than just a single callable.

- Three transforms were added to the default library: `top`, `topleft`, and `topright`.

- Ren'Py can now load files (including images, music, and fonts) from an Android package.

- User-defined statements can now take a block, which the statement is responsible for parsing.

- Wrote documentation for:

  - Menus
  - Transforms
  - Creator-Defined Displayables

  Several indexes were added to the documentation, and the style was updated.

- Ren'Py now uses the libjpeg-turbo library, for faster jpeg loading. Ren'Py now uses libav 0.7.1, for improved compatibility with movie formats.

- Removed support for the iLiad platform.

- PowerPC support has been removed from the main Ren'Py distribution. It's available as a download from the Ren'Py web site.

Thanks to Aleema for contributing the new themes and color schemes.

## Ren'Py 6.12.2

This release contains the following changes:

- ATL Transforms with parameters compile correctly.
- MultipleTransition works in conjunction with pauses.
- The mouse is shown when a quit action is run while a movie is playing.
- A fix for a lockup that occurred when the user entered the game menu while a transition was running.
- RENPY_SCALE_FAST works again.
- Ren'Py compiles with newer versions of ffmpeg.
- Skipping ends when the game restarts.
- Fixed a problem with texture upload that made games noticeably slower.
- Choose a better default size for windows on small monitors, like netbooks.
- xfill and yfill now work for vbox and hbox, respectively.
- Click-to-continue fixes.
- Side image fixes.
- Documentation fixes.

Thanks to David Gowers and zhangning for contributing patches to this release.

## Ren'Py 6.12.1

### Image Attributes

The process of showing images is now attribute-based. Image names now consist of a tag, and zero or more attributes. When showing an image, the order of attributes is no longer important – it's now possible to define an image using one set of attributes, and show it using those attributes in a different order.

Attributes are also "sticky". This means that we attempt to preserve as many attributes as possible when showing a new image.

For example, say we had the following images:

    image eileen beach happy = "eileen_beach_happy.png"
    image eileen beach woozy = "eileen_beach_woozy.png"

We can now show the first image using the command:

    show eileen happy beach

Since the order of attributes no longer matters, this will show the "eileen beach happy" image. If we follow this with the show statement:

    show eileen woozy

the image "eileen beach woozy" will be shown. (Assuming no other images exist. If the image "eileen happy woozy" existed, an ambiguity error would occur.)

When an image tag is shown without any attributes, then the current attributes are retained. Now, one can write:

    show eileen at right

to display Eileen on the right side of the screen, without changing the attributes supplied to an image.

Say Attributes. Image attributes can be updated as part of a say statement. A character can be given an image argument, giving the name of an image that character is linked to. As part of the say statement, image attributes can be given before the dialogue string. These attributes are given to the linked image.

For example, if we define a character using the code:

    define e = Character('Eileen', image="eileen")

the code:

    e woozy "I think I'm getting too much sun."

is equivalent to:

    show eileen woozy
    e "I think I'm getting too much sun."

whenever an image with the tag eileen is being shown.

Side Image. This release features a new implementation of Side Images, which allows side images to be defined like other images, and allows side images to be integrated with screens easily.

Sticky Transforms. Finally, showing an image without providing a transform or ATL block will now continue the previous transform that an image with that tag was using. Previously, it caused those transforms to stop.

### Error Handling

Ren'Py now has a new exception handing framework. Instead of always crashing when an error occurs, Ren'Py will now display the error message on the screen, and give the user the following choices, as appropriate to the situation:

- Rollback
- Reload
- Ignore
- Open Traceback
- Quit

When an editor is defined, Ren'Py will allow the user to click on a filename and line number to open that line in the editor.

The framework is used to handle exceptions and parse errors.

### Other

When in OpenGL mode, Ren'Py now remembers the window size between sessions. (This can be disabled using `config.save_physical_size`, and it may make sense to do so if your game is using the pre-screen preferences system.) Choosing the "Window" display preference now resizes the window to 100% of normal size.

Added the `xcenter` and `ycenter` position and transform properties. These set the position of the center of a displayable.

The `renpy.vibrate()` function allows Ren'Py to ask Android devices to vibrate.

The hyperlink style, callback, and focus functions have now been moved to the `hyperlink_functions` style property. This allows the functions to be changed on a per-style basis.

Indentation errors are now reported on the indented line, and not the line preceding the erroneous indentation.

Added the `SetScreenVariable()` and `ToggleScreenVariable()` actions. These allow screen-local variables to be changed.

Ren'Py now attempts to elide personal information from filenames. Where possible, filenames are reported relative to the base or Ren'Py base directories, rather than the root of the filesystem.

The new `box_wrap` style property allows hboxes and vboxes to automatically wrap when they reach the edge of their enclosing area.

Actions now can have an `Action.unhovered()` method. This method is called when an action supplied as a hovered parameter loses focus.

Added the `Tooltip` class, which makes it easier to define tooltips as part of a screen.

Added `config.debug_text_overflow`, which controls the logging of cases where text exceeds its allocated area.

Ren'Py no longer attempts to adjust the system level mixer controls, which means that it's no longer possible to raise the volume from within Ren'Py. Controlling the system volume exhibited bugs on all three platforms, including hard-to-predict volume changes that affect other applications.

Along with the new features, transitions have been documented in the new manual.

Archives are now automatically detected in asciibetical order. See the documentation for `config.archives` for more details.

Bug fixes:

- launchpad bug 734137 - Timers do not participate in rollback.
- launchpad bug 735187 - Ren'Py get stuck when using {nw}. (Thanks to Franck_v for tracking this down.)

## Ren'Py 6.12.0

### Android Support

Ren'Py now supports the Android platform. This includes support for a large fraction of Ren'Py's functionality, although we were unable to add support for imagedissolves and movie playback. It should be possible to package a Ren'Py game and distribute it through the Android market.

Android support required several changes in Ren'Py:

- The OpenGL renderer has been extended to support OpenGL ES.
- For performance reasons, much of the display system has been rewritten in the Cython language. This also should improve performance on other platforms.
- Support was added for the Android lifecycle. Ren'Py automatically saves when the android device suspends, and reloads (if necessary) upon resume.
- We added the concept of Screen Variants. This allows a single game to have multiple interfaces – such a mouse interface for computer platforms, and a touch interface for Android-based smartphones and tablets.
- We built a system that allows one to package a game separately from Ren'Py. This allows one to build packages without having to set up the Android NDK (you'll still need the Android SDK, Java, Python, Ant, and a lot of patience).

### New Widgets and Displayables

Added the SpriteManager displayable. This provides a high-performance way of drawing many similar sprites to the screen. This can scale to hundreds of particles, provided those particles are mostly similar to each other.

Added the Mousearea widget. A mousearea allows hovered and unhovered callbacks to occur when the mouse enters and leaves an area of the screen. Since it doesn't participate in the focus system, a mousearea can include buttons and bars.

Added Drag and Drop widgets and displayables. The drag and drop system can support:

- Windows being repositioned by the user.
- Card games.
- Inventory systems.
- Drag-to-reorder systems.

### Image Prediction

Ren'Py is now better at predicting image usage. Along with predicting images used by normal gameplay, it now attempts to predict images that are used by screens one click away from the user. For example, during normal gameplay, it will predict images on the first screen of the game menu. While at the game menu, it will predict the other screens of the game menu, and also the images the user will see when returning to the main menu. This prediction is automatic, but only occurs when using screens.

Screens may be invoked at any time, in order to allow for image prediction, unless they have a predict property of False. This means that displaying a screen should not have side effects. (Most screens only have side effects when a button is clicked or a bar changed – that's still fine.)

Ren'Py now supports hotspot caching for screen language imagemaps. When `config.developer` is true, Ren'Py will write a PNG file in the game/cache/ directory containing image data for each of the hotspots in the imagemap. If the cache file exists (regardless of the config.developer setting) it will be loaded instead of loading the hotspot images. As the cache file is often much smaller than the size of the hotspot images, it will load faster and reduce image cache pressure, improving game performance. This behavior only applies to screen language imagemaps, and can be disabled with `config.imagemap_cache`.

This should remove most of the need for `renpy.cache_pin()`. While not an error, the use of cache pinning can cause unnecessary memory usage when the wrong image is loaded.

### Screens

Ren'Py now ships with a default set of screens, which are used by the demo and installed by default when a new game is created. You can find them in template/game/screens.rpy, and they can be used by copying that file into your project. These screens are not 100% compatible with the previous layout system – for example, some styles have changed. That's why games must opt-in to them.

The definition of the items parameter of the Choice and NVL screens has changed, and games will need to be updated to work with the new version.

Character arguments beginning with `show_` are passed to the Say screen. This allows things like show_side_image and show_two_window to work with screens. The screens we ship support these options.

The new `config.imagemap_auto_function` variable allows the game-maker to control the interpretation of the `auto` property of imagemaps and imagebuttons.

The imagemap caching behavior described above applies only to screens.

The `FilePageName()` and `FileSlotName()` functions make it easier to name slots

### Other Improvements

Ren'Py 6.12 includes a number of other improvements:

- We've continued writing the new manual. Notably, we have rewritten the documentation for displayables.
- When taking a screenshot, `config.screenshot_callback` is called. The default implementation of this function notifies the user of the location of the screenshot.
- The `Solid()` and `Frame()` displayables are now tiny and no longer take up (much) space in the image cache.
- We now create a log.txt file, which replaces the old opengl.txt, and can log other subsystems.
- Several missing properties have been added to the screen language.
- Ren'Py now treats filenames as if they were case-insensitive. This means that filename mismatches on Linux should no longer be a problem.

### Bug Fixes

- launchpad bug 680266 - Ensures that dynamic displayables update before Transforms that use them.
- launchpad bug 683412 - Do not crash if a shader fails to compile.
- Fixed a bug that caused Ren'Py to crash when the system volume was lowered to 0, but not muted.
- Fixed a bug that prevented `Render.canvas()` from working with the OpenGL renderer.

## Ren'Py 6.11.2

### New Features

This release includes four new themes, generously contributed by Aleema. You can see and change to these new themes by clicking the "Choose Theme" button in the launcher.

### Software Update

The jEdit text editor included with Ren'Py has been updated to version 4.3.2, a supported version that should be able to run most plugins.

### Behavior Changes

The maximum default physical size of the Ren'Py window is now 102 pixels smaller than the height of the screen. This should prevent Ren'Py from creating windows that can't be resized since they are much bigger than the screen.

Buttons now only pass key events to their children when they are focused. This allows a screen language key statement to be used as the child of a button, and only activate when the button is focused.

MoveTransition was rewritten to correctly deal with cases in which images changed their order. This may lead to differences in behavior from the old version, where the ordering was undefined.

### Bug fixes

Fixed launchpad bug 647686, a regression that prevented sounds from looping properly.

Fixed launchpad bug 661983, which caused insensitive hotspots to default to the idle, rather than ground, image when no insensitive image was supplied.

Fixed launchpad bug 647324, where ImageDissolves are rendered as if specified with alpha=True whether or not alpha=True was set.

Fixed a problem that caused the game to start when picking "No" after clicking the (window-level) quit button.

Fixed a problem that prevented AnimatedValue from functioning properly when delay was not 1.0. Thanks to Scout for the fix.

Fixed a problem that caused movies to display incorrectly when the screen was scaled using OpenGL scaling.

## Ren'Py 6.11.1

### New Features

Add the `AlphaBlend()` displayable and the `AlphaDissolve()` transition. These take two displayables, and use the alpha channel of a third displayable to blend them together. (The third displayable is often an animation, allowing the effect to change over time.)

The new Modes system allows one to invoke callbacks when switching from one type of interaction to another. This can be used, for example, to automatically hide the window before transitions.

Imagemaps created using the screen language now only have a size equal to that of their ground image. (Previously, they took up the entire screen.) This change makes it easier to position an imagemap at a different location on screen, such as the bottom.

Imagemaps now take an alpha argument. If true (the default), hotspots are only focused if the mouse is over a non-transparent part of the idle or hover image. If set to false, the hotspot is focused whenever the mouse is within its boundaries.

Added the `renpy.focus_coordinates()` function, which returns the coordinates of the currently focused displayable, when possible.

The new `renpy.notify()` function and `Notify()` action make it simple to flash small status messages on the screen, such as might be used to notify the user of a completed quicksave or screenshot.

The new `HideInterface()` action allows the interface to temporarily be hidden, as a screen language action.

The developer menu now includes a command that will list all the files in the game directory.

The urllib and urllib2 modules from the Python standard library are now distributed as part of Ren'Py. These modules allow data to be retrieved from web servers.

The launcher now includes an experimental updater, that makes it easier to update to the latest pre-release. Hitting Shift+U at the launcher's main screen will cause Ren'Py to be updated.

### Fixes

`MoveTransition()` now respects the xoffset and yoffset parameters.

Fixed several bugs with screen-language imagemaps.

Fixed a bug (#626303) that was caused by an incorrect texture unit check. Thanks to tmrwiz for the fix.

Transforms no longer cause a divide by zero exception when the zoom, xzoom, or yzoom properties are 0.

Clockwise and counterclockwise revolution in transforms now works.

Fixed a bug with scaling, that occurred when switching between the scaled software and GL renderers.

Hidden screens are no longer considered when assigning default focus.

FieldValues with max_is_zero set to True now work properly. Thanks to SleepKirby for the fix.

## Ren'Py 6.11.0

### OpenGL Support

Ren'Py will now take advantage of a computer's OpenGL hardware acceleration, if supported. This OpenGL support has several user-visible changes:

- The window containing a Ren'Py game can be resized or maximized, using standard window controls. When the window's aspect ratio does not match the game's aspect ratio, black bars will be added.
- Displaying in full-screen mode should not change the monitor's resolution. This will prevent the game from being distorted when displayed on a monitor with a different aspect ratio.
- Unless disabled in the video driver configuration, Ren'Py will use vertical blank synchronization, eliminating image tearing.
- GPU rendering is used, which should make drawing the screen faster in most circumstances.

Software rendering is still supported, and Ren'Py will automatically fall back to software rendering if it detects an improperly configured video card.

You can test that Ren'Py is in OpenGL mode by attempting to resize the window. If it's resizable, it's OpenGL, otherwise, software rendering is being used.

### Screens and Screen Language

This release introduces a new screen system, which allows one to use the new screen language to declaratively specify portions of the user interface. The screen language supersedes layouts, overlay functions, imagemaps, and most other means of customizing the out-of-game menus and the in-game screens.

The previous way of customizing the behavior of the game menu, the layout system, had problems, especially when using imagemap layouts. Screens were single-purpose, and it would be difficult to (for example) load a quick-save game from the main menu, without extensive Python code.

The screen system addresses this by providing a pool of functionality, in the form of Actions and BarValues. This makes it possible to pick and choose functionality, and add it to screens as is deemed necessary.

### Transform Changes

- If a transform does not define one of the position properties `xpos`, `ypos`, `xanchor`, or `yanchor`, that property will be taken from the transform's child, if the defines that property.

  This makes it possible to have one transform control a displayable's vertical motion, and the other control the horizontal. But this is incompatible with previous behavior, and so can be disabled with the `config.transform_uses_child_position` variable.

- The new config.default_transform variable allows a transform to specify the initial transform properties of an image that does not have a more specific transform applied to it. Its default value is center, a transform that shows the image at the center-bottom of the screen.

  This can lead to a behavior change. When an image is shown, and then shown transforms, the transform will be initialized to the bottom center of the screen, not the top-left. The reset transform can be used to reset the position to the top-left.

- Transform (and ui.transform) have been changed so that their arguments can now be prefixed with a style prefix. One can write ui.transform(idle_rotate=30, hover_rotate=90) and have it work.

- Added the rotate_pad transform property, which controls how Transform pads rotated displayables. When set to False, _not_ the default, it's now possible to rotate a (100, 50) displayable by 90 degrees, and have the result be (50, 100) in size.

### Other Changes

- The Ren'Py documentation is in the process of being rewritten. This changelog is now being maintained as part of the Ren'Py documentation.

- Added support for composite style properties, that allow several style properties to be set using a single parameter. The new composite style properties are:

  - pos - takes a pair, and uses it to set xpos and ypos.
  - anchor - takes a pair, and uses it to set xanchor and yanchor.
  - align - takes a pair, and uses it to set xalign and yalign. (And hence xpos, ypos, xanchor, and yanchor.)
  - area - take (x, y, height, width) pair, and tries to set properties such that the displayable will be placed inside the rectangle. This sets the xpos, ypos, xanchor, yanchor, xfill, yfill, xminimum, yminimum, xmaximum, and ymaximum properties.

- ui.add can now take transform properties as keyword arguments. If at least one transform property is present, ui.add will create a transform that wraps the displayable it's adding to the screen.

- The new `LiveTile()` displayable tiles its child, without consuming a large amount of memory to do so.

- `config.quit_action` allows one to specify an action that is run when the quit button (in the corner of the window) is pressed. config.game_menu_action allows one to specify an action that is run when entering the game menu.

- The `config.screenshot_crop` configuration variable controls the area of the screen that it stored when the user presses the screenshot key.

- The `renpy.music.register_channel()` method now has two additional parameters, file_prefix and file_suffix. These are prepended and appended to filenames provided to the registered channel, respectively.

- The new `renpy.list_files()` method returns a list of files in the game directory and archives. This can be used to write your own automatic image loading method, among other things.

- The interaction between Character and Text has been rewritten to ensure that text is only tokenized once. This required changing a few of the methods on ADVCharacter and NVLCharacter, so code that inherits from those classes should be checked.

- The distribution code has been moved into launcher/distribute.py. This file can be run from the command line to build distributions in shell scripts and other automated processes.

- When there are transparent areas on the screen, and `config.developer` is true, the transparent areas are filled with a checkerboard pattern.

- The new `input`, `side`, `grid`, and `fixed` styles were created, and the corresponding displayables use them by default.

- When a style is accessed at init time, and doesn't exist, we divide it into two parts at the first underscore. If the second part corresponds to an existing style, we create a new style instead of causing an error.

- The Python compiler has been rewritten to use the Python ast module. This should both improve performance, and improve error handling for Python syntax.

  Because of this change, Ren'Py now ships with and requires Python 2.6.

- The following numbered bugs were fixed:

  - 520276 - ctc does not appear when cps interrupted
  - 526297 - im.Rotozoom()s crash when Ren'Py is scaled down. (Thanks to Spiky Caterpillar for the bug report and fix.)
  - 543785 - Launcher bug on select Projects Directory
  - 583112 - rollback while a movie displayable is shown leaves a video frame onscreen
  - 595532 - Wrong text in tutorial game. (Thanks to Viliam Búr.)

- The following other bugs were fixed:

  - Renamed the internal show and hide methods of Displayable, so those names can once again be used by user-defined displayables.
  - Rewrote MultipleTransition (which is used by Fade) to fix some problems it was exhibiting.
  - Take the condition parameter to Character into account when determining if an nvl clear occurs before the next interaction.

## Older Changelogs

Older changelogs can be found at:

> https://www.renpy.org/dl/6.10.2/CHANGELOG.txt