Squidge Inc Logo Squidge Inc Logo

End of 2020 and Merlin's Quest

Before I get into the details of my journey to creating a choose your own adventure experience in pure JavaScript, HTML and CSS - I will briefly talk about another post I considered doing, started working on, then scrapped - or you can skip ahead if you wish.

A COVID Christmas

Yes, sadly my household were all hit with the COVID-19 virus on Christmas Day. It unfortunately wrote off the whole festive period for us. What was an already quiet Christmas turned into something completely different, and really not the way we had wanted to see out 2020.

The phone text received for a positive test result, and the instructions to isolate, with further information and help links
I don't think anyone wants to see this text on their phone - but it breaks down a lot of complicated information, and provides help and support as well.

I also became more unwell about a week afterwards - so couldn’t see the New Year in, not that I care much for it usually, but seeing the back of 2020 was symbolic for a lot of people I think, including myself. Thankfully I’m fully recovered now, as are the rest of my family, but whilst in the midst of it all I did have an idea…

I started considering writing a post on the user experience of the testing, isolation, medical support and overall ‘management’ of being a family who tested positive for COVID. The drive-through testing experience prompted it, with my daughter showing the initial high temperature symptoms (that came back positive within 24 hours). But in all honesty - when it came to writing the words for the post, I found myself wanting to move past a time when I was scared, unwell for longer than I’d ever been, upset that I lost such valuable time with my family and frustrated to have lost the time to rest after a tough year.

I spoke to genuinely lovely people throughout those weeks - the NHS via the Test and Trace calls and via the amazing (and often taken for granted) free 111 service.

Were there some problems with how things were done - yes. Did it really matter in the overall scheme of things - no.

I spoke to genuinely lovely people throughout those weeks - the NHS via the Test and Trace calls and via the amazing (and often taken for granted) free 111 service. My wife and I did the postal tests to confirm we both had the virus - again, were there problems doing such a complex test ourselves - yes. Did it matter - no.

I’ve seen a lot of criticism of people throughout what are still unprecedented times - we may have reluctantly adjusted to restrictions in our day to day lives, but ultimately we’re all still figuring out how to handle and plan for a future that is changing almost daily.

I also want to focus my efforts on looking to a future where we can all be together again, and hopefully the testing, isolation and fear of the virus has faded away to something we may remember, but can happily choose to forget.

I realised quite quickly that going through all that we went through, talking about the good parts and shining a light on any problems, or things that could be done better, wasn’t really in the spirit of what those services are there for.

So many people are working so hard to keep us safe, to support us when we’re scared and unwell, and ultimately fighting to save the lives for those who were not as lucky as my family. I’d much rather say thank you to those people, and continue to follow the guidelines to protect anyone from going through what my family and I went through.

I also want to focus my efforts on looking to a future where we can all be together again, and hopefully the testing, isolation and fear of the virus has faded away to something we may remember, but can happily choose to forget.

A dinner plate with a Christmas dinner next to a cracker and Christmas napkin
Although we missed our December 25th Christmas dinner... we still had one, a month later :)

Choosing to Build an Adventure

So, with that out the way, lets move onto a project that has its roots way back in my early experiences of coding, and was prompted by a chance glance at one of my daughter’s comic books.

I think ‘choose your own adventure’ stories are remembered fondly by a certain age group. For me, being now in my 40’s (when did that happen?!), it’s actually linked to one of the first coding experiences I had at school. Typing in a set of commands and narrative snippets into a trusty Commodore 64 computer to allow the player (or, in reality, my friends next to me) to type answers to a series of questions, and drive them down a series of story paths.

I had choose your own adventure books too - where after reading a page a choice would have to be made that would take you off to different pages of the book.

Some more complex examples played with health points, others with randomised elements, even battle dynamics by throwing dice - but they ultimately all played the same - read a portion of text, then make a choice what to do next.

A screen from the Hobbit text adventure game, that shows a door, a chest and simple text description and response
The Hobbit text adventure game - it hasn't aged well, but it had a long, intricate story.

‘The Hobbit’ is remembered by many as one of the early, more complex, and successful choose your own adventure titles. There were the rather unnatural ‘Go East’ commands for traveling in certain directions, or the frustrations of trying to get the right phrase to progress the story (given the open-text response nature of the answer input) - but as an early form of computer-based adventure gaming, at the time, it was great! If you are curious, there is a fully playable browser version.

So, fast-forward to 2020, and I spy a page in my daughter’s latest issue of The Phoenix comic. And it’s a choose your own adventure story.

The Wonderful Mind of a Nine Year Old

The more I looked at the page in the comic, the more I saw the easy possibility of creating a similar interactive narrative that could work through a web interface. The story could be broken down into a series of ‘cards’ - and on each card you have an optional image, a segment of the story, and the path choices defined by a series of buttons that would link to the a follow-on story card.

A choose your own adventure in The Phoenix comic
Where the inspiration came from for our own adventure - from The Phoenix comic.

Despite having worked with a good friend on a real book - such a multi-threaded story seemed a bit daunting, and I didn’t have an idea where to start.

That’s where having a wonderfully creative 9 year old in your household, and many, many daily exercise walks in the sunshine of 2020’s first UK COVID lock-down really helps.

The more we talked, the more a story started to develop - you would be Merlin’s apprentice, and you’d be on a quest for 3 potion ingredients (yep, always the rule of 3 in games!). This worked well as I could put some nice conditional elements into the story that would ‘lock’ any paths you’d already gone down, and potentially ‘unlock’ others once you had all the ingredients.

I had grand plans to add an inventory, and even a health bar - but was reminded by a certain smaller person that that would distract from the story, and sounded a bit boring!

The Toffee Nosed Bat and Narrative Spaghetti

Having decided our first ingredient would be for the wing of a bat (all my daughter’s idea), we used this as our first test story-line. Having the quest broken down into potion-specific segments really helped, as I could release the quest for testing amongst friends and family members an ingredient at a time.

After setting-up the key mechanics of how the story cards would work, I could type the cards, one at a time, and effectively link them together, based on the options on each - creating the story-line. We were unlimited in our options… we just needed to plug the words in, and go…

A childs drawing of a large eyed, purple, bat
My daughter provided all of the lovely illustrations for the story

The Toffee Nosed Bat ingredient story was written with my daughter by my side, as I typed as fast as I could (often not fast enough) to start building the narrative paths to her specifications. Except I realised something rather quickly… it got complicated, very complicated, very fast.

Every branch that you create in the narrative opens up a path that can lead to more and more branches.

A linear story is very straight forward - you start at the start, and you end at the end. However, the power and creative potential you have with a multiple-choice story very quickly turns into a bit of a monster of spaghetti narrative threads.

Every branch that you create in the narrative opens up a path that can lead to more and more branches. You could spend a lot of time down one path, to realise that you have to track right back to the natural start of that path, and then do the same for every narrative permutation after that. It makes your brain hurt!

Detroit: Become Human - a game by Paris-based studio Quantic Dream, actually showed all of the narrative threads you’d seen after each chapter, and where there were more to explore. I thought this was a great insight into just how many outcomes you could get out of any given act in the game.

A graphic that shows the branching narrative 'nodes' of a complex branching story
The UI to show the unlocked and locked narrative paths in Detroit: Become Human was a mini-game in itself

But gaming companies - especially those who create complex conversational interactions - have tools that manage this spiders-web of narrative paths. I just had a massive text file, where I had to keep tabs of all of the various paths you could go down, in a linear format. So I quickly came to the decision that we’d have to ‘sort of fake’ the multi-threaded nature of the story.

Story Tokens

We always had it that you could choose to collect the potion ingredients in any order that you wished (which created its own issue if you found yourself wanting to refer to an earlier event the player may not have seen yet!). But we quickly decided that within each ingredient story, there would be one main narrative, and the paths you could take off this main narrative would end in an entertaining demise of your character, or carefully return (pretty quickly!) to the main story path - maybe revealing a little backstory, or more insight into a future scene or puzzle.

The player wouldn’t be punished for making a ‘wrong’ choice either - we realised that we could reward, and show ‘story tokens’ for visiting less obvious narrative choices, adding a bit of challenge to collect all of the story tokens… of which the story (at time of writing) has 76(!). We would always provide a link back up the narrative path to the point where they should have gone another way, as well.

A still from the original Secret of Monkey Island game, showing a town at night, with the player character and shifty looking town resident with a parrot on his shoulder
The Secret of Monkey Island was one of the earliest games I played where you weren't punished for making a mistake, in fact, you couldn't die in the game at all.

With the Toffee Nosed Bat ingredient narrative path done, we were so proud. It was fun to click through the cards, and we added several additional narrative options that fleshed out the number of choices you could make as you made your way to the elusive winged creature.

But the issue with this first path was that it was simply trial and error to get to the end of the main narrative path. You had some funny moments as you made your way towards the bat, and some deliberately ambiguous choices too - but the next ingredient would have to do something… different.

Narrative Puzzles

The ‘Tale of Newt’ - yep, I know that looks like it’s spelt wrong… it isn’t, trust me - added another layer to the trial and error nature of the narrative choices. Puzzles. Well, in this case, more the requirement for the player to realise that they need to start paying attention to what characters said to them - and introduced some clear points where logical thinking and memory had to play a part vs just having to guess which choice would drive you in the correct narrative direction.

Players could still just click on the path choice buttons randomly to see where they took them, if they wished, but in some cases there would be a LOT of them to choose from.

An example page from Merlin's Quest that shows 10 possible path choices
One example of where the answer is easy, if you had been paying attention - or you have to see where one of the 10 potential paths may take you!

My daughter and I loved coming up with the puzzles in the later potion narratives. With the ‘Ink of Kraken’ we took the bold decision of deciding to split that narrative into two mini-quests - that would unlock the main ingredient narrative line. It was complicated, but by then we had learned a lot from the previous two ingredient paths, and ‘Ink of Kraken’ is actually bigger and takes longer than the previous two ingredient paths combined!

A Lesson in Natural Game Design

Unintentionally we’d created a natural evolution of game mechanics as you make your way down the ingredient list. As a result, Merlin actually warns you right at the start that each ingredient is more difficult than the previous one.

If you do them in order you will learn the base narrative choice/consequence mechanic, then you’ll learn that the story will provide key details that you need to recall later in the narrative, then you are introduced to more complex multi-threaded quests, that roll all of those skills together, and also add more complex riddles and puzzles.

I won’t lie - it was a bit of labour of love to complete ‘Ink of Kraken’ - and all the while my daughter and I were trying to figure out a natural sequence of events that would lead to the face-off with the Kraken itself - and how that would relate to the mini-quests you’d done to get there.

My daughter sent it to her form teacher at school, and one Friday afternoon her whole class played the game through on laptops - something that made me very proud...

It’s very freeing knowing you can take a story in any direction, and many others at the same time, but we had to reign back some more complex ideas, just because the mechanics were just too complicated sometimes, or some of the puzzles were too ambitious for the card-linked, multiple choice structure I’d designed.

It was rewarding to still get feedback from our rapidly expanding group of testers that the game was fun to play, and really did challenge them in places.

My daughter sent it to her form teacher at school, and one Friday afternoon her whole class played the game through on laptops - something that made me very proud, especially as she had contributed SO much to the story, and provided such lovely drawings for the key scenes as well.

Merlin’s Quest

Having done all of the work on the ingredients, it became apparent that this wasn’t actually the main quest! The ingredients were there so you could then take on the main quest that Merlin had yet to reveal…

At the time of writing this final portion of the game is just in note form - my daughter and I have mapped out the skeleton of the quest that you go on - but there is still a surprising length of gameplay in the potion stories.

There are plans on getting lost in the world of Merlin with my daughter again, but for now, you can enjoy the journey up to the point where you’ve collected all of the ingredients. Do let me know how you get on!


The following portion of the article goes into more of the technical background of the game. Completely up to you if you want to delve into this, as it has code snippets and all sorts.

By the Power of JSON

If you’ve read some of my other posts, you may have got the vibe that I’m a HUGE fan of the Jamstack approach to projects. The Merlin’s Quest project was one such project. The key for me was to figure out the best way to make the project scale, have it as performant as possible, but not rely on any messy backend. It also meant that no other calls are made after the initial loading of the URL - you have everything you need to play the game right there!

So - my solution? I decided that all the settings and the narrative for the adventure would be kept in a single JSON file - with separate objects for each of the cards that represented each portion of the story.

{
"adventureName": "Merlin's Quest",
"adventureId": "2206201719",
"adventureObjects": ["Wing of Bat", "Tale of Newt", "Ink of Kraken", "Magical Armor", "Unbreakable Flask"],
"adventureCards": [
{
    "cardId": "introduction",
    "cardTitle": "Are you ready?",
    "cardCopy": "You are about to embark on an interactive adventure with Merlin the wizard. Choose your path wisely or you may find yourself having to retrace your steps!<br /><br /><span style='display: block; text-align:center; font-size:16px;'><i>Story by Kayley & Squidge</i><br /><i>Illustrations by Kayley</i><br /><i>Coding by Squidge</span>",
    "cardImage": "20200406_130010.jpg",
    "cardActions": [
        {
            "actionText": "Start",
            "cardLink": "start"
        },
        {
            "actionText": "Wait, how does this work?",
            "cardLink": "help"
        }
    ]
}

Breaking this down - the opening section addresses some global settings - naming the story (so I can just use the same file to create more stories in the future and keep the project template untouched). The adventureId linked to the localStorage item name I created to save a players progress. If I introduced breaking changes I could ensure that a new save item was created that didn’t conflict with an older id.

When we get to the story card objects themselves, hopefully they’re fairly self explanatory:

{
    "cardId": "potionBench",
    "cardTitle": "The Potion Mixing Bench",
    "cardCopy": "&quot;I'm so pleased to see you're interested in how you mix potions&quot; says Merlin as he walks you to his messy potion bench.<br /><br />&quot;You will need 3 ingredients to mix your first potion, the <i>Potion of Invisibility</i>&quot;.<br /><br />&quot;This is a useful potion in a lot of situations, but be wary that the affects are quick to wear off, and if you are to use it on your quest, be very careful that you use it at the right time...&quot;<br /><br />You'll need 3 main ingredients to mix this potion, though be warned, the further down the list, the more tricky the ingredient is to get:",
    "cardImage": "20200406_130010.jpg",
    "cardActions": [
        {
            "actionText": "Go and find wing of bat",
            "cardLink": "potionAStart",
            "lockedWith": ["Wing of Bat"]
        },
        {
            "actionText": "Go and find tale of newt",
            "cardLink": "potionBStart",
            "lockedWith": ["Tale of Newt"]
        },
        {
            "actionText": "Go and find Ink of Kraken",
            "cardLink": "potionCStart",
            "lockedWith": ["Ink of Kraken"]
        },
        {
            "actionText": "Ask Merlin about the quest",
            "cardLink": "startQuest"
        }
    ]
}

The cardId was unique, and allowed me to create a simple script that could look through the JSON object to pick out and populate the relevant card information. The title, copy and (optional) image were all standard content options on each card. The cardActions allowed me to create as many buttons after the story copy, with any text I wished - the cardLink would then correspond to another cardId in the JSON - forming the link to the next narrative object. I had to come up with a pretty robust naming convention for the cardId to avoid any doubling-up of names, but that wasn’t too hard. The lockedWith item only appears periodically (there is also a corresponding ‘unlockedWith’ item), but allowed the button to be ‘locked’ (or unlocked) after looking at the player’s localStorage items - if we quickly look at another story item example, you can see how this was done in the JSON:

{
    "cardId": "potionAComplete",
    "cardTitle": "Congratulations!",
    "cardCopy": "The bat smiles at you. &quot;You are a clever human aren't you, not getting too close to the Toffee Nose bat is a very good idea. Also, I need my main wings to fly, but this little wing...&quot; he pauses, as you notice the small wing on his back splitting, until it looks like a small butterfly on its back. &quot;...is something that will gift you the ingredient you need - don't come closer though. As my name suggests, I have a rather curious nose, that you may not be able to resist!&quot;<br /><br />The bat plucks one of the small wings from its back and hands it to you, smiling. Giving you a little wink, he flaps off into the darkness of the cavern, and is gone.<br /><br />Congratulations you have got the <i>Wing of Bat</i>.",
    "cardImage": "20200720_133124.jpg",
    "objectId": "Wing of Bat",
    "cardActions": [
        {
            "actionText": "Return to Merlin",
            "cardLink": "potionBench"
        }
    ]
}

The presence of an objectId meant that this object title would be added to the players localStorage item to allow me to check and unlock previously locked paths. Here’s an example of a kkPlayer2206201719 (note that unique adventureId being used in the name):

A console readout of a players saved JSON file for the game
Sorry for the screen capture - this shows a fairly simple player localStorage item

The playerName hasn’t actually been used to-date - my plan was to allow the player to name themselves, and have that appear at various moments in the game, but I’ll save that for a future update I think! After this though, you can see a simple array of the objects they have collected so far, the playerPosition stores the current cardId they’re on - so if they’re using the same device, they get dropped right back where they left off when the page loads (I did also add the option to clear this in later updates). Finally the playerTokens is an array of every narrative card they’ve visited that has a tokenId reference - and it copies that reference. The idea (again, for a future update) was to have a breakdown of all of the tokens they have found, and a teasing list of ‘secret’ ones they have yet to discover. I thought having names on each of the tokens was a good idea… though thinking of witty names for all 76 was an extra layer of work I didn’t plan for! I saw them as the same as the achievements or trophies you get on consoles.

As it happens, I did a nod to the achievement mechanic when you find one of the potion ingredients, but I’ll leave you to discover that when you play the game

Headshot of David Kidger David Kidger is a UX / UI designer and developer. He founded Squidge Inc to help folks build better, audience focused applications and websites.
Liked reading this post? Why not share it: