Tutorial: Inverting GUI Colours in Ren'py
Tags: posts, renpy, tutorial, accessibility,
Thanks to various people on the DevTalk discord.
Motivation
It's important for accessibility reasons that user interface elements use high contrast between the background and text. But this generally means picking one of dark text on a light background or light text on a dark background, and some users will find it much easier to read the reverse.
By offering an 'invert user interface colours' toggle, your game becomes more accessible without having to create a whole separate colour scheme from scratch.
Inverting the Colours
Here's a screenshot of my original UI:
Add this code whereever you define default variables and transforms etc:
default persistent.gui_is_inverted = 0.0 transform invert_gui: matrixcolor InvertMatrix(persistent.gui_is_inverted) define config.layer_transforms = {"screens":[invert_gui]}
This will invert the colours of everything on the "screens" layer, like so:
If you want to keep the hue the same and just invert the brightness, use this version instead:
default persistent.gui_is_inverted = 0.0 transform invert_gui: matrixcolor InvertMatrix(persistent.gui_is_inverted)*HueMatrix(180*persistent.gui_is_inverted) define config.layer_transforms = {"screens":[invert_gui]}

If the inverted version isn't very readable, tweak the colours in gui.rpy, making sure they still look good uninverted.
Adding a toggle to the Preferences Menu
Search for "screen preferences" in screens.rpy to find the preferences screen. Wherever makes sense to you, add something like this:
vbox: xsize 400 spacing 5 label _("UI Colours") style_prefix "check" textbutton _("Standard Colours") action SetVariable("persistent.gui_is_inverted", 0.0) textbutton _("Inverted Colours") action SetVariable("persistent.gui_is_inverted", 1.0)

Uninverting specific images
Inverting some images looks pretty weird. To stop that, we need to invert the images twice, since that will cancel out.
Save and load screen preview images
In screens.rpy, search foradd FileScreenshot(slot) xalign 0.5and replace it with
add FileScreenshot(slot) xalign 0.5 at invert_gui
Main menu background
Here's my original main menu:
I need to work on the aesthetics and contrast but it will do as an example.
Here it is with the colours inverted and the hue corrected:
If you like how the main menu image looks when it's inverted, you can skip this step. Otherwise, in screens.rpy, search for
add gui.main_menu_backgroundand replace with
add gui.main_menu_background at invert_gui
You may have to increase the opacity of parts of gui/overlay/main_menu.png, depending on your specific user interface design.
Here's the new version:
If both options look bad you could create a unique main menu image which only displays when
persistent.gui_is_inverted>0