Alexa presents an opportunity to extend games into the physical spaces around us. Alexa allows can create new gameplay experiences, as part of a social living room or even in public buildings and spaces.
However, developing Alexa Skills and using cloud services (no matter how well supported - and they are) needs some effort and programming skills. By combining Alexa with third party tools we can support the design of new experiences and help game and interaction designers make new game designs and novel interactions.
Take Twine for example. Twine is a well documented third party tool that can be used to create interactive stories. Users of Twine can create their own stories where players will read a part of the story before choosing where the story leads next.
For example, if you were recreating part of the 1982 classic text adventure: The Hobbit, you might have a Twine storyboard would look like the following:
The original game was a classic (see the Wikipedia entry), and Twine might help you create your very own text adventure.
Twine can publish your stories to the Internet and is able to format the stories in different ways. Twine's stories can be exported to HTML and played on a website - you can see some of them here http://twinehub.weebly.com/ but there are other exciting examples. In a recent Ludum Dare competition it was even used to create an 8-bit styled adventure (see http://ludumdare.com/compo/tag/twine/).
But to the best of my knowledge no one has yet allowed a Twine story to be played on Alexa...
Spoken Stories
Spoken Stories allows you to create a story in Twine and play this on your Alexa enabled device.
The Spoken Stories Alexa Skill was created for two reasons: i) to get me up to speed with programming and designing Alexa Skills, and ii) to see how an Alexa Skill might playback a Twine story, and what could be learnt from doing this.
To use this Alexa Skill, a designer will need the Twine application from the https://twinery.org/ website, and an additional proofing format called TwineJson that exports a story in JSON format.
Given the Hobbit Twine story, and using the tool TwineJson, you could now export to the JSON format.
To be accessible to the Alexa Skill, the JSON file would need to be published on a website e.g. using some example PHP code like the following, or maybe, something like Github's Gist.
<?php
header('Content-type:application/json');
$json = file_get_contents( "story.json");
$bom = pack('H*','EFBBBF');
$json = preg_replace("/^$bom/", '', $json);
echo $json;
?>
DevelopmentThe development work for this Alexa Skill was done over the weekend - starting on the evening of Friday 16th December, 2016.
I began by looking at the examples from https://github.com/amzn/alexa-skills-kit-js and started from the reindeerGames sample as it supported answers and a persistent session.
The Alexa Skill I made from this was pretty simple, so I'll summarize some of the things that I should have known, and know now.
AMAZON.Literal: Amazon uses something called slots to allow the Alexa user to give answers to questions. I began with the slot type LITERAL which allows any form of response. LITERAL works a little differently from the other slot types and requires the following syntax in its utterance file, which allows up to three arbitrary words to be spoken in response.
{one|SlotName} using LITERAL
{one two|SlotName} using LITERAL
{one two three|SlotName} using LITERAL
However, the use of LITERAL means that Alexa was expecting any spoken word and it struggled to make out what I was saying. Instead, I created a custom slot type - which contains just the words in my example story - with the addition of the word 'Start', so the story could continue after presenting the user with a help card.
BOM: When fetching a JSON file you can run into some problems when you come accross a BOM (Byte Order Marker) when the fetched file includes a magic number at the start of the sequence. This was easy to spot as the string.length function returned a different length than string I was seeing in my web browser. My Alexa Skill contains code to find and remove these leading characters.
Text type: ReindeerGames has a handy function to send the response back to the user which used the text type "Plain Text". I used this to tell Alexa to say something to the user. See the function below:
function buildSpeechletResponseWithoutCard(output, repromptText, shouldEndSession) {
return {
outputSpeech: {
type: "PlainText",
text: output
},
reprompt: {
outputSpeech: {
type: "PlainText",
text: repromptText
}
},
shouldEndSession: shouldEndSession
};
However, I decided to use SSML. SSML allows the user to put pauses inline with the text and even play audio samples from other web-sources. e.g. you could send a string with a human perceptible pause e.g. "Hi, let me think about that for a moment.<break time='3s'/>I agree". This is how you might add SSML to the previous function:
function buildSpeechletResponseWithoutCard(text, repromptText, shouldEndSession) {
var outputSSML = "<speak>" + text + "</speak>";
return {
outputSpeech: {
type: "SSML",
ssml: outputSSML
},
reprompt: {
outputSpeech: {
type: "SSML",
ssml: outputSSML
}
},
shouldEndSession: shouldEndSession
};
}
So those were some of the issues I faced. Not many really. So what story did I think would be good for a Twine example? Well not a story, more traditional play...
Example: Pat-a-cakeI chose Pat-a-cake as an example because I have previously worked with a creative play practitioner. They suggested a simple game: Pat-a-cake, which they indicated might be suitable for 5+ age groups and a good place to start.
The following diagram shows how this (simplest) of games might be created in Twine. Note, the story also contains an addtional passage "Help" which is hard coded from the Alexa Skill (and linked to the Amazon.HelpIntent) to provide the user some clue to how this Alexa Skill should be used.
One you have a Twine story, you can then export this to the JSON format. I uploaded to GitHub's Gist so its easily accessible to my newly created Alexa skill. A snapshot follows of the exported JSON follows.
[
{
"pid": 1,
"position": {
"x": 303,
"y": 98
},
"name": "start",
"tags": [
""
],
"content": "Pat a cake<break time='500ms'/> [[pat a cake]] ",
"childrenNames": [
"[[pat a cake]]"
]
},
{
"pid": 2,
"position": {
"x": 307,
"y": 303
},
"name": "pat a cake",
"tags": [
""
],
"content": "bakers [[man]]",
"childrenNames": [
"[[man]]"
]
},
This JSON shows the first two Twine passages. After hearing the word "Pat-a-cake" the player must respond with the word "pat a cake". They then hear the word "bakers" and are expected to respond with the word "man".
Through creating a game in Twine, I was able to play around with what words the player might guess until I found a sequence that worked well. The code uses a regex replace function to hide the otherwise audible Twine options which are specified in brackets e.g. [[man]]. If you were using my Alexa Skill and you were creating a text adventure, you might write. You can go North [[North]] or South [[South]]. When the code strips the bracketed text, the choices will still be audible.
Future workTo allow other parties to create their own experiences - it would be desirable to support Account Linking. This would allow stories to be written in Twine and saved straight into a convenient file store such as Amazon Drive or Dropbox that can be accessed directly from Alexa - thus avoiding the need to change the URL.
A custom slot type was setup specifically for Pat-a-cake which contained the words in this rhyme. I'm interested to know how these could be read in from an external source and allow the user to avoid this step.
Comments