-
Notifications
You must be signed in to change notification settings - Fork 172
Game: Temporary page
The game has two global singletons - SourceAcademyGame
and GameGlobalAPI
SourceAcademyGame is a Phaser.Game
instance, meaning it is persistent across different Phaser.Scene
s.
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 |
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.
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.
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.
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
.
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
.
The class, Parser Validator, validates the Checkpoint object before it is played by the engine. It ensures two things:
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.
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.
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.
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