How to write a 5e game for Twine

I'm not a programmer. I know a little bit of HTML and wiki markup, but never coded anything more complex than a quadratic equation solver on a TI-85. To write this game, I used Twine. It's pretty easy to do basic links and formatting on Twine, but I've written this tutorial for the more complex stuff. Please add any tricks or tips you learn.


Anything you publish in the 5e system for distribution beyond your close friends must follow the Open Game License. This means you can't use any spells, monsters, items or character options outside the SRD / Basic rules. You also can't publish anything that takes place in an official world: no Minsc & Boo, no Exandria, and no Icewind Dale. You have to include the text of the OGL within your game (title page is fine). The most difficult for me is that you can't directly refer to your game as being a Dungeons & Dragons game. Please don't violate these rules, or it will make it harder on everyone.

Basic tutorial

There are already some great tutorials on writing the basics of any Twine game

The cookbook page is especially useful. It has info on creating a dungeon crawl map, dice rolling, and key mechanisms. The (link:) and (link-reveal:) commands are great for showing hidden text while staying on the same page. I use for my image hosting.


In Twine, go to the lower left-hand corner and select "Edit Stylesheet." Here's mine:

@import url('<a href=""></a> family=Roboto|Walter+Turncoat&display=swap');
 body, tw-story {  font-family: 'Roboto', sans-serif;  font-size: 18px;     color: #050505;     background-color: white; }
tw-sidebar {   position: fixed;   top: 0;   left: 1;   width: 20%;                        /* padding-right of the tw-story element. */    max-height: 100%;    margin-top: 0%;                    /* padding-top of the     tw-story element. */    padding: 0 0.5em 0.5em 0.5em;    text-align: right;    background-color: transparent;
tw-icon {
text-align: right;
padding-right: 0.75em;

This imports the fonts from Google fonts, sets the background color (I initially tried a parchment color, but didn't like it) and sets the default font for the game. Then it puts in a link to the sidebar.


To make a sidebar, first start a new passage, not linked to anything. At the top give it the tag "footer" (no quotes). Then I put in the following code:

(append: ?SideBar)[\
<img src="<a href=""></a>" width="40"> d20: (link-repeat: "roll")[(random: 1, 20).]   d20: (link-repeat: "roll")[(random: 1, 20).]  <img src="<a href=""></a>" width="30"> d12: (link-repeat: "roll")[(random: 1, 12).]   d12: (link-repeat: "roll")[(random: 1, 12).]   <img src="<a href=""></a>" width="30"> d10: (link-repeat: "roll")[(random: 1, 10).]  d10: (link-repeat: "roll")[(random: 1, 10).]  <img src="<a href=""></a>" width="30"> d8: (link-repeat: "roll")[(random: 1, 8).]  d8: (link-repeat: "roll")[(random: 1, 8).]  <img src="<a href=""></a>" width="30"> d6: (link-repeat: "roll")[(random: 1, 6).]  d6: (link-repeat: "roll")[(random: 1, 6).]  <img src="<a href=""></a>" width="30" align="center"> d4: (link-repeat: "roll")[(random: 1, 4).]  d4: (link-repeat: "roll")[(random: 1, 4).]  ]

I've since updated my code to be completely self-contained by providing relative references and uploading a zip with all the images.

Stat blocks 

Here's the formatting I used for stat blocks:

###SKELETON <img src="<a href=""></a>" width="200"> (font: 'Arial')[*Medium undead, lawful evil*,  Armor Class 12,  Hit points 13
10 (+0)
DEX 14 (+2)
CON 15 (+2)
INT 6 (-2)
WIS 8 (-1) =====|
5 (-3)]
''Damage Vulnerabilities:'' Bludgeoning
''Damage Immunities:'' Poison
''Condition Immunities:'' Exhaustion, Poisoned
<small>Stats modified from 5e SRD</small>

Changing situations The most complex fight I wrote was against the cultist.

''Cult fanatic's turn'' (if still alive)
(set: $turn to it + 1)
(if: $turn is 1)[The old man tries to ignore your attacks. Taking his dagger, he cuts a chunk of muscle from Martine's corpse and begins to chew on it. As he eats the dead flesh, the candles' light changes color from yellow-orange to blue.] (if: $turn is 2)[The cultist turns toward you with his dagger. He strikes out toward you for (text: (random: 1, 20) + 3). If this is equal to or greater than your AC, you take 3 points of piercing damage.] (if: $turn is 3)[The cultist chants a spell. You feel no effect to yourself, but the room becomes colder and a wind with no apparent source whips around the two of you. An eerie wail sounds throughout the catacombs. The old man grins.] (if: $turn > 3)[The wail increases in volume and you feel a wave of nausea in the pit of your stomach. Giggling insanely, the cultist lashes out with his dagger for (text: (random: 1, 20) + 3).  If this is equal to or greater than your AC, you take 3 points of piercing damage.]
''On your next turn''
If you drop to 0 hp, [[you die]]
(if: $turn < 4)[If the cult fanatic drops to 0 hp, [[he dies]].] (else:)[If the cult fanatic drops to 0 hp, [[he dies->wraith]].]
You can stay in [[melee range]].
You can [[retreat->stay away]] to another part of the room. The cult fanatic gets an attack as you move away for (text: (random: 1, 20) + 3). If this is equal to or greater than your AC, you take 3 points of piercing damage.

On a previous page I wrote (set: $turn to 0) to set up the $turn variable. The melee and ranged attack responses are on different pages, but everything else is the same between the two. Each time you visit either melee or ranged page, it adds +1 to $turn. The cultist has different behaviors depending on the turn. His death also sends you to different pages depending on if you finished before turn 4 or not.


The output of Twine is to HTML, so you can basically publish your game anywhere. makes it pretty easy to set up a game page with a donation option, but you could easily publish on your own site. If you're a DM for a multiplayer game, you can write a short solo adventure for one or each of your players and then just send them a HTML page as an attachment.

Leave a comment

Log in with to leave a comment.