0 votes
by (140 points)
So I'm new to Sugarcube 2 (I've used Sugarcube I for a while, though I'm in no way an expert.) I was able to load external or local Javascript files by using a simple <script src = > tag in Sugarcubes HTML. I don't believe this is good practice, but the thing is - the only reason I want to do this is because I find it extremely irritating organizing my code within the Twine interface. I use Notepad++, and I really just cant go without it. Yes I could simply copy and paste, but it is so annoying to have to do that to check for every couple of lines of code.

So if there is a way to load these files, or otherwise bypass the Twine interface (just for Javascript) I would really, really like to know.

Side note: I have really bad OCD, and one of the things I do is seperate most of my code into different files, unrelated things go into one file and so on. A bit silly I know, but I just feel more comfortable that way. Anyway, thanks.

3 Answers

+1 vote
by (23.6k points)

If it's the interface that causes problems then maybe Twee would do the job.

+1 vote
by (159k points)

The Twine (1.x and 2.x) applications are just one way to generate a story HTML file, you can also generate them using a TWEE command line compiler (like TweeGo or Twee2) and your favorite Text Editor.

TweeGo allows you to automatically embed the contents of your external JavaScript and CSS in the generated HTML file as long as such extenal files are stored relative to the correctly.

eg. With a folder & file structure something like the following:


... you could use a command line statement like the following in the c:\my-project folder to generate a story.html (within the same folder) that contains all the Passages from the TW file as well as the JavaScript & CSS from the JS & CSS files.

tweego -f sugarcube-2 -o story.html src


0 votes
by (44.7k points)

I used to use Notepad++ a lot myself, but I've mostly moved over to using Visual Studio Code for JavaScript now, since it has a bunch of extensions to help check JavaScript for bugs and such (if you're interested, I use the ESLint, DeepScan, JSHint, and Numbered Bookmarks extensions).

Anyways, to answer your question, here's how you can load external files and have them work in Twine 2.  First, put this code in your JavaScript section:

if (window.hasOwnProperty("storyFormat")) {
	// Change this to the path where your HTML file is
	// located if you want to run this from inside Twine.
	setup.Path = "C:/Games/MyGameDirectory/";  // Running inside Twine application
} else {
	setup.Path = "";  // Running in a browser
setup.JSLoaded = false;
importScripts(setup.Path + "YourExternalCode.js")
	.then(function() {
		setup.JSLoaded = true;
	}).catch(function(error) {
		alert("Error: Could not find file 'YourExternalCode.js'.");

Just change "C:/Games/MyGameDirectory/" to the directory where your HTML and JavaScript files are located, and change "YourExternalCode.js" to the name of the JavaScript file you want to access.  Then that code can detect whether you're playing through Twine or not, and set the file path appropriately before starting to load the JavaScript file.

It's important to note that the code doesn't get loaded immediately by importScripts(), so you can check the value of "setup.JSLoaded" (set in the above code) to tell if it has loaded properly yet or not before executing any code which depends on that JavaScript.  For example:

var IntervalID = 0;
if (setup.JSLoaded) {
} else {
	IntervalID = setInterval(JSWait, 100);  // Starts waiting for external JavaScript to load.
function JSWait() {  // Checks to see if JavaScript has loaded yet.
	if (setup.JSLoaded) {
		clearInterval(IntervalID);  // Stop waiting
function SomeFunction() {
	// Your code that depends on the loaded JavaScript here.

That code checks to see if the external JavaScript has loaded yet or not, and if it hasn't, then it waits until it has before triggering the "SomeFunction()" function.

Also note that in your external files you'll need to put "SugarCube." in front of SugarCube functions and properties.  So if you had code that used "State.variables" to get SugarCube variables, then in the external JavaScript version you'd have to do "SugarCube.State.variables" instead.

Hope that helps!  :-)