# Transforms

Transforms are used in order to turn a displayable into another displayable. There are several kinds of transforms, and various ways to create them. The built-in transforms are used to control where an image is placed on the screen, while user-defined transforms can cause more complex effects, like motion, zoom, rotation, up to complex color effects.

## Quickstart

Transforms can be applied to images by passing them to the `at` clause of the show or scene statements. The following applies the `right` transform to the `eileen happy` image:

    show eileen happy at right

Multiple transforms can be applied by separating them with commas. These transforms are applied from left-to-right.

    show eileen happy at halfsize, right

Simple ATL transform:

    transform slide_right:
        xalign 0.0
        linear 1.0 xalign 1.0

    label start:
        show eileen happy at slide_right
        pause

Showing transforms with Python:

    label start:
        $ renpy.show("eileen happy", at_list=right)
        pause

Simple Python transform using `At()`:

    init python:
        def show_eileen_rotated():
            rotated = Transform(rotate=45)
            show_stmt = At("eileen happy", rotated)
            renpy.show("eileen", what=show_stmt)

    label start:
        $ show_eileen_rotated()
        pause

## Built-in Transforms

Ren'Py ships with a number of transforms defined by default. These transforms position things on the screen. Here's a depiction of where each built-in transform will position an image.

                  +-----------------------------------------------------------+
                  | topleft, reset               top                 topright |
                  |                                                           |
                  |                                                           |
                  |                                                           |
                  |                                                           |
                  |                          truecenter                       |
                  |                                                           |
                  |                                                           |
                  |                                                           |
                  |                                                           |
    offscreenleft | left                   center, default              right | offscreenright
                  +-----------------------------------------------------------+

The `offscreenleft` and `offscreenright` transforms position images off the edges of the screen. These transforms can be used to move things off the screen (remember to hide them afterwards, to ensure that they do not consume resources).

The transforms are:

center

  Centers horizontally, and aligns to the bottom of the screen.

default

  Centers horizontally, and aligns to the bottom of the screen. This can be redefined via `config.default_transform` to change the default placement of images shown with the show or scene statements.

left

  Aligns to the bottom-left corner of the screen.

offscreenleft

  Places the displayable off the left side of the screen, aligned to the bottom of the screen.

offscreenright

  Places the displayable off the right side of the screen, aligned to the bottom of the screen.

reset

  Resets the transform to the default values of each property, removing any properites set before it.

right

  Aligns to the bottom-right corner of the screen.

top

  Centers horizontally, and aligns to the top of the screen.

topleft

  Aligns to the top-left corner of the screen.

topright

  Aligns to the top-right corner of the screen.

truecenter

  Centers both horizontally and vertically.

## ATL - Animation and Transformation Language

The Animation and Transformation Language (ATL) is a high-level language which can create animations, move displayables across the screen, set their position, apply transformations, and more. These can be changed over time, and in response to events.

ATL transform objects, which are created using the Transform Statement down below, are displayables and can be used as such (even though they will be transparent when their child displayable is not set) : they can be passed to a screen's Add element, or to a Show expression statement, or to the `renpy.show()` function.

### Ren'Py script statements

There are three Ren'Py script statements which can include ATL code.

#### Transform Statement

The `transform` statement creates a new transform that you can use to animate and position displayables in your game. The transform is reusable, and can be applied to images and other displayables throughout your game using the `at` clause of the show and scene statements.

Transforms can also act as Displayables and be displayed directly. However, unlike other displayables which exist in the global image namespace (see Defining Images), transforms are created as variables in the appropriate named store (or the default store).

The transform is created during init time (when the game starts up).

Syntax

> Basic form:

>     transform <transform_name>:
>         <atl_block>

> With parameters:

>     transform <transform_name>( <parameters> ):
>         <atl_block>

Usage

> Name | Type | Description
> --- | --- | ---
> transform_name | word | Name of the transform. Must be valid Python identifiers separated by dots (e.g., `my_transform` or `sprites.bounce`)
> parameters | -- | (Optional) Parameters of the transform
> atl_block | block | ATL code block defining the transform

> You can add parameters to make your transforms flexible and reusable. Parameters work similarly to Python function parameters.

> Currently not supported:

> - Positional-only parameters (using `/`)

> - Required keyword-only parameters (after `*` without defaults)

> - `*args` (variadic positional parameters)

> - `**kwargs` (variadic keyword parameters)

> Note

> - If your transform has parameters without default values, you must provide values for all of them before you can use it as a transform

> - See also: ATL curry and partial parameter passing

Example

>     transform left_to_right:
>         xalign 0.
>         linear 2 xalign 1.
>         repeat

>     transform ariana.left:
>         xalign .3

>     transform animated_ariana_disp(duration=1.0):
>         "ariana"
>         pause duration
>         "ariana_reverse"
>         pause duration
>         repeat

>     label start:
>         show eileen happy at left_to_right
>         pause
>         show animated_ariana_disp
>         pause

#### Image Statement with ATL Block

The second way to include ATL code in a script is as part of an image statement. As its inline counterpart, it binds an image name (which may contain spaces) to the given transform. As there is no way to supply with parameters, it's only useful if the transform defines an animation.

Syntax

>     image <image_name>:
>         <atl_block>

Usage

> Name | Type | Description
> --- | --- | ---
> image_name | word(s) | Name of the image
> atl_block | block | ATL code block defining the transform

Example

>     image animated_ariana_img:
>         "ariana"
>         pause 1.
>         "ariana_reverse"
>         pause 1.
>         repeat

#### Scene and Show Statements with ATL Block

The final way to use ATL is as part of a show or scene statement. This wraps the image that's being shown inside an ATL transformation which is created on the fly and applied to the image.

Syntax

>     show <image_name>:
>         <atl_block>

>     scene <image_name>:
>         <atl_block>

Usage

> Name | Type | Description
> --- | --- | ---
> image_name | word(s) | Name of the image
> atl_block | block | ATL code block defining the transform

Example

>     show eileen happy:
>         xalign 1.

>     scene bg washington:
>         zoom 2.

### ATL Syntax and Statements

ATL statements may be inline, or make up a block within the ATL block in which it is written. With some exceptions described in the relevant statements, the statements in an ATL block are executed in order, from top to bottom.

If an ATL statement requires an expression to be evaluated, such evaluation occurs when the transform is first executed (that is when using a `show` statement, or displaying the transform as part of a screen), and not when the particular ATL statement is executed.

The following are the ATL statements.

#### Properties Statement

This statement sets the value of a transform property.

Syntax

>     <property_name> <property_value>

Usage

> Name | Type | Description
> --- | --- | ---
> property_name | word | Name of transform property (eg. `xalign`, `alpha`, ...)
> property_value | Varies | Value of property

> The statement first gives a series (at least one) of property names, each followed by the new value to set it to. See List of Transform Properties for a list of transform properties, their meaning and the values they take.

Example

>     transform rightoid:
>         xalign .9

>     transform ariana.left:
>         xanchor .3 xpos 100

#### Number Statement

This statement pauses the execution of the ATL block for the given duration. The "pause" keyword is optional.

Syntax

>     pause <duration>

Usage

> Name | Type | Description
> --- | --- | ---
> "pause" | keyword | (Optional) Keyword indicating a pause
> duration | float, int (expr) | Time in seconds to pause

Examples

>     transform pause_example(duration=0.5):
>         xalign 0.0

>         # Pause for 2.0 seconds.
>         pause 2.0
>         xalign 1.0

>         # Pause for `duration` seconds.
>         pause duration
>         xalign 0.5

>         # Pause for 3.0 seconds.
>         3.0

>         repeat

#### Interpolation Statement

The interpolation statement is the main way of getting smoothly animated transformations. The values change over time from their starting value to the given value.

A warping function is used to control how the interpolation progresses over time.

Syntax

> Basic form:

>     <warper_name> <duration> <atl_property> [<atl_property> ...]

> Using a warper function:

>     warp <warper_function> <duration> <atl_property> [<atl_property> ...]

> Block form:

>     <warper_name> <duration>:
>         <atl_property>
>         <atl_property>
>         ...

Usage

> Name | Type | Description
> --- | --- | ---
> warper_name | word | Name of a built-in warper
> warper_function | str, function (expr) | Warping function with signature `(t: float) -> float`
> duration | float, int (expr) | Time in seconds for the interpolation
> atl_property | Properties Statement | Property to interpolate

> The interpolation will persist for the given duration, and at least one frame.

> When Transform Properties are given, the value each is given is the value it will be set to at the end of the interpolation statement.

> It is also possible to interpolate a Transform Expression Statement, which should in this case be an ATL transform containing only a single properties statement. The properties from the transform will be processed as if they were written directly in this interpolation.

Examples

> Basic usage:

>     show logo base:
>         xalign 0.0 yalign 0.0

>         # Take 2.0 seconds to move things to the bottom-left corner.
>         linear 2.0 yalign 1.0

> Using warper function:

>     show logo base(warper_expr="easein"):
>         xalign 0.0 yalign 0.0

>         # Use the warper in the parameter to move to the right side of the screen.
>         warp warper_expr 1.0 xalign 1.0

> Multiple properties:

>     show logo base:
>         xalign 0.0 yalign 0.0

>         # Changes xalign and yalign at the same time.
>         linear 2.0 xalign 0.5 yalign 0.5

>         # The same thing, using a block.
>         linear 2.0:
>             xalign 0.5
>             yalign 0.5

> Creator-defined warper:

>     init python:
>         def my_warper(t):
>             return t**4.4

>         my_warpers = [my_warper]

>     transform custom_warper_example:
>         xpos 0
>         warp my_warper 3 xpos 100
>         warp my_warpers[0] 5 xpos 520

Property Interpolation

With spline motion (curved path):

>     <atl_property> knot <knot_value> [knot <knot_value> ...]

> Name | Type | Description
> --- | --- | ---
> knot_value | Varies (expr) | Value of the property control point

> The starting point is the value of the property at the start of the interpolation, the end point is the value given in `<atl_property>`. The knots are used to control the spline.

> A quadratic Bezier curve is used for a single knot, a cubic Bezier is used when there are two, and Catmull-Rom is used for three or more knots. In the former two cases, the knot or knots are simply control nodes. For Catmull-Rom, the first and last knot are control nodes (often outside the displayed path) and the other knots are points the path passes through.

>     transform spline_motion_single_property:
>         # Start at the bottom right, zoomed out a bit.
>         zoom 0.5 xalign 1.0 yalign 1.0

>         # Move from to the bottom center, overshooting a bit. Quadratic Bezier curve.
>         linear 2.0 xalign 0.5 knot 0.0

>         # Move to the top, slowing down at the center. Cubic Bezier curve.
>         linear 2.0 yalign 0.0 knot 0.2 knot 0.8

>         # Move to the left, oscillating first. Catmull-Rom spline.
>         linear 2.0 xalign 0.0 knot 1.0 knot 0.5 knot 0.0

>     transform spline_motion_multi_property:
>         # Start at the bottom right, zoomed out a bit.
>         zoom 0.5 align (1.0, 0.0)

>         # Use a spline motion to move (x, y) simultaneously in a slight S shape.
>         linear 2.0 align (0.5, 1.0) knot (0.0, .33) knot (1.0, .66)

With circular motion

>     <atl_property> clockwise
>     <atl_property> counterclockwise
>     <atl_property> circles <number_of_circles>

> Name | Type | Description
> --- | --- | ---
> number_of_circles | int (expr) | Number of full rotations for circular motion

> The start and end locations are compared (which are set by `pos`, `align`, `angle` and `radius`, ...) and the polar coordinate center is determined (which is `around`). Ren'Py will then compute the number of degrees it will take to go from the start angle to the end angle, in the specified direction of rotation. If the circles clause is given, Ren'Py will ensure that the appropriate number of circles will be made.

>     show logo base:
>         xalign 1.0 yalign 0.0

>         # Set the location to circle around.
>         anchor (0.5, 0.5)

>         # Use circular motion to bring us to spiral out to the top of
>         # the screen. Take 2 seconds to do so.
>         linear 2.0 yalign 0.0 clockwise circles 3

With a transform expression

>     <transform_expression>

> Name | Type | Description
> --- | --- | ---
> transform_expression | Transform (expr) | Transform to interpolate to

> In this case, the be an ATL transform containing only a single properties statement. The properties from the transform will be processed as if they were written directly in this interpolation.

>     show logo base:
>         xalign 1.0 yalign 0.0

>         # Move to the location specified in the truecenter transform in 1.0 seconds
>         ease 1.0 truecenter

#### Pass Statement

The `pass` statement causes nothing to happen: a no-op.

Syntax

>     pass

> This can be used when there's a desire to separate statements, like when two sets of choice statements (see below) would otherwise be back-to-back. It can also be useful when the syntax requires a block to be created but you need it to be empty, for example to make one of the choice blocks not do anything.

#### Repeat Statement

The `repeat` statement causes the block containing it to resume execution from the beginning.

Syntax

> Basic form:

>     repeat

> With count parameter:

>     repeat <count>

Usage

> Name | Type | Description
> --- | --- | ---
> count | int (expr) | (Optional) Number of times to execute the block

> A block ending with `repeat 2` will execute at most twice in total, and `repeat 1` does not repeat.

> The repeat statement must be the last statement in a block

Example

>     show logo base:
>         xalign 0.0
>         linear 1.0 xalign 1.0
>         linear 1.0 xalign 0.0
>         repeat

#### Block Statement

The `block` statement simply contains a block of ATL statements. This can be used to group statements that will repeat.

Syntax

>     block:
>         <atl_block>

Example

>     show logo base:
>         alpha 0.0 xalign 0.0 yalign 0.0
>         linear 1.0 alpha 1.0

>         block:
>             linear 1.0 xalign 1.0
>             linear 1.0 xalign 0.0
>             repeat

#### Parallel Statement

The `parallel` statement defines a set of ATL blocks to execute in parallel.

Syntax

>     parallel:
>         <atl_block>

Usage

> Name | Type | Description
> --- | --- | ---
> "parallel" | keyword | One or more parallel blocks
> atl_block | block | ATL block for this parallel branch

> When you use multiple parallel blocks, they all run at the same time. The parallel statement finishes when the last block finishes.

> Each parallel block should be independent and modify different Transform Properties. For example, one block might control horizontal movement (`xalign`) while another controls vertical movement (`yalign`). If two blocks try to change the same property at the same time, the behavior is unpredictable and should be avoided.

> Parallel statements are greedily grouped into a parallel set when more than one parallel block appears consecutively in a block.

Example

>     show logo base:
>         parallel:
>             xalign 0.0
>             linear 1.3 xalign 1.0
>             linear 1.3 xalign 0.0
>             repeat
>         parallel:
>             yalign 0.0
>             linear 1.6 yalign 1.0
>             linear 1.6 yalign 0.0
>             repeat

#### Choice Statement

The `choice` statement defines one of a set of potential choices. Ren'Py will pick one of the choices in the set, and execute the ATL block associated with it, and then continue execution after the last choice in the choice set.

Syntax

> Basic form:

>     choice:
>         <atl_block>

> With weight:

>     choice <weight>:
>         <atl_block>

Usage

> Name | Type | Description
> --- | --- | ---
> "choice" | keyword | One or more choices
> weight | float (expr) | (Optional) Weight of this choice, defaults to 1.0
> atl_block | block | ATL block for this choice

> Choice statements are greedily grouped into a choice set when more than one choice statement appears consecutively in a block. If the simple_expression is supplied, it is a floating-point weight given to that block, otherwise 1.0 is assumed.

> The `pass` statement can be useful in order to break several sets of choice blocks into several choice statements, or to make an empty choice block.

Example

>     image eileen random:
>         choice:
>             "eileen happy"
>         choice:
>             "eileen vhappy"
>         choice 2.0:
>             # More likely to be chosen.
>             "eileen concerned"

>         pause 1.0
>         repeat

#### Animation Statement

The `animation` statement must be the first statement in an ATL block, and tells Ren'Py that the block uses the animation timebase (`at`) rather than the normal showing timebase (`st`). For more information, see Timebases.

Syntax

>     animation

Usage

> The animation timebase starts when an image or screen with the same tag is shown. This is generally used to have one image replaced by a second one at the same apparent time.

Example

>     image eileen happy moving:
>         animation
>         "eileen happy"
>         xalign 0.0
>         linear 5.0 xalign 1.0
>         repeat

>     image eileen vhappy moving:
>         animation
>         "eileen vhappy"
>         xalign 0.0
>         linear 5.0 xalign 1.0
>         repeat

>     label start:
>         show eileen happy moving
>         pause
>         show eileen vhappy moving
>         pause

> This example will cause Eileen to change expression when the first pause finishes, but will not cause her position to change, as both animations share the same animation time, and hence will place her sprite in the same place. Without the animation statement, the position would reset when the player clicks.

#### On Statement

The `on` statement defines an event handler.

Syntax

> For one event

>     on <event_name>:
>         <atl_block>

> For multiple events

>     on <event_name>, <event_name>, ...:
>         <atl_block>

Usage

> Name | Type | Description
> --- | --- | ---
> event_name | word | Name of one or more events to handle
> atl_block | block | ATL block to execute when event occurs

> `on` blocks are greedily grouped into a single statement. On statement can handle a single event name, or a comma-separated list of event names.

> This statement is used to handle events. When an event is handled, handling of any other event ends and handing of the new event immediately starts. When an event handler ends without another event occurring, the `default` event is produced (unless the `default` event is already being handled).

> Execution of the on statement will never naturally end. (But it can be ended by the time statement, or an enclosing event handler.)

Example

>     show logo base:
>         on show:
>             alpha 0.0
>             linear .5 alpha 1.0
>         on hide:
>             linear .5 alpha 0.0

>     transform pulse_button:
>         on hover, idle:
>             linear .25 zoom 1.25
>             linear .25 zoom 1.0

#### Displayable Statement

The displayable statement sets or replaces the child displayable of the transform when the statement executes. You can also optionally add a transition effect when changing from one displayable to another.

Syntax

> Basic form:

>     <displayable>

> With transition:

>     <displayable> with <transition>

Usage

> Name | Type | Description
> --- | --- | ---
> displayable | Displayable (expr) | The new child image or visual element to display
> transition | Transition (expr) | (Optional) Transition when changing displayables (eg. `dissolve`, `fade`)

> Note

> Not all transitions work in this context. In particular, Dict Transitions, and `move-` and `ease-` transitions won't work here.

> Using transforms as displayables: If you pass another ATL transform that already has a child displayable, your current ATL block will pause and wait for that included transform's animation to finish before continuing.

> Warning

> If you pass a transform without a child, it will make your transform transparent and won't display anything. A child-less ATL transforms might be interpreted as a Transform Expression Statement, which will yield different results.

> For beginners: Always make sure your displayable is something visible, like an image filename (`"logo.png"`) or a displayable with content.

Example

>     image atl example:
>         "logo_base.png"

>         pause 1.0

>         "logo_bw.png" with Dissolve(0.5, alpha=True)

#### Transform Expression Statement

This statement includes another ATL transform as part of the current ATL block.

Syntax

>     <transform_expression>

Usage

> Name | Type | Description
> --- | --- | ---
> transform_expression | Transform (expr) | Transform to interpolate to

> This only applies if the ATL transform has not been supplied a child (see the top of the page for how to do that), otherwise it will be interpreted as a Displayable Statement. The contents of the provided ATL transform are included at the location of this statement.

Example

>     transform move_right:
>         linear 1.0 xalign 1.0

>     image atl example:
>         # Display logo_base.png
>         "logo_base.png"

>         # Run the move_right transform.
>         move_right

#### Contains Inline Statement

This statement sets (or replaces) the child of the current ATL transform to the value of the expression, making it useful for animation.

Syntax

>     contains <displayable>

Usage

> Name | Type | Description
> --- | --- | ---
> displayable | Displayable, Transform (expr) | Child displayable or transform

> The Displayable Statement is less explicit and bears ambiguity with the transform expression statement, but it allows for a transition to be used for replacing the child. This statement can be particularly useful when an ATL transform wishes to contain, rather than include, a second ATL transform.

> Note

> Use this statement when you want your ATL transform to contain another ATL transform as its child. This is particularly helpful when you need the child to be a separate transform object rather than just including its code directly.

> Otherwise, the Displayable Statement is a simpler way to set the child displayable, and it has the advantage of specifying a transition that plays when replacing the old child with a new one.

Example

>     transform an_animation:
>         "1.png"
>         pause 2
>         "2.png"
>         pause 2
>         repeat

>     image move_an_animation:
>         contains an_animation

>         # If we didn't use contains, we'd still be looping
>         # and would never reach here.
>         xalign 0.0
>         linear 1.0 yalign 1.0

#### Contains Block Statement

The contains block, like its inline counterpart, sets the child of the transform but in a different way.

Syntax

>     contains:
>         <atl_block>

Usage

> One or more contains blocks will be greedily grouped together inside a single contains statement, wrapped inside a `Fixed()`, and set as the child of the transform.

> Each block should define a displayable to use, otherwise an error will occur. The contains statement executes instantaneously, without waiting for the children to complete.

Example

>     image test double:
>         contains:
>             "logo.png"
>             xalign 0.0
>             linear 1.0 xalign 1.0
>             repeat

>         contains:
>             "logo.png"
>             xalign 1.0
>             linear 1.0 xalign 0.0
>             repeat

#### Function Statement

The `function` statement allows ATL to use Python code.

Syntax

>     function <func>

Usage

> Name | Type | Description
> --- | --- | ---
> func | function (expr) | Function to call, with signature `(trans: Transform, st: float, at: float) -> float | None`

> The functions have the same signature as those used with `Transform()`:

> - The first argument is a transform object. Transform Properties can be set as attributes on this object.

> - The second argument is the shown timebase, the number of seconds since the function began executing.

> - The third argument is the animation timebase, which is the number of seconds something with the same tag has been on the screen.

> - If the function returns a number, it will be called again after that number of seconds has elapsed. (0 seconds means to call the function as soon as possible.) If the function returns None, control will pass to the next ATL statement.

> This function should not have side effects other than changing the transform object in the first argument, and may be called at any time with any value as part of prediction.

> Note that `function` is not a transform property, and that it doesn't have the exact same behavior as `Transform()`'s function parameter.

Example

>     init python:
>         def slide_vibrate(trans, st, at, /):
>             if st > 1.0:
>                 trans.xalign = 1.0
>                 trans.yoffset = 0
>                 return None
>             else:
>                 trans.xalign = st
>                 trans.yoffset = random.randrange(-10, 11)
>                 return 0

>     label start:
>         show logo base:
>             function slide_vibrate
>             pause 1.0
>             repeat

#### Time Statement

The `time` statement is a control statement.

Syntax

>     time <value>

Usage

> Name | Type | Description
> --- | --- | ---
> value | float/int (expr) | Time in seconds from start of block execution

> When the value given in the statement is reached, the next statement begins to execute. This transfer of control occurs even if a previous statement is still executing, and causes any such prior statement to immediately terminate.

> If the time statement is reached before the given value, the transform pauses and waits until the time statement would take control.

> When there are multiple time statements in a block, they must strictly increase in order.

Example

>     image backgrounds:
>         "bg band"
>         xoffset 0
>         block:
>             linear 1 xoffset 10
>             linear 1 xoffset 0
>             repeat # control would never exit this block

>         time 2.0
>         xoffset 0
>         "bg whitehouse"

>         time 4.0
>         "bg washington"

#### Event Statement

The `event` statement causes an event with the given name to be produced.

Syntax

>     event <event_name>

Usage

> Name | Type | Description
> --- | --- | ---
> event_name | word | Name of event to produce

> When an event is produced inside a block, the block is checked to see if an event handler for the given name exists. If it does, control is transferred to the event handler. Otherwise, the event propagates to any containing event handler.

### External events

The following events are triggered automatically within an ATL transform:

`start`

  A pseudo-event, triggered on entering an `on` statement, if no event of higher priority has happened.

`show`

  Triggered when the transform is shown using the show or scene statement, and no image with the given tag exists.

`replace`

  Triggered when transform is shown using the `show` statement, replacing an image with the given tag.

`hide`

  Triggered when the transform is hidden using the `hide` statement or its Python equivalent.

  Note that this isn't triggered when the transform is eliminated via the Scene Statement or exiting the Contexts it exists in, such as when exiting the game menu.

`replaced`

  Triggered when the transform is replaced by another. The image will not actually hide until the ATL block finishes.

`hover`, `idle`, `selected_hover`, `selected_idle`, `insensitive`, `selected_insensitive`

  Triggered when a button containing this transform, or a button contained by this transform, enters the named state.

### ATL curry and partial parameter passing

An ATL transform defined using the Transform Statement can have its parameters set at different times. When calling an ATL transform like a function, the resulting value is still a transform, and the parameters that were passed a value are treated as though the value is the new default value of the parameter.

For example:

    transform screamer(child, screamee, wait_time=2, flash_time=.1):
        child
        pause wait_time
        screamee
        pause flash_time
        child

    # doing this doesn't raise an error (it would if it were a Python function)
    define shorter_screamer = screamer(wait_time=1)

    define eileen_excited_screamer = screamer(screamee="eileen excited", flash_time=.2)

    label start:
        show hhannahh happy at screamer(screamee="hhannahh surprised", wait_time=1.5)
        "Here is one way"

        show eileen vhappy at eileen_excited_screamer
        "Here is another"

        show patricia sad at eileen_excited_screamer(screamee="patricia wow")
        "And you can also do this"

Note that the `shorter_screamer` transform, just as the `screamer` transform, cannot be used directly like `show eileen at screamer`, since their `screamee` parameters do not have a value.

Note also that, like labels and screens, the default values of the parameters of a transform directly created by the Transform Statement will be evaluated at the time when the transform is called, not at the time when it is defined.

However, the transform resulting from calling another transform (such as `shorter_screamer` in the example above, or also the transform applied to patricia) has all the default values of its parameters already evaluated, whether they come from the evaluation of the default values in the original transform (such as `shorter_screamer`'s flash_time parameter, or patricia's transform's wait_time parameter), or from values passed to it in a call earlier in the line (such as `shorter_screamer`'s wait_time parameter, or patricia's transform's screamee and flash_time parameters).

### Special Child Parameter

If an ATL transform has a parameter named "child" and that parameter receives a value, regardless of the kind of parameter or the way it receives a value (by a positional argument or by keyword, and even if the parameter is positional-only or keyword-only, and defaulted or required), then in parallel the child of the transform is set to the value of the parameter.

Note that the default value of the parameter doesn't count, the parameter has to receive a value from the outside.

Conversely, when that ATL transform is used as a transform, the `child=` keyword argument will be passed, and so in addition to setting the child, if a parameter is there to receive it (excluding positional-only parameters, since it is passed by keyword), it will have the child's value when the transform executes.

For example, this enables to swap between the supplied child and another displayable:

    transform lucy_jump_scare(child):
        # the child is implicitly set as the child of the transform
        pause 5

        # Jump scare
        "lucy mad"
        pause .2

        # Go back to the original child
        child

It can also be used to place the original child inside a `contains` block:

    transform marquee(width, height=1.0, duration=2.0, child=None):
        xcenter 0.5
        ycenter 0.5

        crop (0, 0, 0.5, 500)

        contains:
            child
            xanchor 0.0 xpos 1.0
            linear duration xanchor 1.0 xpos 0.0

The old_widget and new_widget keyword-able parameters (meaning that they should not be positional-only) have a special use as part of ATL Transitions.

## Warpers

A warper is a function that can change the amount of time an interpolation statement considers to have elapsed. They are defined as functions from t to t', where t and t' are floating point numbers, with t ranging from 0.0 to 1.0 over the given amount of time. (If the statement has 0 duration, then t is 1.0 when it runs.) t' should start at 0.0 and end at 1.0, but can be greater or less. The following warpers are defined by default.

`pause`

  Pause, then jump to the new value. If `t == 1.0`, `t' = 1.0`. Otherwise, `t' = 0.0`.

`linear`

  Linear interpolation. `t' = t`

`ease`

  Start slow, speed up, then slow down. `t' = .5 - math.cos(math.pi * t) / 2.0`

`easein`

  Start fast, then slow down. `t' = math.cos((1.0 - t) * math.pi / 2.0)`

`easeout`

  Start slow, then speed up. `t' = 1.0 - math.cos(t * math.pi / 2.0)`

In addition, most of Robert Penner's easing functions are supported. To make the names match those above, the functions have been renamed somewhat. Graphs of these standard functions can be found at https://easings.net/.

Ren'Py Name | easings.net Name
--- | ---
ease_back | easeInOut_back
ease_bounce | easeInOut_bounce
ease_circ | easeInOut_circ
ease_cubic | easeInOut_cubic
ease_elastic | easeInOut_elastic
ease_expo | easeInOut_expo
ease_quad | easeInOut_quad
ease_quart | easeInOut_quart
ease_quint | easeInOut_quint
easein_back | easeOut_back
easein_bounce | easeOut_bounce
easein_circ | easeOut_circ
easein_cubic | easeOut_cubic
easein_elastic | easeOut_elastic
easein_expo | easeOut_expo
easein_quad | easeOut_quad
easein_quart | easeOut_quart
easein_quint | easeOut_quint
easeout_back | easeIn_back
easeout_bounce | easeIn_bounce
easeout_circ | easeIn_circ
easeout_cubic | easeIn_cubic
easeout_elastic | easeIn_elastic
easeout_expo | easeIn_expo
easeout_quad | easeIn_quad
easeout_quart | easeIn_quart
easeout_quint | easeIn_quint

These warpers can be accessed in the `_warper` read-only module, which contains the functions listed above. It is useful for things in Ren'Py which take a time-warping function, such as `Dissolve()`, which you can use like:

    with Dissolve(1, time_warp=_warper.easein_quad)

New warpers can be defined using the `renpy.atl_warper` decorator, in a `python early` block. It should be placed in a file that is parsed before any file that uses the warper. This looks like:

    python early hide:

        @renpy.atl_warper
        def linear(t):
            return t

## Replacing Transforms

When an ATL transform, a built-in transform or a transform defined using the `Transform` class is replaced by another transform of these categories, the properties of the outgoing transform are inherited by the incoming transform. That inheritance doesn't apply for other kinds of transforms.

When the show statement has multiple transforms in the `at` list, the transforms are matched from last to first, until one list runs out. For example:

    show eileen happy at a, b, c
    "Dialogue !"
    show eileen happy at d, e

The `c` transform will be replaced by `e`, the `b` transform will be replaced by `d`, and nothing replaces the `a` transform.

At the moment of replacement, if both transforms are of suitable kinds, the values of the properties of the old transform are copied to the new transform. If the old transform was animated, the current intermediate value is inherited. For example:

    transform bounce:
        linear 3.0 xalign 1.0
        linear 3.0 xalign 0.0
        repeat

    transform headright:
        linear 15 xalign 1.0

    label example:
        show eileen happy at bounce
        pause
        show eileen happy at headright
        pause

In this example, the image will bounce from left to right and back until the player clicks. When that happens, the `xalign` property of the `bounce` transform will be used to initialize the `xalign` property of the `headright` transform, and so the image will move from where it was when the player first clicked.

The position properties (`xpos`, `ypos`, `xanchor`, `yanchor`, and properties setting them such as `xalign` or `radius`/ `angle`) have a special rule for inheritance : a value set in the child will override a value set in the parent. That is because a displayable may have only one position, and a position that is actively set takes precedence.

Finally, when a `show` statement does not include an `at` clause, the same transforms are used, so no inheritance is necessary. To reset all transform properties, hide and then show the displayable again. To break the animations applied to a displayable (but keep the position), you can use:

    show eileen happy at some_animation
    "Wow, so this is what antigravity feels like !"

    show eileen:
        pass
    "But I'm happy when it settles down."

## Timebases

Two timebases exist and are commonly confused:

- `st` (shown timebase): begins when this displayable is first shown on the screen.

- `at` (animation timebase): begins when an image with the same tag was shown, without being hidden.

When the displayable is shown without a tag, `st` and `at` are the same.

Note

By default, transforms use `st`. Use animation to switch to `at`.

## Transform Class

One equivalent to to the simplest ATL transforms is the Transform class.

class Transform(child=None, *, function=None, reset=False, **properties)

  Creates a transform which applies operations such as cropping, rotation, scaling or alpha-blending to its child. A transform object has fields corresponding to the transform properties, which it applies to its child.

  child

    The child the transform applies to.

  reset

    If True, the transform will reset properties to their default values when it is shown, rather than inheriting those properties from the transforms it replaces.

  function(trans: Transform, st: float, at: float, /) → float | None

    If not None, this function will be called when the transform is rendered, with three positional arguments:

    - The transform object.

    - The shown timebase, in seconds.

    - The animation timebase, in seconds.

    The function should return a delay, in seconds, after which it will be called again, or None to be called again at the start of the next interaction.

    This function should not have side effects other than changing the Transform object in the first argument, and may be called at any time with any value as a part of prediction.

  Additional keyword arguments are values that transform properties are set to. These particular transform properties will be set each time the transform is drawn, and so may not be changed after the Transform object is created. Fields corresponding to other transform properties, however, can be set and changed afterwards, either within the function passed as the function parameter, or immediately before calling the `update()` method.

  hide_request

    This attribute is set to true when the function is called, to indicate that the transform is being hidden.

  hide_response

    If `hide_request` is true, this can be set to false to prevent the transform from being hidden.

  original_child

    This is the child Displayable that was set when the transform was created, before any calls to set_child. This may be None if no child was during creation.

  set_child(child)

    Call this method with a new child to change the child of this transform.

  update()

    This should be called when a transform property field is updated outside of the function passed as the function argument, to ensure that the change takes effect.

  unique():

    This should be called on a newly created transform to mark it as unique. Usually, transforms are copied when when added to a displayable, resetting transform state. Calling this prevents thart behavior, and is useful when you want to create a transform that maintains state across multiple uses, or that needs to be accessed from outside its function argument.

    This function returns the Transform.

## Applying transforms to displayables in Python

There are several ways to apply transform `t` to displayable `d` in Python:

1. The most universal and most recommended way is `At(d, t)` (see below). It works with all transforms.

2. `d(child=t)` works with all ATL transforms.

3. `t(d)` works with all Python transforms, as well as with ATL transforms that don't have any positional parameters.

At(d, *args)

  Given a displayable d, applies each of the transforms in args to it. The transforms are applied in left-to-right order, so that the outermost transform is the rightmost argument.

      transform birds_transform:
          xpos -200
          linear 10 xpos 800
          pause 20
          repeat

      image birds = At("birds.png", birds_transform)

Note

The resulting value may not be able to be displayed, if there remains parameters of the transform that have not been given a value, as can be the case with transforms defined using the Transform Statement.

Note

The resulting value may still be a transform that can be applied to yet another displayable (overriding its previous child) ; that's the case with ATL transforms which are still usable as transforms even when having their child set.

## Callables as transforms

Finally, simple Python callables can be used as transforms. These callables should take a single displayable as an argument, and return a new Displayable. For example:

    init python:

        # this transform uses the right and left transforms
        def right_or_left(d):
            if switch:
                return At(d, right)
            else:
                return At(d, left)

That means that certain builtins which take a displayable and return a displayable, such as `Flatten()`, are also transforms and can be used as such.