Draws a flowchart graph of any Visual Novel from Renpy .rpy files !


Keywords
branches, branching, flow, flowchart, graph, graphviz, label, labels, renpy, renpy-applications, renpy-mod, story, visual-novel, visual-novels
License
AGPL-3.0
Install
go get github.com/ewenquim/renpy-graphviz

Documentation

Ren'Py graph vizualiser - branches flowchart generator

Go Reference Go Report Card Link to online demo GitHub Workflow Status Coverage

GitHub Repo stars

This is a tool written in Go that allows you to visualise the routes of your Ren'Py story.

Routes of the Question, the classic Ren'Py example

Examples

Doki Doki Litterature Club will no longer have secrets for you!

An extract from my personnal VN, Coalescence. You can't imagine handling a heavy VN like this one without graphic tools... (the labels aren't blurred on the real image)

🔎 HOW TO USE?

Online version -try online!

You can test this tool in the browser. If you really want to get .png files, please download the software version. Note that I will not maintain this website, it is not guaranteed to represent the library 100%.

https://renpy.amethysts.studio

Software version -install it on your computer

  • Download latest version
  • Move the program in your game folder
  • Run it from the command line ./renpy-graphviz or by clicking on the icon in your file manager
    • you might have to give yourself the permissions: don't worry my program isn't a virus ! Run chmod +x renpy-graphviz* on Unix.
  • renpy-graphviz.png just appeared, enjoy !

The command line version is more powerful as you can add flags and a path, see the documentation by typing renpy-graphviz -h

Go library

go install pkg.amethysts.studio/renpy-graphviz@latest

If you are a Go user and want to integrate this in a Go lib/program, it is totally possible. The /parser module is very powerful.

🏷 Tags

Ren'Py scripting isn't strict, so sometimes there are situations the script cannot know what is going on in your story. So I made a tag system to enforce some behaviours. For example

label chapter_1: #renpy-graphviz: TITLE

Before tags, you must write renpy-graphviz in a comment to ensure there are no collision with existing words in your VN. Here are the tags available:

  • BEHAVIOUR TAGS
    • BREAK: breaks the current flow, for parallel labels for example
    • IGNORE: ignores the current label. Jumps to this label still exist
    • SKIPLINK: avoid long arrows by creating a "shortcut" - read the doc below before using
    • FAKE_LABELS: simulates labels and jumps
    • INGAME_LABELS: same but interacts with real label/jumps
  • STYLE TAGS

BREAK

Cancels any "guessed link".

Expected with BREAK script.rpy

label one:
  "blah blah"

label two:
"bla bla"

# renpy-graphviz: BREAK

label three:
"the end"

IGNORE

Ignore the current line. If this is a jump to a label that isn't ignored, the label will still appear on the graph but not the arrow that should go towards it.

Expected IGNORE script.rpy

label one:
label two: # renpy-graphviz: IGNORE
label three:

SKIPLINK

Avoids long arrows by creating another label with the same name. Beware, the label can't have any children and is marked by an asterix to show it is a copy.

Expected SKIPLINK script.rpy

label one:
    if condition:
        jump six # renpy-graphviz: SKIPLINK
    else:
        pass

label two:
label three:
label four:
label five:
label six:

FAKE_LABEL(a) & FAKE_JUMP(a, b)

Creates a node or an arrow in the graph without having to create label thing in your Ren'Py script. It is disconnected from the "normal flow", label and jump in your script (see example below).

FAKES script.rpy

# You can mix different tags on the same line
# renpy-graphviz: FAKE_LABEL(a) TITLE
# If b/c does not exists, it creates it
# renpy-graphviz: FAKE_JUMP(b, c)

label real_1:
# There will be no 'indirect link' from `real_1` to `d`
# renpy-graphviz: FAKE_LABEL(d)

# Implicit jump from `real_one` to `real_two`
# (normal behaviour as `d` is ignored by the normal flow)
label real_2:

# No jump from `real_two` to `a` or `d`
# renpy-graphviz: FAKE_JUMP(a, d)

INGAME_LABEL(i, a) & INGAME_JUMP(i, b)

Same that above but interacts with the "normal flow", your label, call and jump from your Ren'Py script. You need to specify an indentation level.

# renpy-graphviz: INGAME_JUMP(8, destination)

is the equivalent of:

        jump destination
INGAMES script.rpy

# renpy-graphviz: INGAME_LABEL(0, start)
# renpy-graphviz: INGAME_JUMP(4, option_one)

# Creates a link from `start` to `option_two` even
# if there was a jump before -like normal jumps
# renpy-graphviz: INGAME_JUMP(4, option_two)

label option_one:
    "dialogue"

# should follow the previous label (implicit jump)
# renpy-graphviz: INGAME_LABEL(0, indirect_label)

# jumps from `indirect_label` to `option_two`
    jump option_two

TITLE & GAMEOVER

Set some styles

TITLE / GAMEOVER script.rpy

label routeone :  # renpy-graphviz: TITlE
    d "Hello World!"
    if condition:
        jump bad_ending

label routeAlternative:
    d "Normal bubble"
    jump good_ending


label bad_ending: # renpy-graphviz: GAMEOVER
    d "Bad ending"
    return

SHAPE & COLOR

You can set yourself a custom color or shape for a label

SHAPE and/or COLOR script.rpy

label first: # renpy-graphviz: SHAPE(rect) COLOR(red)
    jump second # renpy-graphviz: SHAPE(septagon) COLOR(#ffdd67)

Limitations

This require your VN to be structured in a certain way, so it's possible that it isn't perfect for you. Feel free to raise an issue here, or to change your VN structure, by adding tags manually.

Your contribution to the project are appreciated!

CONTRIBUTING

See the CONTRIBUTING.md file

LICENSE

This program is free and under the AGPLv3 license.

Beware, if you use this program, you must credit it somewhere on your game.

Used Renpy Graph Vizualiser from EwenQuim

Enjoy! ❤️