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 []

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.

Specific vs General parser

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 Parsers

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 Redux 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 and look like this: action#17. The action IDs are stored inside the object that triggers the action.

Text 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 in the text file require that variables of certain type be declared. e.g. show_dialogue(hi) means that hi must be a valid dialogue ID, or change_location(hallway) means that hallway is an actual location ID.

Since usage/reference of ID can come before declaration of the ID, thus we cannot throw error when encountering a variable usage without declaration. Thus, the solution is to store all the assertions in a data structure inside Parser validator. This data structure can store all the assertions made such as assert hi is a dialogue ID or hallway is a location.

Then, just before returning the checkpoint object, we verify all the assertions are correct by checking the gameCheckpoint for whether all 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:

  • Comments - 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

Awards Manager

  • Renders the Awards Menu, which displays assets corresponding to user's collectibles and achievements.

Background Manager

  • Renders the background image for every location
  • Performs action(s): change_location

Bounding Box Manager

  • Creates, renders, and manages bounding box sprites within every location.
  • Pulls state from State Manager and listens for state changes related to bounding boxes in current location.

Character Manager

  • Creates, renders, and manages character sprites within every location.
  • Pulls state from State Manager and listens for state changes related to characters in current location.

Dialogue Manager

  • Renders dialogues as specified by Dialogue Objects retrieves from State Manager
  • Renders dialogues in Talk mode or when ShowDialogue action is called.
  • Performs action(s): show_dialogue

Escape Manager

  • Renders the Escape Menu, which provides options for Settings and going back to Main Menu.

Input Manager

  • Registers all keyboard and mouse event listeners, so that they can be deleted at the end of every scene.

Layer Manager

  • Places Arranges all layers in order

Object Manager

  • Creates, renders, and manages character sprites within every location.
  • It pulls state from State Manager and listens for state changes related to objects in current location.
  • Performs action(s): make_object_blink, make_object_glow

Phase Manager

  • Performs state transitions by activating and deactivating modes
  • Keeps track of previous active states using a phase stack.

Pop Up Manager

  • Performs actions(s): add_popup

Save Manager

  • Loads user data at the start of entire game
  • Saves game data every start of checkpoint and every time a series of actions is performed.
  • Saves settings to backend

Sound Manager

  • Plays and pauses sounds throughout the game

State Manager

  • Manages user progression throughout the game by keeping track of the game checkpoint which contain game map as well as objectives
  • Keeps track of variables such as list of triggered interactions and actions
  • Performs actions: add_item, remove_item, add_mode, remove_mode, complete_objective

User State Manager

  • Manages states exclusive to the user, but not related to his progression in one particular checkpoint
  • Stores achievements, collectibles, and assessments completed by the user.
  • Performs action(s): obtain_collectible
Clone this wiki locally