Changes potentially requiring updates to scripts are flagged with +++. Major bug fixes that could affect many systems are indicated with !!!. New in Ren'Py 5.5.2b -------------------- Fixed bug in packaging. New in Ren'Py 5.5.2a -------------------- Fixed bug in lint. New in Ren'Py 5.5.2 ------------------- +++ SFonts are now rendered in color. When a non-(255, 255, 255, 255) color is supplied to a SFont, the supplied image is remapped so that each channel has its value interpolated between 0 and the supplied color. Most importantly, this means that white pixels will have the supplied color. This functionality means that drop shadows are now rendered correctly. Fixed a bug that prevented Animations with long or no repeats from functioning correctly. New in Ren'Py 5.5.1 ------------------- Fixed a bug with clipping rectangle computations, when faced with an image larger then the screen. Added im.Flip, an image manipulator that allows images to be flipped in a vertical or horizontal direction. Fixed a longstanding bug in the DSE that prevented event.only and event.solo from working. The save_name variable can now be a unicode string. Fixed the voice.rpy and kanamode.rpy extras to work with modern versions of Ren'Py. Added provisions for utf-8 characters in the window title, on platforms that allow that. There is now a new displayable, DynamicDisplayable, that executes an expression upon each interaction and uses the result of that expression as a displayable. There is now support for hypertext in Ren'Py, using the {a=argument}{/a} text tags. This support can be further controlled using the config.hypertext_callback variable. New in Ren'Py 5.5.0 ------------------- The library.script_version should be set to (5, 5, 0) to take advantages of changes in this version. The big feature of this release is the new Ren'Py default theme, which can be enabled by calling theme.roundrect(). This theme can easily be recolored. An alternate version of this theme can loaded by calling theme.roundrect_red(). The call should be placed after library.script_version and config.screen_width have been assigned to. +++ config.with_callback has been changed. It now takes two arguments. The first is the transition being performed. If this transition is a None transition created as part of a scene, show, or hide statement, then the second argument is the transition found in that statement. Otherwise, it is None. config.with_callback is now requried to return a transition, which replaces the specified transition. Hopefully, this is enough to make with_callback useful, by always giving the callback information specified by the user. The list of characters used by SFonts was wrong, so that has been fixed. The documentation has also been improved to include a convenient list of what those fonts should look like. Character has been updated to pass arguments beginning with show_ as keyword arguments to its show_function and predict_function. There is a new function, ui.frame(), which has been split off from ui.window(). While both functions create a window, the default style of frame is one that allows widgets to be placed atop it. (Whereas ui.window() generates a window optimized for text.) There is a new property, box_first_spacing, that if not None gives the spacing between the first and second elements of a hbox or vbox. The xfill and yfill properties also are now used by vboxes and hboxes. renpy.music.play and renpy.music.queue have been updated to take lists of filenames as well as single filenames. If a list of filenames is given, and loop is True, Ren'Py will loop through the list of filenames, rather than a single filename. Two variables, library.main_menu_music and library.game_menu_music allow one to cause music to be played when in the main and game menus, respectively. By setting the library.always_has_joystick variable to True, one can access the joystick menu even if no joystick is connected to the computer. This enables a joystickless developer to customize the joystick menu. A bug that prevented music changed by a game menu from reverting back when leaving the game menu has been fixed. A bug that prevented a fixed click-to-continue indicator from working has been fixed. The screenshots taken with the 's' key are now PNGs, rather than BMPs. There is a new image operation, im.Recolor, that can be used to recolor each channel of an image. A new config variable, config.sound, can be used to completely disable the sound subsystem. Fonts can now be read out of .rpa archives. A number of styles have been renamed. The following are the style name changes: style.error_window -> style.error_root style.file_picker_window -> style.file_picker_frame style.file_picker_window_vbox -> style.file_picker_frame_vbox style.gm_nav_window -> style.gm_nav_frame style.gm_root_window -> style.gm_root style.joy_vbox -> style.js_frame_vbox style.joy_window -> style.js_frame style.joyfunc -> style.js_function style.joyfunc_label -> style.js_function_label style.joyprompt -> style.js_prompt style.joyprompt_label -> style.js_prompt_label style.mm_menu_window -> style.mm_menu_frame style.mm_menu_window_vbox -> style.mm_menu_frame_vbox style.mm_root_window -> style.mm_root style.prefs_pref -> style.prefs_pref_frame style.prefs_window -> style.prefs_frame style.yesno_window -> style.yesno_frame style.yesno_window_vbox -> style.yesno_frame_vbox Basically, the purpose was to normalize styles with the frame vs window distinction, and to normalize the abbreviation of joystick as js. Previous style names will work for the forseeable future. New in Ren'Py 5.4.5 ------------------- There is now a variable, library.script_version, that should be set by all scripts to (5, 4, 5). While this variable isn't used yet, it will be used by future version of Ren'Py (the 5.5/6 series) to ensure that current scripts remain compatible with changes to Ren'Py proper. Ren'Py now supports SFonts, which are image files containing character images and separator information. Once SFonts are registered (using renpy.register_sfont), they can be used any place TTF fonts can, although they cannot be scaled, recolored, bolded, italiced, or underlined automatically like TTF fonts. Despite this, SFonts have some advantages. They are bitmapped fonts, with all the legal advantages that implies (in the US). They also allow special effects to be precomposed onto fonts, if necessary. Ren'Py's implementation of SFonts is a new one, not borrowing from other libraries. It supports the use of an arbitrary unicode character set (defaulting to the usual ASCII-oriented SFont character set) and kerning. Slow text and skipping conflicted, in that when skipping one will see the slow text effect. This may be a regression, but it's fixed now. Properties can now be deleted from styles. Deleting a property from a style allows it to be inherited from that style's parent, using the usual inheritence rules. There is now a function, ui.clear(), that clears out a layer. This allows the ui functions to be used on non-transient layers, although not all widgets may be used in this way. Ren'Py now takes some new command line options. The --savedir option allows the user to set the directory in which Ren'Py saves data in. This allows Ren'Py games to be run from a non-writable directory. The --version option prints the version of Ren'Py. The --compile option causes Ren'Py to compile rpy files into rpyb files. There is now a variable, config.lint_hooks, that contains functions that are called at lint time. A new extra, translations.py, gives all of the translatable strings in the Ren'Py common code. +++ Fixed a bug in renpy.music.set_music, in which the test was inverted in the code. (But not in the documentation.) This may require a script change if your game uses the undocumented behavior of that button. New in Ren'Py 5.4.4 ------------------- Updated the gallery extra to support showing arbitrary displayables, rather than just images with filenames. It was also updated to support tuples, corresponding to composing one image atop another, and lists, which display things in sequence. To support this, the tuples used by gallery take a third argument which gives a filename which is used, somewhat indirectly, to compute the thumbnail. Clarified that the voice extra can take non-wave sound files, such as OGG Vorbis and especially OGG Speex files. Also, made voice automatically sustain through pauses. Fixed a bug in Ren'Py that was causing the voice extra to malfunction. The bug was caused by the contents of the config namespace being copied at the wrong time, leading it to not be restored properly to default values when Ren'Py was reset (as the Main Menu choice.) Removed a leftover debugging statement that caused Ren'Py to spew out all of the say statements in .rpy files it parsed. New in Ren'Py 5.4.3 ------------------- The format of archive files has been changed, to store each media file contiguously on disk. This allows us to use disk access to retrieve files from archives, whereas previously the files had to be reassembled in memory before use. Eliminating this memory assembly can drop the resident size of Ren'Py significantly. (When music was playing, there was a memory overhead equal to double the size of the playing file... this has been eliminated.) While Ren'Py remains compatible with the older-format archives, regenerating the archives for a game allows it to take advantage of the new format. RELEASING.txt has been updated and corrected. Empty strings are now allowed in Say statements, although it's not immediately obvious to me why they would be used, except in some strange cases, or as placeholders. The presence of tabs in a script causes a more appropriate error message to be generated. Previously, they simply caused random parse errors. Fixed a bug preventing dump_text.bat and archiver.bat from working. New in Ren'Py 5.4.2 ------------------- The renpy.display_say function was refactored into two functions, renpy.display_say and renpy.show_display_say. In it's original incarnation, display_say had been a simple function responsible for showing dialogue to the user. Over the past few months, it has accreted logic for click-to-continue and for slow text, among other features. This made it hard to change the behavior of display_say, as a function overriding it would have to implement all that logic itself. To fix this, we've created a new function, renpy.show_display_say, and made Character and display_say take a new parameter, show_function. This function is now responsible for actually placing widgets on the screen. It has a reasonably well-defined interface, to allow it to be overridden by user code in a way in which display_say is no longer practically able to be. +++ The two_window_say extra has been rewritten to take advantage of this refactoring. To update, you'll need to copy over the new copy of two_window_say. You'll then need to change Character objects with the argument "function=two_window_say", to instead have the argument "show_function=two_window_say". In return for this, features such as pauses in text and slow text now work with two_window_say. Ren'Py now displays dialogue shown via a rollback as quickly as possible. This is a change from the previous behavior, which was to show such dialogue at the speed set by the "Text Speed" preference. The sound module has been rewritten to play sound (or silence) all the time, rather than pausing and restarting sound playback as necessary. This eliminates popping and errors in some edge cases, like playing a very short sound. Fixed a bug in the move transition that manifests itself if the move transition is used while a transient is on the screen. Fixed a bug that prevented ImageDissolves from working correctly on big-ending platforms, like PowerPC-based Macs. Fixed a bug that caused crashes with a presplash image on non-mac computers. New in Ren'Py 5.4.1 ------------------- Integrated the results of "Project Bardiche". This project aimed to improve the cross-platform compatibility of Ren'Py by building it with the same libraries, compiled with the same options, across all three supported platforms. As a secondary goal, we will also make available in a single bundle the source to all of these libraries, and a script that can be called to build them all from scratch. The biggest user-visible change is that fonts are now rendered the same on Linux and Windows. Previously, Linux fonts tended to be a little less thick, which could lead to text being placed differently. With this release, we also give the image and font file formats that we officially support. We support PNG, JPG, GIF, BMP, and TGA images (although the latter two are discouraged, due to a lack of compression). We support TrueType fonts. It is now possible to declare a Character with interact=False. Made movies work more reliably on Windows and Mac. Movie() now takes an fps argument, which specifies how many frames per second of the movie to display. This gives the system some time to actually go and render the movie itself. !!! Fixed a serious bug that caused Ren'Py to crash whenever a text speed slower than 100% was selected. New in Ren'Py 5.4.0 ------------------- This release introduces time correctness to the display subsystem of Ren'Py. Previously, time was a kinda flexible concept in Ren'Py. Objects were shown sometime before the first frame of an interaction, and the frames that we drew represented a smear of time, rather than some precise instant. This release changes that. Each frame now represents a single instant in time, and the timebases for things like animations, motions, and transitions all begin at the instant of the first frame of the first interaction in which they are present. We also have precisely defined two timebases that displayables can use. The displayable timebase starts at the instant of the first frame in which a given displayable was present, while the animation timebase begins at the instant of the first frame in which an image with the same tag is present. Having two timebases makes it easier to specify what we want happening when, say, an animation is placed inside a motion. Animations default to the animation timebase, while motions default to the motion timebase, but both have an option (anim_timebase) that lets you specify which timebases is wanted. For example, one may want to switch a looping motion onto the animation timebase if one wants to allow the character's expression to change while the motion continues. We've implemented a more precise timeout system in Ren'Py. Previously, if we wanted to have an event occur at some time after a displayable has been shown, we'd have to use use the 20hz periodic event and deal with it as part of that. The meant that our best timing precision was 50ms, and often it was significantly worse (up to 100ms or so). Now, we can schedule precise timeouts for event delivery, down to the ~10ms range. Among other things, this allows for more accurate pauses, and skipping to occur at a rate faster than the previous limit of 10 screens per second or so. Integrated a Zoom function into Ren'Py. This function lets you zoom into or out of an image. renpy.music.play() now takes a if_changed parameter. If given as True, and the music to be played is already playing, then the music will not be stopped and restarted. Use this when you want to immediately restart the music if and only if the music differs from the currently playing music. Added Fixed, HBox, and VBox functions to the script namespace. These functions allow multiple displayables to be used when only a single displayable is expected. SnowBlossom now takes a start parameter, the value of which should be an amount of time in seconds. The starting times of the various particles are spread out over this amount of time. The say and menu statements now supports unicode escapes. These should be a \u followed by 1-4 hex digits, and are used to include a unicode character. For example, \u00a0 will include the unicode NO-BREAK SPACE character. +++ We have changed the way placement of images work. Now, when used as a widget, images and animations default to the same placement as everything else (xpos=0, ypos=0, xanchor=0, yanchor=0). When used in an image (shown with show or scene), the placement of other displayables is now similar to that of an animation or image. The goal of this change is to make more regular programming using the ui functions, and the new semantics should lead to behavior that is similar to the old semantics. Fixed a bug that cause Animations and anim.Filmstrips to ignore position properties supplied to them. Now, these object properly respect position properties supplied to them. !!! Fixed a bug that caused Ren'Py to crash when attempting to predict images from transitions associated with say or menu statements. The screenshot key (s) now creates numbered screenshots. Made some internal changes that allow us to integrate better with libraries written in pygame, especially PGU. This could someday in the future allow for maps written in PGU to be integrated into a Ren'Py game. (http://www.imitationpickles.org/pgu/) New in Ren'Py 5.3.3 ------------------- Implemented a particle animation system, which allows absurdly high amounts of control of particles that are on the screen. It also allows these particles to be created during the middle of the interaction. The primary purpose of this Particles displayable is to allow for things like snow and falling cherry blossom leaves. We also have a special case constructor, SnowBlossom, that is intended for snow, cherry blossoms, and rising bubbles. Finally got around to defining which audio formats Ren'Py officially supports. On the 3 platforms we produce binaries for, Ren'Py supports WAV, MP3, OGG Vorbis, OGG Speex and MOD (Whatever formats ModPlug supports, including MOD and XM). All these formats were tested on all three platforms, and shown to work. Implemented tight sound and music support. Tight sounds are sounds that do not stop, but instead are expected to seamlessly blend with the following sound or music segment. While these were supported in prior versions of Ren'Py, there was an issue with fadeout. If a fadeout occured near the end of a sound segment, the sound would suddenly stop. While this isn't an issue with normal tracks, for tracks involving tight loops this isn't desirable. Tight loop mode makes fadeouts span tracks, making the fadeout sound correct. Tight loop support only supports spanning a single track boundary, so the fadeout should be shorter then a single track length. Ren'Py now tracks which menu choices have been chosen by the user (ever, in any game), and gives the choices that have been chosen at least once the new styles menu_choice_chosen and menu_choice_chosen_button. By changing some of the properties of these styles, it's possible to the user a distinction between the choices the user has chosen once, and those the user has never chosen. Added a new function, anim.Filmstrip, that allows one to make an animation out of an image containing a number of frames. A set type that participates in rollback has been made available to user scripts. This type is named "set". The code that supports seensets in menus has been modified to accept a set along with a list. We now use modplug instead of mikmod. This fixes some problems with mod playing that were caused by mikmod not really being able to safely play two mods at the same time. (These problems occured even when someone only played one mod at a time, due to the way in which Ren'Py preloads sound files.) We now compute the set of rectangles to blit to the screen more precisely. If we have two non-overlapping updated areas of the screen, we now blit them individually, where previously we blit the smallest rectangle containing them both. (Which could be many times the size of the two updates, if they were small and widely separated.) This change makes particle animation more efficient. Made lint report the number of words per screen of dialogue. Also, made lint not throw Ren'Py into an infinite loop, fixing a regression. Fixed a problem in which animations were not showing their first frame. Worked around a bug in SDL that could cause popping in the case where a sound file was being mixed in at a length that was not a multiple of 4 samples. New in Ren'Py 5.3.2 ------------------- Joystick support now exposes Hold to Skip and Hide Text functionality to the user. We now support the fading in of PCM (that is, non-MIDI) music and sounds. Fixed a regression in voice.rpy. New in Ren'Py 5.3.1 ------------------- Ren'Py now includes support for using a joystick to play the game. To configure joystick support, go into Preferences, click Advanced..., and then click the function you wish to assign to a joystick axis or button. ImageDissolve now support a ramp parameter, which can be used to give the ramp explicitly. Now, we preload the images that are used in say statement, menus, and transitions. This means that just about every image in a basic game should be preloaded, which should in turn lead to an improved user experience and a lack of pauses for image loading. To support this, the Character function grew a predict_function argument, and there are now also predict_menu and predict_say functions at the top-level. Setting a config or library variable that does not exist is now an now raises an error. Previously, this was ignored silently. If it exists, renpy.zip is added to the python search path. This lets one replace the renpy/ directory with a renpy.zip file containing that directory, if so desired. A non-nested return now returns the user to the main menu, rather than dumping him out of Ren'Py entirely. Fixed a bug that required Tab to be pressed twice to re-enable skip mode after skipping was terminated by hitting a menu. Maybe fixed a bug that was preventing non-fullscreen video from working. (I'm not totally sure this is a real bug.) Fixed a bug that prevents certain MOD files (including the .xm files that shipped with the non-Ren'Py game Transfer Teacher) from working under Ren'Py. This required the creation of a new Ren'Py Launcher for Macintosh, as well as a new release of the renpy module installer for Windows. New in Ren'Py 5.3.0 ------------------- This changelog has been updated to flag changes requiring (or suggesting) script updates, or providing major bug fixes. !!! Script compatibility has been broken, but for a good reason. The previous version of Ren'Py stored python blocks in the script as bits of python bytecode in the .rpyc file. This has a problem. Python bytecode is not guaranteed to be forward or backwards compatible. Without some sort of versioning, an upgrade of python could cause these bytecodes to be silently interpreted incorrectly, which could lead to games failing to work properly. To fix this, several things have changed. The .rpyc files now store the python script, rather than just the bytecode. The bytecode has been moved into a bytecode.rpyb file, which is automatically created when a script changes. This file contains versioned bytecode, and is automatically regenerated if either the source code changes or the version of python used to run Ren'Py changes. It is always generated into the game directory. While it is possible to include bytecode.rpyb into a .rpya file (under the same conditions as .rpyc files can be added to .rpya files), realize that it may spring into existence in the game directory automatically if the user tries to run Ren'Py with a newer or older version of python. One should ship bytecode.rpyb as part of a completed Ren'Py game. There are now a few changes to Ren'Py to allow it to better support scripts that are not games. Some of the internal messages have been changed to remove the word "game". While "game" has still been left in the most prominent places (the main and game menus), this is because these places are the most obvious to the user, and hence the most likely to be translated using library.translations. For the same reason, Ren'Py will also search for the game in a data/ directory if the game/ directory is not found, and it will then look for the game scripts in data.rpa along with game.rpa. ImageDissolve now supports a number of different kinds of alpha ramps. Along with the default linear, we now support cubic, double-cubic, and mirrored-double-cubic ramp types. These types of ramps allow for smoother or sharper ImageDissolve transtions. Thanks go to shaja for contributing the code that implements this. +++ Alpha channels are now supported on text colors. When rendering text with a color or drop_shadow_color having an alpha that is not 255, that alpha is then used to scale the alpha channel of the drawn text. This basically means that alpha is now respected in text, wheras previously it was ignored. The default drop_shadow_color is now (0, 0, 0, 255), for compatibility with the way drop shadows were rendered previously. If user code renders text with an alpha that is not 255, the alpha should be set to 255 to ensure the text is rendered the same way as before. The DSE has been updated. There are now new event.only() and event.choose_one() condition functions, and a basic guide to writing events in the DSE can be found in extras/dse/EVENTS.txt. Now, user code can import python modules from the game directory and .rpa archives. A guide to using Python to extened Ren'Py can be found in doc/EXTENDING.txt. For now, it's just about how to use pygame code with Ren'Py. Renamed extras/chinese.rpy to extras/east_asian.rpy, and changed the line breaking algorithm to one that can be used with both Chinese and Japanese text. It may also be usable with Korean, but I'm not sure about that. Made the zero-width-space character break lines if necessary, so it can be used to have auto-breaking with Thai. All defined preferences are now found in library.all_preferences, which provides a level of indirection when customizing the preferences screens. Now, we force the presplash to be shown using windib. This can fix potential directx incompatibility bugs with Windows XP. This only is an issue if a game has a presplash, the bug was fixed for regular code in 5.1.1. The presplash is also shown faster now, before the rest of Ren'Py loads. Fixed a bug that affected voice. This required splitting config.interact_callbacks into config.interact_callbacks and the new config.start_interact_callbacks. The latter is called exactly once per interaction, while the former is called whenever an interaction starts or restarts. Fixed a bug with non-ascii text and the new log feature. Now, invoking Ren'Py with --profile on the command line does the same thing as setting config.profile in the script, without requiring the user to actually change the script. Moved most of the code that used to be in run_game.py into renpy/bootstrap.py (the renpy.bootstrap module.) This shouldn't really affect anything, but it does make run_game.py a bit cleaner. New in Ren'Py 5.2.1 ------------------- Added a command that allows the user to skip to the next choice. Primarily intended for developers, this feature needs to be enabled by setting config.fast_skipping to True before it can be used. Once enabled, fast skipping can be activated by typing '>'. It jumps the user to the next interaction that isn't a say, a transition, or a call to renpy.pause() Setting config.log to a filename will now cause a log of the user's actions to be written to that filename. Added (optional, and discouraged) monkeypatch protection through the --lock command-line option. Fixed a regression, introduced in 5.1.6, that prevented what_prefix and what_suffix from working. New in Ren'Py 5.2.0 ------------------- Restructured the distribution. All of the tools are now in the tools/ directory, while the dse has been moved to extras/dse, with a script to launch it found in tools/. Implemented a new warp feature. By supplying a filename and line number, this feature tries to jump you to the statement preceding that line. It isn't perfect, but for some games, this lets you have a live preview of the game. Please see the reference manual for instructions on how to invoke this, and a number of caveats. Also implemented an editor feature. By pressing E (that's shift-e), one can launch an editor at the location of the current statement in the Ren'Py program. To enable this, one needs to set config.editor to the command line for your favorite text editor. Again, see the reference manual (for config.editor) for more details. Implemented a new function, renpy.get_filename_line(), which returns the filename and line number of the currently executing statement. This can be used in conjunction with renpy.watch() to constantly display the line number of the current statement. Fixed a bug in the text widget that caused it to be sized incorrectly in certain cases. Fixed an incorrect reference to a wav that became an ogg in the demo. Modified renpy.watch() so that it coerces the result of evaluating its argument to unicode, meaning it's no longer necessary to manually do so. New in Ren'Py 5.1.6 ------------------- Fixed Motion (the class that implements Move and Pan) to allow motions to be used as transitions, in conjunction with the say and menu statements. Previously, they only worked with the with statement. Added a new variable, config.with_callback, that can be used to specify a function that is called when a with statement runs. This can be used, for example, to put up a window when a transition occurs, which has the effect of preventing the window from disappearing. Implemented a new text tag, {fast}. This tag causes the slow text display to start from a given point in the text string. This allows one to show some text, run some command, and show the same text with additions, and have the slow text display occur correctly. Character objects now can take properties prefixed with what_ or window_. Properties prefixed with what_ are applied to the text being spoken, while those prefixed with window_ are applied to the window containing everything. Unprefixed properties are still applied to the label giving the name of the character speaking. There is now a new function, LiveComposite, that can composite together arbitrary displayables, rather than just images. It has the same API as im.Composite, but should be used when one of the things you wish to composite is an animation. A new variable, config.auto_choice_delay, has been added. If not None, this variable gives a number of seconds that Ren'Py will pause at an in-game menu before picking a random choice from that menu. We'd expect this variable to always be set to None in released games, but setting it to a number will allow for automated demonstrations of games without much human interaction. The kanamode.rpy extra has been updated to support some of the newer features, like slow text and auto-forward mode. +++ Archives now combine the index and the data into a single file. Now, instead of needing .rpa and .rpi files, only a .rpa file is needed (and is created). The code and the archiver have been updated to support this new format. The code still supports reading the old format, for compatibility purposes. When archives are re-created, the .rpi file can be deleted with no ill effects. There is now a new function, renpy.block_rollback(), that prevents Ren'Py from rolling back through the point at which it was called. Renamed config.overlay_during_wait to config.overlay_during_with, since the former name was a mistake. New in Ren'Py 5.1.5 ------------------- There are now two new variables, library.main_menu_positions and library.game_menu_positions. If not None, then we expect these variables to be maps between main or game menu navigation button labels, and properties that will be supplied to those buttons. This is intended to allow the user to manually position the various buttons. This shuts off the default positioning code, so if you position one button in a menu, you'll need to position them all. Added a new extra, menu_positions.rpy, that demonstrates the new positioning code. Added a new extra, quick_save.rpy, that adds a quick save feature to Ren'Py. This feature adds a single save slot that can be quickly accessed without going through the game menu. It also adds a quick load button to the main menu, which causes a load from this slot. The button is disabled if no quick save game exists. +++ To support this, changed the format of library.main_menu. Now, instead of being a list of pairs, library.main_menu is a list of triples. The new third component is an expression, which must evaluate to true for the menu button to be enabled. Fixed a bug in lint that was caused by the introduction of the onlayer clause in Ren'Py 5.1.3. This bug caused lint to fail entirely, so not it works again. Added raw string literals, although they're not a documented feature. New in Ren'Py 5.1.4 ------------------- Implemented two new text tags, {w} and {p}. {w} pauses the display of dialogue, waiting for the user to click to continue. {p} does the same thing, but also breaks the line where it occurs. Added a framerate limiter. When enabled by setting config.framerate, Ren'Py limits the number of frames that are displayed per second to the supplied values. This tends to smooth out the framerate, and hence the percieved smoothness of the program. It will lower the overall framerate, but make it more regular. Some improvements in the auto-forward mode. AFM will no longer dismiss text when it is still being drawn onto the screen. (Because the text speed is not infinite.) There is now also an AFM callback that can be used to control if an auto-forward occurs. This is intended to be used with the new renpy.sound.is_playing call, to prevent auto-forwarding from occuring if when a voice is being played. I'm not bothering to actually implement much of the voice functionality until someone seriously proposes a voiced game, but I do want to add in the infrastructure. Increased the default rollback length back to 100, now that we have a readback extra people can use if they want to. Updated readback so it works a little better. Updated LICENSE.txt, to point to a mirror site that contains the source code for the LGPL libraries used in the various binary distributions of Ren'Py. New in Ren'Py 5.1.3 ------------------- The scene, show, and hide statements now take an onlayer clause, which gives the layer that the operations occur on. So if we declare high to be another layer (by setting config.layers to something like [ 'master', 'high', 'transient', 'overlay' ]), then one can use a statement like "show eileen happy onlayer high" to show the given image on the high layer. This image will not be removed when scene statements clear other layers, such as the default master layer. +++ To support the above, the parameters to renpy.show() changed in an incompatible way. If your code uses renpy.show(), it will need to be upgraded. Instead of considering the second and later parameters to be at expressions, it now takes as its second parameter a list of all at expressions. (This lets us use the third parameter to accept the layer name.) The label 'after_load' is now called after a game is loaded, if it exists on disk. This label can be used to upgrade save files, restore music, and the like. It's now possible to pick the screen the game menu enters when it is invoked, by setting the _game_menu_screen variable. Simplified the demo game script by moving the style stuff out of that first init block, and down to the bottom of the script where it's out of the way of a first viewing. Hopefully, this will reduce the shock of someone first encountering Ren'Py. Documented how to modify and replace the game and main menus, and how to add in one's own preferences. New in Ren'Py 5.1.2 ------------------- Ren'Py now supports embedding images inside text. Please read the documentation of ui.text for some important caveats about how this works, but basically, the input of ui.text can be a string or a list containing strings and widgets. In the latter case, the widgets are rendered inside the text. One can also use a text tag like {image=filename.png} to include an image anywhere a text tag works. One thing to realize is that images so included cannot be any bigger then the text they are included with. A new widget, anim.Blink, blinks a child widget in and out of existence by varying its alpha channel. Character now allows for the use of a click-to-continue widget when the widget finishes showing text to the user. While many widgets can be used, this feature is especially useful with Images, Animations, and anim.Blink. The click-to-continue widget can be nestled in with the end of the text, or placed at a fixed location on the screen. Custom mouse support has been totaly rewritten. It now supports animated mice, and changing the mouse cursor based on the kind of interaction that is ongoing. Rather than describe the changes here, read the documentation of config.mouse to understand the new behavior. Please note that config.mouse has changed, and so if you use it in your game (and AFAIK noone does), it will need to be modified. Custom mouse support has also had significant performance improvements. Ren'Py can now read the script files out of an archive file. The archive used can either be game.rpa and game.rpi, or name.rpa and name.rpi, where name is the name of the file that is used to start Ren'Py, with the extension and any prefix (before an including an underscore) stripped off. New in Ren'Py 5.1.1 ------------------- Fixed a bug that prevented the various day-planners from working, in both the demo game and the DSE. (This was a bug in the game more so then a bug in Ren'Py proper.) !!! Fixed a bug on Windows that manifested with DirectX under some circumstances. We now use SDL's windib driver, which seems just as fast for the software surface stuff we're doing. Updated native midi support on the Mac, eliminating a non-obvious race/locking problem. A new version of the Ren'Py launcher for Macintosh comes with this release. Removed the .rpyl files that were added in 5.1.0, as they wound up not being needed after all. New in Ren'Py 5.1.0 ------------------- +++ There is now a new sound system, supporting playing up to 8 mp3, ogg vorbis, ogg speex, mod, or wav files at once. Midi can also be played, but is limited to one midi file at a time. Audio files can be read out of archives. Music and Sound now have their own mixers, which control the system mixer. The low-level audio api has been ripped out and replaced with new renpy.sound and renpy.music apis, which are somewhat higher-level, and more flexible. In order to support this, we've temporarily dropped Mac support. In a few weeks, we'll be releasing a tool that restores and improves Ren'Py's compatability with the Macintosh platform. To help support this tool, this release includes .rpyl files for the demo game and DSE. The bar widget has been extended. It can now be adjusted by the user, and it can show a thumb in the middle. Various volume and speed preferences have been adjusted to take advantage of the new bar widget. All of the backgrounds in the demo-game script and in the reference now are of the form "bg name". This lets one run a command "show bg newbg" to replace the background without replacing the current screen. The demo game also has been prefixed with a UTF-8 BOM, so editors should (hopefully) load and save it as UTF-8. There is now a new font text tag. By writing {font=Font1,Font2}, one can change the font in the middle of a block of text. Use this wisely. Font files with extensions are now also searched for in the system font directories, although we do not recommend this unless you are having encoding problems. Menu labels and choices support percent-substitution, like say statements always have. Now, all of the im image constructors take properties as arguments. This lets placement properties be applied to images, as with regular widgets. A new extra, chinese.rpy, implements word-wrapping for the Chinese language. Or at least tries to. Fixed a bug which made the images created with im.Rotozoom incompatible with im.Alpha. Fixed a weird focus bug that manifested upon rollback when resized frames were on the screen. New in Ren'Py 5.0.1 ------------------- The hovered callback on buttons was no longer working. This is now fixed. Also added a complementary unhovered callback. Documented them both on ui.button(). A number of changes have been made to Ren'Py, the cumulative effect of which is to shrink the package size by a bit. The python math module is now included with Ren'Py. The presplash screen now displays without a titlebar. Ren'Py now always runs internally in 24 or 32 bpp mode. It will still run on a 16 bpp machine, but there will be a conversion from 32 -> 16 bits when it is displayed. This fixes a number of transitions that did not work in 16 bit mode. Fixed a bug with im.Size in which 800x600 was used as the default target size, instead of the current screen size. Fixed a bug that prevented drop_shadow = None from working. New in Ren'Py 5.0 ----------------- Blessed 4.8.10 as the 5.0 stable release. Minor changes to images in the demo game. New in Ren'Py 4.8.10 -------------------- Added config.font_replacement_map, which is used to map from a regular font to a version of that font that is specialized as italic, bold, or both. New in Ren'Py 4.8.9 ------------------- There is now a preference that controls skipping after choices. The new function renpy.choice_for_skipping should be called by user code to indicate that a choice is occuring, and therefore we might want to end skipping. Fixed a bug that was preventing RevertableObjects from supporting properties. New in Ren'Py 4.8.8 ------------------- Auto-forward-mode has been implemented. It is controlled by its own preference, which gives the number of seconds for which a given number of characters is shown to the user. The number of characters is configured by config.afm_characters, which defaults to 250. The number of characters is determined by the length of the string shown to the user with a number of bonus characters added to it. The number of bonus characters is configurable in config.afm_bonus, which defaults to 25. Auto-forward-mode can be hidden from the user by setting library.has_afm to False. +++ The preferences screen has been redesigned, to have three columns. Code that manipulates library.preferences may need to be adjusted. Unicode support has been extended to names in the script. Now names in the script can contain unicode characters, as well as ascii characters. This includes labels and image names. Right now, we consider all unicode characters to be alphabetic, so be sure to use ASCII space where spaces are required. New in Ren'Py 4.8.7 ------------------- The new DSE dating-sim engine code is now present in the dse/ directory. It's not documented, apart from the comments in the source code, but it can be run by running the new run_dse program. The image statement now passes its argument to the Image function, in loose mode. This means that strings and tuples are turned into single and composited images, respectively. So it's now possible to write: init: image control room = "control_room.jpg" instead of having to write: init: image control room = Image("control_room.jpg") Of course, the old way still works. There is now a new transition type, ImageDissolve. It lets us creat dissolve transitions in which pixels are dissolved at different times, which can be used for a range of effects. Two such effects are 'squares' and 'blinds'. A number of other types are defined in the source of the demo game, in their own section. A new im.Tile image operator has been introduced. This operator tiles a source image until it reaches a specified size, or the size of the screen if no size is specified. Ren'Py now supports a presplash screen. If the file presplash.png is present in the game directory, it is shown to the user on startup. This occurs before any loading or initialization occurs, so the size of the window it is shown in is determined by the size of the presplash.png image itself. As per user request, we have made programmatic equivalents of the image, scene, show, and hide statements available. These functions are named renpy.image, renpy.scene, renpy.show, and renpy.hide, respectively. Ren'Py now supports a new classification of layer, top layers. Top layers are layers that are displayed above any transition. This is useful if you want to have an overlay that is shown even when a transition is in progress. To have the overlays be displayed as a top_layer, remove the string 'overlay' from config.layers and append it to config.top_layers. A new config variable, config.enable_fast_dissolve, was introduced. Setting this to False can fix a potential bug in the dissolve transition when used with an overlay layer that has an alpha channel that is not fully transparent or opaque, at the cost of 25% of the performance of dissolve. It usually can be kept at True with no ill effects. Fade has been reimplemented in terms of Dissolve. This means that fades will be as fast as dissolves. Fade now also can take a widget, instead of a color, as an argument. If this widget is an Image, it means that we will dissolve from the old screen to the image, hold at the image for a given amount of time, and then dissolve from the image to the new screen. The ImageReference class is now documented and present in the game's namespace. This lets us refer to an image by name from user code. Added a RENPY_DISABLE_SOUND environment variable, which if set disables support for sound in Ren'Py. (For use on platforms where sound doesn't quite work.) Fixed a bug in lint. Fixed bugs that caused overlays to jump in and out during transitions, restoring the pre-4.8 behavior. The definitions found in common/definitions.rpy are now documented in the reference. This gives a default set of transitions and positions, as well as an image (black). New in 4.8.6 ------------ Ren'Py now takes a new option, --lint. (Or for those of you under Windows, run lint.bat, editing it if necessary.) This option, when supplied, causes Ren'Py to run checks for dozens of errors in the script. Many of these checks test for problems that will only occur at runtime, on platforms other than Windows, or when loading a save-game after a change in script. This is the subtle stuff that my script-review service was for... now it's automated, so you don't need me anymore. Lint should be run before you release any game with Ren'Py, from now on. In general, you should not release a game if lint gives you any errors, but instead you should fix those errors first. Lint also produces a count of the number of say statments and menus in a program. DynamicCharacter and Character have been unified into a single class, such that now calling DynamicCharacter is equivalent to calling Character with dynamic=True. Character (and DynamicCharacter, and renpy.display_say) now take a new argument, image. If this argument is set to True, then the name of the character is interpreted as an image filename. This image is used where the character's name would go, in place of a textual name. Fixed a bug that prevented newlines from being recognized in text widgets. (Introduced when I rewrote tokenizing in the previous release.) Fixed a bug in the _renpy module, in which we accidentally used the height, rather than the width, of an image. New in 4.8.5 ------------ Added a new state-machine based animation function, anim.SMAnimation. This function creates animations by applying images and transitions specified by the states and edges of a nondeterminstic state machine. The result is that it's possible to specify complicated random patterns of behavior. This can allow a character to blink randomly, allow random backgrounds to be shown, and even allow things to randomly move around the screen. The SMAnimation framework can also be used to describe very complicated, even nondeterministic, motions. This is done by declaring a SMAnimation with None for the images, and then passing it in to the at clause. I should point out that despite the complexity of the interface, the S and M in SMAnimation stand for state machine, and not anything else. Honest. All motions (Motion, Pan, Move, and anim.SMAnimation when used as a motion) can now be used as transitions, in which case the motion is applied to the screen (or layer, as appropriate). This let us put together two new transitions, hpunch and vpunch, which shake the screen horizontally and vertically, as appropriate. Useful for when the POV character gets punched by a particularly feisty girl. There are now two new image operators. im.Map can map the pixels values in an image to different values. Using this, one can adjust the colors of an image. The im.Alpha function is built on top of this, and allows one to alter the alpha of an image. (It even adjusts a pre-existing alpha channel.) The definitions of transitions and placements, which were once in script.rpy, have been moved into common/definitions.rpy. There is now a new config variable, config.text_tokenizer. This variable is used to give a function that breaks a line of text up into words, spaces, and other things. Providing a custom function here allows for control of where line breaking is allowed, useful for languages that have different rules about that. Fixed the gallery.rpy extra, so that it now works properly with the main menu being in a menu context. The demo game was updated to demonstrate the new feature, as well as to have a new, drop-shadowed window frame. New in 4.8.4 ------------ The format of the compiled script (.rpyc) files has changed. The new format is more efficent, both in terms of space and memory. Unfortunately, the format change is not backwards compatible, and the automatic upgrade function probably won't work. So you'll need to delete the rpyc files from the game directory when you copy it over. Removed some unnecessary conversion from pixellate, improving its performance when running on a computer with 32 bits per pixel graphics. The xanchor and yanchor arguments can now take numbers between 0 and 1 as well as names. Functions returned by Motion now can either return an xpos, ypos tuple or a xpos, ypos, xanchor, yanchor tuple. Move has been upgraded so that it can take similar tuples as the start and end arguments, letting us interpolate the location of the anchors while moving an image around. The above modification allowed us to implement a new move transition. This transition attempts to find images that are present in both the old and new scenes, but have changed location between the two scenes. Such images are moved from the old location to the new location over the duration of the move transition. This makes it easy to smoothly move characters from one location to another on the screen. The demo script was updated and reorganized, to demonstrate more features. Now, all transitions are demonstrated, as well as things like renpy.input, DynamicCharacter, Move, and Pan. A slightly updated version of the script for Moonlight Walks is now in the scripts/ directory. It's there as an example for people to learn from. This script has been updated to work with Ren'Py 4.8, and to fix a tense error. !!! Fixed another segfault in windows native midi support. New in 4.8.3 ------------ !!! Ren'Py no longer uses the psyco specializing compiler. The relatively small (about 2%) speed increase it gave wasn't worth the hassle involved in dealing with memory leaks and other semantic changes. This change significantly lowers Ren'Py's memory usage, and fixes a major memory leak that was introduced in the 4.8 series. !!! A number of race conditions were fixed in the windows native midi code. The upshot of this is that we can now play midi on windows without there being a small chance of crashing each time we start a new track. +++ The config.music_interact variable is gone. It's been replaced by config.interact_callbacks, which is a list of functions to call before each interaction. (This will help us support voice.) A new Motion function allows the user to give a function that controls how a displayable moves on the screen, allowing for customizable motions. Pan and Move have been reimplemented in terms of Motion. All three functions now take repeat and bounce parameters. Repeat causes the motion to repeat after a single period is over, while bounce causes the motion to bounce from extreme to extreme. Finally, a new voice extra has been added as extras/voice.rpy. This is a simplified version of what will eventually be Ren'Py's voice system. Right now, the only feature missing is that voices for characters cannot be enabled or disabled individually, but may instead only be manipulated in the aggregate. New in 4.8.2a ------------- !!! Clicking preferences on the main menu jumpled to an undefined label. This is now fixed. A new extra has been added. The commentary.rpy extra adds an optional commentary window, which is shown only when the commentary preference it adds is enabled. To support the above, statements are only marked as seen if they have actually been shown to the user (by ui.interact being called during the statement.) New in 4.8.2 ------------ Unicode support in python blocks now works. This allows unicode strings to be used with Ren'Py. This is especially useful when naming characters and translating the various menus into your native language. Please note that the only unicode allowed is inside unicode strings, which begin with a u before the first quote. Unicode outside of unicode strings is an error. We apologize to the non-english-speaking world for not noticing this one sooner. +++ The main menu was moved out of the context that the main body of the game code executes in, into its own context. The only effect this should have on user code is that some of the menu options changed from simple label names into more complicated jumps. But it does allow us to share the main menu with the game menu, which is something I've had requests for. A number of minor changes were made to the menu at this time. The README_RENPY.txt file was updated, to make it more current and useful. The Character and DynamicCharacter objects were updated to take a condition argument. If this argument does not evaluate to true when a line of dialogue is executed, the line is not displayed to the user. A new extra was added (in two_window_say.rpy) that places the name of a speaking character, and what they are saying, in two windows that can be styled separately. The biggest change in Ren'Py was the addition of the _renpy module. This is a C module that enhances the functionality of pygame, allowing us to provide transitions and apply effects that simply weren't possible before. A compiled version ships with the windows binaries, installers are available for windows and mac from the Ren'PY website, and source is included in the module/ directory to compile it under Linux and Unix. The presence of the _renpy module allows for two new features. The first is that the thumbnails of save images are now smoothly scaled down, which improves their look quite a bit. The second new feature is the new pixellate transition, which pixellates the old screen, swaps pixellated screens, and then depixellates the new screen. One can see this feature in action by right clicking to access the game menu... for this release, we've set the game menu transition to be pixellate. New in 4.8.1 ------------ Character objects are no longer limited to displaying through renpy.display_say, but can now be supplied a function argument, which is a function that is called instead. This will make it easier to radically change how dialogue is displayed. The ui.grid object now has a new argument, transpose, which allows widgets to be added down the columns first. It also is smarter about allocating space to subwidgets when xfill or yfill are set. +++ The file entries in the load and save screens are now arrainged in a grid, which has the style file_picker_grid. This means that we should now be smarter in the presence of games of varying size, and we should wrap text if it gets too long. As part of this, library.file_page_length has now been broken out into two variables, library.file_page_rows and library.file_page_cols. renpy.music_stop now supports a fadeout parameter, for orthogonality with the new renpy.music_start. Now, python blocks have the correct filename and line numbers annotated onto them. This means that tracebacks generated in python blocks will show a .rpy file and the appropriate line, rather than showing "" and a random line as they did before. There are two new style properties, xmaximum and ymaximum. These two properties limit the size of the widgets that they are applied to, as if that widget was placed inside a ui.sizer(). (In fact, ui.sizer() is now implemented in terms of these properties.) !!! Now, we only restore or rollback to places where all of the transient layers are empty. This prevents a bug in which additional dialogue will be lost when a restore or rollback occurs. +++ The way in which preferences are displayed has been made more configurable. Now, there is a new variable, library.preferences, which is a map from a style to a list of preferences to be displayed in a vbox with that style. There are now two new styles (prefs_left and prefs_right) which control the placement of the default preference columns. There is a new spinner preference type, which allows a value to be incremented or decremented. This preference is now used to adjust the speed at which text is shown to the user. So now this is controlled by the user, rather than the config.annoying_text_cps parameter. If you don't want to give the user this control, you can set library.has_cps to False. A number of new styles define the spinner. An empty string is now rendered as if it was a string consisting of a single space. This fixes a bug in which an empty string was rendered with zero width and height. New in 4.8 ---------- A new system was implemented to manage widget focus. This new system allows the focus to be moved from widget to widget using the keyboard, without requiring the keymouse behavior be used. Because of this new system, the keymouse behavior is now a no-op. +++ To simplify the code and make every widget compatible with the new focus code, a number of widgets were reimplemented in terms of buttons. This includes the ui.menu widget, which is the widget that is used when presenting the user with choices. Menu buttons are of the new style style.menu_choice_button, while their labels remain of style style.menu_choice. Background images and padding can now be styled onto these menu buttons. A number of new image manipulators have been made available in the new im package. These are objects that can load an image (im.Image), crop an image (im.Crop), scale images (im.Scale), rotozoom images (im.Rotozoom) and composite images (im.Composite). The latter is much more flexible than the previous image composition system, as it now supports placing images at arbitrary locations on an arbitrarily big canvas. Image (by itself) is now a function that creates the appropriate image manipulators, retaining compatibility with its behavior in previous releases. The image cache is now based on image size, rather than number of images. This prevents a large number of small images from filling up the cache. We now load images before starting the timer for a transition. This prevents us from popping into the middle of a transition because we spent some time loading images. This behavior can be controlled by config.load_before_transition. The ui.imagemap widget has been rewritten in terms of ui.imagebuttons and im.Crops. Some styles have changed names as a result. Ren'Py now keeps track of the images that have been shown to the user. This is the basis of this release's new extra, gallery.rpy, which manages a gallery of unlockable CG. The audio system has been rewritten, and a number of low-level audio functions have been exposed in the new audio file. These functions control audio directly, but do not save the state of audio in a save file. The high-level music functions have been rewritten and placed in the music.rpy file, allowing a sufficently adventurous game author to change the way music is played. Two changes have been made to the renpy.music_start() function in the high-level sound api. The startpos argument was removed (as it was a pain to support), and a new fadeout argument was added, which lets the fadeout time be controlled for each new song that is played. The low-level sound api now lets us do the following things: [list][*] Play up to eight sound effects at once. [*] Cancel a playing sound effect. [*] Pause and unpause the playing music. [/list] There is now a new, state that a widget can be in. Along with hover, idle, and activate, a widget can now be insensitive. This is the state that all non-focused widgets are in. Having the new insensitive state means that we can eliminate the various disabled_button styles, so we did. In general, in this release, many styles have changed names. In prior versions of Ren'Py, the bar widget could respond to clicks. This was never used, and won't work well with the keyboard focus control system. So, it's been eliminated. Now, if the label "enter_game_menu" exists, it is called when entering the game menu. It's expected that the main purpose of this label will be to play music when in the game menu. Using the default music system, the code to do this would look like: [code] label enter_game_menu: $ renpy.music_start("game_menu_music.mid") return [/code] A number of bugs were fixed, including bugs with the style system, and with animation refresh. Tab characters are now expanded to tab stop at eight spaces, rather than to a fixed spacing of eight spaces. Old code using tabs may need to be reformatted. The 'h' key now hides the windows on the screen. This means that all Ren'Py functionality is now available through the keyboard, at least for people with a 1-button mouse. (cough ... Mac ... cough) Finally, setting the environment variable RENPY_DISABLE_FULLSCREEN to a non-empty value will disable fullscreen support, for those people (that person?) who had it crash their systems. New in 4.7.2 ------------ This release should be compatiable with the .rpyc and .save files produced by 4.7.1. !!! The new readback extra caused save files to reach a size and/or complexity that caused errors in cPickle on Windows, which in turn lead to a repeatable crash of Ren'Py, and left a corrupt save file in the saves directory that prevented further saving and loading of games. This has been addressed in two ways. The first is the use of pickle (as opposed to cPickle) throught Ren'Py, a change that may slow down the engine a little but should ensure correctness. The second is that we now catch the errors produced by corrupt files, and (if config.debug is not set) proceed by ignoring that file. There is now a new extra, readback.rpy. This implements readback, in addition to, or instead of, rollback. Readback is limited in a number of ways, insofar as it only shows text without changing pictures or other things. As part of implementing readback, we added a new function, say, that is called when the user gives dialogue consisting of a pair of strings. There are a number of changes that improve support of the Mac OS X platform. The foremost among them is that we ship a new file, run_game.pyw. This is identical to run_game.py, but is necessary for the game to run in a graphical environment on the Mac. (It also will run the game without a console window on Windows, if you have the appropriate dependencies.) Ren'Py still requires that PyObjC and pygame are installed on a OS X 10.3 box before it can run. The way font line spacing is computed was changed in this release, in the hope of making it consistent on all three platforms. We now ignore font linesize hints, which seem to be computed incorrectly on some platforms, and instead set the line spacing to be equal to the ascent and descent of the font. The user can increase or decrease the line spacing by setting the new line_spacing text property. The old line_height_fudge property is now ignored. The style.rpy common file was updated to take account of this change. To aid the user in finding the source of error messages, we now report the name of the file being parsed when an error occurs during the parse phase. The tutorial has now been renamed "The Ren'Py Reference Manual", as it's really more of a poorly-organized comprehensive reference then a tutorial. This is in the hope that the Ren'Py user community will one day write a more reasonable tutorial. A number of errors in the reference were corrected. The functions used in keymaps can now return values, which are returned to the ui.interact() that called them. This was needed to support readback. LICENSE.txt has been updated to include the names and URLs of software that a windows build of Ren'Py depends on, the licenses of which you will be required to comply with when releasing a Ren'Py game. New in 4.7.1 ------------ Added a new tool, dump_text.py/.exe, that dumps all of the text from a Ren'Py script file. It uses a heuristic approach that is imperfect, but is hopefully accurate enough to be useful for purposes like spell-checking a script. The text is dumped into the file text.txt in the current directory, and on windows that file is then displayed to the user. By default all of the rpy files in the game directory are displayed, but supplying a filename parameter can change that. Fixed a bug that was preventing parser error messages from being reported on Windows. Fixed a bug in Render.subsurface that lead to weird effects when doing an irisin or irisout on a sufficently complicated scene. See http://lemmasoft.renai.us/forums/viewtopic.php?p=4612#4612 for the discussion. New in 4.7 ---------- The demo was updated to show the new features in 4.7. The big new feature in this release is text tags. Text tags is a markup language that allows text properties to be changed inside a single unit of text. It lets you emphasize individual words by making them bold, bigger, or a different color. Rather than explaining it fully here, let me point you to the new "Text Tags" section of the documentation. There were two changes that were made to Ren'Py to support text tags. The first was that interpolation now quotes the interpolated text, making it impossible to introduce a text tag via interpolation. The second change is that renpy.input() and friends now take as arguments strings giving allowed and excluded characters. The default is to exclude the '{' and '}' characters, meaning that it's impossible for a user to input a text tag. Finally, this release features even more defensive programming involving sound. Now, if the mixer does not initialize, no further sound operations will be performed. New in 4.6.2 ------------ 4.6.2 was never officially released, as it didn't cure all of the sound woes, and didn't have much else in the way of new features. Added a speed test, which tests the speed of the dissolve transition on a user's system. This test can be accessed by typing 'S' during the demo (that's shift+the 's' key). Fixed a bug with sound on systems with no soundcard in them. (Also, put in a note to remind myself not to re-introduce that bug.) Fixed a bug in which imagemaps would not redraw properly. New in 4.6.1 ------------ Fixed a major memory leak in the rendering code. This leak was rendering 4.6 and 4.5 unusable on smaller systems. Executed 250,000 statements (well, 5 statements in a loop, while skipping), and ensured that there was no memory leak during the execution of these statements. Added a memory profiler. You can see it by supplying the --leak option to run_game.exe or .py, but don't expect to understand it. Changed Dissolve so that it tries to use compositing when it can. This means that it only draws to the screen once... which is a little bit of a speedup on a really expensive operation. Fixed a bug that was preventing predictive image loading from working. New in 4.6 ---------- The demo was updated to show some of the new features listed below. There's now a third state that hovered widgets can go into. The activate state is enabled when a button is clicked or a menu choice is selected. The activate state can only be seen when a transition occurs immediately after a button is clicked or a menu choice is selected. The margin and padding properties have been broken up, so it's now possible to specify margin and padding for the left, right, top, and bottom of a windows. The biggest internal change in this version is the introduction of a layer system in Ren'Py. Transitions can now work on an individual layer (as well as the previous behavior of the whole screen), so it's possible to do things like sliding in and out the dialogue box. It's now possible to use transitions when entering and leaving the game menu, by assigning a transition object to library.enter_transition and library.exit_transition, respectively. The preferences screen can now be entered from user code, and is now part of the main menu. Character objects now support an interact argument when called directly. If it's False, then no interaction occurs. This lets a character window become part of a larger screen. Two new extras have been added: [list] [*] button_menu.rpy changes the way menus are displayed. Each menu choice is displayed in its own button, roughly centered on the screen. A single menu caption is displayed as narration, if such a caption exists. [*] overlay_menu.rpy changes the behavior of right click from showing the game menu to showing a bank of buttons that, when clicked, bring the user to the game menu. [/list] The overlay code was overhauled. It's now not possible for an overlay function to return a list of widgets. Instead, the overlay functions are expected to add widgets to the screen using the ui functions. Calling the new function renpy.restart_interaction will, among other things, cause the overlay functions to be called again, if one wants to replace the overlay on the screen. A new variable, config.overlay_during_wait, controls if overlays are shown during the execution of wait statements. Init blocks of the same priority are now assured to run in the order that they appear in a script file. The renpy.interact() function has been eliminated. Use ui.interact() instead, as it performs more error checking. Fixed a bug in which some redraws were ignored, and another in which the input widget failed to eat characters. (So typing 'f' in an input widget would be passed through, and eventually cause the game to go to fullscreen mode. No longer.) 4.5's demo script had a bug that cause it to crash, after playing the MPEG-1 movie. It was a bug in the demo script, and not in Ren'Py proper. It's fixed. New in 4.5 ---------- We now ship an extras directory, with interesting sample code. It includes: [list] [*] fullscreen.rpy, containing code to automatically switch the game into fullscreen on the first run, while preserving the user's preference on later runs. [*] 640x480.rpy, which shows how to customize Ren'Py for a game that runs at 640x480. [*] kanamode.rpy, contains the code to emulate the interface of the various Digital Object games, which display text one line at a time, but keep a page of text on the screen at once. ([url=http://www.bishoujo.us/hosted/kanamode.jpg]screenshot[/url]) [/list] Added a new CropMove transition. This single class is the root of not one, not two, but fourteen transitions, in the forms of wipes, slides, slideaways, and rectangular irises. You can see some of these transitions in action in the demo, which now has a new section, "What's new with Ren'Py?" Added support for playing MPEG-1 movies. Rather than explain it all here, we'l just mention that you can read the new "Movies" subsection of the "Multimedia: Sound, Music, and Movies" section of the Ren'Py manual. We support both hardware-accelerated full-window movies and using a movie as a widget. This is also shown in the what's new section of Ren'Py. Added ui.grid(). This is a widget that places its children in a grid. The children must have sizes that do not consider the amount of space available for the grid to work. Added ui.pausebehavior(). This separates pausing from the saybehavior paving the way for uninterruptable pauses (a bad idea, IMO) and menus that dismiss themseleves after a certain amount of time. A new function, renpy.exists(), can check to see if a given file can be found in the searchpath. This could be used, for example, to make a game that only tries to play music if an add-on music package is downloaded, and the files placed in the appropriate place. Added the ability to bind mouse events to mouseup as well as mousedown, and changed some of the default bindings to be on mouseup rather than mousedown. If you make changes to config.keymaps, you'll need to change mouse_1 to mousedown_1, and so on for various other button numbers. Moved the place we look for menu sounds from the style of the choices in the menu to the style of the menu itself, as that seems more rational. Also, gave menus their own style. (Can't believe I forgot that.) Made a few changes to the library screens. First of all, we rationalized (to some extent, it's still pretty ugly) the names of the styles for library widgets. So some of that may have changed. We placed preferences and the yes/no dialogue inside windows, which can be styled by the user. We then routed all button and label creation through two functions, _button_factory and _label_factory. By overriding these functions, the user can (for example) replace the default textbuttons with imagebuttons. Made 'f' toggle fullscreen at the main menu. This will help on virtual windows, where the mouse doesn't work right in fullscreen mode. Improved rendering speed. Now, we aggressively cache things to minimize re-renders, and only draw to the screen the parts of the screen that have changed. In common cases, such as the case where only some text has changed, this can greately improve performance. In other cases (transitions), we have to redraw the entire screen anyway, so there's little improvement. Fixed a bug in which hiding the UI was not working properly. (This broke the center mouse button behavior.) New in 4.4.2 ------------ Improved the configurability of the say and menu statements, also changing the way they work. Say statements without a speaker specified are routed through the narrator character, while all menu statements are routed through the menu function. Customizing these functions can customize how Ren'Py interacts with the user, making it a much more flexible engine. As part of this, we changed the way character objects work. They are now called directly to display dialogue, rather than having the say method called on them. If your game uses variables named "narrator" or "menu", you will need to rename them. Changed the way spaces are handled by the text widget. Specifically, they are no longer merged, so it's possible to include spaces in dialogue and thoughts. Please note that the parser still merges adjacent spaces, unless you escape them with a backslash. Added a new widget, ui.sizer, that can shrink the amount of space allocated to its child. Added two new text properties, first_indent and rest_indent. These properties control how many pixels of indentation to put before each line of text. Added a function, color, that can translate a hex triple or quadruple into a Ren'Py color. New in 4.4.1 ------------ 4.4.1 is being released to test some sound fixes, and so it isn't really isn't that complete or well-tested. Fixed some longstanding bugs with midi music on Windows. First of all, we now ship with the 1.2.6 version of SDL_mixer, which fixes a bug in 1.2.5. That bug caused panning to go to the hard left. We also try to read the windows midi device volumes, and set our volume to match the first one we can read. This should prevent really loud midi music from happening. Also, increased the size of the sound buffer to 4096 samples, to prevent skipping. Some new features: Now, adding interact=False to a Character object will prevent an interaction from occuring. Implemented functions to get the amount of time elapsed during the game, renpy.clear_game_runtime() and renpy.get_game_runtime(). New in 4.4 ---------- Added a number of features to allow Ren'Py to support statistics-based dating simulations. The first is a new ui.bar() widget, which allows the display of a bar graph. The demo has been enhanced to include a stats and schedule screen, to show how this could be used. You can get to it by asking how to write your own games in the demo, or you can follow the below link to get a screenshot. [url]http://www.bishoujo.us/hosted/screenshot.jpg[/url] Another feature that has been added were 'jump expression' and 'call expression' statements, allowing computed jumps and calls. Together with an imporoved scheduler and yet-to-be written event dispatcher, this provides the foundation for SBDSes. Now, setting a property on a style also sets the hover_ and idle_ variants of that property. This makes changing a property of an inherited style a bit saner. In addition, hover now propagates to all children of a button. This means that hover will now work with the styles in the file chooser. Added support for layering images. This support (invoked by passing a tuple as an image filename) allows a single image to be constructed from multiple image files, saving disk space while still keeping performance. Improved skipping. Now, along with control causing skipping of seen dialogue, TAB toggles skip mode. An indicator displays to let you know that skip mode is enabled. Finally, if a game author wants to disable skipping, he can set config.allow_skipping to false. (The following were also in 4.3.2, which was a private release to test the fixes for UTF-8 support.) There were two bugs with UTF-8 support. The first was that we didn't understand the byte-order mark, and choked on the syntax error. The second was that the error-reporting code wasn't passing unicode errors through properly, so one couldn't even see the real error. Both are now fixed. Improved the reporting of errors that occur during script loading and interpreter initialization by no longer giving a line number when none is appropriate. Ren'Py now uses the name of the executable to choose the directory to read the script from. It does this by looking at the name of the executable that was used to run Ren'Py. It strips off the extension, and anything preceding the first underscore in the name, if such a thing exists. It then looks to see if that directory exists, and if it does, uses it. For example, if the program is named "run_en.exe", the "en" directory is used, while if the program is named "homestay.exe", the directory "homestay" is used. The config variable config.searchpath is a list of directory that are searched for image files and other media (but not scripts, since all scripts are loaded before the variable can be set). This allows multiple game directories to share images, music, and other data files. Once again, I redid the file chooser and default styles. The new file chooser displays 10 entries in two columns, with each entry being shown with an image. The files are now orginized into numbered slots, and it's possible to save in a slot without saving in all previous slots. There were also some changes to the non-user-visible parts of loading and saving. Speed Enhancements: We now precompile python blocks in Ren'Py scripts, and store the compiled code in the .rpyc files. This makes loading an unmodified script significantly faster. On my system, this more than halved the time it took for the demo script to load. On the dowside, when a script is changed, it now can take somewhat longer for it to begin running, as all the changed code needs to be recompiled. Overall, it's a win, provided you ship the .rpyc files to your users. Did another round of profiling, and found that styles were significanly slowing the system down. So I rewrote them to be much faster. This change shouldn't be user-visible, except that your game will feel a bit peppier. Added a 1-entry cache for solid fill surfaces. If your game uses them, this might make it go faster. New in 4.3.1 ------------ New, but undocumented, in 4.3 was the console.exe windows binary. This is a windows executable that opens a windows console. This could be useful if one wants to have a script that prints debugging information to standard output, as in: [code] $ a = 1 $ print "a =", a [/code] There is now a new style property, enable_hover. This must be set to True for a widget to respond to hovering by changing its style. However, if it's set to False, no style change/redraw occurs, making Ren'Py snappier. It defaults to True. Ren'Py is now built with psyco, the python specializing compiler. This makes program startup a bit slower, but in return the running time once it's loaded should be faster. A new config variable, config.window_icon, allows the user to specify an image file to use for the window icon. Counterintuitively, this should probably be a PNG, as the ICO format is not supported by the SDL_image library. Game menu navigations and preference buttons now have their own styles, allowing their look to be customized. A bug that prevented the reloading of persistent data on windows has been fixed. New in 4.3 ---------- Now, when the library first starts up, it tries calling the "splashscreen" label, if it exists. The splashscreen will not be called in the case of a full reset (known to the user as a return to the main menu). Added a new text property, antialias, that controls the antialiasing of text. Also made the font property optionally take a comma-separated list of font names, which are searched for in the Added a new class, DynamicCharacter, which is now the preferred way of having a character with a changable and/or user-input name. A new random number generator has been implemented as renpy.random. This random number generator cooperates with rollback, always producing the same random numbers when a rollback occurs. Added a set of UI functions, that allow the user to build up a user interface themselves. These could be useful when implementing more complex games, such as those that require the user to schedule a day in advance. Also new is a new imagebutton, a button consisting of two images. Sticky postions have been implemented. Enabling this (using the variable config.sticky_positions) cause the at clause corresponding to a given character to be remembered, allowing the character to change emotion without changing places on the screen (or requiring a second at clause). Rewrote the implementation of preferences, to clean up the code. Moved it into its own file, preferences.rpy. Also, made it possible for a user to add his own preferences into the system, although that isn't really recommended. The various imagemap functions now have a new parameter, unselected, which gives an image to use when a hotspot is present but not hovered. This lets us distinguish between between hotspots that are present and exist, and hotspots that are totally absent. This could be used to implement something like an image gallery that only displays unlocked images. Implemented config.keymap, which allows the changing of keys and mouse buttons that trigger various Ren'Py events. There's now a new look for loading and saving games, that allows 10 saves to be presented at once. I strongly recommend removing the library.file_page_length line at the start of your game scripts, if it exists. Fixed a bug in sound.init that lead to crashes in some cases. Fixed a bug in ast.Node.predict that was causing an exception when config.debug was turned on. New in 4.2 ---------- Ren'Py now ships with a common directory that is used to store the library files, as well as the files needed by a minimal game. (Such as a default font.) The idea here is to allow one to copy a game directory from one version of Ren'Py to another, and have it just work. One can upgrade from 4.1 to 4.2 by deleting script.rpy, script.rpyc, library.rpy, and library.rpyc, and then copying in the game directory. We've also eliminated the default background images. To go back to the images used with Ren'Py 4.1, add the following lines to your script, and copy the images out of the 4.1 distribution, or your 4.1 based game. [code] init: $ style.mm_root_window.background = Image("mainmenu.jpg") $ style.gm_root_window.background = Image("gamemenu.jpg") $ style.window.background = Frame("frame.png", 125, 25) [/code] Fixed several bugs with the archiver. This version just might actually work on Windows. Added a new variable, config.hard_rollback_limit, which limits the number of steps the user can rollback the game, interactively. This limit now defaults to 10 steps. (suggested by Grey) Added a second parameter to renpy.pause, that allows us to pause until a particular offset in the background music is reached. (suggested by Alessio) Added keyboard mouse controls that can be used to move the mouse around on the game and main menus. This allows us to manipulate the game and main menus without having to touch the mouse. This is mostly for completeness. (suggested by Alessio) Changed the way in which overlays work. We now have the variable config.overlay_functions, which contains a list of functions, each of which returns a list of displayables that will be added to the screen. (sorta-kinda suggested by Alessio) Removed renpy.set_overlay, since config.overlay_functions is a more flexible way of doing the same thing. Now, defining the label main_menu allows you to totally replace the main menu with something of your own devising. Changed the documentation to reflect this, as well as the changes in startup that happened in 4.1. Added a program called "add_from", which adds from clauses to all bare call statements found in the program. Replaced the menu_selected and menu_unselected styles with a single menu_choice style which participates in the hover protocol. This may change user code, if you change the menu colors. To fix this, replace style.menu_selected.color with style.menu_choice.hover_color, and style.menu_unselected.color with style.menu_choice.idle_color. Added the ability to play sound effects, by calling the renpy.play function. Added a preference that allows the user to control if sound effects are played or not. Added sound styles, which are used to define the sounds that are played when buttons, imagemaps, and menu choices are hovered and activated. (By default, no such sounds are played.) Implemented that annoying thing where text is typed on the screen one character at a time. Also added a preference that allows the user to disable it. Used all the restraint I could muster to avoid defaulting that preference to off. Added the ability to fade out music when changing music tracks. This is controlled by the config.fade_music variable. (suggested by Alessio) Added parameterized images, and the ability to show text as image using a command like: [code] show text "American Bishoujo Presents..." [/code] Added a Move function, which can be used in at to allow an image to be moved on the screen. This is best used when the image is smaller than the screen. (suggested by Alessio) Changed the format of archive files, to make them somewhat harder to reverse-engineer. This requires the user to regenerate the archive files. To make this easier, we now ship a batch file (called archive_images.bat) that automatically archives the images found in the game directory. Added a new function renpy.wait that is equivalent to the wait statement, and made it and renpy.pause return True if they are interrupted, or False if the run to their natural completions. This now makes it possible to jump somewhere else when the user click, rather than blindly going to the next label. For example: [code] # Actually, this runs before the library main menu. label main_menu: scene black show text "American Bishoujo\nPresents" \ at Move((0.5, 0.0), (0.5, 0.5), 3.0, xanchor='center', yanchor='bottom') if renpy.pause(6): jump _library_main_menu show text "A PyTom Game" at Position(xpos=0.5, ypos=0.5, xanchor="center", yanchor="bottom") if renpy.with(fade) or renpy.pause(4): jump _library_main_menu $ renpy.transition(fade) jump _library_main_menu [code] Updated renpy-mode.el to add imenu support, so (X)Emacs users can use the speedbar to jump around in a script. If you don't know what this means, you probably don't care. Improved the comments in the demo script, to make it a better example. Added a syntax-highlighted version of the demo script to the tutorial, to make it easier on peoples eyes. New in 4.1 ---------- Added the ability to customize the main menu by giving a list of buttons on the main menu and the labels that they jump the user to. Added the ability to center-click to hide any displayed text or menus. Added the ability to have a color mouse that we can move around the screen. Added a persistent object, which has fields that are persistent across games. Made the preferences part of this object, so that they are persisted across sessions. For simplicity's sake, made seen_ever part of that persistent object. Added a special character called "centered", which causes the text it displays to be centered in the screen without any window. Added two new styles (centered_window and centered_text), which are used for this, and a new property, textalign, which controls the horizontal alignment of text within the Text object itself. Keywords are now special in all contexts. So you can no longer include keywords in image names. Sorry. Improved parse error messages. They now include the text of the line and a caret indication the location in the line where the parse error occurred. Added a with clause to say statements and menus. This lets one display dialogue, thoughts, or menus using a transition. In conjunction with this, changed a bit the semantics of with statements, and with clauses on show, hide, and scene statements. Rewrote the section on transitions in the documentation to reflect the new reality. Added the ability to translate the text of the game menu. Together with the ability to change the main menu, this makes Ren'Py fully localizable, except for error messages. Check out the Localization section in the tutorial for more details. Added confirmations for quitting and overwriting a save game. This also includes quitting by trying to close the window. Added a preferences screen, which lets users change the Ren'Py preferences. Right now, this includes Windowed/Fullscreen, Music Enabled/Disabled, CTRL Skips Unread/All messages, and Transitions controls which transitions are performed. Added a Pan function which can be used in an at clause. This allows us to pan over a background image.