<h3>Twine...? Wahhh?</h3>\
Twine is a free, open-source <<footnote "Which license?">>GNU General Public License<</footnote>> tool for creating <<linkappend "non-linear, interactive stories.">>
Otherwise known as interactive fiction -- specifically, a type of [[interactive fiction]] called hypertext.<</linkappend>><<script>>
UIBar.stow();
<</script>>
/* Variables so the user can randomize their traits */
/* First and last names */
<<set $firstNames to ["Charity", "Benji", "Beatrix", "Enid", "Bonnie", "Mellisandre", "Seraphina","Maria"]>>
<<set $lastNames to ["Midwinter","Moonshadow", "Blackwood", "Featherstone", "Lightmoon", "Nightwing", "Sovendark"]>>
/* Physical traits */
<<set $hairColors to ["white", "red", "black", "brown", "blonde", "dark brown", "dirty blonde", "mousy", "raven", "light brown", "auburn", "tawny", "inky", "blue black", "silver", "ash brown", "corn yellow", "chestnut", "jet black", "alabaster", "copper", "strawberry blonde", "umber", "salt and pepper"]>>
<<set $eyeColors to ["blue", "brown", "black", "green", "gray", "hazel", "obsidian", "aquamarine", "topaz", "charcoal","emerald", "sky blue", "sapphire", "slate", "amber", "chocolate", "jade", "mud brown", "indigo", "cornflower blue", "coal black", "bottle green", "amethyst"]>>
/* Story traits */
<<set $pronouns to ["He/him", "She/her", "They/them"]>>
<<set $traits to ["Defense","Intelligence","Stealth","Strength"]>>
/* Set traits to random for the first time the user opens the character creator */
<<widget "randomizeCharacter">>
<<set $firstName to $firstNames.random()>>
<<set $lastName to $lastNames.random()>>
<<set $hairColor to $hairColors.random()>>
<<set $eyeColor to $eyeColors.random()>>
<<set $pronoun to $pronouns.random()>>
<<set $trait to $traits.random()>>
<</widget>>
/* Call widget at first to set traits to random */
<<randomizeCharacter>>
<h3>Twine...? Wahhh?</h3>\
Twine is a free, open-source <<footnote "Which license?">>GNU General Public License<</footnote>> tool for creating non-linear, interactive stories
Otherwise known as interactive fiction -- specifically, a type of interactive fiction called hypertext.<<do>>\
<<if _click is 1>>Well, if that's IF, what's hypertext?<</if>>\
<<if _click is 2>>Are you sure you wanna know...?<</if>>\
<<if _click is 3>>Well, alright!<</if>>\
<</do>>
What is interactive fiction (abbreviated as ''IF'')? That's complicated! In the past people //loved// to argue about it... But today, most people have settled on <<linkappend "broad, inclusive definitions.">>
One definition, according to the <a href="https://iftechfoundation.org/frequently-asked-questions/" target="_blank">Interactive Fiction Technology Foundation</a>:
<blockquote>... a kind of video game where the player’s interactions primarily <<linkappend "involve text">>... Interactive fiction is a kind of literature, but the reader takes an active role rather than a passive role. The story can only move forward in response to the <<link "reader’s actions">>\
<<set _click += 1>>
<<if _click gte 4>> <<goto "hypertext">> <</if>>
<<redo>>
<</link>>, and those actions change the experience of the story.<</linkappend>></blockquote>\
<</linkappend>>
\
<<set _click to 0>>//Hypertext// is a type of ''choice-based'' interactive fiction. It's called choice-based because, rather than allowing free-form input, it presents the player with a list of pre-defined choices each turn.
A hypertext game is unique from other types of IF in that...
<blockquote>... [it] invites the player to direct interaction with its own story text, clicking on <span id="highlight-link"><<link "highlighted words or phrases">>\
<<append "#highlight" t8n>>.. Each of those bold-weight phrases might, with a click, take the player to a new scene or location, expand in-place to reveal new text (and perhaps new choices), or accomplish other effects.<</append>>\
<<replace "#highlight-link">>highlighted words or phrases<</replace>>
<</link>></span> – rather like one navigates around a website<span id="highlight">.</span>\
<<footnote>>Source: <a href="https://ifcomp.org/about/if" target="_blank">IF Comp FAQ</a><</footnote>>\
</blockquote>\
In other words, hypertext takes the //link// -- the native language of the internet -- and turns it into a source of <<cycle "_tmp">><<optionsfrom ["surprise", "experimentation", "possibility"]>><</cycle>>.
[[Let's learn more about Twine...|Terminology]]<h3>What are the terms to know?</h3>\
<ul>
<li>''Twine'' -- the open-source Twine app <<footnote>>available on both web and desktop<</footnote>>, maintained by <a href="https://www.patreon.com/cw/klembot" target="_blank">Chris Klimas</a>, which allows users to create hypertext games via a drag-and-drop graphical editor. </li>
<li>''Twine game''<<footnote>>alternately known simply as "a Twine"<</footnote>> -- a hypertext game made with Twine (the finished product!)</li>
<li>''twee'' -- a markdown format for Twine source code. Allows developers to write games in <<linkappend "their favorite IDE">> -- VS Code is by far the most popular for Twine development :) --<</linkappend>> rather than using the Twine app.\
<ul><li>Currently standardized to Twee v3. Modern Twine app can import/export Twee v3 natively.</li></ul>\
</li>
<li><a href="https://www.motoslave.net/tweego/" target="_blank">''tweego''</a> -- modern twee compiler, maintained by <a href="https://www.patreon.com/thomasmedwards" target="_blank">Thomas Michael Edwards</a>
<ul><li>if you are writing your Twine source code in an IDE instead of the Twine app, <em>then use this compiler!</em></li></ul>\
</li>\
</ul>\
Twine games are part story, part game -- and some Twines are more one than the other, depending on who you ask. Twine terminology can flip-flop between the two mediums -- but most people in the IF commmunity will say things like //player//, //gameplay loop//, and //inventory management//, indicating their opinion that hypertext fiction is, first and foremost, an [[interactive medium|Links and Passages]].
Twine has a //looong// history -- it first debuted in 2009! -- but today, the modern Twine ecosystem runs on something called [[Story Formats]], as well as [[macros]].<<footnote>>These may not be what you think! While "macro" has a standard definition in Computer Science (link to this), the term is used a bit differently in Twine... Keep playing to learn more!<</footnote>>how long should twine presentation be?
probably 30 minutes.
To talk about:
What is interactive fiction? What is hypertext?
History of Twine?? Came out in 2009, created by Chris Klimas. He's still working on it. And also what is Twine?? It's interactive fiction game engine.
How does Twine work? What is Twine under the hood? Twee vs Twine?
- also talk about tags, script passages, and html/css :)
Story formats -- Harlowe, Sugarcube, etc.
Why was Twine successful? Macros!
- maybe have a little guide on how the people there can write their own macros :) and link to hiev's guide. as well link to sample macropacks.
The best part of Twine -- its extensibility and opensource nature!
- Also it's just html so anyone can use it :)
The downsides of Twine :( its extensibility means that it doesn't come with a lot of built-in functions -- no native inventory system, no native way to register shortcut key commands (although maybe sugarcube allows for this...?)
where do i put my twine?
- host it on itch.io, some ppl on GeoCities.
- as well enter it in comps! IF Comp + spring thing
<h3>Story Formats</h3>\
You can think of a story format as the "engine" of a Twine game. Their code is always bundled with every completed Twine game.
The Story Format controls the way a Twine game looks and feels:
<ul>
<li>its default styling</li>
<li>the user experience (how games are saved, moves are undone/etc)</li>
<li>how it loads passages</li>
<li>what macros/functions it provides developers</li>
</ul>
\
From <a href="https://twinery.org/cookbook/introduction/story_formats.html">The Twine Cookbook</a>:
<blockquote>...story formats are more like dialects of the overall language of Twine along with their own visual changes.</blockquote>
There are [[multiple story formats available]] in Modern Twine.<<footnote>>AKA Twine 2<</footnote>><h3>Macros</h3>
\
Twine wouldn't be what it is today without ''macros''.
In Computer Science, a macro has a defined definition. But in Twine, macros are more like functions:
<div class="vocab">\
<div class="word">macro</div>\
<div class="definition">\
a section of pre-defined code that can be called, as many times as needed, inside a passage \
</div>\
</div>\
Macros are commands -- they tell Twine to //do// something! They allow Twine developers to easily achieve more complex effects and game flows than the simple link-passage paradigm allows.
Twine 2 (modern Twine) comes with many [[built-in macros.]]<h3> Interactivity and Twine</h3>
\
Twine's main //gameplay loop// rests in the concept of ''links'' and ''passages''.
A [[passage|passage content]] is a block of text. A [[link|link content]] is the connection between two passages.
In this way, Twine links/passages can represent many different things... \
<ul>
<li>the connection between two <<linkappend "related">> (or even disparate!)<</linkappend>> ideas</li>
<li>moving the story forward</li>
<li>a choice the player makes (e.g., ''Accept the magician's quest'' or ''Steal the alien space ship'')</li>
<li>navigating time or space (e.g. ''Go left'' or ''Later that day...'')</li>
<li>exploration/investigation/discovery</li>
<li>....the sky is the limit, really!</li>
</ul>
\
<<if hasVisited("link content", "passage content")>>[[Ready for more terminology...?|Terminology]] <</if>><h3>My Passage</h3>
\
Hello there! :)
<<return>>In the Twine app/twee, we write a link like so:
{{{ Please [[click me|My Passage]]!}}} <<footnote>>\
The link text always goes on the left, followed by a pipe and then the link destination. Alternately: {{{ [[click me->My Passage]] }}}
<</footnote>>
renders as
<span class="twine-example">Please \
<<link "click me" "My Passage">> \
<<run Dialog.close()>> \
<</link>>!</span>
When that link is clicked, Twine forwards the player to the passage titled "My Passage" -- the old block of text is replaced with the new block of text, after a short (optional) transition.
Links go //inside// a [[passage|passage content]]'s content.
<<if hasVisited("passage content")>> [[Return->Links and Passages]] <</if>>In the Twine app, we create a new passage by clicking Passage > New in the topbar menu. (This will create a new square on the screen, that can be dragged/dropped wherever makes the most sense on our passage map.)
<<image "twine_screenshot.png">>
<<image "twine_map.png">>
\
In twee, we create a new passage anywhere in our .twee file by pressing enter twice, then prefacing the passage title with {{{ :: }}} -- like so:
<pre><nowiki>:: My Passage Title
This is the content of my passage. My passage content will continue for as long as I want, until I specify a new passage.
:: My Second Passage Title
This is the content of my second passage. [[A link to the first passage.|My Passage Title]]
</nowiki></pre>
Passages are connected by //[[links|link content]]// between them.
<<if hasVisited("link content")>> [[Return->Links and Passages]] <</if>><<image "twine_meme.jpeg">>
<h2>If you want to learn about menus.... you've come to the right place.</h2>
\
<span class="intro-container">
<h1 class="intro-text">Welcome to my Twine Game. It is about Twine.</h1>
</span> \
\
<div class="intro-links">
[[Twine...? Wahhh??]]
[[Resources]]
</div><<widget "image">>
<<set _imageUrl to setup.ImagePath + _args[0]>>
[img[_imageUrl]]
<</widget>>
/* character creator widgets */
<<widget "traitSelector">>
<<if _args[0]>>
/* Set selected class if this is the current trait */
<<if _args[0] is $trait>>
<<set _selectedClass to "trait-container-" + _name.toLowerCase() + "-selected">>
<<else>>
<<set _selectedClass to "trait-container-unselected">>
<</if>>
/* Actually display the trait */
<span @class="'trait-container trait-container-' + _args[0].toLowerCase() + ' ' + _selectedClass">\
<<set _traitImgPath to setup.ImagePath + _args[0].toLowerCase() + ".png">>\
<span class="trait-image">\
<<link [img[_traitImgPath]]>>\
<<set $trait to _args[0]>>
/* Can't do redo macro here as it resets scroll position -- so toggle classes manually */
<<setSelectedTrait _args[0]>>
<</link>>\
</span>\
<<print _args[0]>>\
</span>\
<<else>>
No trait provided!
<</if>>
<</widget>>
<<widget "setSelectedTrait">>
<<if _args[0]>>
/* Iterate through all the trait decals and remove/add the appropriate classes to indicate which trait has been selected */
<<for _i, _name range $traits>>
<<set _currentTraitContainerClass to ".trait-container-" + _name.toLowerCase()>>
<<set _currentTraitSelectedClass to ".trait-container-" + _name.toLowerCase() + "-selected">>
/* Add selected class if this is the trait we are selecting */
<<if _name.toLowerCase() is _args[0].toLowerCase()>>
<<addclass _currentTraitContainerClass _currentTraitSelectedClass>>
<<removeclass _currentTraitContainerClass "trait-container-unselected">>
<<else>>
<<addclass _currentTraitContainerClass "trait-container-unselected">>
<<removeclass _currentTraitContainerClass _currentTraitSelectedClass>>
<</if>>
<</for>>
/* Rerender trait name */
<<redo "traitName">>
<</if>>
<</widget>><div class="resources"><h2>This is my Twine Resources Masterlist!</h2>\
\
This page complies all the resources linked in this game, as well as additional resources to help you as you dive into the wonderful world of Twine.
<h3 id="toc">Table of contents</h3>\
<ul>
<li><a href="#develop-twine">If you want to develop...</a>
<ul>
<li><a href="#twine-itself">Getting Twine</a></li>
<li><a href="#story-formats">Story Formats</a>
</li>
<li><a href="#macro-sets">Macro Sets</a>
</li>
</ul>\
</li>\
<li><a href="#community">If you want to join the community...</a>
<ul>
<li><a href="#games-to-play">Games to Play</a>
</li>
<li><a href="#comps">Competitions</a>
</li>
<li><a href="#forums">Forums to Join</a>
</li>
</ul>
</li>
</ul>\
<h3 id="develop-twine">If you want to develop your own Twine</h3>\
<h4 id="twine-itself">Getting Twine</h4>\
<ol>
<li><a href="https://twinery.org/" target="_blank">Twinery.org</a>
<ul><li>Download the Twine app here and get started making your own games! :)</li></ul>\
</li>
<li><a href="https://joshuagrams.github.io/tiny-qbn/doc/tweego.html" target="_blank">Twee</a>
<ul><li>This is a guide to using Twee, if you don't want to use the Twine editor. This is how you make Twine games in your IDE of choice (although most people use Visual Studio Code).</li></ul>\
</li>\
</ol>\
<details>\
<summary>Need even more help getting started with Twee?</summary>\
Twee is more complicated than Twine, that's for certain. However, the benefits of Twee can be worth it: better file organization, built-in syntax highlighting, and a robust workflow for longer, more complex games.
See a list of <a href="https://github.com/cyrusfirheir/twee3-language-tools" target="_blank">tools</a> Cyrus Firheir & others have made for VSCode to help with Twine (includes syntax highlighting and a story map viewer).
Chapel also has a <a href="https://github.com/ChapelR/tweego-setup" target="_blank">default setup repo</a> for Twine games in Twee, designed to get you up and running with everything you might need from the start.
</details>
\
<h4 id="story-formats">Story Formats</h4>
Links to the documentation for each of the four story formats that come packaged with the Twine app.<<footnote>>It's recommended for beginners to start with ''Sugarcube''<</footnote>>
<ul>
<li>Harlowe
<ul><li><a target="_blank" href="https://twine2.neocities.org/">Harlowe docs</a></li></ul>\
</li>\
<li>Sugarcube
<ul><li><a target="_blank" href="https://www.motoslave.net/sugarcube/2/docs/">Sugarcube docs</a></li></ul>\
</li>
<li>Snowman<ul><li><a target="_blank" href="https://videlais.github.io/snowman/">Snowman docs</a></li></ul></li>\
<li>Chapbook\
<ul><li><a target="_blank" href="https://klembot.github.io/chapbook/guide/en/">Chapbook docs</a></li> </ul>\
</li>
</ul>
See <a target="_blank" href="https://twinery.org/cookbook/starting/twine2/storyformat.html">more information here</a> about choosing between the formats.
\
<details>\
<summary>Pssst! Want to learn about even more Story Formats than just these four?</summary>\
Since anyone can make a Story Format, there are loads more that people have made over the years. See <a href="https://github.com/ChapelR/twine-resources#other-formats" target="_blank">this guide</a> for a list of some of the more popular third-party formats, and <a href="https://twinery.org/reference/en/story-formats/viewing.html" target="_blank">this guide</a> for installing a third-party format to use with Twine.
</details>
\
<h4 id="macro-sets">Macro Sets</h4>\
Various Twine creators have compiled their own macro sets, or lists of macros they have created for anyone else to use.
To use any of these macros, you will add them to your Javascript passage.
<ul>
<li><a href="https://twinelab.net/custom-macros-for-sugarcube-2/#/" target="_blank">Chapel's Custom Macro Collection</a>
<ul><li>VERY feature-rich macro set, super helpful for the Twine beginner!</li></ul>\
</li>\
<li><a href="https://github.com/123moonhead123/TwineImagePack" target="_blank">ImagePack Macro for Twine SugarCube - by Moonhead</a>\
<ul><li>Easy way to display random images in Sugarcube</li></ul>\
</li>
<li><a href="https://github.com/hituro/hituro-makes-macros" target="_blank">hituro-makes-macros -- Just some Twine Macros for SugarCube, and Chapbook</a>\
<ul><li>Some interesting macros here, including a chat system macro and a time system macro (for dynamic time systems or time schedules, like modeling days of the week)</li></ul>\
</li>
<li><a href=" https://github.com/cyrusfirheir/cycy-wrote-custom-macros" target="_blank">Cycy wrote custom macros</a>\
<ul><li>A small list of macros made by the creator of Twee3 Language tools for VSCode (includes the yaml file to use these macros with Twee in VSCode).</li></ul>\
</li>
<li><a href="https://github.com/HiEv/UInv" target="_blank">Universal Inventory System (UInv) for Twine 2/SugarCube 2 by HiEv</a>\
<ul><li>An inventory system for use with Sugarcube -- haven't tried it myself, but it's supposed to be pretty complex, offering a lot of the normal inventory functionality you'd expect.</li></ul>\
</li>
<li><a href="https://hiev-heavy-ind.com/Sample_Code/Sample_Code.html#Main%20Menu" target="_blank">Sugarcube Sample Code by HiEv</a>\
<ul><li>Not macros, really, but more code samples using TwineScript (as in, using the built-in macros that come packaged natively with Sugarcube). These samples are still very useful, as they show that the default macros are still pretty powerful/functional, especially when combined with each other.</li></ul>\
</li>
</ul>
\
<h3 id="community">If you want to get involved in the community...</h3>\
<h4 id="games-to-play">Games to Play</h4>
There are //thousands// of fun (and completely free! 😉) Twine games to play online.
Probably the most extensive collection can be found using <a href="https://itch.io/games/tag-twine" target="_blank">the Twine tag on itch.io</a>.
Or, if you prefer, you can also search the <a href="https://ifdb.org/search?searchfor=system:Twine" target="_blank">Interactive Fiction Database</a>, which is a more curated selection of games notable within the Interactive Fiction community. The IFDB database also features reviews from members of the community, as well as a list of awards/competitions the game may have won.
<details>\
<summary>Some games I like...</summary>\
<a href="https://ifdb.org/viewgame?id=ap1651hvjldbuugj" target="_blank">Birdland</a>, <a href="https://ifdb.org/viewgame?id=6hyfsgy8yzhyecgz" target="_blank">(do not) forget</a>, <a href="https://ifdb.org/viewgame?id=7wip22dpvlzil83" target="_blank">rat chaos</a>, <a href="https://ifdb.org/viewgame?id=dwgm9le9d8uh2ibq" target="_blank">the uncle who works for nintendo</a>, <a href="https://ifdb.org/viewgame?id=mxj7xp4nffia9rbj">howling dogs</a>, <a href="https://ifdb.org/viewgame?id=tqlte48fgxxlbxem">ULTRA BUSINESS TYCOON III</a>
</details>\
<h4 id="comps">Competitions to Enter</h4>\
There are many competitions to enter within the Interactive Fiction community. All competitions welcome newcomers -- and most (unless they say otherwise) welcome Twine games!
Some competitions are just for bragging rights, while others award prizes. The majority of competitions are held either once (one-off themed comps) or yearly. See a list of competitions held once every year, below.
//All// of these competitions allow non-entrants to vote and rank the games -- if you can't enter a game that year, you could always participate as a player :)
<h5>IF Comp</h5>\
<ul><li>By far the biggest. For games below 2 hours. Held in September every year. <a href="https://ifcomp.org/" target="_blank">Link</a></li></ul>
<h5>Spring Thing</h5>\
<ul><li>Second biggest usually. For longer games. Held in Apirl/May every year. <a href="https://www.springthing.net/" target="_blank">Link</a></li></ul>
<h5>IntroComp</h5>\
<ul><li>For works in progress. Held in the fall. <a href="https://introcomp.org/" target="_blank">Link</a></li></ul>
<h5>EctoComp</h5>\
<ul><li>For spooky games >:) Held during October. <a href="https://itch.io/jam/ectocomp-2025" target="_blank">Link</a></li></ul>
<h5>NeoTwinyJam</h5>\
<ul><li>For Twines less than 300 words. <a href="https://itch.io/jam/neo-twiny-jam-26" target="_blank">Link</a></li></ul>
<h4 id="forums">Forums to join</h4>\
The IF community has various places on the internet where they gather to share code samples, provide technical help, discuss games, or participate in the general community.
<ul>
<li><a href="https://intfiction.org/" target="_blank">IntFiction forum</a>\
<ul><li>Main forum for all things IF! Also has a dedicated section to discuss Twine games.</li></ul>\
</li>
<li><a href="https://www.reddit.com/r/twinegames/" target="_blank">Twine subreddit</a>
<ul><li>Focused mainly on technical help for Twine coders, doesn't have quite the community focus that the IF forum does. But the reddit has a few regulars who are very good at providing support and offering advice to anyone who asks.</li></ul>\
</li>
</ul></div>\
<a href="#toc">Return to the top of the resource masterlist</a> <h3>Twine's Native Macros</h3>
Modern Twine has an indulgence of macros for developers, ready to use in Twine out of the box.
For example, Twine macros <<linkappend "allow developers to...">>
<ul>
<li>use control statements</li>
<ul><li>if/else, for, switch</li></ul>
<li>manipulate variables (define, set, update, print, etc)</li>
<ul><li>can be used for: character creation, complex state management, dynamic story paths</li></ul>
<li>trigger DOM updates</li>
<li><<type 200ms keep>>animate text<</type>></li>
<li>manage game state</li>
<ul><li>such as: undo/redo player turns</li></ul>
<li>utilize multi-media</li>
<ul><li>can include: sounds, images, even videos</li></ul>
<li>....and more!</li>
</ul>\
And if Twine's native macros aren't enough, you can always define your own [[custom macros]] (written in Javascript).
Remember...
<h2>Twine games are just HTML files -- Javascript, HTML, and CSS. Anything that can be done on a web page //''can''// be done in Twine!</h2>
<</linkappend>><h3>Custom Macros</h3>
The <em>real</em> power of Twine lies in custom macros -- or, the ability for enterprising coders to extend Twine's native functionality.
Custom macros can be defined in Twine's ''Script'' passage.<<footnote>>In the Twine app menu, see Story > Javascript to open the Script passage. For Twee, you just tag any passage with "script" to have it count as story script.<</footnote>>
''All macros are written in vanilla Javascript.'' They also have access to all of Twine's APIs.<<footnote>>E.g., the //Config// api allows devs to change the story's settings/default configuration, and //Engine// api allows devs to manipulate the player's history.
For a full list of APIs, see <a target="_blank" href="https://www.motoslave.net/sugarcube/2/docs/#config-api">the Sugarcube docs</a><</footnote>>
[[For example, here's how I wrote my footnote macro...|my own custom macro]]<h3>Which Formats are Available?</h3>
The most popular formats are:
<ul>
<li>Harlowe
<ul><li><a target="_blank" href="https://twine2.neocities.org/">Harlowe docs</a></li></ul>\
</li>\
<li>Sugarcube
<ul><li><a target="_blank" href="https://www.motoslave.net/sugarcube/2/docs/">Sugarcube docs</a></li></ul>\
</li>
<li>Snowman<ul><li><a target="_blank" href="https://videlais.github.io/snowman/">Snowman docs</a></li></ul></li>\
<li>Chapbook\
<ul><li><a target="_blank" href="https://klembot.github.io/chapbook/guide/en/">Chapbook docs</a></li> </ul>\
</li>
</ul>
See <a target="_blank" href="https://twinery.org/cookbook/starting/twine2/storyformat.html">more information here</a> about choosing between the formats.
<<linkappend "My advice...?">>\
<span class="intro-container">
<h1 class="intro-text">Sugarcube is the best and every other format sucks.</h1>
</span>\
And one of the reasons is ''Sugarcube'' has the [[best macros...|macros]]<<footnote>>Every piece of code I provide, assume I'm talking about Sugarcube ¯\_(ツ)_/<</footnote>>
<<if hasVisited("custom macros")>>[[Okay, so what do all these macros and story formats amount to...?->What is so great about Twine]]<</if>>
<</linkappend>>
<h3>What is so great about Twine?</h3>
Twine has LOTS of benefits!!!
It's <<linkappend "extensible...">> <<linkappend "accessible...">> and <<linkappend "open source! :)">>
Everything about Twine is free and open source -- the Twine app, the Story Formats, the macros, even the Twine games themselves!
The Twine community prizes innovation, as well as supporting fellow developers by sharing code and providing technical support.<<footnote "Pssst!">>Check out <a href="https://intfiction.org/c/authoring/twine/46" target="_blank">theintfiction forum</a> or the <a href="https://www.reddit.com/r/twinegames/" target="_blank">Twine Reddit</a> if you ever need help!<</footnote>>
[[But surely it can't be that good...?|What is kinda bad about Twine]]
<</linkappend>><</linkappend>><</linkappend>><h3>What's the catch...?</h3>
Twine has LOTS of drawbacks!!!
It's <<linkappend "extensible...">> <<linkappend "accessible...">> and <<linkappend "open source...?">>
No, the open source is a good thing! ¯\_(ツ)_/¯
The ''flipside'' of Twine's accessibility and extensibility is that...
To be //accessible//, it can't get too complex.
And so, to make up for that, it's //extensible// -- but when it's extensible, it doesn't feel the need to provide [[everything a game developer might want.]]<</linkappend>><</linkappend>><</linkappend>>
<h3>My Footnote Macro</h3>
The code in my script passage:
<pre><nowiki>Macro.add("footnote", {
skipArgs : false,
tags : null,
handler: function() {
// Throw error for incorrect num arguments
if (this.args.length > 1) {
return this.error("footnote macro takes 0-1 arguments");
}
var footnoteHint;
// If an argument is provided, use that as the footnote hint
// otherwise, use footnote count
if (this.args.length > 0 && this.args[0]) {
footnoteHint = this.args[0];
} else {
// Store this passage's footnote count in Sugarcube's temporary variable store
const tvars = State.temporary;
if (tvars.numFootnote === undefined) {
tvars.numFootnote = 0;
}
tvars.numFootnote += 1;
footnoteHint = tvars.numFootnote;
}
// Add footnote tooltip + tooltip text
$(this.output).wiki('<div class="footnote"><sup class="footnote-hover">[' + footnoteHint + ']</sup><div class="footnote-text">' + this.payload[0].contents + '</div></div>');
}
});
</nowiki></pre>
Note: This way of adding macros is particular to [[story formats|Story Formats]] -- I am basing everything in this Twine off the ''Sugarcube'' Story Format.
And how it's used in my passage:\
<pre><nowiki>My text. <<footnote "Footnote Hint">>The text that appears in the footnote.<</footnote>></nowiki></pre>\
Displays as: My text.<<footnote "Footnote Hint">>The text that appears in the footnote.<</footnote>>
<<if hasVisited("multiple story formats available")>>
[[So what do all these macros and story formats amount to...?|What is so great about Twine]]
<</if>>Twine doesn't natively provide support for...
<ul>
<li>inventories</li>
<li>keyboard commands</li>
<li>complex UIs/styling</li>
<li>combat systems</li>
<li>turn-based dialogue (VN-style)</li>
<li>anything other than simple animations</li>
<li>localization</li>
</ul>\
You want any of that?
<h2>Gotta roll your own! ¯\_(ツ)_/¯</h2>\
Complex games //can// be developed in Twine... it's just a bit of headache :(
[[But don't let that scare you...]]Some absolutely wonderful games have been developed with Twine! <<linkappend "Some of my faves?">> rat chaos, Ultra Business Tycoon III, do (not) forget, Birdland, King of Bees in Fantasy Land.... find more at <a href="https://ifdb.org/search?searchfor=system:Twine" target="_blank">ifdb.org.</a><</linkappend>>
<span class="intro-container">
<h1 class="intro-text">And you can develop your own game, too!</h1>
</span> \
Download the app! Read the cookbook! Read the docs!
[[Make your game ;)]]<h3>Once you're done</h3>
Feel free to host on <<linkappend "itch.io">>--by far the most popular for free Twine hosting!--<</linkappend>> or Neocities.
There are various competitions<<footnote>>Some with very nice prizes 👀👀<</footnote>> you can enter your game into. These are held yearly by the interactive fiction community and are ''always'' free to enter.
<h2>IF Comp</h2>
<ul><li>By far the biggest. For games below 2 hours. Held in September every year. <a href="https://ifcomp.org/" target="_blank">Link</a></li></ul>
<h2>Spring Thing</h2>
<ul><li>Second biggest usually. For longer games. Held in Apirl/May every year. <a href="https://www.springthing.net/" target="_blank">Link</a></li></ul>
<h2>IntroComp</h2>
<ul><li>For works in progress. Held in the fall. <a href="https://introcomp.org/" target="_blank">Link</a></li></ul>
<h2>EctoComp</h2>
<ul><li>For spooky games >:) Held during October. <a href="https://itch.io/jam/ectocomp-2025" target="_blank">Link</a></li></ul>
<h2>NeoTwinyJam</h2>
<ul><li>For Twines less than 300 words. <a href="https://itch.io/jam/neo-twiny-jam-26" target="_blank">Link</a></li></ul>
[[Okay I think that's all I got.]]<h1>Thanks for learning about Twine! 🥰</h1>
<<link "Restart">><<script>>Engine.restart()<</script>><</link>>
[[See a list of Twine resources.|Resources]]
[[Twine Macro Code Samples]]
[[Twine Resources|Resources]]<h3>Macro Samples</h3>
[[Character Creation]]<h3>Simple Character Creator in Twine</h3>
All these code examples use what is called //TwineScript// -- basically a name for the markup/macro language below.
In my StoryInit passage<<footnote "What's StoryInit?">>The StoryInit is a specially named passage that contains macro code that is supposed to be run when the story is started. Here is a good place to initialize all your variables.<</footnote>>\
<details>\
<summary>Inside StoryInit</summary>\
<pre><nowiki>/* Variables so the user can randomize their traits */
/* First and last names */
<<set $firstNames to ["Charity", "Benji", "Beatrix", "Enid", "Bonnie", Mellisandre", "Seraphina","Maria"]>>
<<set $lastNames to ["Midwinter","Moonshadow", "Blackwood", "Featherstone", "Lightmoon", "Nightwing", "Sovendark"]>>
/* Physical traits */
<<set $hairColors to ["white", "red", "black", "brown", "blonde", "dark brown", "dirty blonde", "mousy", "raven", "light brown", "auburn", "tawny", "inky", "blue black", "silver", "ash brown", "corn yellow", "chestnut", "jet black", "alabaster", "copper", "strawberry blonde", "umber", "salt and pepper"]>>
<<set $eyeColors to ["blue", "brown", "black", "green", "gray", "hazel", "obsidian", "aquamarine", "topaz", "charcoal","emerald", "sky blue", "sapphire", "slate", "amber", "chocolate", "jade", "mud brown", "indigo", "cornflower blue", "coal black", "bottle green", "amethyst"]>>
/* Story traits */
<<set $pronouns to ["He/him", "She/her", "They/them"]>>
<<set $traits to ["Light-footed","Deft-handed","High-minded","Big-hearted">>
/* Set traits to random for the first time the user opens the character creator */
<<widget "randomizeCharacter">>
<<set $firstName to $firstNames.random()>>
<<set $lastName to $lastNames.random()>>
<<set $hairColor to $hairColors.random()>>
<<set $eyeColor to $eyeColors.random()>>
<<set $pronoun to $pronouns.random()>>
<</widget>>
/* Call widget at first to set traits to random */
<<randomizeCharacter>></nowiki></pre>
</details>\
<details><summary>Inside my widget passage</summary><pre><nowiki><<widget "traitSelector">>
<<if _args[0]>>
/* Set selected class if this is the current trait */
<<if _args[0] is $trait>>
<<set _selectedClass to "trait-container-" + _name.toLowerCase() + "-selected">>
<<else>>
<<set _selectedClass to "trait-container-unselected">>
<</if>>
/* Actually display the trait */
<span @class="'trait-container trait-container-' + _args[0].toLowerCase() + ' ' + _selectedClass">\
<<set _traitImgPath to setup.ImagePath + _args[0] + "_decal.webp">>\
<span class="trait-image">\
<<link [img[_traitImgPath]]>>\
<<set $trait to _args[0]>>
/* Can't do redo macro here as it resets scroll position -- so toggle classes manually */
<<setSelectedTrait _args[0]>>
<</link>>\
</span>\
<<print _args[0]>>\
</span>\
<<else>>
No trait provided!
<</if>>
<</widget>>
<<widget "setSelectedTrait">>
<<if _args[0]>>
/* Iterate through all the trait decals and remove/add the appropriate classes to indicate which trait has been selected */
<<for _i, _name range $traits>>
<<set _currentTraitContainerClass to ".trait-container-" + _name.toLowerCase()>>
<<set _currentTraitSelectedClass to "trait-container-" + _name.toLowerCase() + "-selected">>
/* Add selected class if this is the trait we are selecting */
<<if _name.toLowerCase() is _args[0].toLowerCase()>>
<<addclass _currentTraitContainerClass _currentSelectedClass>>
<<removeclass _currentTraitContainerClass "trait-container-unselected">>
<<else>>
<<addclass _currentTraitContainerClass "trait-container-unselected">>
<<removeclass _currentTraitContainerClass _currentTraitSelectedClass>>
<</if>>
<</for>>
/* Rerender trait name */
<<redo "traitName">>
<</if>>
<</widget>>
</nowiki></pre>
</details><details>\
<summary>Inside my Character Creation passage (the character creater)</summary>\
<pre><nowiki><<nobr>><<button "Randomize Character">>
<<randomizeCharacter>>
<<redo>>
<</button>><</nobr>>
<<do>>\
<h1>Your Character</h1>
First Name: <<textbox "$firstName" $firstName autofocus>> Last Name: <<textbox "$lastName" $lastName>>
Pronouns: <<listbox "$pronoun" autoselect>> <<optionsfrom $pronouns>> <</listbox>>
Hair Color: <<listbox "$hairColor" autoselect>> <<optionsfrom $hairColors>> <</listbox>> Eye Color: <<listbox "$eyeColor" autoselect>> <<optionsfrom $eyeColors>> <</listbox>>
<h1>Your Background</h1>
Your Trait (gives bonuses to actions based on what you select): <<do tag "traitName">> <<print $trait>><</do>>
<<nobr>>
<div class="traits-container">
<<for _i, _name range $traits>>
<<traitSelector _name>>
<</for>>
</div>
<</nobr>>
<</do>></nowiki></pre></details>
[[See it in action...|Character Creator Example]]<<button "Randomize Character">>
<<randomizeCharacter>>
<<redo>>
<</button>>
\
<<do>>\
\
<h1>Your Character</h1>
First Name: <<textbox "$firstName" $firstName autofocus>> Last Name: <<textbox "$lastName" $lastName>>
Pronouns: <<listbox "$pronoun" autoselect>> <<optionsfrom $pronouns>> <</listbox>>
Hair Color: <<listbox "$hairColor" autoselect>> <<optionsfrom $hairColors>> <</listbox>> Eye Color: <<listbox "$eyeColor" autoselect>> <<optionsfrom $eyeColors>> <</listbox>>
<h1>Your Background</h1>
Your Trait (gives bonuses to actions based on what you select): <<do tag "traitName">> <<print $trait>><</do>>
<<nobr>>
<div class="traits-container">
<<for _i, _name range $traits>>
<<traitSelector _name>>
<</for>>
</div>
<</nobr>>
<</do>>