Multi-Resolution Game Development With GameBuilder Studio Check it out!
NEW Version 0.9.7 has arrived! New Blazing Fast Particle Engine & More Game Actions. Check it out
Trying to figure out local storage?
  • Hey guys, 

    I've just finished the hungry hero tutorial and now I'm just trying figure out how to add the high score so it shows up on the title page. I'm trying to save the score after the game finishes but I'm a little confused with how to use the local storage option to both load and save an integer and couldn't find much documentation on it. Do I just make up a storage key name? Do I not even need the property name/value chosen? 

    Any help would be appreciated! Thanks.
  • 15 Comments sorted by
  • Here is what I did to get the best score to update correctly on a Top Score(AKA Best Score or whatever you prefer) renderer which pops up on the User Interface layer when the game over screen shows when the player dies.
    I already set up a Top Score renderer as mentioned.

    On the top of the side bar, click on Globals, here I set up a Global Property called BestScore and left it set to 0

    Everything else I added to a GlobalGameState object outside of the game screen area.


    I set up a Rules Component called BestScore 
    that checks for When the @GameStateMachine.currentState = GAME_OVER

    Trigger a Local Store action.
    Label: BestScoreStore
    Action Type: STORE
    Storage Location Name: “HighScores”
    Save Data From:
    Property Name: “BestScore”
    Property Value: Entity.ScoreTxt.Properties.score 

    Trigger a Local Store action.
    Label: BestScoreGlobalProperty
    Action Type: STORE
    Storage Location Name: “HighScores”
    Load Stored Data To:
    Property Name: “BestScore"
    Load Stored Property To:  Globals.Data.BestScore     


    ______________________________________________________________

    Next
    I set up an additional Rules Component called NewBestScore
    that checks for When the @GameStateMachine.currentState = GAME_OVER
    AND
    checks for a property.
    #ScoreTxt.Properties.score  >  #Globals.Data.BestScore

    Trigger a Local Store action.
    Label: NewBestScoreStore
    Action Type: STORE
    Storage Location Name: “HighScores”
    Save Data From:
    Property Name: “NewBestScore”
    Property Value: Entity.ScoreTxt.Properties.score

    Trigger a Local Store action.
    Label: NewBestScoreToGlobalProperty
    Action Type: LOAD
    Storage Location Name: “HighScores”
    Load Stored Data To:
    Property Name: “NewBestScore"
    Load Stored Property To: #Globals.Data.BestScore

    Trigger a Local Store action.
    Label: DisplayNewBestScore
    Action Type: LOAD
    Storage Location Name: “HighScores”
    Load Stored Data To:
    Property Name: “NewBestScore"
    Load Stored Property To: #TopScoreTxt.Renderer.text      *NOTE* this TopScore is the renderer that pops up on the Game Over screen.

    Otherwise Trigger.
    Label: DisplayLastBestScore
    Action Type: LOAD
    Storage Location Name: “HighScores”
    Load Stored Data To:
    Property Name: “BestScore"
    Load Stored Property To: #TopScoreTxt.Renderer.text 

    _____________________________________________


    I imagine you can use whiter Label and Property naming you prefer. This works for me if I click a Play Again button which restarts the level immediately OR if I click a Main Menu button which goes to the main menu where someone can click Play and when their next session is Game Over, the last best high score is displayed.


  • Hi @TheBot Local Storage is being simplified for the next release. To store a value a Local Storage action requires a key name with quotes around it. (i.e. "HighScores") Currently the input field is missing the expression icon which is a bug. You also need to specify the property name being stored in the key with quotes around the name. (i.e. "BestScore") Then you need to pass it a value by pointing to a property or just passing an explicit value directly in the input field.

    To load that same property from local storage you need to use another Local Storage action and change the Action type drop down to "Load". Use the same key name and the same property name and pass a reference to a property where you want the value to be stored once it is loaded.
  • Awesome I'll try that out. I appreciate the help, Lavon. One other quick question about virtual time...is there a way to reset it? I've tried setting it to integer 0 but that didn't seem to work. 
  • @TheB0t there is no way to reset virtual time but what you can do is keep track of your own time variable and increase it by using a constrain property action and adding the deltaTime to the last value of the property every frame. Then reset that value to 0 when you want.
  • Got it all to work. Thanks for the guidance! Now a pro version owner! 
  • Confused on saving High Score, am I on the right track here?

    On a Global Game State (generic object) I Added a Rules Component which listens for a property of 
    When: @GameStateMachine.currentState = GAME_OVER
    Trigger a Local Storage.
    Action Type: STORE
    Storage Key Name: “HighScores”
    Property Name: “BestScore”
    Property Value:  Entity.ScoreTxt.Properties.score 

    (My property value is the property on my score text which is on the UI layer of the game screen)


    Then to get the High Scores to pop up on screen I also add another Local Storage action
    Action Type: LOAD
    Storage Key Name: “HighScores”
    Property Name: “BestScore”
    Load Property To:  


    If I am on the right track, What would I enter in the Load Property To field?
  • @BenFromOregon "Load Property To" is a reference to a location/property that you want the stored value to be set on. So if you want to display the stored value then you would point to the "text" property on the Renderer on the UI entity.
  • Thank you. I believe I set to up right and set the "Load Property To" to point to a UI element  which displays the best score when the game is over.

    Only question is:
    It stores and loads the score , but if the user goes to the main menu and starts again, the best score seems to be lost, and when the new game is over and the 'Best Score' pops up on the UI layer, it was the score that was just stored.
    On one of the GBS written tutorials Here, On the Local Storage section it is written " This works online and on mobile devices."
    Does this mean that when we test this Store Location action by clicking 'Launch' it will behave differently than when we test on a mobile device?
  • @BenFromOregon no, the local storage action will perform the same across all supported platforms. It sounds like you need to store a "LastScore" and a "BestScore" property. You should only update the BestScore property when the LastScore is more than the the last "BestScore" value.

    The "Storage Key Name" is like a folder name. It is the location of where the data will be stored on the user's computer. So that can be reused if you need to store multiple properties under one location.

    Local storage however will not store a value on one device and let you retrieve it on another device. Just want to be clear on that.
  • Finally got it! 
    I will post it here within a day or more or less.
  • Hey @BenFromOregon i tried to setup a local storage functionality and yes it works perfect. But when i tested on a device (Iphone 6) i noticed that when i open the game it works. When i close completely the game and restart, the last best score is displayed correctly. But when i continue playing the last best score is replaced with new actual score. So why and where is the problem here. Maybe you now the solution @Lavon

    Thank you I hope it is understandable :)
  • @Xman Yeah this can seem tricky, sometimes when I look at what I did it doesn’t make sense, but it works every time even if I close the game and restart it. I am not working with an iphone6 though so who knows.


    Here are all the components in my game related to saving and displaying a best score.


    First:
    For the best score I have a text renderer left at 0 called TopScoreTxt and I position this off-screen while the game is running and move it on-screen when the game over screen pops up.

    Also While the game is running I have another text render left at 0 called ScoreTxt. This updates the score as the game is being played so a user can see the score increase. It is reset to 0 every time the game starts as you will see below on number 4. This also has a Data/Properties Container added to it with a property I called score set at 0.


    Second:
    On the GLOBALS tab in the editor I have a global I called BestScore and set it to integer 0.

    Third:
    On a dummy object from the GBs editor placed off-stage I have the following 4 Components:

    1)
    *the storage location name I call "HighScores" is kind of invisible, I don't have it anywhere else than what you will see below.*
    *Also you will need to use quotes as I have on the storage location name and property name.*

    A Rules component I called BestScore that checks for a property of:    
    When @GameStateMachine.currentState = GAME_OVER

    Trigger:  ActionType: STORE
    Storage Location Name: “HighScores”
    Property Name: “BestScore”
    Property Value:  Entity.ScoreTxt.Properties.score 

    Trigger:  ActionType: STORE
    Storage Location Name: “HighScores”
    Property Name: “BestScore”
    Property Value:  Globals.Data.BestScore


    2)

    A Rules component I called LastBestScore that checks for 2 properties of:    
    When @GameStateMachine.currentState = GAME_OVER

    When #ScoreTxt.Properties.score > #Globals.Data.BestScore

    Trigger:  ActionType: STORE
    Storage Location Name: “HighScores”
    Property Name: “NewBestScore”
    Property Value:  Entity.ScoreTxt.Properties.score 

    Trigger:  ActionType: LOAD
    Storage Location Name: “HighScores”
    Property Name: “NewBestScore”
    Load Stored Property To:  Globals.Data.BestScore


    Trigger:  ActionType: LOAD
    Storage Location Name: “HighScores”
    Property Name: “NewBestScore”
    Load Stored Property To:  #TopScoreTxt.Renderer.text


    Otherwise:
    Trigger:  ActionType: LOAD
    Storage Location Name: “HighScores”
    Property Name: “BestScore”
    Load Stored Property To:  #TopScoreTxt.Renderer.text



    3)

    A State Logic Map:
    State Machine reference: @GameStateMachine
    StateMachine: GameStateMachine

    Logic Mappings:
    On State Change To: GAME_STARTED
    Trigger:  ActionType: LOAD
    Storage Location Name: “HighScores”
    Property Name: “BestScore”
    Load Stored Property To:  #Globals.Data.BestScore



    4) *when the game starts I am updating the Score and the Score Display*

    A State Logic Map:
    State Machine reference: @GameStateMachine
    StateMachine: GameStateMachine

    Trigger;(Change Property)
    #ScoreTxt.Properties.score  (integer)= 0

    Trigger;(Change Property)
    #ScoreTxt.Renderer.text (reference)= #ScoreTxt.Properties.score
    *and check pass a value as a reference



    Hope this helps, good luck!

  • @Xman I also created a button so a user can clear the best score back to 0 if they want to. When you get that working, let me know if you're interested.
  • @BenFromOregon @Xman you guys are over complicating this process. All you need are two properties called "currentScore" and "lastBestScore". The currentScore property is always reset to 0 when the game starts and gets increased during game play. Once the game is over you simply check if the currentScore is greater than the lastBestScore value and if it is you set the lastBestScore to the currentScore value. 

    Now to persists and reload the lastBestScore value all you have to do is have one Local Storage action that stores the lastBestScore value either on game over or listen for the system exiting event on a rules component to trigger it. On level load you have another Local Storage action that loads the last stored lastBestScore value and sets it. That is all you need. Two properties and two local storage actions. One to store and one to load. 

    Its just like saving a document on your computer. You give the file a name and select the folder to save it in. When you want to read the document again you open the file with the same name.

    So the current score renderer should always read the "currentScore" property and the best score renderer should get its value from the "lastBestScore" property.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

Tagged