ucfopen / Materia

Engage students with easily embedded apps for online courses. Supercharge your course with compelling experiences and game mechanics.
https://ucfopen.github.io/Materia-Docs/
GNU Affero General Public License v3.0
36 stars 33 forks source link

State Persistence for widgets #1075

Open clpetersonucf opened 6 years ago

clpetersonucf commented 6 years ago

For Hospital Sim, a long-requested feature is to be able to "save" your work in case you lose it. As it is, if you navigate away or close your tab, the work you've done is gone.

As a possible solution, we've worked on a "state persistence" prototype - that is, temporarily storing state information about what the student has done in the widget player, and being able to recall that information if the student reloads the player.

Currently, the prototype uses sessionStorage, with most of the logic in materia-client-assets as it's mostly contained within the enginecore and Materia's player.js. This is so the logic is agnostic and optional for widgets.

The current implementation is as follows:

  1. A widget saves state data in the player by calling Materia.Engine.saveGameData() and passing the state information as an object.
  2. The enginecore sends the state data to Materia's player.js via postMessage.
  3. The player stores the state data in sessionStorage, as well as the Play ID and current URL (this could potentially be replaced with the context ID? Which would be far better)

When a user reloads the page or navigates away and back to the player,

  1. The widget checks to see if any state information was saved within its Widget.Engine.start() function, via Materia.Engine.resumeGameData()
  2. The enginecore passes the request to Materia's player.js via postMessage.
  3. The player searches sessionStorage for valid game data, identified via the URL. It sets the Play ID to the stored one, and sends the state data back to the enginecore via the sendToWidget postMessage.
  4. The enginecore calls Widget.Engine.resume and passes along the instance, qset, and version parameters, along with the state object.
  5. The widget's Widget.Engine.resume basically functions the same as start, except it applies the state information to return the player to the state the user last had it.
clpetersonucf commented 6 years ago

To test locally, you'll have to check out branches on 3 different repos:

Materia: hackday/resume-support-for-widgets materia-client-assets: issue/1075-state-persistence Hospital Sim: issue/74-state-persistence-prototype

Refer to the steps posted in #1074 to update materia-client-assets in your local Materia install.