Posted on by

Storyboard StateWhile it’s fairly straight-forward to switch between scenes using the storyboard API, what’s not so obvious is how to manage persistent data even among scene changes.

The reason why this can be confusing is the fact that most storyboard scenes are represented by their own module (e.g. scene1.lua, scene2.lua), and it can be difficult to determine what the best way to share data across multiple files is, especially since scenes can be created and destroyed at any time.

In today’s tutorial, I’m going to show you a few ways that you can share data between scenes, and manage a singular overall “state” in your app despite the loading and unloading of multiple scenes—no matter how many you might be working with.

Parameter Passing

When you call storyboard.gotoScene() to switch from one scene to another, you can optionally pass in parameters that can be accessed from the createScene, willEnterScene, and enterScene events of the next scene.

In the example below, we’ll pass a “score” variable from the gameplay scene to the gameover scene:

gameplay.lua


-- ...

storyboard.gotoScene( "gameover", {
effect = "fade",
time = 800,
params = {
score = 100
}
})

-- ...

gameover.lua


-- ...

function scene:enterScene( event )
local score = event.params.score

print( "You scored: " .. score )
end
scene:addEventListener( "enterScene", scene )

-- ...

Persistent Variables

When you need to pass some data from one scene to the next, the parameter passing method I just showed you is probably your best bet. However, sometimes you need data to persist throughout the entire app, and be accessible from all scenes—for this, parameter passing isn’t very practical.

In this case, you can either use global variables (not recommended), or you can create a “state” table that’s attached to the storyboard object which will be accessible from all of your scenes (since all scenes must “require” the storyboard module).

Here’s an example of how to have a ‘score’ property that’s accessible from all scenes while still avoiding the use of globals:

main.lua


local storyboard = require "storyboard"

storyboard.state = {}
storyboard.state.score = 0

-- ...

gameplay.lua


local storyboard = require "storyboard"

-- ...

storyboard.state.score = storyboard.state.score + 100;
storyboard.gotoScene( "gameover", {
effect = "fade",
time = 800
})

-- ...

gameover.lua


local storyboard = require "storyboard"

-- ...

function scene:enterScene( event )
print( "Your score is: " .. storyboard.state.score );
end
scene:addEventListener( "enterScene", scene )

-- ...

Since all scenes must require( “storyboard” ), then they all share a common object. In main.lua, we declare a “state” table, so we can add as many variables to that table, that are accessible from all modules that ‘require( “storyboard” )’, without polluting the global namespace!

There are probably other ways to share data between scenes and across modules, but these methods are the ones we recommend. What are some other effective ways you’ve shared data across multiple modules and scenes?


Posted by . Thanks for reading...

8 Responses to “Managing State Between Scenes”

  1. Ben

    That’s super handy. I have been passing params when using gotoscene but it doesn’t work when using overlays and the hideOverlay command so this will come in very useful.

    Reply
  2. Michael

    I like your storyboard.state suggestion. I’ve been using either SQLite or a file to save state between storyboard scenes. If you don’t need to store a lot of date, look for ICE in the Code Exchange. It uses SQLite, but it hides the complexities.

    Reply
  3. Ugo

    Can someone explain to me why and how using Global variables is not recommended ?

    I have a GlobalVariables.lua where i store all my globals. Why is this method not recommended?

    Thanks, Ugo

    Reply
  4. Greg

    Re. “can either use global variables (not recommended)” – why is this the case technically? What is wrong with using a global myParams type variable?

    Reply
  5. Walter Fettich

    What about display objects? I am in the situation where someone can move a sprite in my scene and when he exits it and comes back the sprite has to be in the same place.

    There’s even a more complicated one where you can draw something and when you come back the drawing has to be there.

    How would I do that?

    Reply

Leave a Reply

  • (Will Not Be Published)