Side Images
===========

Many visual novels include a picture of the character that is speaking as
part of their interface. Ren'Py calls this image a side image, and has
support for automatically selecting and displaying a side image as part
of the dialogue.

The side image support assumes that a :func:`Character` is declared with
a linked image tag::

    define e = Character("Eileen", image="eileen")

When a character speaks, Ren'Py will search for a side image to show. The
side image must have:

* The "side" tag.
* An attribute corresponding to the linked image tag of the speaking character (in this case, "eileen").
* As many attributes as possible that are currently associated with the linked image tag of the speaking character.

Ren'Py will then search for a unique image matching these criteria. If one is found, it will be used as the side
image. If no image or more than one image is found, then no side image will be shown.

For example, say we have the following script::

    define e = Character("Eileen", image="eileen")

    image eileen happy = "eileen_happy.png"
    image eileen concerned = "eileen_concerned.png"
    image eileen space suit = "eileen_space_suit.png"


    image side eileen happy = "side_eileen_happy.png"
    image side eileen = "side_eileen.png"
    image side eileen space = "side_eileen_space.png"
    image side eileen suit = "side_eileen_suit.png"

    label start:

        show eileen happy

        e "Let's call this line Point A."

        e concerned "And this one is point B."

        e space suit "And this one is point C."

At point A, the character ``e`` is speaking, which is linked to the image
tag "eileen". The "eileen happy" image is showing, so "eileen" must be included,
and "happy" may be. We look for an image with the "side" tag, and as
many of those attributes as possible – and we match "side eileen happy",
which is the side image Ren'Py will display.

At point B, the "eileen concerned" image is showing. The "eileen" attribute must be included, and "concerned" may be.
We look for an image with the "side" tag, and as many of those attributes as possible, and we match "side eileen",
as the "side eileen concerned" image doesn't exist.

Finally, at point C, the "eileen space suit" image is showing, the "eileen" attribute must be included, and "space" and
"suit" may be. We look for an image with the "side" tag, and as many of those attributes as possible, and we match
"side eileen space" and "side eileen suit". Since both of these have the same number of attributes, Ren'Py refuses
to choose between them, and no side image is shown.


Invisible Characters
--------------------

Another use of the side image is to show an image of the player character,
when that character has dialogue. The way to do this is to link an image to
the character, and then use the say with attributes construct to select
the side image to show.

For example::

    define p = Character("Player", image="player")

    image side player happy = "side_player_happy.png"
    image side player concerned = "side_player_concerned.png"

    label start:

        p happy "This is shown with the 'side player happy' image."

        p "This is also shown with 'side player happy'."

        p concerned "This is shown with 'side player concerned'."

Config and Store Variables
--------------------------

There are a number of attributes of side images that can be controlled
using config variables.

.. var:: _side_image_tag = None
.. var:: config.side_image_tag = None

    If _side_image_tag is not None, it takes precedence over config.side_image_tag.

    If this is given, then the side image will track the given image tag,
    rather than the image associated with the currently speaking character. For example,

    ::

        define e = Character("Eileen", image="eileen")
        define config.side_image_tag = "eileen"

    Will make the side image track the "eileen" image tag, which is associated
    with the ``e`` character.

.. var:: config.side_image_only_not_showing = False

    When set to true, the side image will only show if an image with that tag
    is not already being shown on the screen.

.. var:: _side_image_prefix_tag = None
.. var:: config.side_image_prefix_tag = 'side'

    If _side_image_prefix_tag is not None, it takes preference over
    config.side_image_prefix_tag.

    The prefix that is used when searching for a side image.

.. var:: config.side_image_null = Null()

    The Null displayable to use when not displaying a side image. This can
    be changed, but only to other Null objects. One reason for doing so
    would be to set the side of the Null (eg. ``Null(width=200, height=150)``)
    to prevent dissolves from being cut off.

.. var:: config.side_image_same_transform = None

    If not None, a transform that is used when the new side image shares the
    same image tag as the previous side image.

.. var:: config.side_image_change_transform = None

    If not None, a transform that is used when the new side image does not
    share the name image tag (or one of the new or old side images does not
    exist).


Transforms and Transitions
--------------------------

The :var:`config.side_image_same_transform` and
:var:`config.side_image_change_transform` transforms are called with two
arguments – old and new side image displayables – each time the side
image is displayed. These can be used to move around side images, or
use a transition to go between side images.

This causes the side image to slide in and out when the character
associated with that image changes::

    transform change_transform(old, new):
        contains:
            old
            yalign 1.0
            xpos 0.0 xanchor 0.0
            linear 0.2 xanchor 1.0
        contains:
            new
            yalign 1.0
            xpos 0.0 xanchor 1.0
            linear 0.2 xanchor 0.0

    define config.side_image_change_transform = change_transform

This is used to dissolve between old and new side images when the
character remains the same. (For example, when the character changes
emotion.) For the :class:`Dissolve` to work correctly, both side images must
be the same size. ::

    transform same_transform(old, new):
        old
        new with Dissolve(0.2, alpha=True)

    define config.side_image_same_transform = same_transform


When the :func:`SideImage` is scaled down, it might make sense to enable
mipmapping in the :func:`Dissolve`::

    transform same_transform(old, new):
        old
        new with Dissolve(0.2, alpha=True, mipmap=True)

    define config.side_image_same_transform = same_transform

Functions
---------

.. include:: inc/side
