Close Menu
Metacognitive

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    What's Hot

    Why Self-Awareness Is a Core Pillar in Modern Drug Rehabilitation Clinics?

    May 2, 2025

    The Role Of Javascript In Enhancing The Online Shopping Experience For NFL Jerseys

    February 25, 2025

    Proven Tips To Create Customer Loyalty While Launching Your New Business

    January 27, 2025
    Facebook X (Twitter) Instagram
    Metacognitive
    • Summary
    • Programming
    • JavaScript
    • Productivity
    • Thoughts
    Facebook X (Twitter) Instagram
    Metacognitive
    Home»Metacognitive»How to create a story game with Javascript
    Metacognitive

    How to create a story game with Javascript

    By Jonathan ReynoldsOctober 27, 20228 Mins Read
    Facebook Twitter Pinterest LinkedIn Tumblr Email
    Share
    Facebook Twitter LinkedIn Pinterest Email

    Creating an interactive fiction or a text-adventure game using Twine and sometimes Javascript.

    If you don’t know Javascript or what that is, don’t worry! You’ll be able to learn along the way or even go without it at all. What we are going to explore is an open-source tool to build interactive stories – Twine (or see its website).

    It allows us to make nonlinear stories. It can be presentations, fiction, or text-adventure games. In a nutshell, Twine creates an HTML file with all the content. So, it looks like a usual web page, and the tool is the constructor. You can upload such a “website” on the web or mobile platforms, i.e., anywhere that can parse HTML.

    An example of a non-linear story (interactive fiction)

    If you’re particularly interested in games / interactive fiction, see an extensive collection of them. So what sort of games are possible? All of them since we can add Javascript. However, the easiest way is to do text-adventure games. Why? You don’t need to program anything or much. You add stories and connect them in a meaningful way using links. I.e., if you choose “A”, the story “AA” will be shown, if you choose “B”, the story “BB” will be shown.

    See also what you can create with the tool from their docs.

    Creating such a page takes a few minutes on the Twine website(you can do that online). You can add Javascript, videos, music, images, customize styles via CSS and do the linking and playing around. It’s a great way to start. Next, I will show you a different approach if you’re used to coding in any developer’s editor and want version control.

    Try online first, especially if your story/game is small and only needs a little custom functionality.

    Why you may need Javascript

    You can go without it and feel fine. But if you have custom stuff, you’ll use some macros and scripts. What are they? Imagine Twine as a core, but it has various engines that do things differently. It supports four such engines(story formats) to make the creation process more accessible. Each of them varies in complexity. In this article, I’ll be using SugarCube.

    This story format has many built-in things you may need. For example:

    1. Saving a game, resuming it from a save.
    2. Various events to react to. E.g., when a story is rendered, started rendering, etc.
    3. Macros, i.e., useful built-in blocks/functions. For example, buttons, custom links, conditional rendering, setting variables, DOM manipulations, etc.
    4. Audio handling.
    5. And many other valuable things.

    A Twine project in a developer way

    Let’s create a simple project where we want to use custom Javascript and CSS styles, but more importantly – we want to have version control! I don’t use the tool’s online or desktop version because I can only manage stories as files and have their versions by commit.

    You’ll need to install Tweego, a tool that can parse stories as files in any preferred text editor. Be aware of its limitations, though:

    1. When writing this article, the last update of Tweego was two years ago.
    2. Thus, you may not have all of the features from the supported story formats(e.g., Sugarcube).

    Now you need to create a project folder:

    $ mkdir twine-project
    $ cd twine-project
    $ git init

    You can move the Tweego executable to this folder as well and add it to .gitignore

    It’s up to you how to organize files now! An example structure may look like the following:

    .gitignore
    README.md
    bin/
    src/
    ├─ config.tw
    ├─ styles/
    │  ├─ menu.css
    │  ├─ main.css
    ├─ modules/
    │  ├─ menu/
    │  │  ├─ menu.tw
    │  │  ├─ menu.js
    

    In the bin folder you have the Tweego executable to build the output to HTML(we’ll get to that). All the story(game)-related code is under src folder. Tweego will put all Twine(`.tw`) files, CSS styles, Javascript scripts into one HTML. Therefore, it doesn’t matter what project structure you have.

    Twine format

    Now, closer to the coding: what is config.tw? This is where your code will be in Twine format. Take a look at the specification. You may name this file whatever you want. It’s named config for readability. There, we specify the settings for our game:

    :: StoryTitle
    My first game
    
    :: StoryData
    {
    	"ifid": <a serial number of your game>,
    	"format": "SugarCube",
    	"format-version": "2.30.0",
    	"start": <a name of the story that will be shown first>
    }
    
    :: StoryAuthor
    <your name if you want>
    
    
    <<script>>
    // in case you'll need to have 3rd-party scripts
    // remove this <<script>> section at all for now
    importScripts(
    	'https://cdn.jsdelivr.net/npm/chance'
    )
    <</script>>

    You need to generate a serial number for your game, i.e., IFID. Read more about how to do that here. But for now, you can use 0000A000-A0E0-00C0-00B0-CF000E000D0E to skip this boring step.

    format tells Tweego which story format to use. We’ll use SugarCube. format-version is a version for this story format, currently supported is 2.30.0 only. However, there are newer versions(a limitation of Tweego).

    start is a story that will be shown first. Let’s create a file start.tw with this content:

    :: StartOfMyGame
    
    This is the first screen of my game, yay!
    
    [[Start playing]]
    [[Read about the author]]
    

    The :: here indicates the ID of your passage(i.e., a page). It can be anything, e.g., :: start-of-my-game or :: something like this. Now that you have the ID, change your config.tw to have:

    "start": "StartOfMyGame"

    After the passage(page) ID, you do whatever you want. In our case, we wrote, “This is the first screen of my game, yay!”, and it’ll be rendered as regular text, that’s it! The [[Start playing]] thing is a link to another passage(page).

    To build that to HTML, run Tweego(it’ll be watching for files changes):

    $ ./bin/tweego -w src -o ./output/index.html

    Here, we’re telling it to watch the src folder and build an output HTML into the output folder as index.html. Run this command, and you’ll see the HTML output in that folder. Don’t forget to add output to .gitignore. Open output/index.html in a browser and you’ll see something like this(with a more dark background color):

    We create the links, but we also need to create such pages. So, we need to change the start.tw:

    :: StartOfMyGame
    
    This is the first screen of my game, yay!
    
    [[Start playing]]
    [[Read about the author]]
    
    :: Start playing
    <<back>>
    It's another page called "Start playing".
    
    :: Read about the author
    <<back>>
    I'm the author. This is my page.

    We’ve added two more pages, so whenever you click on, for example, “Start playing”, you’ll be redirected to the “Start playing” passage:

    We see a new link here – “Back”! <<back>> is a SugarCube macro that redirects a user to the previous passage(`StartOfMyGame`). It’s a more convenient way of doing that than storing a navigation history each time.

    We might create these two new passages in the other files or create all the game passages in one file. It doesn’t matter because Tweego puts all of the files together into a single HTML file. You don’t need to care about importing something!

    Adding Javascript to Twine stories

    Let’s imagine we want to store some information about a player’s choices. There are two approaches:

    1. We may use the <<set>> macro.
    2. We may use Javascript.

    When using <<set>>:

    :: StartOfMyGame
    
    This is the first screen of my game, yay!
    
    <<link "Start playing" "StartPlaying">>
    	<<set $choice to "StartPlaying">>
    <</link>>
    <<link "Read about the author" "AboutTheAuthor">>
    	<<set $choice to "AboutTheAuthor">>
    <</link>>
    
    :: StartPlaying
    <<back>>
    It's another page called "Start playing".
    The choice is <<= $choice>>
    
    :: AboutTheAuthor
    <<back>>
    I'm the author. This is my page.
    The choice is <<= $choice>>

    A few new things here:

    1. <<link>> macro does the same as [[ ]], but it adds more customizability. In our case, we kept the link text, but indicated a different passage ID(`StartPlaying`, e.g.). Also, we can do something when a link is pressed, e.g., a <<set>> instruction below.
    2. <<set>> macro stores a variable.
    3. <<= $choice>> is a macro to evaluate expressions. In our case, it’s displaying $choice variable we set before.

    We can achieve the same using Javascript(however, it seems unnecessary complicated in this example):

    :: StartOfMyGame
    
    This is the first screen of my game, yay!
    
    <<link "Start playing" "StartPlaying">>
    	<<script>>
    		State.setVar('$choice', 'StartPlaying (Javascript)')
    	<</script>>
    <</link>>
    
    
    :: StartPlaying
    <<back>>
    It's another page called "Start playing".
    The choice is <<= $choice>>

    I removed the second passage to not duplicate the code. Here are a few new things:

    1. We still do the scripting inside <<link>> macro. But we use <<script>> macro now. Inside of it, we use a global object State‘s method setVar which does the same as <<set>> in the previous example.
    2. We still display the $choice variable not using Javascript, but we could find that HTML block using jQuery(which is built-in in SugarCube scripts), and then set the value of it to $choice, but it’s unnecessary.

    When you use Javascript, you have access to the story format’s APIs, so it’s more customizability. However, you may not encounter such complexity in your game.


    That’s it for now! There are more things to do in a game, of course. But you have the documentation and tools to discover and learn more independently.

    Jonathan Reynolds

    Jonathan Reynolds is a seasoned mining industry expert with over 15 years of experience in mineral exploration, project management, and strategic development. As a lead content strategist at Kingsrose Mining, he shares insights on sustainable mining practices, investment opportunities, and the future of the industry. Jonathan holds a Master’s degree in Geology from the University of Colorado and has worked on mining projects across North America, Europe, and Asia.

    PROGRAMMING
    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Jonathan Reynolds
    • Website

    Jonathan Reynolds is a seasoned mining industry expert with over 15 years of experience in mineral exploration, project management, and strategic development. As a lead content strategist at Kingsrose Mining, he shares insights on sustainable mining practices, investment opportunities, and the future of the industry. Jonathan holds a Master’s degree in Geology from the University of Colorado and has worked on mining projects across North America, Europe, and Asia.

    Related Posts

    Why Self-Awareness Is a Core Pillar in Modern Drug Rehabilitation Clinics?

    May 2, 2025

    AI sets new limits for humanity

    May 3, 2023

    Next.js vs. React: what should you use?

    October 25, 2022
    Leave A Reply Cancel Reply

    Recent Posts

    • Why Self-Awareness Is a Core Pillar in Modern Drug Rehabilitation Clinics?
    • The Role Of Javascript In Enhancing The Online Shopping Experience For NFL Jerseys
    • Proven Tips To Create Customer Loyalty While Launching Your New Business
    • AI sets new limits for humanity
    • How to create a story game with Javascript

    Recent Comments

    No comments to show.

    Archives

    • May 2025
    • February 2025
    • January 2025
    • May 2023
    • October 2022
    • September 2022
    • May 2022
    • March 2022
    • January 2022
    • November 2021
    • September 2021
    • August 2021
    • June 2021
    • March 2021
    • October 2020
    • January 2020

    Categories

    • Business
    • Lifestyle
    • Metacognitive
    Facebook X (Twitter) Instagram Pinterest
    © 2025 Copyright Reserved Metacognitive.

    Type above and press Enter to search. Press Esc to cancel.