sigildocs

Chapter 10: Game Design

Now we'll apply what we've learned to build a text adventure game.

What We're Building

A classic text adventure (interactive fiction) where the player:

  • Explores rooms connected by directions
  • Examines objects and interacts with items
  • Collects inventory
  • Solves simple puzzles

The final game will compile to a standalone executable you can share.

Game Concept

The Lost Key: You wake up in a mysterious house. Somewhere inside is a golden key that unlocks the front door. Find the key and escape!

The world:

    [Kitchen] -- east --> [Hallway] -- east --> [Study]
                              |
                           south
                              |
                          [Garden]

Data Modeling

We need to represent:

  1. Rooms — locations with descriptions and connections
  2. Items — objects the player can examine or take
  3. Player state — current room, inventory
  4. Game state — overall game status

Room Structure

(import (sigil struct))

(define-struct room
  (id)                      ; Symbol: 'kitchen, 'hallway, etc.
  (name)                    ; Display name: "The Kitchen"
  (description)             ; What the player sees
  (exits default: '())      ; ((direction . room-id) ...)
  (items default: '()))     ; List of item ids

Item Structure

(define-struct item
  (id)                      ; Symbol: 'key, 'lamp, etc.
  (name)                    ; Display name: "a golden key"
  (description)             ; When examined
  (takeable default: #t))   ; Can player pick it up?

Game State

(define-struct game-state
  (current-room)            ; Symbol
  (inventory default: '())  ; List of item ids
  (rooms)                   ; Alist of (id . room)
  (items))                  ; Alist of (id . item)

Project Structure

We'll organize the code into modules:

adventure/
├── main.sgl           ; Entry point
├── game.sgl           ; Main game loop
├── world.sgl          ; Rooms and items
├── commands.sgl       ; Command parsing
└── display.sgl        ; Output formatting

Setting Up the Project

Create a directory:

mkdir -p adventure
cd adventure

Create the module files. We'll start simple and build up.

main.sgl:

;;; The Lost Key - A Text Adventure
(import (adventure game))
(run-game)

This is our entry point — it just imports the game module and runs it.

Game Loop Design

The core loop:

  1. Display the current room
  2. Show prompt
  3. Read player input
  4. Parse command
  5. Execute action
  6. Check win/lose conditions
  7. Repeat
(define (game-loop state)
  (display-room state)
  (display "> ")
  (let ((input (read-line)))
    (if (eof-object? input)
        (quit-game)
        (let ((new-state (handle-command input state)))
          (if (game-over? new-state)
              (end-game new-state)
              (game-loop new-state))))))

Commands to Support

Basic commands:

  • look — describe current room
  • go <direction> — move to another room
  • take <item> — pick up an item
  • drop <item> — drop an item
  • inventory or i — list carried items
  • examine <item> — describe an item
  • quit — exit the game

Direction shortcuts:

  • n, s, e, w — short for go north/south/east/west

Thinking About State

In functional style, each command produces a new state rather than modifying the old one:

(define (go-north state)
  (let ((current (game-state-current-room state))
        (exits (room-exits (lookup-room state current))))
    (let ((north-room (assq 'north exits)))
      (if north-room
          (game-state state current-room: (cdr north-room))
          (begin
            (display "You can't go that way.")
            (newline)
            state)))))

Passing state as the first argument creates a copy with only current-room changed.

Exercises

Before we start coding:

  1. Sketch out 4-5 rooms for your game on paper
  2. List 3-4 items the player might find
  3. Think about what puzzle(s) might be fun
  4. What should happen when the player wins?

Planning the Implementation

In the next chapters, we'll implement:

  1. World — Define rooms and items
  2. Commands — Parse and execute player actions
  3. Polish — Save/load, help system, refinements
  4. Distribution — Build a standalone executable

Ready to start coding? Let's build the world.

Next: Game World →