Controller Support Expansion for Ren’Py includes several features to improve controller and keyboard support in Ren’Py. Pick up the tool from itch.io if you haven’t already:
The Controller Support Expansion for Ren’Py also includes a virtual keyboard which can be used to enter input such as character names without requiring a physical keyboard. It has several shortcuts for controllers to make it easy to use.
Examples
The following are some examples of how to use the virtual keyboard to get input from the player.
Example 1
The first example is a very basic way to get input from the player.
default name = "Feniks"
label start():
$ name = universal_input(_("Enter your name:"))
"Your name is [name], is that right?"
This will show an input prompt to the player. If the player is using the mouse and keyboard, they will not be shown a virtual keyboard. If they are using a controller, the input will be shown using the onscreen_keyboard screen.
Example 2
The second example shows how you can pass arguments to the various input functions:
default name = "Feniks"
label start():
$ name = universal_input(_("Enter your name:"), length=20, pixel_width=300,
allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '-")
"Your name is [name], is that right?"
This example is similar to the previous one, but has some constraints on valid input: in particular, it has to be a letter, space, apostrophe, or hyphen, it can be a maximum of 20 characters long, and the total width of the letters can’t be more than 300 pixels wide. These arguments are identical to the ones seen in renpy.input!
Example 3
Here is an example that uses the virtual numpad rather than the keyboard:
default pin = ""
label start():
$ pin = universal_input(_("Enter a 4-digit number:"),
## This could be specified, but it will automatically use the numpad
## since it only allows numbers
# screen="onscreen_numpad",
allow='1234567890', length=4)
"Your PIN is [pin]."
You may also use $ pin = int(pin)
to turn the result into a number rather than a string, if you need to compare it to other numbers.
Example 4
This example has a screen with multiple inputs. The player can select an input, which will show the virtual keyboard if they are using a controller, or simply enable the input if not.
default demo_first_name = "Feniks"
default demo_last_name = "Dev"
default demo_number = ""
screen naming_screen():
## The "object" here is `store` since it's a regular store variable.
## If the variable was persistent.name, it would use `persistent` instead.
default first_name_input = EnterInputValue(store, 'demo_first_name')
default last_name_input = EnterInputValue(store, 'demo_last_name')
default number_input = EnterInputValue(store, 'demo_number')
add "#601249bb"
style_prefix 'demo_name'
vbox:
button:
default_focus True
## Ensure you can type without needing to hover this button
key_events True
## This action "does the right thing" based on whether the player
## is using a controller or not. For it to work, you need to give
## the input a unique ID and pass that into the action. You can also
## pass other properties, like the prompt or whether to dim the
## screen. Passing the ID ensures it gets the same properties
## as the original input, like length and allowed characters.
action UniversalInputToggle('first_name',
prompt=_("Enter your first name:"), dim=True)
has hbox
text _("First Name:")
# The actual input, which uses the EnterInputValue earlier
input value first_name_input id 'first_name' length 15:
allow "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ -'"
pixel_width 400
button:
key_events True
action UniversalInputToggle('last_name',
prompt=_("Enter your last name:"), dim=True)
has hbox
text _("Last Name:")
# The actual input, which uses the EnterInputValue earlier
input value last_name_input id 'last_name' length 15:
allow "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ -'"
pixel_width 400
button:
key_events True
action UniversalInputToggle('number',
prompt=_("Enter a number:"), dim=True)
has hbox
text _("Number:")
# The actual input, which uses the EnterInputValue earlier
input value number_input id 'number' length 4 allow '1234567890'
textbutton _("Done") action Return() xalign 0.5
This example uses the class EnterInputValue
. This is included with the controller support expansion pack, or you can also find it here: https://github.com/shawna-p/RenPyControllerGUI/blob/main/game/optional%20files/mobile_input.rpy. It is a special kind of InputValue which disables the input when the Enter key is pressed, but any other InputValue can be used here as well (link to InputValue in the Ren’Py docs).
The important part is that each of your input
elements needs an ID, and that ID needs to be passed to the UniversalInputToggle
action. Doing so ensures that the virtual keyboard input will have all the same properties as the one on your screen, such as allow
, length
, and more. You can pass in individual properties to overwrite them – the example passes in prompt
so that the prompt appears for the virtual keyboard indicating what the input is for. It also uses dim=True
so that the screen behind the virtual keyboard is dimmed.
Note: Much of the rest of this page is for reference purposes and internal use – these are the functions and actions used to make the virtual keyboard work. If you just want to use the virtual keyboard in your game, use the Examples section to see how to use these features, and refer back to the individual functions and actions used in the examples if you’d like to know more.
Controller Input
Inside screens, the screen language keyword controller_input
can be used to show the virtual keyboard when a controller is used. ControllerInput inherits from the built-in Input class and shares all the same properties as it: see https://www.renpy.org/doc/html/screens.html#input for more. There are a few functions and actions specific to controller input:
InputLetter(id, letter, layer=None)
InputLetter is a screen action which can be used to add a letter to a ControllerInput. It takes three arguments:
id
This is the ID of the ControllerInput. e.g. id="tinput"
letter
This is a string of the text to add to the ControllerInput. e.g. letter="a"
layer
The layer the screen with the ControllerInput is on. This can usually just be None to automatically determine it.
e.g. action InputLetter("my_input", "f")
This action is used in the virtual keyboard screens to add content to the input with the controller.
ShowOnscreenInput(screen=None, transition=None, *args, **kwargs)
A screen action which will show an onscreen keyboard for controller input. It takes the following arguments:
screen
If this is not provided or None, one of “onscreen_keyboard” or “onscreen_numpad” will be used, depending on which characters are allowed in the input. The numpad will only be used if the input only accepts numbers. e.g. screen="onscreen_keyboard"
transition
If provided, this transition will be used to show the onscreen keyboard. e.g. transition=Dissolve(1.0)
args, kwargs
Any other arguments or keyword arguments will be passed along to the input screen being used for the virtual keyboard. In particular, allow
and exclude
keyword arguments may be provided, along with other input keyword arguments, to customize the virtual keyboard.
e.g. ShowOnscreenInput("onscreen_keyboard", dissolve, allow="0123456789")
UniversalInputToggle(id, **kwargs)
UniversalInputToggle is a screen action which can be used to toggle the provided InputValue if the player is using mouse and keyboard, or if the player is using a controller, it will show the virtual keyboard to enter input via ShowOnscreenInput
.
id
This should be the ID of an input
displayable declared on the screen. This will be used to get the correct InputValue and other input properties to re-use on the virtual keyboard screen. e.g. id="my_input"
kwargs
Any other keyword arguments will be passed along to ShowOnscreenInput if the virtual keyboard is used. The most notable are dim
, which you may want to set to dim=True
to dim the screen behind the virtual keyboard, and prompt
, which will be displayed above the input text.
e.g. UniversalInputToggle("first_name_input", dim=True, prompt=_("What's your first name?"))
input_check(s, to_capitalize=False, properties=None, pad=10)
This helper function changes the text in the virtual keyboard to suit the provided input properties and capitalize it if the shift button is active. It takes the following arguments:
s
A string of letters to use for a given keyboard row e.g. "qwertyuiop"
. See https://feniksdev.com/tool/configuration-variables/#Input for the different keyboard rows.
to_capitalize
Whether the letters in the provided string should be returned with their capitalized version or not. See https://feniksdev.com/tool/configuration-variables/#Input for the SHIFT_DICT which is used for symbols and other characters.
properties
This should be a dictionary with properties from the input field, usually automatically provided. If this includes the keys allow
or deny
, those will be used to determine which letters to remove from the string (so they don’t appear as buttons on the virtual keyboard).
pad
By default, virtual keyboard rows are 10 characters long. In order to keep all the virtual keyboard keys focusable even if they do not have valid letters in them for this input, pad=10
fills invalid letter keys with blank input and ensures the row remains at least 10 characters long. This prevents the keyboard from changing sizes when some letters aren’t usable.
universal_input(prompt, default=”, allow=None, exclude='{}’,
length=None, with_none=None, pixel_width=None, screen=None,
mask=None, copypaste=True, multiline=False, **kwargs)
This function borrows from https://www.renpy.org/doc/html/input.html#renpy.input and will choose to use either renpy.input
or controller_input
based on whether the last input type was a controller or not. It can be used in the same situations as renpy.input
and accepts all the same arguments e.g.
default name = "Feniks"
label start:
$ name = universal_input(_("What is your name?"), length=20)
Virtual Keyboard Screens
Controller Support Expansion for Ren’Py comes with two screens which are used to show the virtual keyboard to the player: onscreen_keyboard
and onscreen_numpad
. The former is the most commonly used screen; onscreen_numpad
is only used for input which only accepts numbers as input.
Styling the Virtual Keyboard
Inside the controller_input.rpy file you will find declarations for the two onscreen keyboard screens, as well as a few general styling constants declared at the top (as seen in https://feniksdev.com/tool/configuration-variables/#Input). While advanced users are free to adjust the screens directly, most users should adjust the ckeyboard_ styles below the screen to update the styling.