Part II · Growing the Project
Chapter 6: Organizing Your Code
Your program is five chapters long now, and it's all still one long list
of statements running top to bottom. That's worked fine so far, but
imagine adding a second room, then a third. Printing an inventory list is
already something you'd want to do more than once, and copying that same
for each block everywhere it's needed is exactly the kind of thing that
gets messy fast. Functions are how you give a piece of code a name and
reuse it wherever you need it.
Declaring a Function
A function is a named, reusable block of code.
function showHeader()
writeln("=== The Hollow Cottage ===")
end functionOnce it's declared, you call it by name, with parentheses, every time:
showHeader()Parentheses are required even when a function takes nothing, an empty
() is how QF Code knows you mean "call this" rather than just mentioning
its name.
Parameters and Arguments
Most useful functions take input. Parameters are the names a function expects, arguments are the actual values you hand it when you call it.
function greet(name)
writeln("Welcome, " + name + ".")
end function
greet("Alice")
greet(playerName)The number of arguments you pass must exactly match the number of parameters the function declares, no more, no fewer. Inside the function, a parameter behaves just like a regular local variable, you can read it, and you can reassign it, without affecting whatever was passed in from outside.
Returning a Value
Some functions don't just do something, they hand something back. That's
what return is for.
function double(value)
return value * 2
end function
var result = double(21)
writeln(result) // 42If a function reaches end function without ever hitting a return, it
hands back empty automatically, not an error, just nothing useful. If
you're expecting a value from a function and getting empty instead,
the first thing to check is whether every path through that function
actually returns something.
A Note on Scope
A function can read global variables, the ones declared at the top level of your program, but it cannot see local variables belonging to whoever called it. Each call gets its own private workspace.
var cottageName = "The Hollow Cottage"
function announce()
writeln("Welcome to " + cottageName + ".") // fine, cottageName is global
end functionOne honest limitation worth knowing now, not discovering the hard way later: QF Code 1.1 doesn't support closures. A function can't reach back into another function's local variables just because it happens to be defined nearby. If a function needs a value, the cleanest way to give it one is to pass it as a parameter.
Hoisting: Calling Before Declaring
QF Code registers every top-level function before your program actually starts running. That means you're free to call a function above the point where it's declared in the file:
greet("Alice")
function greet(name)
writeln("Welcome, " + name + ".")
end functionThat runs just fine. It's worth knowing this exists, but it's also fine to just declare functions before you use them, the way this book will, since that's usually easier to follow when you're reading your own code later.
Growing the Adventure
Time to pull the repeated inventory-printing logic out into its own function.
// The Hollow Cottage
// Chapter 6
const cottageName = "The Hollow Cottage"
function showInventory(items)
writeln("You are carrying:")
for each item in items
writeln("- " + item)
end for
end function
writeln("You are standing outside " + cottageName + ".")
var playerName = input("What is your name, traveler? ")
writeln("Welcome, " + playerName + ".")
var tries = 0
var solved = false
while tries < 3 and not solved
tries = tries + 1
var answer = input("There is a riddle carved into the door. It asks: what has keys but no locks? ")
if answer == "piano" then
writeln("The door swings open. You step inside.")
solved = true
else
writeln("Nothing happens.")
end if
end while
if not solved then
writeln("The door refuses to budge. You'll have to find another way in.")
else
writeln("The cottage is dusty but intact.")
var inventory = array()
append(inventory, "rusty key")
append(inventory, "half-burned candle")
writeln("On the floor, you notice:")
showInventory(inventory)
writeln("You pick up both items.")
end ifNothing about what the player sees has changed. What's changed is that
showInventory can now be called again, anywhere, anytime you want to
show the player what they're carrying, without retyping the loop.
Make It Yours. Write one more function of your own, something that
takes a parameter and does something with it, a function that describes a
room, announces a sound effect, or checks whether an item is in the
inventory. It doesn't need a return value yet if you don't want one.
Chapter Checkpoint
Open either known-good checkpoint directly in QF Code, or download the .qfc file to keep locally. The IDE opens in a new tab and does not run the program automatically.
Start this chapter
Chapter 6 starting checkpoint.
Continue from here
Chapter 6 completed checkpoint.
Starting code: the Chapter 5 checkpoint.
Completed code (Chapter 6):
// The Hollow Cottage
// Chapter 6
const cottageName = "The Hollow Cottage"
function showInventory(items)
writeln("You are carrying:")
for each item in items
writeln("- " + item)
end for
end function
writeln("You are standing outside " + cottageName + ".")
var playerName = input("What is your name, traveler? ")
writeln("Welcome, " + playerName + ".")
var tries = 0
var solved = false
while tries < 3 and not solved
tries = tries + 1
var answer = input("There is a riddle carved into the door. It asks: what has keys but no locks? ")
if answer == "piano" then
writeln("The door swings open. You step inside.")
solved = true
else
writeln("Nothing happens.")
end if
end while
if not solved then
writeln("The door refuses to budge. You'll have to find another way in.")
else
writeln("The cottage is dusty but intact.")
var inventory = array()
append(inventory, "rusty key")
append(inventory, "half-burned candle")
writeln("On the floor, you notice:")
showInventory(inventory)
writeln("You pick up both items.")
end ifCopyright © 2026 Edison Mooers. Published by Gibidda Press. Free for personal learning and qualifying noncommercial educational use. Commercial training, organizational use, redistribution, and adaptation require written permission. Full use terms.