Author: John Stewart (Page 1 of 24)

Twine Game Data to Google Sheets via Javascript

Using Twine, a free, open-source, text-based game software, you can build choose your own adventure games that explore the untaken paths in literaturepromote empathy through simulated experiences, and provide role-playing adventures in historical scenarios. Twine games are often used in the classroom, because you can quickly build an educational experience about whatever subject you choose. They are also heavily used in the interactive fiction world as a medium for short stories and novels.

In the XP Twine workshop that Keegan and I are leading, several of the faculty members asked how Twine games could be used to track students’ understanding of concepts. One faculty member is building a game that simulates entrepreneurial business investment. In the game, students can try out different investment strategies and equity stakes as they try to become a successful venture capitalist. The professor wanted to be able to track the choices they made in game in order to spur in class discussion.

Twine games take the form of HTML files with embedded CSS and JS. In my latest round of tinkering, I figured out how to use javascript within a Twine game to send an HTTP post message to pass game-play data to a Google Spreadsheet, thereby creating a database that records each game-play.

Google Sheet/Apps Script Code

In order to track this game data, I suggested that we push the data from Twine to a Google Spreadsheet. Following the lead of Tom Woodward, I’ve found that Google Spreadsheets are a relatively easy place to collect and analyze data. I wanted to use Google Scripts, which are mostly javascript and a few custom functions, to receive data and parse it into the cells of the Google Sheet.

Martin Hawksey wrote a blog post a few years ago called “Google Sheets as a Database – INSERT with Apps Script using POST/GET methods (with ajax example).” Martin had set up an Ajax form that could be embedded in any website that would pass data to his Google Script which would then record it in his Google Sheet. Martin’s code (below) receives an HTTP Get or Post call generated by an Ajax form, parses the parameters of that HTTP call, and stores those parameters in a Google Sheet. Martin also provides comments in his code to help users customize the Google script and initiate it as a Web App.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//  1. Enter sheet name where data is to be written below
        var SHEET_NAME = "DATA";
 
//  2. Run > setup
//
//  3. Publish > Deploy as web app 
//    - enter Project Version name and click 'Save New Version' 
//    - set security level and enable service (most likely execute as 'me' and access 'anyone, even anonymously) 
//
//  4. Copy the 'Current web app URL' and post this in your form/script action 
//
//  5. Insert column names on your destination sheet matching the parameter names of the data you are passing in (exactly matching case)
 
var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service
 
// If you don't want to expose either GET or POST methods you can comment out the appropriate function
function doGet(e){
  return handleResponse(e);
}
 
function doPost(e){
  return handleResponse(e);
}
 
function handleResponse(e) {
  // shortly after my original solution Google announced the LockService[1]
  // this prevents concurrent access overwritting data
  // [1] http://googleappsdeveloper.blogspot.co.uk/2011/10/concurrency-and-google-apps-script.html
  // we want a public lock, one that locks for all invocations
  var lock = LockService.getPublicLock();
  lock.waitLock(30000);  // wait 30 seconds before conceding defeat.
 
  try {
    // next set where we write the data - you could write to multiple/alternate destinations
    var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
    var sheet = doc.getSheetByName(SHEET_NAME);
 
    // we'll assume header is in row 1 but you can override with header_row in GET/POST data
    //var headRow = e.parameter.header_row || 1; Hawksey's code parsed parameter data
    var postData = e.postData.contents; //my code uses postData instead
    var data = JSON.parse(postData); //parse the postData from JSON
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    var nextRow = sheet.getLastRow()+1; // get next row
    var row = []; 
    // loop through the header columns
    for (i in headers){
      if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp' column
        row.push(new Date());
      } else { // else use header name to get data
        row.push(data[headers[i]]);
      }
    }
    // more efficient to set values as [][] array than individually
    sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
    // return json success results
    return ContentService
          .createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
          .setMimeType(ContentService.MimeType.JSON);
  } catch(e){
    // if error return this
    return ContentService
          .createTextOutput(JSON.stringify({"result":"error", "error": e}))
          .setMimeType(ContentService.MimeType.JSON);
  } finally { //release lock
    lock.releaseLock();
  }
}
 
function setup() {
    var doc = SpreadsheetApp.getActiveSpreadsheet();
    SCRIPT_PROP.setProperty("key", doc.getId());
}

I edited Martin’s original code in lines 39-41. In his code, he’s looking for Post data in a slightly different format than what I generate. Rather than using the parameters from the HTTP Post, my code uses the data from the Post.

Twine Game Code

Rather than using an Ajax form, I wanted to pass variables that had been collected during gameplay in a Twine game. Twine is built on javascript, so I decided to replace Martin’s Ajax form with a javascript HTTP Post function embedded in Twine. Based on research on how Twine works, I decided that the best way to do this would be to write the javascript code directly into a Twine game passage. My passage, called PostData, would presumably come at or very near the end of my game after all interesting variables have been set:

Twine Screen ShotI wrapped Twine’s script syntax <script></script> around the standard xhr XMLHttpRequest() function. This sends an HTTP Post to whatever url is provided (like the url for your Google Script Web App) with a json package defined in the var data line. Here’s this code (please note that you need to add the <script></script> modifiers in Twine:

1
2
3
4
5
6
var xhr = new XMLHttpRequest();
var url = "URL for the Google App";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/json; charset=UTF-8");
var data = JSON.stringify({"var1": harlowe.State.variables['var1'], "var2": harlowe.State.variables['var2'], "var3": harlowe.State.variables['var3']});
xhr.send(data);

However, in order to pull variables out of the Harlowe version of Twine that I was using, I also needed to add the following code by editing the Story Javascript:

Twine Javascript Screen Shot

This bit of Javascript passes all variables defined within the Twine game into an array (window.harlowe) that is accessible by Javascript code that is embedded in the game. Here’s the code in case you want to try this out:

1
2
3
if (!window.harlowe){
	window.harlowe = {"State": State};
}

I hope this work will be useful in studying any Twine game to see how players are moving through the game. You could record any variables in the game and also the games ‘history’ to see which passages each player went through. This has obvious uses for educational games in being able to provide feedback to players, but it also has implications for game design more broadly with the increased use metrics.

Implement in your own game

In order to implement this for your own game, I would suggest following these steps:

  1. Copy the Javascript code above (starts with if (!window)) into your Twine game’s Javascript panel
  2. Copy the PostData code above and paste it into a TwinePost passage towards the end of your game
  3. Then replace the variables in the TwinePost passage so that harlowe.State.variables[‘var1’] becomes harlowe.State.variables[‘your variable name here’] for each of the variables you want to track
  4. Click this link to get a copy of my Google Spreadsheet
  5. Make sure the column headers in the spreadsheet match your variable names from the TwinePost passage
  6. In the Google Sheet, click on Tools->Script Editor and follow Martin Hawksey’s instructions for steps 2-5
  7. When you publish your Script as a Web App, it will give you a URL for the Web App. Copy this URL and paste it into the URL variable in your TwinePost passage code.
  8. You’re done. Play your game and see if everything works. If it doesn’t work, tweet at Tom Woodward. He’s good at fixing code and has nothing but free time on his hands.

I am excited about this code because it answers a question for several of our faculty members and makes Twine games more useful as formative assessments. Hawksey did an excellent job in keeping his code very generalized, and I’ve tried to preserve that, so that you can track whatever variables you want.

You could also use the HTTP Post javascript code outside of Twine in any other web site or web app to pass information to your Google Sheet. Tom has blogged a couple of times about using code to send data to Google Forms and autosubmitting into a Google Spreadsheet. I think the process described above denecessitates that Google Form pass through and moves us a step closer to Google sheets as a no-SQL data base alternative.

Omeka of One’s Own

One of the recurring concerns/complaints surrounding the Domain of One’s Own project is the inescapability of WordPress. Most students and faculty on OU Create and other Domains projects use WordPress sites, either for personal portfolios or class blogs. As a counterpoint, I wanted to feature a few of the Omeka sites that that have been built on OU Create in the past few months.

OmekaLogoLike WordPress, Omeka is a php based platform with a one-click installer in Reclaim Hosting environments. Unlike WordPress, Omeka is not built for blogging but rather for cataloguing. Omeka is particularly useful for collecting meta-data about documents, images, movies, baseball cards, or other media. It was originally developed and is still maintained by the Roy Rosenzweig Center for History and New Media at George Mason University.

Below are screenshots of several OU projects along with the creators’ descriptions of each. You can click on the image to go to the project’s site.

Water

The Carl Albert Center’s Local Digital History Lab is a project based initiative that focuses on preserving history and highlighting important policy issues in the state of Oklahoma. It combines the archival resources at the Center with materials and experiences donated by the public. The first series of lab events focus on the intersection between environment, extreme weather, and public policy in the state.

Each lab bolsters connections between archival collections and the communities they serve. The events also contextualize important issues by organizing community digitization events and making harvested materials available to the public online.

The site features archival materials made available by the Carl Albert Center Congressional and Political Collections, the City of Tulsa Engineering Services Department, and members of the public. It includes over 4,000 pages of digitized text, 255 photographs, 90 maps, and over 100 minutes of oral history.

New Deal

The United States changed rapidly during the 1930s in response to a series of economic, environmental, and social factors. The Great Depression transformed the relationship between the national government and its citizens. The physical landscape was also altered through massive public works projects and conservation initiations. Moreover, this was one of the richest periods of creative cultural activity the nation has seen.

Created by students at the University of Oklahoma, this site documents and explores the 1930s and its enduring legacies in Oklahoma. Please explore the digital exhibits and collection of photographs, documents, videos, and maps discovered and created during the research process.

Visit the About This Project Page to learn about the creation of the site.

Screen Shot 2017-09-19 at 1.55.12 PM

One of the professors from the Making Modern America project, David Wrobel, has continued his use of Omeka in a follow up class on John Steinbeck’s literature. Working again with librarian extraordinaire Sarah Clayton, Dean Wrobel’s students are putting together exhibits examining the various facets of Steinbeck’s work from his travels, to his work on the War and his relationship with Oklahoma.

VITAL

Videos for Italian Teaching and Learning is a curated database of openly available videos. Daniela Busciglio and her collaborators are collecting and tagging videos to help students work on various grammatical and thematic concepts. By sharing these videos online, Daniela can share these resources with undergraduates at OU, and with learners of all levels and at all schools.

Women's Advocacy Network

In January 2017, 13 members of WAN’s Gulu subgroup worked with faculty and students from the University of Oklahoma to conduct a “Photovoice” project. Photovoice is a method that combines the power of photography with critical group reflection to interrogate everyday aspects of life.

The project began with each WAN participant creating individual photos intended to show elements of daily life, including both life-giving aspects, but also significant challenges. Many participants chose to recreate memories from life in captivity. Others focused on how they live now. After the individual photography, the participants used the photos to teach each other about their own perspectives and to discuss common themes and desires for change in northern Uganda. The exhibit presents photos from each participant along with her personal statement.

The goals of the both the project and this exhibit are twofold. First, the photographs are meant to teach the viewer about the participants’ lives, their concerns, and their desires for change.  Second, the project is intended as an opportunity for the participants to reflect on their priorities and WAN’s activities aimed at improving conditions for women in post-conflict northern Uganda.

Documentary Narrative

Focusing on the history of race and education in Oklahoma, students will utilize this platform to gather and discuss primary sources that inform the rich and complicated history of the state around schooling concerns. For students engaging in historical projects, it is essential to critically examine not only literature that informs our field, but similarly engage in research projects within classes that will put theory into practice. This course, Documentary and Narrative, examines problems and methods of non-empirical/non-experimental research in history of education.  Particular attention will be paid to qualitative methods that collect data from documents, from oral history interviews, and from observations and experiences in settings that utilize approaches related to case study and narrative inquiry techniques.  Use of primary and secondary sources, field notes, and case study applications are discussed along with the roles that the researcher plays in terms of generalization and interpretation. Similarly, this platform will facilitate conversations on ways to engage in historical research that informs the evolving technological changes we are witnessing today, as a vital conversation on the survival of the field.

Making Conferences Fun

I am currently helping to organize a couple of conferences and am trying to think about what I have enjoyed about conferences in the past. I don’t typically remember the talks at a conference as much as the un-planned stuff. I met Ben Scragg over dinner at OLC and have considered him my food guru ever since. I remember watching Keegan lure people into playing a Switch game where they milk cows. At InstructureCon, Keegan and I attended a board game night that filled an entirebuilding. My fondest memories are of exploring Washington DC with my future wife and Prague with my friend John Perkins.

Picture of me and my future wife from Washington DC, 2007

With all that in mind here are a couple of ideas I’m pitching for the upcoming conference season. Let me know if these sound good and also what other things you would include in an ideal conference.

1. Healthier food and activities 

I feel like conferences are usually sort of gluttonous with buffet lines and eating out every night and all. Having healthy snacks and lunch options would be good and I remember there being some healthy options last year. Similarly, morning group activities like yoga and runs could be informally organized or we could work with the conference center. Outdoor activities like lawn games could be fun too and give people a way to get moving midday. If they already have an area like this at the conference center, we could flag it in handbooks and encourage people to hang out there.

2. Breakout room type activities

I feel like breakout rooms aren’t quite over yet and might be a good group activity. There are things you can do with boxes rather than actually locking people in a room that make it possible to set this up in any conference space, and there are also digital break out activities that we could run across the conference center.

3. Game night

I’d like to use one of the conference spaces to have a game night with board games and video games. We could also include some online games for the virtual attendees. I think this might help people meet others at the conference and just be a fun thing to do.

4. Craft maker space

A place with rocking chairs and work tables where you can sit and knit or make bracelets or paint or whatever would be a nice relaxation and meeting thing. We could probably even provide some supplies for fairly cheap.

5. Unconference space for hands-on computer coding and tool workshops 

I’m envisioning a small space where 10-12 people could meet at a time. On the outside of the space people could stick up post it notes or write on a glass wall or whiteboards or whatever as to the types of hands on workshops that they want. We could poll people ahead of time using social media to plan the events for the first day. Every hour or so a volunteer would lead people through WordPress, Omeka, Drupal, HTML Coding, Slack, or Canvas LMS training or whatever else they ask for. During the first day as people throw up new ideas, we also try to encourage people to sign up to lead those events and then recruit to fill whatever events need to be filled. 

6. Livestreaming

I’ve got a couple of people in mind who have live streaming / life streaming experience who might be willing to stream their whole conference experience. If they could also do a workshop on the first day on how to do this and how to do light-weight versions of this (taking photos and sharing them on Instagram, Twitter streaming, etc) , we might be able to get other people to join in. This will take up a large amount of bandwidth, so we may need to either find someone willing to use their data, or figure out someway to pay for data.

Page 1 of 24

Powered by WordPress & Theme by Anders Norén

css.php