How to publish your Twine game online
From the Story Map screen, choose "Publish to File" from the Build toolbar to turn your Twine 2 story into a single, self-contained HTML file. Twine has no built-in way to manage images or other media, so any pictures, audio or video your story links to have to be published alongside that HTML file in a folder you upload with it, referenced by relative path rather than embedded. Test the published file and its media folder together with a local web server, then zip both for upload.
Last checked
What you need
Twine 2, the current release being 2.12.0. Any Twine 2 version publishes a story the same way, so you don't need to be on the very latest release to follow this guide.
You'll also want:
- A finished story you've played through inside Twine, in whichever story format you wrote it in. Harlowe and SugarCube are the two most commonly used core formats, and both publish to a working HTML file the same way.
- Copies of any images, audio or video your passages link to, kept in a folder structure you control. Twine itself doesn't store or manage these files for you.
- A way to serve files over http:// for local testing, since a published story with linked media won't load its images correctly when opened as a bare local file.
Export for the web
- Open your story and go to its Story Map screen.
- From the Build toolbar tab, choose "Publish to File".
- Pick a file name and location to save the exported HTML file. This name is only for your own reference: it doesn't change the title players see when they open the story. If you want to change how the story appears when published, rename the story itself inside Twine before you publish, not the exported file.
- If your story links to images, audio or video, create a folder next to the published HTML file (for example
images/) and copy those media files into it, matching whatever relative paths your passages already use to refer to them.
That's the whole export step. Twine's own documentation is direct about why there isn't more to it: "Twine doesn't have facilities for managing images, sound, or video," so linking to files you host alongside the published HTML file is the expected workflow, not a workaround. The alternative, encoding media as base64 directly inside the story, is technically possible but Twine's documentation recommends against it because it's harder to work with and makes the published file much larger for no real benefit.
Test it locally
Opening the published HTML file straight from your file system will often play the story text fine but silently fail to load any linked images, since a file:// page can't reliably reach a relative path the way a served page can, and some browsers block it outright for local files.
Serve the HTML file and its media folder together from a one-line local server, for example running python3 -m http.server from the folder containing both the HTML file and your images/ folder, then opening http://localhost:8000 in your browser. Click through every passage that shows an image or plays audio to confirm the paths line up. This step is quick, but it's the only reliable way to catch a media folder that didn't come along for the ride, or a path typo that Twine has no way to warn you about since it never sees the files itself.
Zip it for upload
- Rename the published HTML file to
index.html. The name Twine gave it doesn't matter to the story itself, andindex.htmlis what most browser game hosts, including naughty.games, expect to find. - Zip
index.htmltogether with your media folder so thatindex.htmlsits at the top level of the archive, with folders likeimages/alongside it, not nested inside another folder. - Re-open the zip's contents once to double check the media folder structure inside the archive still matches the relative paths your passages use. A folder that got renamed or moved a level deep during zipping is a common way for images to break only after upload.
- naughty.games accepts builds up to 250 MB unpacked and 2,000 files. A text-only Twine story is tiny, but one built around a lot of full-size images or audio clips can add up; compressing images before you copy them into the media folder is the easiest way to stay well under the limit.
Common problems
The story text loads but every image is broken. The media folder either didn't get uploaded alongside the HTML file, or its folder name or internal structure doesn't match the relative paths your passages use. Compare the path in your passage text to where the file actually sits in the zip.
Everything worked when I tested locally by double-clicking the file, but broke after uploading. Text-only stories often survive being opened as a local file, which can hide a problem that only shows up once real hosting and relative paths are involved. Always test through a local server, not by opening the file directly, so you're testing the same thing your host will serve.
The published file is enormous. This usually means images were embedded as base64 data inside the story rather than linked as separate files. Twine's own documentation advises against base64 embedding for exactly this reason: it bloats the file and is harder to maintain. Switch to linking external image files in a media folder instead.
Twine says "Publish to File" isn't available, or nothing happens when I click it. Make sure you're on the Story Map screen for the specific story you want to publish, not the library view of all your stories. The Build toolbar tab and its "Publish to File" option apply to whichever story is currently open.
A macro or feature from one story format doesn't work after I switched formats. Harlowe and SugarCube have different macro syntax and built-in features, so a passage written for one won't necessarily run correctly in the other. Publishing itself isn't affected by story format, but the story's actual behavior is, so double check any format-specific macros after switching.
Save or variable state doesn't persist for returning players. Both Harlowe and SugarCube can save progress to the browser depending on how your story is written, but that storage is tied to the domain and browser a player used, so moving the game to a new host or a player clearing site data will reset it, same as any other browser game.
Publish it
Once your story and its media play correctly from a local server, it's ready to go on naughty.games. Zip index.html at the top level together with your media folder, up to 250 MB unpacked and 2,000 files, and upload it; review usually takes about 2 working days. Hosting is free and non-exclusive, so keeping the story listed on itch.io or elsewhere too is fine, there's no revenue share, and you keep 100% of whatever your own Patreon, SubscribeStar, Ko-fi, Steam or itch links earn. We pick which games to promote by hand, looking at average time played, how many players come back the next day, and how many play past the first minute.
Head to /submit when you're ready to upload.
Questions
- Which story format should I publish with, Harlowe or SugarCube?
- Either publishes to a working HTML file the same way. Harlowe is the default and simpler to start with; SugarCube has more built-in features but expects more scripting knowledge. Pick the one you wrote the story in.
- Can I just put my images inside the Twine file with base64?
- You can, but Twine's own documentation advises against it: base64 images are harder to work with and make the published file much larger. Linking to a media folder you upload alongside the HTML file is the recommended approach.
- Do I need to rename the published file to index.html?
- The file name you choose in Twine doesn't affect what players see in the story itself, so renaming the exported file to index.html before zipping is safe and is what most browser game hosts, including naughty.games, expect.
- Why do my images show up in Twine but not in the published file?
- Twine doesn't manage image files for you. If a passage links to an image by relative path, that image file has to be uploaded in the same folder structure alongside the published HTML file, or the browser has nothing to find.
- What Twine version should I use?
- The current stable release is Twine 2.12.0. Any Twine 2 release publishes stories the same way, through "Publish to File" on the Build toolbar.
Sources
Free hosting, real players on phone and desktop, and a stats console.