Hannah Clare Wray Hazi

I love making beautiful things.

Sep 16, 2019

Telling Stories With Python And Ren'Py

This is a write-up of a workshop I've given at CamPUG and PyCon UK 2019. It was a lot of fun to deliver, and my participants came away with their own mini-games written in Ren'Py. I was impressed by the range of creative stories, everything from getting lost in Cardiff, storming Area 51, coaxing a grumpy cat, visiting a music festival, going to space, defeating animated fleas, visiting every pub in Cambridge, a child's guide to the Divine Right of Kings, interactive graffiti and more!

I hope this post will be useful as a reference for workshop participants and those who couldn't make it along.

What is Interactive Fiction?

You might be familiar with the concept of interactive fiction from "Choose Your Own Adventure" books.

Ever since computers came on the scene there has been interactive fiction here, too. Zork, one of the earliest examples, is a dungeon-crawling game where the player explores The Great Underground Empire by typing text commands.

Using later tools like Parchment and Twine people are still creating these text-based interactive fiction games. A text-based game I've enjoyed recently is Moonlit Tower by sci-fi author Yoon Ha Lee.

Visual Novels are a genre of interactive fiction that combines pictures and text as a storytelling tool. They originated in Japan and many famous examples such as Fate/Stay Night and Symphonic Rain are Japanese. These games are often romance or relationship-themed, each path perhaps leading to a relationship with a different character.

Ren'Py

Ren'Py Icon

Ren'Py is a visual novel creation engine written in Python. It has its own syntax and style, but also allows you to embed pure Python for more complex gameplay mechanics.

It is cross-platform and works on Mac, Linux and Windows. All that you need alongside it is a simple text editor that can convert tabs to spaces, such as gedit.

What can you do in Ren'Py?

Label Jump For Branching Stories

Road Not Taken Screenshot

I would humbly suggest my own game The Road Not Taken as a useful introduction to the label / jump mechanic. Take a look in the script.rpy file to follow how the game works. It demonstrates how menus work in the game and how you can use them to move to different choices, similar to a GOTO statement. It also includes an example of embedding music within gameplay to add a mood to a scene. Feel free to copy and modify it as a basis for your own games.

Custom GUI

Hotel Shower Knob Screenshot

Hotel Shower Knob, a game where you have to puzzle out an unfamiliar hotel bathroom to take a shower, is a good example of a custom GUI. Inside options.rpy the creator replaced the usual cursor with a custom image of a hand:

## The mouse clicker thingy.

define config.mouse = { 'default' : [ ('cursor.png', 66, 95)] }

This makes for a unique visual experience. As the hand is Creative-Commons licenced, you could use it in your own games, too!

Embedded Python

Two Worlds Screenshot

Because Ren'Py is written in Python (2.7, if you're interested) it's easy to embed Python statements within it to acheive more complex effects such as creating mini-games. There are two ways to do this - prefixing single lines with $ or using an indented block with the python: statement. I used python: statements within Ren'Py to create Card objects for my game Two Worlds.

The key thing to notice is the definition of the Card class:

# Define the card objects used to play the games with
init:
    python:

        flowers = ["card-front-land-flower%d.png" % i for i in range(1, 3)]

        class Card(object):
            def __init__(self):
                self.face_up = False
                self.selected = False
                self.number = 0
                self.coords = [0, 0]
                self.back = "card-back-land.png"
                self.front = flowers[0]
                self.paired = False

            @property
            def coord_text(self):
                return "{}, {}".format(self.coords[0], self.coords[1])

This happens during the init: block, before the game starts, so it is available from the beginning. I subsequently used this in the sea_game.rpy and land_game.rpy files using the ui.interact() statement and action If to connect it with Ren'Py responses to on-screen clicks.

Persistent Data

Another useful trick is the ability to store persistent data between plays of the game.

Example From Long Live The Queen An example from Long Live The Queen

This allows more satisfying gameplay such as unlocking new routes after a complete playthrough, and keeping track of player stats like Strength or Skill. Anything that can be pickled is suitable for this treatment. A simple example:

if persistent.secret_unlocked:
        scene secret_room
        e "I see you've played before!"

To unlock this path the user must hit a piece of code that sets $persistent.secret_unlocked = True

persistent is a special keyword in Ren'Py, so you shouldn't use it for anything else. Unlike other variables, if you haven't yet initialised it when you reach the if statement Ren'Py won't complain.

Useful sources of free images and sounds for your games

There are various community projects to collect images and sound to use in games with Creative Commons or similar licences.

I've found px here a useful collection of images, particularly photos.

I used Fraqtive to create the card images and backgrounds for Two Worlds.

Useful sound sources include Free Music Archive and for sound effects, Free Sound

Example games written in Ren'Py

Benthic Love – Michaela Joffe, Sonya Hallett

Hotel Shower Knob – Yoss III

Death And Burial Of Poor Cock Robin – Lernakow

Long Live The Queen – Hanako Games

And check out the NaNoRenO game jam each year during the month of March – or better still, take part!

Apr 12, 2019

Agile Workshop

I recently attended a Certified Scrum Master course taught by Tobias Mayer of Adventures With Agile. I really enjoyed the course and the style in which it was taught. There was no death by Powerpoint! Tobias actually constructed a board on the wall with columns to keep track of the tasks comprising the course, and we added extra task cards for further discussion and questions as we went along.

The board Here's what the board looked like near the start of the two day course.

We held 'Sprints' of an hour or so at a time, diving into aspects of Agile and then reviewing how it went, to improve our group process. Sometimes the teacher would stand and talk about a concept for a while, but mostly the course was interactive, especially during the second day where we broke out into groups for longer sessions.

The exercises we did included 'Point and Go': a game where players stand in a circle and have to

  • Point to someone else whose place you want to take
  • Wait for them to say "Go"
  • Start moving forwards to them
  • Before you reach them, they have to find another place to go (and the cycle continues!) This was unexpectedly hard! It was a metaphor for how difficult it can be to break out of an established pattern of behaviour at work. Even once we got into a rhythm, if things sped up or someone panicked, our orderly pattern fell apart.

Another exercise I enjoyed was coming up with different metaphors for Scrum. We broke out into groups and thought up some different ideas - I was impressed by the variety and how each of them fitted different parts of what Scrum can look like. Some of my favourites were:

  • a garden growing and changing over time
  • a cocktail bar developing new drinks
  • a stand-up comedian working on their routine
  • a graffiti crew making a work of art for their neighbourhood
  • Jurassic Park (this was mine!)

A Product Owner is like a Duchess A mindmap from my notes about the different Scrum roles

Following the training, I'm a Certified Scrum Master. There have been some intelligent criticisms of this certification process, including by some of its founders. The fact that there is a certification exam seems to somewhat devalue the training experience itself. I didn't really need to complete the training to do the certification exam - its questions are purely based on the Scrum Guide and a few on the Agile Manifesto. How well can a multiple-choice test about a short document really hope to measure someone's competence in such a fuzzy relationship-centred domain as taking on the role of a Scrum Master? It's always going to fall short, I think. I've acted as a Scrum Master for several years already without the certification, so I was interested to see what it covered and didn't touch on.

I passed the exam. But the things that will really stay with me are the advice of the trainer and the discussions I had during the course, especially with others whose companies are also on the path to adopting more Agile practices. I certainly recommend Tobias as a teacher: his creative exercises and the way he presented the course helped grow my understanding and confidence in the role of Scrum Master. I'd like to attend his Scrum Master Clinic - I think it will really help to have that ongoing mentoring and peer advice.