Sprint 3: Player State - UQdeco2800/2021-studio-6 GitHub Wiki
Descriptions
This is a high level description of how player's information is carried from one game area to the next. As game areas are being disposed and recreated whenever player transitions from one level to the next, player information is repeatedly being deleted and reused (not updated). In addition to this, when player dies, player will need to start from the beginning of the game once again which may cause user to be frustrated. This is not ideal as player's information should be maintained and tracked as user progresses towards the completion of the game and player should be able to revert back to the closest checkpoint (safehouse). In order to accomplish such a task, 2 design patterns were adopted - the memento and singleton. These design patterns were used because player information can be stored internally during game without the need to create external files and at the same time it is ideal for managing the state of a single player at a time (of course this would be different if this game was a multiplayer game). With these design patterns taken into account when the codes were written, player info can then be stored internally to be carried forward (upon creating a new game level) and can be reverted backwards to the closest checkpoint (when player dies).
Player State
Player state is created, updated and created at the following in game:
- Player state is created for the first and only time when the game starts for the very first time. This will be used as the original starting player state that will be reused again for restoration when user wants to restart the game.
- Player state updates occurs whenever player goes into safehouse only. The state of player is updated (after game is started - this is mandatory) when player enters safehouse after each game level. Player state is saved at the very start of safehouse level to allow player to buy different items in an attempt to play the game differently with a different weapon, armor or ability if they want to.
- Player state can be restored when game is restarted (which restores player's state to the first ever player state created as mentioned in the first point) and when user wants to revert back to the closest checkpoint (which is the safehouse level prior to the level where player has died as mentioned previously)
Implementation of carrying and storing player state
- Player state information: This is the most important aspect of being able to carry player state. With the use of the memento design pattern, a POJO called
PlayerMemento.java
is used to store all relevant information required to successfully carry player state from one level to the next. In addition to related information with regards to player like ammo, what weapon player is carrying and etc, the most important data to be stored was checking the current game level of player when the state was updated or created. This data variable will enable the system to identify where player is currently at to successfully revert player to the closest checkpoint (previous safehouse level) or restart if required. - Player state manager:
PlayerStateManager.java
is involved in the creation, update and restoration of player state. This is a singleton class purely because there are multiple locations in the game for which player data is required. In addition to that, player class (originator involved in the storing of player state internally) would also need to be updated whenever there is a change in player data which can occur in multiple locations in the code base. This is an essential class to track player state, update and makes managing more straightforward since there is only a single player state to keep track of. - Player caretaker:
PlayerCaretaker.java
is responsible for enabling the originator (player class) to be saved or restored to it's original version if required. These are done due to the fact that it contains the history of all memento objects created (which is created and stored internally when a player class is created or updated). With this history of all the mementos, the caretaker can then acquire specific mementos based on unique IDs and Strings to be used to restore the player class to a specific version depending on what happens in the game whether it may be reverting to the closest checkpoint or restarting the entire game.
Design Justification
- By implementing this, user will now be able to play the game normally (previously whenever player enters a new level, all information is lost). Player data will now be carried forward as player completes the game - which incentivizes player to have the urge to collect as much coins as possible (or ammo) to purchase better weapons or abilities in the safehouse
- This opens a new dimension to the player's experience when playing the game as player would more than likely take bolder/riskier moves to pick up more coins and ammos throughout the game to increase their survival rate in order to complete the game. With regards to improving player's experience, player will no longer need to start from the beginning of the game now upon dying as the successful implementation of player state will now enable player to revert back to the most recent safehouse level - enabling player to better plan how they would replay the level for which they have died in.
Design Pattern
- As mentioned, the singleton and memento design patterns were used. These patterns were chosen specifically because of how multiple aspects of the game would require the player data for updating and displaying, there are multiple game levels for which player information would need to be stored momentarily internally to be carried forward from one game level to the next and enabling player state to be restored to a specific checkpoint if/when player dies in a specific game level in game
- The memento design pattern was used as it enables the system to produce snapshots of player's state. This is essential when the system will need to restore player state to a previous state (when user wants to revert back to the closest checkpoint to try beating a specific level of the game) and allows player state to be carried forward (as each game level is destroyed when a new game level is created in the game). When a game level is destroyed and a new (next) game level is created, the most recent updated player state that was snapshotted previously will be used in the new game level created - thus, preserving and successfully carrying player data from one level to the next.
- The singleton design pattern is also adopted because the system needs to have a single instance that has access to the player state. Since the player state (data) will be used in multiple different parts of the game, it is ideal to have a singleton class (
PlayerStateManager.java
) that is responsible for managing and keeping track of player's most recent state (which is used whenever a new game level is created and when player's HUD interface requires updating).