# Web API for the use by the Rule Game client: pregame and postgame experience

Version 6.029, 2025-02-19

This document describes an addition to the Rule Game Web API, designed to provide the client with the bundle of files controlling the player's pregame and postgame experience (PGE). This was discussed in email by Vladimir and Kevin with Paul and Gary around 2022-11-10.

## Introduction

The pregame experience includes everything that the player will encounter before he actually starts moving game pieces on the board. This includes the IRB-approved consent pages, and the "instruction booklet", i.e. the sequence of information pages that the player is shown after he has accepted the consent page and before he starts playing.

The postgame experience includes everything that the player will encounter after he has finished playing.

## API calls

All web calls use the GET method.

API calls returning JSON structures

- Get page consent.html (This can be done for several other pages as well. The query parameter `name` can be any of (`consent.html debriefing.html debriefing.uid.html demographics_instructions.html demographics.json`))
- Get booklet size; the result is in the field `bookletSize`

The return structures for the two above calls have the fields `error` and (if error==true) `errmsg`. The caller should check the error field, and if it is true, prominently display `errmsg`.

API call returning an image:

- Get booklet page No. 0 (Regardless of how pages are numbered in the instruction booklet directory, here they are retrieved under numbers 0 through n-1, where n is the number returned by getBookletSize) In the above call, if an error has occurred, it will be detected through the HTTP response code not being equal to the usual 200.

  ## What calls the client may need to make

  For a given playerId, say `foo`, the client will likely need to make the following calls, more or less how they are listed in PAGE_ORDER:

  - `game-data/PregameService/getPage?playerId=foo&name=consent.html` -- As with all calls returning a JSON structure, check the error field in the returned JSON structure. If error==true, report the error (print the errmsg field). If false, get the HTML snippet from the `value` field, for use instead of Page.CONSENT. (The HTML snippet does not include the checkbox and CONTINUE button; they need to be appended).
  - `game-data/PregameService/getBookletSize?playerId=foo` -- the `bookletSize` field of the returned structure will contain the number of images (pages) in the instruction booklet.
  - For each j in the range [0 .. bookletSize-1], make the call `GetBookletPageServlet?playerId=foo&pageNo=j`. This will give the image data (PNG, JPEG, etc) for the j-th page, similarly to how GetImageServlet returns a custom image of a game piece. (Note: you don't have to number your image files on the server starting from 0. You can start numbering from 1, have gaps, etc; the server will sort them by file name taking into account the numeric part of the name, and will offer them to the client in this order).
  - We don't customize the string for LOADING_TRIALS, since nobody asked for that.
  - `game-data/PregameService/getPage?playerId=foo&name=consent.html`
  - `game-data/PregameService/getPage?playerId=foo&name=demographics_instructions.html`, for Page.DEMOGRAPHICS_INSTRUCTIONS
  - `game-data/PregameService/getPage?playerId=foo&name=demographics.json` -- here, the `value` field contains the text of the JSON file corresponding to what's found in client's `demographics.ts`. (Rather than a JSON structure). The client will have to interpret it as JSON (I assume there's a JSON parser in TypeScript?), and if a parsing error occurs, report an error. The JSON data can then be used to build DEMOGRAPHICS just like the code from `demographics.ts` is used now.
  - Either `game-data/PregameService/getPage?playerId=foo&name=debriefing.html` (if `!HAS_UID`) or `game-data/PregameService/getPage?playerId=foo&name=debriefing.uid.html` (if `HAS_UID`). This is HTML code, but it has `{completionCode}` inside, to be filled in by the client.

  ## Where the server gets the files

  From `game-data/pregame/pregameExperienceName`. This is where the experiment designer should put them, using the usual SOP for editing experiment control files.

  The default experience is called `default`. As of mid-2023, there are 3 others:

      :/opt/tomcat/game-data/pregame> pwd
      /opt/w2020/game-data/pregame
      :/opt/tomcat/game-data/pregame> ls
      default/  doubling/  relational/  stalemate/

  ## Conditional entries on the demographics page

  Since ver. 6.029, it is possible for some of the entries on the demographics questionnaire to be presented only to some participants: either only to the good players (those whose "goodness score", as defined below, was equal to or greater than a certain threshold), or only to the not-so-good ones (those whose "goodness score", was below a certain threshold).

  Defining the goodness score. The Rule Game Server computes the so-called goodness score for each player participating in experiments with the DOUBLING incentive scheme. The value is a real valued number, on the scale 0.0 to 1.0. It measures the player's prowess at guessing the rules; the value is computed as the ratio of the number of "mastered" rule sets to the total number of the rule sets in the experiment plan. (A "mastered" rule set, in this incentive scheme, is one where the player was able to make 10 error-free move attempts in a row). Thus a player who mastered no rules will have score=0.0, while one who has mastered all rules will have the score of 1.0.

  GUI Client obtaining the goodness score. Whenever the GUI client makes a call to `game-data/PregameService/getPage` (for example, to retrieve `demographics.json`), the response contains, among other fields, the field named `goodnessScore`. E.g. ( `http://wwwtest.rulegame.wisc.edu/w2020/game-data/PregameService/getPage?name=demographics.json&playerId=pbk2024JAN12a` ):

      {"error":false,
          "bookletSize":11,
          "goodnessScore":0.6666666666666666,
          "path":"/opt/w2020/game-data/pregame/doubling",
          "value":"[\n  {\n    \"type\": \"radiogroup\",\n    \"name\": \"gender\",\n ...here\"\n  }\n]\n"
          }

  Use in questionnaire entries. Here's an example of an entry that the client should only show to players with goodnessScore ≥ 1.0:

          {
          "goodnessGE": 1.0
          "type": "radiogroup",
          "name": "subsequent",
          "isRequired": true,
          "title": "You performed very well in our game! Would you like to be contacted in order to participate in additional experiments?"
          "choices": ["1|Yes", "0|No"],
          "colCount": 0
        },

  Entries also can be created to be shown only to players with the score below a specified threshold (in this case, 0.25)

      {
      "goodnessLT": 0.25
      "type": "text",
      "name": "whySoPoor",
      "title": "Why do you think you performed so poorly?"
      },

  ## How the server determines which pregame experience to offer to a given player

  This is how the experiment designer controls the choice of the pregame and postgame experience.

  - If the player's trial list file contains the column named `pregame`, its value (from the first line of the file) is understood to be the name of the PGE offered to the player.
  - Otherwise, for the sake of backward compatibility, we check if the trial list has column namd `init`. If it exists, it's mapped to the PGE as follows:

            if (init == 3) {
               // INSTRUCTIONS_R =  [R1, R2, R3, R4, R5, R6, R7, R8] = instructions_relational
               pregame = "relational";
            } else if (init == 11) {
               // INSTRUCTIONS_11 = [I11_1 ... ] = doubling_scheme
               pregame = "doubling";
            } else if (init == 2) {
               // INSTRUCTIONS_2 = [I2_1 ... ] = stalemate_instructions
               pregame = "stalemate";
            } else {
               pregame = "default";
            }

  - Otherwise, the `default PGE` is used.

  ## Advice to experiment designers

  Once Kevin has added the support for customized PGEs to the client, researchers can start using the following suggested Standard Operating Procedure when creating a new customized PGE for a series of experiments.

  - Review the SOP for experiment design. The PGE file bundles are managed in a similar way to trial list files, rule set files, etc. They live in subdirectory `pregame` under the main `game-data` directory.
  - In your local copy of the game-data directory (update it from the GitHub repository first, if you have not done so lately!), go to `pregame`, and see which experience bundles are there already. Take one of them as your example, e.g. `default`
  - Copy the entire bundle to a new directory (under `pregame` as well), e.g.

        	cd pregame
        	cp -pa defaul my-new-experience

  - In your new experience directory, edit the consent page, debriefing page, etc, as needed for your planned group of experiments.
  - If you have produced a new bunch of image files (e.g. PNG or JPG) for the instruction booklet, put them into `my-new-experience/instructions` instead of the default image files. It is up to you how you name the files, but in order for them to be presented to the player in the desired order, make sure they have a numerical component in the file names, so that the server can discern your desired order. For example, `slide-1.png, slide-2.png`, ... `slide-12.png, slide-13.png`. (Leading zeros in the numbers are fine, if you like using them. You can choose to name your files e.g. `slide-01.png, slide-02.png`, ... `slide-12.png, slide-13.png`.)
    If the file names have no numerical component, or if the first numerical component in them is the same, they will be sorted in the usual "dictionary order" (based on ASCII character code), e.g. "2PG-about.png, 2PG-intro.png, 2PG-story1.png, 2PG-story2.png", much like `ls | sort` would sort them.
  - In the trial list files for your new experiments, put the name of the new experiment in the `pregame` column. (This supersedes the technique of putting the hard-coded instruction bundle ID number in the `init` column, which you may have done in the past, prior to server ver 6.*; that's obsoleted now).
  - Check everything into the GitHub repository. Thanks to Kevin's auto-deployment magic, the files should show in /opt/tomcat/game-data on sapir pretty soon.
  - For testing purposes, it's suggested that you create a "quick play" experiment plan, whose trial list will have just 1 line (1 rule set), with only 1 or 2 episodes to play. Then use the GUI play launch page (or its version with the dev client) to start a session with your test plan. Go through all the steps, from the consent page to the debriefing page, to see if the GUI client reports any errors (e.g. missing or unparseable files), or something looks wrong.

  [HOME]