Welcome to Code for Initiative!

You turn on your computer and open your browser. You’ve used online tools to help plan and run sessions for your favorite table-top RPG, but your world requires something….more. You know what you need, but you’re not sure how to find it. It dawns on you….

You can build it yourself! If only you knew how to get started. You followed a link and you’ve discovered a website that says it can help you learn programming to help you run sessions. What do you do?

Code for Initiative! 

Introduction

Consider this your “Session 0.” We need to go over some basics before we get started.

Programming can help you create custom tools that are suited to exactly what you need for YOUR game.  Do you need to roll initiative for a horde of goblins? Need to quickly generate some NPCs? Want to build random encounters on the fly? Programming can help speed up these processes!

Additionally, once you know how to program you can use those skills for other professional and personal projects….it’s win-win! In these tutorials you will learn the basics of Python and how you can utilize it to automate some aspects of your game nights and prep work.

Python

All of our lessons (for now) will be done in Python. There aren’t many pre-requisites for learning Python and there are plenty of great resources to help you learn if you find yourself getting lost. My hope is that introductory projects relevant to TTRPGs will give you  a solid base of knowledge and inspiration to keep you learning after you finish the tutorials!

Why Python?

For practical reasons…..it’s what I currently know best! In general, it’s because Python is relatively easy to learn and has tons of great resources to help you along the way.

Python 2.7

Python 3 is the future for Python, but Python 2 is still widely supported with a lot of great resources. Transitioning from Python 2 to 3 isn’t too much work, so we’ll start with 2.7 and you can take the next step and move to Python 3 if you stick with it!

Installing Python

If you’re using a Windows machine, you can download Python 2.7 at this link.

If you’re using an Apple computer it will have Python 2.7 pre-installed.

Set Up

Using the Command Line Interface

The command line interface on your computer will be the way you navigate through directories and run your scripts. The command line program on a Mac is known as “Terminal” and in Windows, it is the command prompt. They have different commands. This page contains some common commands while this page contains a list of the Windows equivalent commands. Spend some time learning how to do things like listing files in a directory, change your current directory.

Note: I will be referencing the commands used on Macs, so Windows users will have to invest some extra time in learning how the Windows command prompt works.

Text Editors

To write scripts, you will need a text editor. The default “Text Edit” or “Notepad” program on your computer would work, but it’s often better to use a code editor specifically tailored to programming tasks. Most text editors that are tailored to programming have helpful features such as syntax highlighting and debugging tools built in.

Some recommended editors include:

I’d also like to put in a mention for the Solarized Dark theme in whatever editor you choose.

Saving and Running a Script

Creating and Saving a Python File

Open your text editor of choice (I’ll be using Visual Studio Code) and create a new file. From here, simply “Save As…” and type a file name followed by “.py” Python scripts end with the .py extension, so make sure you’re saving all of your Python files with .py! I’m naming this first script “initiative.py” and saving it to my Desktop.

Saving as initiative.py

Writing in Python

An empty file won’t do us much good, so let’s write something simple to get started! It’s tradition when learning a programming language to have your program return a “Hello World” message, but let’s make it a little more interesting. To get some text on to your screen using Python, you will need to use a “print” statement followed by the text to display. That might look something like this:

print "Let's code for initiative!"

It’s important to notice that the text we wish to output is encased in quotation marks. This indicates that we’re working with a “String.” We’ll get into that more later. Let’s try to run this file!

Running Python Scripts

Remember that we saved the “initiative.py” to our desktop. On a Mac, open Terminal and type the following and hit “return”:

cd desktop

This command will Change the Directory to your desktop, where we saved our Python file. You can type “pwd” in Terminal to Print the Working Directory to the terminal window. It should say “Desktop.” If you type “ls”, you will see a listing of all of the files and folders in your current directory.

When you have confirmed you are in the correct directory, type the following to run your script:

python initiative.py

Note: For Windows Users, open the Command Prompt and follow the steps at python.org to run the script.

The output should look something like this:

The terminal window outputs "Let's code for initiative!"

 

Rolling the Dice

You’re ready to roll (pun intended), so let’s learn some Python basics! Code for Initiative!

We’ll be learning about data types, functions, formatting strings, importing functions, and more. By the end of this tutorial, you should be able to roll a digital d20 and adding a modifier for a character.

“Types” in Python

Data in Python can fall into a number of different categories. “Type” refers to how that data can be classified. Some of these types include:

  • Strings
  • Numbers
  • Lists
  • Dictionaries
  • Booleans

We will worry about lists, dictionaries, and booleans later, but to roll for initiative we will need to utilize the Number and String data types.

Numbers are exactly what they sound like, but within the number category, we will mostly make use of the integer type, or “int.” Integers can be positive or negative. They will also always be whole numbers.

The text after the “print” statement in “initiative.py” in quotations is what’s known as a String in Python. Strings are simply a sequence of characters.  Strings can be enclosed in either single quotes or double quotes, but it’s more common to use double quotations for strings in Python.

Using a string in a “print” statement is helpful, but it can also be useful to store strings and other data to solve more complex problems.

Variables

Variables allow us to store information and provide a label to that information. In Python, declaring a variable requires putting a variable name followed by an “=” and the data you wish to store. For example, if we wanted to store the string “We’re rolling for initiative!” we could do the following:

initiative = "We're rolling for initiative!"

We now have a string saved in the variable called “initiative.” The variable name can be just about anything you want it to be, but generally, your variables should be simple and descriptive. Variables can store just about anything you could want, so in addition to storing a string, let’s make a variable to store an integer.

Let’s fudge the dice for now and say that we rolled a natural 20 and save it to a variable called “roll”.

initiative = "We're rolling for initiative!"

roll = 20

print initiative
print roll

When we use variables, we can simply use the variable name rather than re-typing the data every time we wanted to access it. When you run the code, your output should look something like this:

The output says "rolling for initiative" and "20

Rolling for Initiative

Rolling natural 20’s every time would be great, but we want to simulate actual dice rolls. We can quickly achieve this by utilizing the Python Standard Library. The Standard Library contains modules  which provide well-tested resources to accomplish some of the most common tasks programmers encounter.  Let’s learn how to import the “random” module to generate random numbers.

Importing

Before we import, we should read a little bit of the documentation of the “random” module. It’s a good idea to read documentation when using code that you didn’t write yourself. It will help you get used to Python as well as giving you a more complete understanding of what you’re using. After looking in the random documentation, it seems that a method called random.randint(a, b) can help us by returning a random integer, where “a” is the lowest number possible and “b” is the highest number possible.

To use random.randint we first need to import the random module at the top of the file.

import random

Rolling the d20

Let’s overwrite our previous fudged roll by inputting the range found on a d20 into random.randint in the “roll” variable.

roll = random.randint(1,20)

This code will not work without importing the random module first. Always be sure to import your modules at the top of your file. Now, our code looks like this:

import random

initiative = "We're rolling for initiative!"

roll = random.randint(1,20)

print initiative
print roll

If we run the script a few times, we will see different rolls!

The window shows the output of our latest update

Adding a Modifier

Python Operators

Operators are the way that you can adjust or assign values in Python. You have already been exposed to one operator. When we created the “initiative” and “roll” variables, we used the equal sign to assign the values. As such, the equal sign is known as an assignment operator. Python has a number of different types of operators, including arithmetic operators….all of that just to say: Python can do some math for you!

Much of the math in TTRPGs will be addition and subtraction. The operators are exactly what you’re expect, “+” and “-“.  You can also use “*” for multiplication and “/” for division, but let’s start with adding a modifier to initiative.

Let’s assume our character has a +3 initiative modifier. First, let’s assign that value to a variable named “modifier” and then add that to the d20 roll.

import random

initiative = "We're rolling for initiative!"

roll = random.randint(1,20)

modifier = 3

print initiative
print roll + modifier

If you run the code, the results won’t look much different than the previous version. Let’s make some changes to show the value of the roll, the modifier, and the total roll.

String Substitutions and Formatting

If we wanted to print an integer and a string, we would have to perform those operations separately unless we converted the integer to a string. We can accomplish this in a few ways.

We could try converting the integers to strings using the str() function. This is how that might look for the d20 roll:

roll = str(random.randint(1,20))

However, if we wanted to print a statement, it would usually be easier to use the .format() method on a string to insert variables and values into strings. So, assuming a roll of 18 with the same modifier of 3, if we wanted to have a statement that said, “You rolled 18 with a modifier of 3 for an initiative roll of 21.” we could write the following:

import random

initiative = "We're rolling for initiative!"

roll = random.randint(1,20)

modifier = 3

total = roll + modifier 

print initiative
print "You rolled {} with a modifier of {} for an initiative roll of {}.".format(roll, modifier, total)

Note that we added a new variable, “total,” to add the roll and modifier variables. From there, we created a print statement followed by our string. The string we wrote contains curly braces in the three places where we want to substitute data. After the string, we added .format() with the variables we wanted to insert in the statement in the order in which they appeared. If you run this script, you should see something like this:

Rolling for Multiple Characters

Defining Functions

If you have certain tasks that need to be repeated, you can set those tasks up in a function so that they can be duplicated with new input and will behave in a consistent way.

First, we define functions using the “def” keyword. The information to be passed into the function are known as “parameters” when they are in the function definition and “arguments” when the function is called with actual values.  To return a value you will need to add a “return” statement followed by the information you would like the function to output. A function for an initiative roll might look something like this:

def initiative_roll(character, modifier):

    roll = random.randint(1,20)

    total = roll + modifier 

    return "{} rolled {} with a modifier of {} for an initiative roll of {}.".format(character, roll, modifier, total)

The parameters of the function allow for a character’s name to be inserted as well as the initiative modifier. Within the function, we have reusable code for rolling the d20, adding that roll to the modifier, then creating a string saying what the character rolled, their modifier, and the total. Now, let’s see the function in action!

Calling Functions

The “initiative_roll” function can be used to print the statement or store it in a variable. Let’s look at how that looks. First, to print an initiative roll for a character named “Arthur” with a modifier of 2, we would write the following:

print initiative_roll("Arthur", 2)

As an alternative, we could assign the result of the function call to a variable and then print that variable:

arthur_roll = initiative_roll("Arthur", 2)

print arthur_roll

Either way, the result should look something like this when you run the script:

So, if we wanted to roll initiative for multiple characters, we could print the call to the function for each of the characters. Here is the current state of the script:

import random

def initiative_roll(character, modifier):

    roll = random.randint(1,20)

    total = roll + modifier 

    return "{} rolled {} with a modifier of {} for an initiative roll of {}.".format(character, roll, modifier, total)

print initiative_roll("Arthur", 2)
print initiative_roll("Liana", -1)
print initiative_roll("Sybil", 0)

If we run the script, the output will look something like this:

Creating NPCs

Do you need to populate a fantasy town in a hurry? Let’s create some NPCs!

We’ll be learning about lists, loops, and conditionals to generate NPCs. By the end of this tutorial, you should be able to create NPCs from custom lists of traits.

Creating a List

When learning to roll for initiative, we stored individual numbers or strings in variables. We can also save data in something called a “List” in Python. We can store strings, numbers, or even lists within lists! However, we’ll keep it simple to start.

We create the list by giving it a name, using the assignment operator (“=”), and putting data in-between square brackets.  Let’s start by creating an empty list called “hair_color”.

hair_color = []

An empty list may not seem useful now, but you can add items to lists. This is extremely useful as you begin creating more complex programs. To add hair colors to the list, we can do this in two ways:

  • Manually type in the values separated by commas
  • Use the .append() method to add the value to the end of the list
hair_color = ["blonde", "black", "red"]

hair_color.append("brown")

If we print hair_color to the console, we will see the following:

[‘blonde’, ‘black’, ‘red’, ‘brown’]

The .append() method allows us to update the list at any time.

A List of Lists

Hair color won’t be enough to make a detailed character. Let’s make a list of occupations and personality traits:

hair_color = ["blonde", "black", "brown", "gray", "red"]

occupation = ["teacher", "blacksmith", "alchemist", "shopkeeper", "guard", "rat catcher"]

personality_traits = ["abrasive", "cautious", "detached", "easygoing", "jolly", "inattentive", "suspicious"]

From here, we can create a list of all of these lists called, “master_list” by doing the following:

master_list = [hair_color, occupation, personality_traits]

Next, we’ll learn how to iterate through our lists to generate some random NPCs!