Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Chooseable-Path Adventure Tracker


This is a utility to help keep track of where you've been inside a Chooseable-Path Adventure novel such as the ones written by Ryan North 1 (To Be or Not To Be 2, Romeo and/or Juliet 3). It'd also be usable, of course, for the original Choose-Your-Own-Adventure novels on which the concept was based, though a few features included here wouldn't have much use for those books.

My main purpose in writing this is that I'd always wanted to have a better view into what paths I'd already taken in the book, and more to the point, which paths I'd missed. After you've reached a few dozen endings, a lot of the beginning parts start to become a little too familiar, and remembering where you've got unexplored paths can be a bit cumbersome. This utility is basically just a fancy electronic bookmark for myself.

The utility can also output some fancy graphs, using a third party application called Graphviz 4. The graphs can become rather unwieldy as the book is populated, but they're a great way to have a visual "bookmark" of all the places you have yet to explore in the book, and it's probably the most useful thing this utility generates. You can find some examples in the examples directory.

This application is licensed under the New/Modified BSD License. See COPYING.txt for details.



  • Python 5 - The app should be usable with either python2 or python3, though my main desktop still uses python2 as a default, so it's been tested more thoroughly with that version.
  • PyYAML 6 - The app saves its data in the YAML 7 format.
  • Graphviz 4 (optional) - If you want to generate some fancy graphs. The graphs are sort of the most useful feature of the app, by far, so you almost certainly do want this.
  • Colorama 8 (optional) - For nicely-colorized text output in the CLI.

There isn't actually an installation procedure at the moment. I suppose I should probably turn it into a properly-packaged Python thing, but for now I just run it directly from the directory it lives in.

The utility needs to be run from a commandline of some sort. I use Linux, so living in a CLI is second nature to me. Users on Windows or OSX should theoretically be able to use this, though it's not been tested on those platforms. Just make sure to launch it from a commandline (cmd.exe or Powershell on Windows, or Terminal on OSX). Users on other Python-capable platforms are hopefully already aware of what would need to happen there.


The Graphviz installation on Windows does not add itself to your system's PATH variable, which means that this app won't be able to automatically generate PNG or SVG graphs (though you can always do it by hand - see below in the "Graphviz" section). If you'd like to have that happen automatically, either add Graphviz's bin directory to your system PATH, or probably just copy the dot.exe file into the directory containing The path that you'd have to add should be something like:

C:\Program Files\Graphviz2.38\bin


C:\Program Files (x86)\Graphviz2.38\bin

The dot.exe file should be contained inside that directory. For instructions on adding a directory to your PATH, this looks like a reasonable link: (though when they mention C:\Android\platform-tools, substitute the correct path like the one above)

For output colorization, the Colorama library should be used, but that doesn't appear to have a native Windows install. It's still quite easy to install, though. Once you have Python installed, download the zipfile from the Colorama website 8 (the filename should be something like and uncompress it somewhere. Then in a cmd.exe or Powershell session, go into the directory and type:

python install

That should do the trick!


You must specify a filename with the -f or --filename option:

./ -f romeo.yaml
./ --filename romeo.yaml

If the file doesn't exist, you'll be asked if you want to create a new one. I tend to use .yaml for the file extension, but the actual extension doesn't matter. Once you launch the app, you'll have a commandline interface with which to edit the book, create new pages, etc.

You can get some fancy colorization on the app if the python library "Colorama" is installed. You can specify either light or dark with the -c or --color option, if you're using a terminal with a light or dark background, respectively:

./ -f romeo.yaml -c dark
./ --filename romeo.yaml --color light

You can also change the color scheme while the app is running.

Upon launching the app, you'll be presented with a screen similar to the following:

Chooseable-Path Adventure Tracker

Loaded Book "Romeo and/or Juliet"

**** CANON ****
Current Page: 1
Current Character: Other

Summary: Book Introduction

  Page 3 - Spoil the plot (visited, CANON)
  Page 22 - Learn more about the author (visited)
  Page 36 - Play without spoilers (visited, CANON)
[a] Add Choice [d] Delete Choice [c] Character
[p/##] Page [x] Delete Page [l] List Pages [u] Update Summary
[t] Toggle Canonical [e] Toggle Ending [!] Change Book Title
[i] Add Intermediate [o] Delete Intermediate
[s] Save [g] Graphviz [q] Quit [r] Swap Color Style

So up at the top you'll see that page 1 is considered "canon," and we're currently using the character "Other." There's a summary of the current page, and then a list of choices. If there's a Page entry already for the destination page, it'll list "visited" after the choice text, and if the destination choice is considered canonical, it'll list that as well.

Most of the available options are pretty self-explanatory. To add or delete a choice, use a and d. Note that there's currently no way to modify a choice. If you make a mistake, you'll have to just delete the choice and then re-add it.

To change the current character on this page, use c, and you'll end up at a dialog like the following:

Current Characters:
  [1] Juliet
  [2] Other (*)
  [3] Romeo

  [n] New Character
  [d] Delete Character
  [e] Edit Character (name, graphviz colors)

Switch to character number [2]: 

In addition to switching the currently-active character, you can also add and delete characters from this menu, and also edit character names and their graphviz colors.

Back on the main menu, if you use p or just type in a new page number, you'll either switch to that page (if it already exists in the system), or create a new page (if it doesn't). If you create a new page, you'll be prompted for the new page summary, and the character of the page will be retained from the page you were just on.

Pages can be deleted with x, but note that the app will not allow you to delete the page that you're currently on.

To list all pages, use l. This will also print out various statistics about the book that you're editing, like so:

Total pages known: 30
Canon Pages: 24
Ending Pages: 2
Intermediate Pages: 6
Character Counts:
  Hamlet: 16 pages
  Ophelia: 6 pages
  Other: 7 pages
  Ryan North: 1 page

To update the summary of the current page, use u. Pages have two toggle switches: one for canon, and the other for "ending," intended to be used on all the ending pages. (Mostly that's just useful for colorization on the graphs - more on that later.) You can toggle either of those with t and e respectively.

To change the title of the book, use ! (I was running out of keys by the time I implemented that one).

To add or edit "intermediate" pages, use i and o, though this is a feature you probably don't care about. See the section about Pages and Intermediate Pages, below.

To generate a Graphviz dotfile and PNG, use g (more on that in the next section). This will generate two files, a text-based dotfile which Graphviz understands, and a PNG graphic (so long as Graphviz is available in your path).

To change the color scheme currently in use, use r (this is only available if the "colorama" Python library is installed).

Finally, you can save to the current filename with s, or quit with q. The app will ask you if you want to save before quitting.


Graphviz is an awesome application which translates a generally-human-readable text file (in the correct format, of course), and turns it into nifty graphs automatically for you. One of its modes, "dot," is the flowchart-like directional graph which is most useful for visualizing this kind of data, and the utility supports exporting to a "dot" file for graphviz to parse.

When you generate a dotfile in the app with the g option, it will also try to call dot to generate the PNG automatically. This attempt will fail if you don't have dot in your $PATH, but you will still have a dotfile saved so that you can run it manually later.

You can also generate a dotfile outside of the main app UI, with the -d or --dot option, like so:

./ -f romeo.yaml -d
./ --filename romeo.yaml --dot

If already exists, you'll be prompted as to whether you want to overwrite it. Then once you have the dotfile, you can use graphviz's "dot" utility to create a PNG image like so:

dot -Tpng -o romeo.png

Alternatively, I've included a script which will auto-convert any *.dot file in the current directory to a PNG. That's a shell script 9, which is only going to work on systems which support shell scripts. (Linux, of course, works. OSX probably will?) The script has only been tested with "bash" 10, though I'd be surprised if alternate shells like dash wouldn't work.

Graphviz can output to many other formats than just PNG, though I haven't actually tested out the current dotfile generation with anything but PNGs. The generated graphs can get pretty unwieldy, but I've found them to be quite useful even when they get huge.

Each of the characters has a set of colors associated with it, which will be put into the graphviz graphs that are generated. The default colors are black text with a white background. To change the colors, you can use the c option from the main UI, and then hit e to edit a character. The list of colors that Graphviz accepts is found here:


This section is really only useful for someone who's hoping to use this utility to ensure that they've seen 100% of the book in question. In Romeo and/or Juliet, what we call a "page" isn't really a physical page. In fact, the book itself eschews that term, and instead of "Turn to page 282," it just says "Turn to 282." Each number can span multiple physical pages, depending on the length of the text, and each physical page can contain multiple numbers.

This makes it pretty easy for the app to discover if there are any "holes" in the list of discovered pages. In fact, the l option to list pages will include a list of missing "pages" so long as there are fewer than 30 (otherwise the list could be super long). For instance, on my romeo_full.yaml file, you'd see the following:

Missing pages (13 total):
[243, 253, 261, 269, 276, 285, 295, 305, 317, 321, 331, 340, 342]

(Which is expected because I didn't actually catalogue the entire Caesar Cipher puzzle, since the graph quickly becomes ludicrously unwieldy.)

Anyway, for a book set up like Romeo and/or Juliet, where every "page number" corresponds to a choice, and there's no holes, that Missing-Page logic works great as-is.

In traditional Choose-Your-Own Adventure novels, and also in To Be or Not To Be, however, the instructions do refer to actual page numbers, and the options may span multiple pages. Every ending scene in To Be or Not To Be, in particular, will have at least one intermediate page to hold the full-page illustration.

Without a way to catalogue these intermediate pages, it'd be impossible for the app to determine if there are any "holes" in the catalogued pages. So, that's what the app means by intermediate pages. You can add or delete them with i or o. When you go into the delete mode, you'll see all the current pages marked, like so:

Current intermediates:
   2, 5, 47, 358, 480, 481

Intermediate to delete (enter to quit): 

For both adding and deleting, you can just keep typing in numbers if you want to do a bunch all at once, and hit Enter to exit out of the intermediate number management mode.

Again, this is clearly only something that you'd want to bother with if you're: 1) Reading a book like To Be or Not To Be, where choices can span multiple physical pages, and 2) Trying to make sure that you get 100% completion on the book. If that is something you think you're interested in, it's probably best to start cataloguing them right from the start of your reading, so it's not a lot of work to add in later.


The book To Be Or Not To Be features a book-within-a-book called The Murder of Gonzago which uses a completely separate page numbering scheme than the rest of the book. It's a full 24 pages (including "cover") right inbetween the real pages 414 and 415. The pages are numbered with a special system where page 1 is "G001" and page 21 is "G021", etc.

This posed some problems for prior versions of this utility, since we assumed that all page numbers are numeric, and there was no good way to keep track of the nested book. There are a few possible ways to solve this, but in the end it was simplest to just allow page numbers to be non-numeric.

In general, the functionality for dealing with non-numeric page numbers like the sorts found in The Murder of Gonzago doesn't change at all. The one difference is that in order to move to a page like G020, or to switch to that page, you must use the p option directly rather than just typing the page number in at the main command prompt. That's a little less convenient than it could potentially be, but given that this is a very special case unlikely to be found in any other book, I don't think it poses much trouble really.

Note that the "missing page" detection outlined above completely ignores non-numeric pages, so you'll have to just make sure that you've seen the whole Murder of Gonzago by hand, so to speak.


There's a few ways in which the data collected by this app differs from the "data" contained in the actual Choosable-Path Adventure books by Ryan North.

  • In the books, it's the CHOICES which are considered canonical, not the pages themselves. The app assigns canon to the page, though, so there's a few places where you can have two separate "canonical" choices on the same page while using the app. Generally when you have the option to skip over dialogue or the like.
  • The books occasionally have two separate choices which lead to the same page, for humorous purposes. We only support a single choice per target page, so those are collapsed a bit.
  • The book orders the player choices in a way designed to maximize humor. The internal data structure we use does not preserve choice order at all, and will always just sort them in page order.


  • The app doesn't really follow a super-strict separation of data objects and application logic. The main App class probably knows too much about the internal structure of the Book/Option/Character classes, for instance.
  • Strict adherents to PEP8 11 will probably weep in sorrow after looking at this code. I apologize.
  • There's no way to modify existing choices. To make a change to a choice, you've got to delete it and then re-add.
  • Strictly speaking, ending pages should really be using a different node shape, rather than a unique color (when generating Graphviz graphs). I like that the ending color is very noticeable, though. Perhaps we should do BOTH?
  • None of the color presets look good in the default Powershell colors on Windows. Maybe add in a "ps" color scheme? Though I suspect we couldn't use color_dim() so naively, since some colors seem to benefit from DIM while others benefit from BRIGHT.
  • I seem to be inconsistent with "choosable" versus "chooseable." The printed book uses the E, though it seems that the more-canonical spelling is without? Given that the books themselves do not especially respect canon, I don't think that's a particularly strong argument, though.


1: Ryan North's homepage:
2: To Be or Not To Be:
3: Romeo and/or Juliet:
4: Graphviz homepage:
5: Python homepage:
6: PyYAML homepage:
7: YAML specification:
8: Colorama homepage:
9: Shell script info:
10: Bash homepage:
11: PEP 8 style guide:


Choosable-Path Adventure Tracker







No releases published


No packages published