---
# System prepended metadata

title: Renpy Learning

---

# Renpy Learning

## Screen Demo

### Simple Stats Screen
```python=3.8
default player_hp = 15
default player_hp_max = 42
default eileen_hp = 100
default eileen_hp_max = 100

default player_lv = 4
default eileen_lv = 99

screen single_stat(name, hp, hp_max, lv, xalign):
    frame:
        xalign xalign
        vbox:
            spacing 5
            hbox:
                text "[name!t]" min_width 220
                text _(" Lv. [lv]")
            hbox:
                text _("HP"):
                    min_width 40
                    yalign 0.5
                bar:
                    value AnimatedValue(hp, hp_max, 1.0)
                    xmaximum 180
                    ysize 26
                text " [hp]/[hp_max]":
                    yalign 0.5
                    
screen stats():
    use single_stat(_("Player"), player_hp, player_hp_max, player_lv, 0.0)
    use single_stat(_("Eileen"), eileen_hp, eileen_hp_max, eileen_lv, 1.0)

label: screens_demo:
    $ player_hp = 15
    show screen stats
    with dissolve
    e "This will show the stat screen"

    $ player_hp = 42
    e "This will change the screen with dissolve effect"
    
```
The screen will dynamically change if variables are changed Unitill `hide screen`
![Demo](https://i.imgur.com/VSa7kIQ.png)

### More complicated Screen
```python=3.8
define day_periods = [ _('Morning'), _('Afternoon'), _('Evening') ]
define day_choices = [ _('Study'), _('Exercise'), _('Eat'), _('Drink'), _('Be Merry') ]
default day_plan = {
    'Morning' : 'Eat',
    'Afternoon' : 'Drink',
    'Evening' : 'Be Merry'
    }

default stat_strength = 10
default stat_intelligence = 25
default stat_moxie = 100
default stat_chutzpah = 75

style stat_text is default:
    min_width 200
    text_align 1.0
    yalign 0.5

style stat_hbox is hbox:
    spacing 10

style stat_vbox:
    spacing 5

screen day_planner():
    vbox: # Root Vbox
        spacing 5
        frame:
            style_prefix "stat"
            xpadding 100
            xfill True
            vbox:
                hbox:
                    text _("Strength")
                    bar value StaticValue(stat_strength, 100)

                hbox:
                    text _("Intelligence")
                    bar value StaticValue(stat_strength, 100)

                hbox:
                    text _("Moxie")
                    bar value StaticValue(stat_strength, 100)

                hbox:
                    text _("Chutzpah")
                    bar value StaticValue(stat_strength, 100)


        # A grid of three frames, one for each of the periods in the day.
        grid 3 1:
            spacing 5
            xfill True
            for p in day_periods:
                frame:
                    xfill True
                    vbox:
                        label p
                        null height 5
                        for i in day_choices:
                            textbutton i action SetDict(day_plan, p, i)

        # This is a grid containing two empty space and the done button,
        # so everything lines up.
        grid 3 1:
            xfill True
            spacing 5
            null
            frame:
                textbutton _("Done"):
                    action Return(True)
                    xfill True
                    text_xalign 0.5
            null



label: screens_demo2:
    show screen day_planner
    with dissolve
    e "Show the screen with dissolve"

    hide screen day_planner
    with dissolve
    e "hide with dissolve"

```
![](https://i.imgur.com/7l1sPMz.jpg)

### Show Screen 
1. Screen will remain shown until hidden
2. A screen will be hidden when a call returns (Like the following)
```python=
screen simple_screen():
    frame:
        xalign 0.5 ypos 50
        vbox:
            text _("This is a screen.")
            textbutton _("Okay"):
                action Return(True)
                
call screen simple_screen()
```
![](https://i.imgur.com/GCkkxAy.png)

### Parameters into Screen

```python=
screen parameter_screen(message, okay=Return(True), cancel=Return(False)):
    frame:
        xalign 0.5 ypos 50
        vbox:
            text "[message!t]"
            textbutton _("Okay"):
                action okay
            textbutton _("Cancel"):
                action cancel

show screen parameter_screen(_("Hello, world."), cancel=Notify(_("You can't cancel this."))) # pass two functions into a screen
with dissolve
```
![](https://i.imgur.com/8JaqGz4.png)

## Screen Properties
### modal
`modal True` prevent interaction to anything behind this screen(even the conversation)

### tag
To prevent two screen showing together on the screen, use same tag name on both screen (kind of like mutex)

### zorder
Controls the order of the screen(on z-axis)  
default zorder is 0, later come will shown in the front

### variant
`variant "small"` Determines which type of device will this screen be shown

### style_prefix
`style_prefix "red"` Any style defination with name ""red_xx" will be applied to this screen

### Python in screen
Same as script, use `$` as sigle line indicator and `python:` for multi-line.
`"[varname]"` to show variables in strings

python inside screen cannot have side-effects since those code will be run during screen prediction

### Use another screen in a screen
```python=
screen using_stats():
    frame:
        xalign 0.5 ypos 50
        vbox:
            use stat(_("Health"), 90) # uses stat screen defined below
            null height 15
            use stat(_("Magic"), 42)

screen stat(name, amount):
    text name xalign 0.5
    bar value StaticValue(amount, 100) xalign 0.5 xsize 250

```

### transclude
Pass child of the use statement into the position of `tranclude` 
```python=
screen transclusion_example():
    use boilerplate(): # All child of this line will be passed to transclude
        text _("There's not much left to see.")

screen boilerplate():
    frame:
        xalign 0.5 ypos 50

        vbox:
            transclude # this line will be replaced by previous codes
```
## Screen Displayables
### Position properities
All Displayable supports position properities like align, anchor, pos, etc.
### transform
keyword `at` is used for a transform:
```python=
screen at_example():
    frame:
        xalign 0.5 ypos 50
        text _("And the world turned upside down..."):
            at rotated

transform rotated:
    rotate 180 rotate_pad False
```
### style
all displayables can have a style tag:
```python=
style green_text:
    color "#c8ffc8"
        
text _("Flight pressure in tanks.") style "green_text" # oneliner way
text _("Same Style, different code style."):
    style "green_text" 
```
style_prefix can set all styles of children:
```python=
screen style_prefix_example():
    frame:
        xalign 0.5 ypos 50
        vbox:
            vbox:
                style_prefix "green"
                text _("Flight pressure in tanks.")
                text _("On internal power.")
```

### images
if image is in the image directory, can use name to refer.
```python=
add "logo base"
```
Can also use relative path to project root:
```python=
add "images/logo base.png"
```
Solid and other displayables can also be treated as an image
```python=
add Solid("#0000ff", xsize=234, ysize=360)
```
add statement also accepts transform properitites:
```python=
add "logo base" zoom 0.7 rotate 43.21
```
For more complex transform:
```python=
screen add_at_transform_example():
    frame:
        xalign 0.5 ypos 50
        add "logo base" at unrotate

transform unrotate:
    zoom 0.7 rotate 43.21
    linear 1.0 rotate 0
```
### Text
represented by keyword `text`  
in addition to common displayalbes properties, it also takes text style properties.
use `[variable]` to represent variables, and use {tag}word{/tag} to do inline styling

### Boxes and other layouts
Layout displayables: Takes its children and lay them out accordingly:
examples: `hbox`,`vbox`,`grid <x> <y>`
```python=
screen hbox_example():
    frame:
        xalign 0.5 ypos 50
        hbox: # this is a layout displayable
            spacing 10
            text "1"
            text "2"
```
`grid`: keyword `transpose True` can fill top-to-bottom instead of left-to-right
`has <keyword> <style>`: for all children of current layer, if they have keyword `<keyword>` in them, the style `<style>` will be applied.

### Windows and Frames
window are for dialogues and frames are for interactive elements

### Buttons
```python=
screen button_example():
    frame:
        xalign 0.5 ypos 50
        button:
            action Notify(_("You clicked the button."))
            hovered Notify(_("You hovered the button."))
            unhovered Notify(_("You unhovered the button."))
            text _("Click me.") style "button_text"
```
Example of Button interaction:
```python=
screen button_heal_example():
    default health = 42

    frame:
        xalign 0.5 ypos 50
        button:
            action SetScreenVariable("health", 100)
            hbox:
                spacing 10
                text _("Heal") style "button_text" yalign 0.5
                bar value AnimatedValue(health, 100, 1.0) yalign 0.5 xsize 200
```
### Bar
```python=
bar value StaticValue(66, 100) # two displyables
bar value AnimatedValue(n, 100, 0.5) style "bar"
bar value ScreenVariableValue("n", 100) style "slider" # two sliders
bar value ScreenVariableValue("n", 100) style "scrollbar"
# Vertical ones
bar value AnimatedValue(n, 100, 0.5) style "bar"
bar value ScreenVariableValue("n", 100) style "vslider" # vertials here
bar value ScreenVariableValue("n", 100) style "vscrollbar"
```
### viewport
Displays larger than screen 
```python=
screen viewport_screen():
    viewport:
        xalign 0.5 ypos 50 xysize (700, 300)
        
        xinitial 0.5 # initial position of scrollbar
        yinitial 1.0
        
        scrollbars "both"
        spacing 5
        
        draggable True
        mousewheel True
        arrowkeys True
        add "bg band"
```

### imagemap
shows interactive parts with images stacked together.  
Here is a simple example of what image to stack on at different actions
```python=
screen volume_imagemap_example():
    imagemap:
        xalign 0.5 ypos 50
        idle "imagemap volume idle"
        hover "imagemap volume hover"
        selected_idle "imagemap volume selected_idle"
        selected_hover "imagemap volume selected_hover"
        insensitive "imagemap volume insensitive"

        hotspot (237, 171, 126, 50) action Return(True)
        hotbar (51, 96, 498, 52) value Preference("music volume")
```
An easier way to to have all the keywords in the image file so they can be searched automatically.
```python=
screen volume_imagemap_auto_example():
    imagemap:
        xalign 0.5 ypos 50
        auto "imagemap volume %s"

        hotspot (237, 171, 126, 50) action Return(True)
        hotbar (51, 96, 498, 52) value Preference("music volume")
```

## Styles 
### Basics
Style information come from four places:
- From displayable itself (all displayable can have style properities)
```python=
screen style1():
    text _("This text is colored green."):
        style "my_text" # <- Here
        color "#c0ffc0" # <- Here
        at examplepos
```
style properties with `text_` prefix will apply to text inside its scope
```python=
textbutton _("Danger"):
    text_color "#c04040"
    text_hover_color "#ff0000"
    action Return(True)
```
- Argument of a image statement or character statement
```python=
image style2 = Text(_("This text is colored red."), color="#ffc0c0")
define egreen = Character("Eileen", who_color="#c8ffc8", who_bold=True, what_color="#c8ffc8")
```
- style statement. named style presets applied by reference
```python=
style blue_text:
    color "#c0c0ff"
image style3 = Text(_("This text is colored blue."), style="blue_text")
```
If styles are not given, it will inherit from parent
Parent of a style is written as: `<xxx_parentName>`, and all style has a root inheritance of `default`  
For example `blue_text` inherits from `text`, which inherits from `default`.  
To assign parent, use `is` keyword:
```python=
style apple_text is text:
    color "#c0c0ff"
```
Here is a way of apply apple_text on the `text` with style_prefix `apple`
```python=
 text _("This text is colored green.") style_prefix "apple" 
```
Here is a way to highlight selected button:
```python=
style styled_button_text: # keywords idle_, hover_, etc. will be handled for button coloring automaticlly
    idle_color "#c0c0c0"
    hover_color "#ffffff"
    insensitive_color "#303030"
    selected_idle_color "#e0e080"
    selected_hover_color "#ffffc0"

screen style4():

    default result = 1

    frame:
        style_prefix "styled"
        xpadding 20
        ypadding 20

        at examplepos

        vbox: # since styled contains button stats keyword, active key and inactive key will be colored in defined colors
            textbutton "Button 1" action SetScreenVariable("result", 1) # on click result value will change
            textbutton "Button 2" action SetScreenVariable("result", 2)
            textbutton "Button 3" action None

    show screen style4
    with dissolve
```

### Position styles
- `xalign`, `yalign` align on screen
- `xmaximum`, `ymaximum` set max width and height, wrap too long ones
- `xsize`, `ysize` min and max are the same after this. (size is fixed)
- `area(<xpos>, <ypos>, <xsize>, <ysize>)` determin size and position

### Text styles
- inplicit style: a textbutton will have a style named `button_text` by default
- `bold True` set text to bold `italic True`, `underline True`, `strikethrough True`, `vertial True`
- `color #hexval` set color
- `first_indent <indent>` determine how for to indent the first line
- `font <font_name.ttf>` TruType and OpenType fonts are allowed
- `size` size of text
- `justify True` lining las character to the right, make spaces different length across lines
- `kerning -0.5` change char-to-char distances, negative make chars closer
- `line_leading <space_size>` put space before each line. `line_spacing <space_size>` put space between lines
- `outlines [(<width>, <color>, <xoffset>, <yoffset>)]` put outlines around text check [related document](https://www.renpy.org/doc/html/style_properties.html#style-property-outlines) for details
- `text_align <0-1>` align of text (on horizontal direction); 0.5 means centered. `yalign <0-1>` align on vertical direction
- `antialias False` default is true
- `adjust_spacing True` keep char relative spacing when window resized
- `layout nopreak` disable line breaks

### Window and Button Styles
Buttons are windows that are clickable
- pass style as parameter:
```python=
screen button(style):
    default selected = "top"
    frame:
        xalign 0.5
        ypos 50
        background "#0004"
        xsize 350
        has vbox:
            xalign 0.5
        textbutton _("Top Choice"):
            style style
            action SetScreenVariable("selected", "top")
            text_style "example_button_text"
        textbutton _("Bottom Choice"):
            style style
            action SetScreenVariable("selected", "bottom")
            text_style "example_button_text"

style example_button is default:
    idle_background Frame("idle_background.png", 10, 10, tile=True)
    hover_background Frame("hover_background.png", 10, 10, tile=True)
    xalign 0.5
            
style example_button_text:
    xalign 0.5
    color "#404040"
    hover_color "#4040c0"


show screen button('example_button')
```
1. For Text in button
    - same as normal text style
2. For button itself
    - `(idle|hover)_background <Frame>` apply background to button
    - `xalign 0.5` center button
    - `(left|right|top|bottom)_(padding|margin) <value>` or `(left_right)_padding <value>`, `(x|y)margin <value>` to set padding and margin for button
    - `size_group <strName>` all window and button within same group have same size
    - `(x|y)fill` Fill up space available by stretching background
    - `(|selected_)foreground` provide a forground to button
    - `(hover|activate)_sound` sound for button at different actions
    - `focus_mask True` For partially transparent buttons, only non-transparent part of the button will be focused (by focus background image)
    - 

### bar styles
- A bar is made of a full image and an empty iamge.
- `bar_resizing True` resize the image and used instead of full size then crop
- `thumb <img>` show a indicator between full side and empty side
- `(left|right)_gutter <int>` area where thumb cannot be dragged into
- `bar_vertial True` vertical

### Grid Styles
- `hbox` and `vbox` present their child horizontally or vertically
- `(x|y)fill` same as button
- `first_spacing` spacing for the first element (for titling)
- `box_reverse` reverse order of elements
- `box_wrap` fill box till full then next row/column
- `(x|y)spacing` spacing for each element in table
- `fixed` fill all space it has, then show its children back to front
    - `(x|y)fit` layout children of current fixed object, then fit itself to its children
    - `order_reverse` show fron to back instead
```python=
screen fixed(style):
    frame:
        xalign 0.5
        ypos 50
        ypadding 20
        xsize 500
        ysize 400
        frame:
            style "empty"
            background "#fff2"
            fixed:
                style style
                add Transform("logo base", zoom=.9):
                    xpos 10
                    ypos 10
                text "Ren'Py":
                    font "DejaVuSans.ttf"
                    xpos 150
                    ypos 220
                    size 80
                    outlines [ (2, "#333", 0, 0) ]
```

### 