Skip to content

Game: Temporary page

Tiffany Chong edited this page Jul 27, 2020 · 23 revisions

Global Variables at SourceAcademyGame

The game has two global singletons - SourceAcademyGame and GameGlobalAPI

SourceAcademyGame

SourceAcademyGame is a Phaser.Game instance, meaning it is persistent across different Phaser.Scenes. Here, we store managers and variables that persist across scenes - such as sounds and user data.

The following are some key global managers and what they do.

Manager Description
Sound Manager Manager global volume, in charge of switching background music and playing sound effects
Save Manager Keeps track of taking game snapshots and contacting the server to send them over
User State Manager Keeps track of collectibles, achievements, assessments completed by the user

The following are some global variables and what they do.

Variable Description
accountInfo User account info such as his refresh and bearer tokens
setStorySimState A setter for the state of Story Simulator, so that the game engine can have control over React variables
awardsMapping A Map that provides information on how to render each award
currentSceneRef A reference to the current Phaser.Scene, so that we could perform scene related functionalities
gameType Whether we are using Story Simulator or actual game
gameChapters Details of each chapter, its title, background image, and corresponding .txts
ssChapterSimFilenames List of checkpoint files that you want to simulate in Chapter Simulator
isUsingMock When testing out engine, use this to use mock .txts or actual .txts that are specified by Story writers

GameGlobalAPI

Is only usable when the scene is GameManager scene.

It contains all API's of gameManager's managers. We apply the Service Locator pattern, where one global class is called to provide services from other classes onto dependencies.

Parser

Checkpoint object

All Parser classes are static classes. They all modify the public gameCheckpoint: GameCheckpoint variable in Parser.ts. This prevents the need to pass down the game checkpoint object, or for the need to return objects in each function.

Default Checkpoint

In order to parse the two files needed for a checkpoint, (1) default checkpoint text, as well as (2) "checkpoint txt file", we simply call the Parser's "parse" twice with a different text file. During the first call, the Parser is reset and creates a new Checkpoint object. During the 2nd call, we simply mutate and add on to the same Checkpoint object. In the end, we return the Checkpoint object that was created using 2 "parse" calls.

Paragraphs

The parser works by recursively splitting the text checkpoint file into "paragraphs", and dealing with those paragraphs individually. A paragraph is defined by a header and an 4-space/tab indented body (the body can contain lines and further paragraphs).

Sample text:

header1
    line3
    line4
header5
    line6
        line7
        line8
    line9
    line10
        line11
    line12

This sample text has 2 paragraphs. The splitToParagraph function will split this text into into header and body lines[], and produce the following:

Header Body Lines
header1 [line3, line4]
header5 [line6, \tline7,\tline8,line9,line10, \tline11,line12]

Notice that the body lines's first tab has been removed by the splitToParagraph function. However line7, line8, and line11 still have their tabs with them, so that we can preserve the tab hierarchy within the 2nd main paragraph's body.

Here is how the 2nd body paragraph can be split further into several paragraphs:

Header Body Lines
line6 [line7, line8]
line9 []
line10 [line11]
line12 []

Classes

Recursive Delegation

The main class is Parser.ts. This splits the paragraph into its main constituents and assign the job of reading other paragraphs to other parsers: Dialogues, Actions, Locations. etc. Likewise, a location paragraph can assign its body paragraphs for other parsers to interpret, such as Objects, Characters, and Bounding Boxes.

LocationDetails.ts vs Location.ts

We use the LocationDetails.ts paragraph to parse the paragraph with locations as the header. We use the Location.ts paragraph to parse paragraph with a location ID as the header. You may use a similar maming convention if you need to distinguish between a specific header or a general header.

Entity Classes

Base entities such as objects and bounding boxes typically perform the following roles:

  • Create the object/bbox/character with properties using split function for CSV properties.
  • Parse actions and supply actionId's to corresponding actions
  • Register the object into the gamemap's Map<ItemId, Entity> file.
  • Possibly add the entity to a particular location where it should be found.

Parser Converter

Class that converts any string into int/enum used in the game

Parsing Actions

Actions, like most entities also have ID's and have an Object representation format. A string such as add_item(objects, room, car, 3) will be converted to an action object such as the following:

{
  actionType: GameActionType.AddPopup
  actionParamObj: {gameItemType: objects, locationId: room, id: car, duration: 3
  actionCondition: {}
}

The concept is much like React action objects.

All of these actions are stored in GameMap's actions Map<ItemId, Action>.

Unlike most objects, the action ID's are not defined by the storywriter, but are generated by numerically by incrementing actionNumber for every action defined. Action IDs look like this: action#17.

Validation

The class, Parser Validator, validates the Checkpoint object before it is played by the engine. It ensures two things:

1. No duplicate Item ID.

It does this by keeping a set of ID's and checking whenever you add a new one, that the set of ID's is unique. Otherwise, error is thrown.

2. Declaration of all variables based on correct type.

Some lines require that variables must be declared. e.g. show_dialogue(hi) mandates that hi must be a valid dialogue ID, or change_location(hallway) mandates that hallway is an actual location ID.

Usage and declaration of ID can come in different order, thus we cannot validate and throw error immediately once we encounter a variable usage without declaration. Thus, the solution is to store all the assertions in a data structure of Parser validator. This data structure can store all the assertions made such as assert hi is a dialogue ID or hallway is a location. And then just before returning the checkpoint object, we make sure that all assertions are correct by checking the gameCheckpoint for whether the ID's have been declared.

Note that you may make type assertions anywhere during the parsing process.

Asset Parser

This special file is not really part of the Parser.ts set of classes, as it is not called when creating the gameCheckpoint. It just parses collectibles and achievements and produces an Awards Mapping object, encapsulating data about what assets correspond to which achievement/collectible.

Syntax Highlighting

The txt file can be highlighted by using the following extension Source Academy Syntax Highlighter The following lines are highlighted:

  • Comnents - anything beginning with double-slash (though not supported by parser)
  • Functions - anything behind the parenthesis
  • Keywords - boundingBoxes, objects, actions etc, you name it are all highlighted
  • CharacterIds - Anything beginning with @symbol
  • URLs - Anything beginning with a slash
  • Numbers - All digits
Clone this wiki locally