HTML Tutorial Html games with Twine, Sugarcube, and other arcanities.

Purple Nurple08

New Member
May 17, 2024
10
8
Preamble : what is a twine?

I'm not going to pretend that I have extensive knowledge of twine or web development. What I do have knowledge of is how to use both of them, in the albeit narrow way that I do. But More important than that, if you want to make an html game you are most likely to be planning on using twine. A game engine focusing on passage based text games. But what exactly is html? why is it browser based? What are the differences between the Harlowe format and Sugarcube format? What is a format? What did I have for breakfast? These are all very important questions. I won't be answering all of them. Because this is a preamble.

So lets start out with what I am going to be doing in this preamble. The truth of the matter is that twine is a relatively beginner friendly tool, but it's basis is in 3 languages of which upon the entire web is based on. This is the core of what this preamble will be about, but it's not meant to be exhaustive, and in the end, it may not even be relevant. But it is, nonetheless important.

browser based : why html?

The modern internet is quite the spectacle, and it's been in the works for some time now. It's grown and evolved and it's all made possible by modern browsers and evolving languages and developer tools. What twine does, is it takes advantage of this relatively rich developer space and these powerful if archaic tools to form a game engine. The reason then that html games are in browser games is because they need the browser to interpret them. You see, websites are comprised of a few different parts or languages. The most fundamental being Html, which stands for hyper text markup language. The most important of this is the mark up part.

You see, you and I, both being very human, intuitively understand things like where a paragraph begins and ends, or that something that looks like a button is a button. However computers do not have this luxury. And so Html is actually relatively simple, it's purpose is to simply mark up what an element in a webpage is. This definitely has more complexities to it, but Html is the bare bones of a website. And Twine being based around web development tools, uses html. In fact your game is packaged into a html file, that is then opened, read, and interpreted by your browser. Some things that I think are important to note is that this is how most web sites work, in fact if you right click on a website and go to the inspect option, you will be able to see a list of html elements (divs, headers, spans) that the site is compromised of, this is it's html and it's how browsers know how to interpret and display a web page. This is also where Html games get their name.

Css : The s stands for style

So Html is the barebones of a website, it defines the content if you will. But how do we make a website, or our game look fabulous? Actually how do we make a website look like anything at all? For example, links are blue, what if we want them to not be blue? Well, enter the world of Css.

Css stands for cascading style sheet. There are a few important things to note. One, these style sheets can be interchanged. Two, they work off the basis of Html. So to explain, in order to make a link in the first place, we have to define a link element using Html, but then Css can 'hook' onto this Html element, and define rules for how this link should appear in browser. And so if you want to change how something in your story looks, you may have to delve into Css, but also the appearance of your game is defined by Css. Some Twine formats can come with their own stylesheet, or if they have shortcuts to change how something looks it's most likely using Css. This may be important to know for troubleshooting or if you want more control over your game, alternatively, I think it's just decent offhand knowledge to be aware of.

Javascript: Oh Javascript.

Javascript is the scripting language of the web. What this means is that Javascript does stuff. For example let's say we have a button element. We define it with Html, it is now a button, then we style it with Css, it's now a stylish button, but... how does it do stuff? Well the short answer is Javascript. There's a lot to say about Javascript, but it's very expansive and it does a lot of things. And it also does most of the things. If you want to change the color of a Html element when a button is clicked, Javascript. if you want to delete the entire webpage if you hover over an element, Javascript. It allows you to do things. all of the things. But, this actually brings us to story formats. Because you see, Javascript works quite intimately with the other components or languages of a web page. So for example, if you wanted a button to change the color of another element (warning technobabble). you would have to assign the button to a Javascript object, use the add listener function, define what type of event is being listened to for the first argument, then define a function as the second argument. this function would then have to get the element you are targeting by using the relevant function to look up the DOM for the element in question, if you're looking up by class you'll have to define which one in the array it returns is the element you want to use, after you've defined the element to a Javascript object you need to set the style property to the relevant Css rule you want to enforce. This... may not be beginner friendly. So enter story formats.

The most popular being Sugarcube, it's also the format that any future guides will most likely be based around. Basically Sugarcube and other formats are Twine specific languages that are built in Javascript but attempt to make it easier to use. This can be very helpful as it eliminates most of the need to intimately learn all three languages.

However there is something important to know about these formats. They're built in Javascript. This means even when you use them, they are, in essence, translating what you say into Javascript. Since Javascript is the scripting language of the web, when you are making scripts for your game, it all comes back to Javascript for the most part. This also means that you can actually have access to some rather advanced stuff if you're willing to tinker with Javascript. At least if you use a format that allows such things like Sugarcube does. But what this also means, is that your essentially using a language, based in another language, and using it to interact with other languages like Css or Html, and Javascript isn't really the most reliable thing in the first place. It's probably fine if you aren't doing anything crazy, But hopefully part of the helpfulness of this preamble is to have an awareness of the ecosystem you're actually in, and what to google if you run into problems.

overview:

The point of this is to serve as an introduction. Not a particularly good one, or a particularly comprehensive one, but a preamble to one. When it comes to Twine I think it's important to at least have an awareness of it's constituent parts, even if realistically you may not interact heavily with them. It's also aimed at beginners, not in that it's particularly useful or beginner friendly, but just in that this stuff exists, and is a part of what it means to make a html game. Twine and it's formats does a good job at simplifying web development tools into a useable engine to make games with. But these are the tools that it's built upon.

This preamble is purposefully a bit overwhelming, because I think it's useful to know about these different components beforehand, but you don't have to fully understand everything I've said, and a lot of it isn't immediately applicable. It's supposed to be a lot of nonsense that comes together more as you go along in your game making journey. If or when you run into issues, it's supposed to be a resource that you can think back on and go "Oh, maybe this has to do with Css?", and hopefully help with understanding the root cause of some oddities you may run into, or a unique solution to a problem.

I do hope to make more sections to this guide, and when I do, they will most likely be more focused on individual aspects or problems, and also be more limited and less confusing.
 
Last edited:

Purple Nurple08

New Member
May 17, 2024
10
8
Which format should you use? And why is it sugarcube?

The format that you choose to use will impact the way that you script your game, I've used harlowe briefly but moved over to sugarcube, I've never used snowman. I believe there may be a few other formats but these seem to be the big three. So, let's talk about them.

Harlowe

Harlowe is a relatively beginner friendly language, as I recall it's the default one, and it has an inbuilt documentation browser, if you use the default desktop twine editor. Because of this I would say it's decently easy to pick up, and it should be quite useful for basic scripting or simple games.

The reasons that I have for not recommending it however, are that it's quite locked in. Since it is a twine format, it is built in and operates on javascript, however it doesn't allow you to directly access javascript, and is rather removed from some of the other web development paradigms as well. I know that the reason I switched over was because I could not access css functionality.

Now, that was a while ago, it could be user error on my part, and I'm admittedly not the most familiar with harlowe, but my impression is that it's a walled garden of sorts, it doesn't like you going out of that garden, and there's a lot that you are potentially walled off from.

Snowman

I have absolutely no experience with snowman. It seems to run on a more javascript heavy paradigm, I would say that this probably isn't the best for beginners, I would also say that it seems relatively niche, it's probably going to be the most difficult to get support for. But as I said, I'm not super familiar.

The reasons I'd have for not recommending snowman is that, well, I've never used it. And you'd probably have to be a pretty experienced javascript dev in the first place to pick it up, so I think it's probably the least relevant of the three.

Sugarcube

Sugarcube strikes a good balance between ease of use, and offering advanced functionality. It works by providing macros, for things like setting variables, or more tricky things like replacing the content of a html element. or creating a button. It has good documentation, although you have to go to an external site to read it, and an ability to directly tie into the web dev ecosystem.

For example, you can run most javascript directly through the run or set macro. There's even a script macro for running pure javascript. It also pretty directly uses javascript variables, so you can call prototypical functions like splice, push, or sort on an array, or use datatypes like arrays and objects.

So it offers the ease of use with ready made macros to smooth over the trickier parts of javascript, and the ability to basically straight up use javascript if necessary.

overall it's a decent pick, and it's what I would recommend going with.

Overall

There are reasons to use any of the three languages, and only you can know which one is right for you and your game. However in my opinion sugarcube is the most versatile and reasonable format to choose. It's also the format that I'll be basing my guides off of, and it's what I use.
 

Purple Nurple08

New Member
May 17, 2024
10
8
Passage navigation :

The way twine works in general is that the player navigates from one passage to another, so one of the very most basic parts of creating a twine game is moving from one passage to another. In this post I'm going to be going over the different ways to travel between passages, as well as some of the difficulties, or ways in which it's ideal to use this passage style of mechanic.

Basic :

each passage should have it's own name, one of the simplest ways to navigate passages is to link to another passage with a button, or link utilizing this passage name.

So let's look at the button and link macros from sugarcube.

<<button/link "name that shows up" "passage name" >> code to be executed on button or link press <</ button/link>>

Because button and link macros are relatively interchangeable, I've made one example for both, in real use you would use either <<button>> or <<link>> and it's related closing tag. <</button>> <</link>>. The choice of which to use would most likely be largely cosmetic.

An important part to address before going further is that the passage you are linking to should exist, otherwise you may run into issues.

So now, there are a few things to address, the first being that you may want to visit the sugarcube if you want a more in depth understanding of the macros. But for now it may be sufficient to say that in the head of the macro is where it accepts two strings, the first one being what text shows up in the link or button, and the second one being the name of what passage you wish to travel to when the element is clicked upon.

Intermediate :

There's a number of things that you can use when you go to another passage, and also a number of things that can go wrong or be strange.

You see, when you arrive on a passage is when any code or text or really any content is processed on that passage. So in essence when you change passages is when your code is ran, this also means that when you arrive on a passage for a second time it will rerun the code on the passage. There is also a history system by default. All of these things can impact how, when and why your code is ran.

when you arrive on a new passage, it needs to render the passage, in other words it needs to look at the passage and determine what's on it. This is how you are able to interject html into a passage, as well as how the sugarcube code, or other formats are read, and processed into working javascript code, as well as how it knows to hide the formatted code to present a clean passage for the player, and so on.

because of this rendering process things may not work as intended, especially when using sugarcube with an interjected html element. If you've ran into an error where sugarcube doesn't recognize the existence of a html element on the passage, this is because the code is being ran while the page is being rendered, and thus it may not have resolved the html. This can resolved easily with the <<done>> <</done>> macro, that waits until the page has rendered to execute it's contents. There are a number of handy macros similar to this that can help if you understand the unique problems that you are facing, and it may be worth looking through the documentation if you find yourself stuck.

Another more niche issue is variable copying. I presume because of the history feature, when you move from one passage to another, your story variables are copied. At least that's my understanding. Because of this, if you set one, lets say object, variable to another (assign by reference) and then change passages, it may be referencing a totally different variable or some other such nonsense. This is probably quite an advanced issue, however never the less, the way in which passage navigation is done has the potential to cause some opaque problems, so I added this opaque explanation.

Advanced :

I don't have a whole lot to add here, There's basically only one thing I have to say. if you want to change passages with javascript, the solution is to run Engine.play("passage name"); This is useful if you want to make your own buttons or some such, as well as being able to change passages more at will. You can also do this through sugarcube. <<run Engine.play("passage name")>>
 

Satori6

Game Developer
Aug 29, 2023
448
851
An important part to address before going further is that the passage you are linking to should exist, otherwise you may run into issues.
Twine automatically creates the passage when you type its name on a link using SugarCube's markup.

This means that if you type <<link[[Text|Some Passage]]>>, it will automatically create "Some Passage".

this also means that when you arrive on a passage for a second time it will rerun the code on the passage.
May be worth including that there are was to avoid that. eg; hasVisited()

The "advanced" section should also include mentions of Config.navigation.override
 
  • Like
Reactions: Purple Nurple08