Overview
This module is intended to give the student a formal introduction to Go: a mainstream high-level programming language with broad application. The goal of the module is to develop a rudimentary 2-dimensional computer game. To reach this outcome, the student will have to master concepts like:
- Setting up a build pipeline to compile a program
- Creating a valid, compilable program
- Input and output, variables, constants, functions
- Loop-based iteration and recursion
- Arithmetic, boolean logic and if/else control flow
- Arrays, structs and maps
- Working with a 2D game engine
Setting things up
We start by installing all the prerequisite software, and testing the build pipeline with a simple program.
Ensure that the following are installed:
- Now create a file called
welcome.goin a new directory (e.g.it10a\welcome.go) and type in the following:
package main
import "fmt"
func main() {
fmt.Println()
fmt.Println("Welcome to Great Old Escape")
fmt.Println("Copyright (c) 2025 by Andus van Rooyen")
fmt.Println()
}(You’re welcome to make the welcome message say anything you want. Note that fmt.Println() without anything between the brackets leaves an ampty line.)
Press Ctrl-S to save the file. Now go to the “Terminal” tab in the bottom VSCode window. Note that you can drag the window to resize it. Type ls and it should show you the contents of the directory. If you don’t see welcome.go listed when typing ls, you’re probably not in the directory where you saved the project. If you hover over the welcome.go tab in VSCode, it will pop up the path where it is saved. Use cd in the terminal to go to the project directory. Remember that you can type cd .. to go up to the parent directory.
Type go run welcome.go to run your program, and check that you see the welcome message in the terminal.
Running your program
Type the following command in the terminal to run it:
It should display the welcome text. Try changing the text in the program, save it again (Ctrl-S) and run the program again. You should see the change in the output.
You can also build a program to create an executable file: this is a compiled program that only the computer can understand, but that is used to run the program. Now is the time to introduce some new terms:
- Source Code is the program you wrote in Go just now. It uses some words that look like English, but has a grammar of its own. It can be written and read by humans, but a computer has to compile it before it can run. Source code usually consists of text files that are easily edited and viewed by humans.
- Executable Files are files that can be run by the computer, e.g. a calculator app or a game. They are compiled from source code and are in a format that can be easily interpreted by a computer, but is very difficult to read by humans. We call these binary files.
Build an executable file for your program by typing to following command:
If you now type ls in the terminal, you should see a new file: welcome.exe. This is an executable file. On Windows, the .exe filename extension indicates that it is executable.
You can run it by typing .\welcome.exe, which should show the same output as before.
An executable file like welcome.exe is easy to distribute to other people, who do not need Go installed on their computers.
Understanding the program
In this course, we’ll often make use of Claude, an AI chatbot that is particularly good at helping with programming.
Go to https://claude.ai/ and use your Google account or email to sign up. Then go to your program (welcome.go) in VSCode, and type Ctrl-A and then Ctrl-C to copy all of it. Then go to the Claude chat and type the following (use Shift-Enter to create new lines without submitting the question yet):
Please explain the following Go code to me:
```Note that last line: It should be three backticks in a row: That’s the character most likely somewhere on the top left of your keyboard, that looks a bit like `the opening quote in this part of the sentence’.
Once you press Shift-Enter after the three backticks – this indicates a source code block – Claude should open up a field where you can paste your source code. Press Ctrl-V to do so. Then press Enter to send the message to Claude.
Claude should now give you a line-by-line explanation of the program. Please feel free to use Claude to help you understand any of the course material, but don’t ask it to write code for you. Even though it will comply, AI devs often make mistakes, and the purpose of this module is for YOU to build your programming muscles. There is no coding without understanding!
Carefully review Claude’s explanation of the program, and ask him any questions on anything that is unclear. Your course instructor will also be able to help during tutorial sessions.
Let’s chat
Next, we want to modify the program so that it asks the user for a character name, and then greet the user using that name:
Welcome to the Great Old Escape
Copyright (c) 2025 by Andus van Rooyen
What is your character's name? Erandir
Welcome to the game, Erandir!To do this, you will use the following library functions:
fmt.Print("What is your character's name? ")will print text on the screen, but not go to the next line. That’s different fromfmt.Println()which always moves to the next line on the screen.fmt.Scanln(&name)will read input from the user typing at the keyboard, until they press Enter. The text is then stored in thenamevariable.
Variables
We need to be able to store the character’s name somewhere, so that we can display it again later. Values that aren’t known at compile time (i.e. when we write the program source code and compile it with go run or go build) can be stored in variables. You may remember variables from when you studied the graphical programming language Scratch.
Now is a good time do some reading about fundamental concepts. Study the following sections from Go By Example:
- Modify your program by declaring a string variable called
name, and passing it to thefmt.Scanln()Althoughfmt.Scanln()is quick and simple to use here, it’s not a great way to read user input in general. For one thing, it stops reading at any whitespace, whether it’s a space or a newline (Enter). So if you type “Severus Snape” as name, it will just save “Severus” – which may lead to a rather irate professor when you later greet him on a first-name basis. We will look at more advanced input/output (I/O) techniques later in the module.
function to store what the user typed: The&namesyntax may seem weird at first. We’ll go into it in more detail at a later stage (so don’t worry too much about it now), but when you pass a variable likenameto a function, you can give it the value ofname, e.g.foo(name), or you can tell it where thenamevariable lives in the computer’s memory – this is called the address of name.fmt.Scanln(&name)can be read as, “Hey,Scanln, here’s an address where a variable namednamestores a string. Please read some input from the user and store it atname’s address”. So you can think of “&name” to read “the address ofname”. We say that we can pass a variable to a function by name, e.g.foo(name)or by reference, e.g.foo(&name).
fmt.Scanln(&name)Operations
As you saw in the Values section in Go By Example, Go can perform various operations on values using operators like +, -, *, and %. The operators behave differently depending on the types of the values that they operate on (its operands). For example, 3 + 5 will produce a value of 8, whereas "foo" + "bar" would produce the string "foobar" – this is called string concatenation.
- Modify your program so that it asks for the character’s name, and then prints
Welcome to the game, <name>!, where<name>is the string that the user entered.
Stats and modifiers
Next, let’s modify the program so that it creates a random Strength ability score for the character, and print it out with the modifier for that score, e.g.
Welcome to the Great Old Escape
Copyright (c) 2025 by Andus van Rooyen
What is your character's name? Erandir
Welcome to the game, Erandir!
Your strength is 14 (+2)To achieve this, you’ll need to:
- Declare two variables of type
int(integers, or whole numbers) namedstrengthandstrength_mod. Note that typeintcan be negative as well. - Assign a random value from 3 to 18 to
strength. - Calculate the strength modifier and assign it to
strength_mod. - Print out a formatted string composed of a mix of strings and numbers.
Random numbers and string formatting
Study the following before attempting your solution:
- Random Numbers
- String Formatting. You will probably find the following printing “verbs” useful:
%dinserts the correspondingintinto that part of the string.%+dalways prefixes the number with a “+” or a “–”, depending on its sign.
The special sequence \n in a string starts a new line.
If/Else
To calculate the modifier for an attribute that is 10 or higher, you can simply use integer division: For example, for a strength of 11, (11 - 10) / 2 would evaluate to 0, which is the corrrect modifier. Verify that (12 - 10) / 2 evaluates to a modifier of +1.
Negative modifiers are a bit trickier! Suppose a character has a strength of 9; the rules require that the strength modifier is then -1. However, (9 - 10) / 2 evaluates to 0! This is because integer division always rounds towards zero. It “rounds down” for positive values, but it “rounds up” for negative values.
One way to work around this is to check whether the attribute (e.g. strength) is 10 or higher, or not, and then use a slightly different calculation for the two cases. For this you need an if statement with an else branch.
Read the following section from Go By Example:
Instructions
- Modify your program to calculate a random strength value, and to print the strength attribute and its modifier as shown in the example above.
If you run your program multiple times, it should produce different random strength values.
Functions
Your program now calculates the modifier for the strength attribute, but you would need to perform the same calculation for any other attribute: dexterity, constitution, intelligence, or whatever attributes you decide to use in your game. It would be cumbersome to type the same calculation over and over again. Also, if you discover a mistake in the calculation, or decide to calculate it in a different way, you will need to fix it everywhere.
A function is a way to define a certain operation once, so that you can use it repeatedly in many places. Read the following section from Go By Example:
- Create a
Modifier()function that will return the correct modifier for any attribute value passed to it. Then use theModifier()function in yourmain()function to calculate the strength attribute’s modifier and display it.
The function will need the following parameter and return type (we call this the function’s signature):
This means that your function will take one parameter, the value of an integer attribute like strength or intelligence. It will then return an integer, i.e. the value of the modifier.