Cross-platform game and app development for new programmers

Easy Does It

© Lead Image © Valeriy Kachaev, 123RF.com

© Lead Image © Valeriy Kachaev, 123RF.com

Author(s):

Ren'Py helps you create Android, Linux, macOS, Windows, and HTML5 games and apps.

Although you can find some excellent cross-platform development tools, many of these tools come with a steep learning curve for new programmers. Ren'Py [1] is a visual novel engine that has been around for more than 10 years, and it is one of the easiest packages to learn for game and app development.

The nice thing about Ren'Py is that you don't need any previous programming experience. Ren'Py uses a simple "screen language" that allows you to add backgrounds, images, character dialogs, and menus. For more complex requirements, Ren'Py supports inline Python and Python blocks.

The Ren'Py software development kit (SDK) is supported on Linux, macOS, and Windows, with final applications that can be built to run on Android, iOS, Linux, macOS, and Windows and in browsers with HTML5 (Figure 1).

Figure 1: Ren'Py development and build options.

In this article, I introduce Ren'Py with three examples. The first example will be the start of a visual novel. The second example will be a tourist guide with graphic menus, and the final example uses Python to create a dashboard screen that shows dynamic values and bars.

Getting Started

If you want to play with Ren'Py on a Raspberry Pi or an Ubuntu/Debian system, you can load a lightweight installation with:

sudo apt-get install renpy

The apt-get version of Ren'Py, however, does not have any tutorials or extra build features, so it is recommended that you go to the Ren'Py site for the complete installation directions [2].

The Ren'Py user interface creates new projects with all of the required files and supports all of the different build options (Figure 2). The script.rpy text file contains all the logic for an application.

Figure 2: Ren'Py interface.

Visual Novel

A visual novel is sort of like a comic book that can have multiple paths and story lines that users select as they work their way through the novel. The first step is to define some characters and background images. Creating character drawings from scratch can be a lot of work; luckily, you can find some open source solutions that can help out.

Character Creator [3] is an excellent free website you can use to generate male or female head, torso, and full-body images. It also supports a variety of facial expressions (Figure 3). The character image files and all background images are stored in the project's game/images directory.

Figure 3: Character Creator generates character emotions.

The next step is to use a standard text editor and add screen language code to the script.rpy file. Figure 4 and Listing 1 show the code required to display a background with a character and some dialog. Lines 3 and 4 define two characters cop and me. These definitions are used to output or show dialog text. Ren'Py uses labels to jump between code segments. The application begins at the start label (line 10).

Listing 1

Visual Novel

01 # darkstreet - script.rpy
02
03 define cop = Character("Cop")
04 define me = Character("Me")
05
06 image darkstreet = im.Scale("darkstreet.jpg",config.screen_width,config.screen_height)
07
08 # The game starts here.
09
10 label start:
11
12     # Show a background.
13     show darkstreet
14
15     show cop_head at truecenter
16
17     # These display lines of dialogue.
18
19     cop "Hey Kid! Stop right there!\n
20       Why do you have blood on your hands?"
21
22     hide cop_head
23     show me_crying_head at truecenter
24
25     me "It wasn't me...I don't know what happened."
26
27
28     return
Figure 4: Start of a visual novel.

Images in the game/images directory can be displayed simply with:

show image_name at position

In this example, cop_head.png is displayed at the center of the screen (line 15) by:

show cop_head at truecenter

Images can also be resized, rotated, moved, or adjusted. In line 6, the background (darkstreet.jpg) is sized to fill the screen. Dialog is shown by referencing the character and then the dialog text (lines 19-20).

Figure 5 shows the next phase of the story. The policeman is hidden with the hide statement (line 22) and an image of a crying girl (me_crying_head) is shown with some dialog (line 25). The use of hide and show statements allow you to present different characters and backgrounds.

Figure 5: Second character in the visual novel.

At the end of the story, the application finishes with a return statement (line 28).

Tourist Guide

Most apps and games require menus that allow multiple branches or outcomes. A Ren'Py menu is created simply with a menu: statement. Each menu item is defined with button text and a jump statement, which is like an old-school Basic GOTO statement. Each jump has a label to which the code links.

Figure 6 shows the start of a tourist guide for the Bruce Peninsula [4]. A menu is called at the start of the program. Each menu item jumps to a specific section of the code with a label. Within a subsection, (e.g., the beach), a new background and text are shown. After the user sees this information, a jump start statement puts the user back to the main menu.

Figure 6: Tourist guide with menus.

For smaller applications (Figure 7), you can put the submenus, display logic, and Python code directly in the menu: logic.

Figure 7: Submenus and logic within menu options.

Dynamic Screens

Ren'Py supports custom screen layouts that can have labels, text, buttons, and bar charts. In a visual novel, a custom screen could be a small box at the top of the application that shows items like inventory, money, or percent complete.

For the next example, I use Python code with Ren'Py to find some PC hardware readings and present the information on a large custom screen.

The Linux sensors [5] command can be used to show current hardware information:

$ sensors
dell_smm-virtual-0
Adapter: Virtual device
Processor Fan: 2721 RPM
CPU:            +46.0 C
Ambient:        +39.0 C
...

By adding some Bash/Awk code, the CPU and ambient temperature values can be extracted:

# use show Bash/Awk code to get temps
$ sensors | grep CPU | awk '{ printf "%d\n" , $2}'
46
$ sensors | grep Ambient | awk '{ printf "%d\n" , $2}'
39

Python calls Bash scripts with the subprocess.check_output method, which is part of the subprocess library (Listing 2).

Listing 2

subprocess.check_output

$ python
Python 2.7.15+ (default, Oct  7 2019, 17:39:04)
[GCC 7.4.0] on linux2
>>> import subprocess
>>> subprocess.check_output("sensors | grep CPU | awk '{ printf \"%d\" , $2}'", shell=True)
'46'
>>>
>>> subprocess.check_output("sensors | grep Ambient | awk '{ printf \"%d\" , $2}'", shell=True)
'39'

Listing 3 shows the code required for the CPU statistics application (Figure 8). The screen cpu_data(): statement creates a user interface (line 3) that can contain both Python blocks and display elements.

Listing 3

Dynamic CPU Stats Screen

01 # script.rpy - create a Ren'Py screen that shows CPU sensor information
02
03 screen cpu_data():
04
05     python:  # Use Python to get sensor variables
06         now = datetime.now()
07         nowtime = now.strftime("%H:%M:%S")
08         ctemp = subprocess.check_output("sensors | grep CPU | awk '{ printf \"%d\" , $2}'", shell=True)
09         atemp = subprocess.check_output("sensors | grep Ambient | awk '{ printf \"%d\" , $2}'", shell=True)
10
11     frame:   # create a frame with text, values and a bar
12         has vbox
13         label "CPU Stats" text_size 120
14
15         vbox:
16             text "Time : [nowtime]" size 80
17             text "Ambient temp: [atemp] C \n" size 80
18             text "   CPU temp : [ctemp] C " size 60
19         hbox:
20             vbox:
21                 text "0 " size 40
22             vbox:
23                 bar value atemp range 60 xalign 50 yalign 50 xmaximum 600 ymaximum 50 left_bar "#FF0000"
24             vbox:
25                 text " 60 " size 40
26
27 init python:
28     # Define Libaries and any system variables
29     import subprocess
30     from datetime import datetime
31
32 label start:
33
34     # Start with Weather screen
35     show screen cpu_data()
36
37     define cycle = "True"
38     # Cycle every 2 seconds
39     while cycle == "True" :
40         $ renpy.pause(2)
41
42     return
Figure 8: CPU stats screen.

The Python block (lines 5-9), start with a python: statement, and the succeeding lines are indented per the Python standard. CPU and ambient temperature variables (lines 8-9) are created with the subprocess.check_output() call and the earlier Bash sensors statements.

For this screen, a frame: (line 11) is used to group the elements together. Vertical boxes (vbox:) and horizontal boxes (hbox:) are used for further groupings. Python variables are inserted into text output strings with square brackets (lines 16-18). A horizontal bar (line 23) shows the ambient temperature (atemp) with a range of 0-60.

The application begins at label start: (line 32) by showing the cpu_data screen (line 35). An inline Python statement (line 40) pauses the execution for two seconds within a while loop. The screen logic is refreshed after each renpy.pause() iteration.

Building Applications

The Ren'Py IDE has a Launch Project button that allows testing in the native operating system environment. The IDE's Build option allows you to create a variety of different packages (Figure 9).

Figure 9: Ren'Py build options.

The HTML5 build is still in beta; it appears to work well for standard visual novel apps, but I found that it had issues with some Python library calls. The HTML5 build creates a separate directory structure for the Ren'Py application that needs to be mapped into your web server configuration.

If you are looking to do some simple testing, a Python standalone web server (Figure 10) can be run from the project's web directory:

# Run a python standalone server on port 8042
python3 -m http.server 8042
Figure 10: Ren'Py web application.

Final Thoughts

If you're looking to create some simple cross-platform visual presentation apps, Ren'Py is a good fit, it is super easy to learn, and doesn't require strong programming skills. I found the first-time call-up for Android was longer than expected, but I was impressed with the final result.

Ren'Py supports simple screens that can have dynamic bars and text; however, if you're looking to incorporate gauges or line charts. Ren'Py probably isn't the best fit.

Infos

  1. Ren'Py: https://www.renpy.org
  2. Download Ren'Py: https://www.renpy.org/latest.html
  3. Character Creator: https://charactercreator.org
  4. Bruce Peninsula, Ontario: https://visitbrucepeninsula.ca
  5. lm_sensors (sensors) documentation: https://wiki.archlinux.org/title/lm_sensors

The Author

You can investigate more neat projects by Pete Metcalfe and his daughters at https://funprojects.blog.