Skip to main content

m2c2kit internals

To learn how to write trial schema, we have to expose a little bit more of the inner workings of m2c2kit.

tip

If this section is confusing, don't worry. Just think of all of this as a template for where you put your schema, options, and assessment code. You can follow the template and write sophisticated assessments without understanding all these programming concepts.

The Game class

To write m2c2kit assessments, we build upon (extend) a class called Game. Up to this point, the example code has hidden this detail. Think of this class as a blueprint or template that already has lots of built-in functionality for working with assessments.

There are two important methods (a group of code that can be called) on the Game class:

  • constructor() - This is where you define the options, including the trial schema, for your assessment.
  • initialize() - This is where you set up (or initialize) your assessment.
note

All the example code you've seen up to this point has simply been the code that was inside the initialize() method. You've been coding this method all along, without even realizing it!

The Game class in action

Let's look at an example of how the Game class is used. A few things to point out:

  • To create a new assessment, we define a new class that builds on ("extends") the Game class. When you write your own assessments, it doesn't matter what you name it,1 because the user will never see its name. In this example, we call it DocsDemo:
class DocsDemo extends Game {
  • Within the constructor(), we define a variable to contain our schema, called demoSchema. The schema has a variable called trial_index that is an integer; this will record in our data which trial the user is on. We also define a variable called mobile_research_fun that is a boolean (true or false) value of how the user answers our question.
const demoSchema = {
trial_index: {
type: "integer",
description: "Index of the trial within this assessment, 0-based.",
},
mobile_research_fun: {
type: "boolean",
description: "User response to question about mobile research being fun.",
}
}
  • Within the constructor(), we define a variable for overall game options, called options. We will learn more about this later, but for now, just know that the id for this simple example is docs and its name is Documentation Example. The publishUuid is a universally unique identifier (UUID) so that if this assessment code is shared ("published") with others, it can be uniquely identified, even if someone else codes an assessment with the same id and name. We define the size of our game screen as 200 wide by 400 high, we will use Roboto font for our labels, and we set the schema for all of our game's trials to be what we put in the demoSchema variable:
const options = {
name: "Documentation Example",
id: "docs",
publishUuid: "c9ec7b5b-a6cc-4308-9b1c-73b40ae4aa9e",
width: 200, height: 400,
fonts: [{
fontName: "roboto",
url: "fonts/roboto/Roboto-Regular.ttf"
}],
trialSchema: demoSchema
};
Universally unique identifiers

A universally unique identifier (UUID) is 128-bits of data generated with an algorithm to be unique from any other UUID. In text format, they look like 8a523876-907a-4b68-be22-cd6daa8b9566. Whenever you create a new assessment, it must have its own unique UUID.

You can go to a website, such as https://www.uuidgenerator.net/version4, to generate a UUID. If you are using the m2c2kit CLI to scaffold a new assessment, the CLI will automatically generate a UUID and insert it into your code automatically!

In the tutorial, you will see the same publishUuid of c9ec7b5b-a6cc-4308-9b1c-73b40ae4aa9e repeatedly used in different code examples. That is because this is tutorial code -- actual assessments must have their own UUID!

  • The last line of the constructor has the code super(options). This is how we get all the built-in functionality of the Game class. Just always remember to include this at the end of your constructor.

  • Within the initialize(), we write our assessment code, as we have been doing all along. The only difference is the first two lines: await super.initialize() runs some built-in setup code. const game = this allows us to conveniently refer to the game object (this was hidden from you in the previous examples).

async initialize() {
await super.initialize();
const game = this;
const sceneOne = new Scene({ backgroundColor: WebColors.PaleTurquoise });
game.addScene(sceneOne);
}

So far, our assessment doesn't do much, other than make the scene background a light turquoise. But, it defined a trial schema that is ready to accept data!

Loading...

Footnotes

  1. For the tutorials, however, do not change the class name (DocsDemo) or the value of id specified in options! This tutorial website engine expect the class name to be DocsDemo, and the value of id to be docs, and it will not work if you rename these.