Saving/loading questions (SOLVED)

  1. How can i save more than 1 table in the same file? A table containing the stars after clearing the level, a table containing the game options, etc.
  2. When using pprint(my_table) i can see “1 = value”, instead of 1 how can i see the name of the table?

An example:

I want to save in the same file, the stars you got after completing every level, the game options, the player coins and lives, player current stage… Load everything at game start and at any point access the coins table stored in the file and check the value for example.

2 Likes

sys.save() and sys.load() expect a filename and a table as the only arguments, but there’s nothing preventing the table from being as simple or complex as you want it to be. Put everything you wish to save in a table and pass it along to sys.save():

local save_state = {
	level_stars = { 3, 2, 1, 2, 3, 0 },
	options = { sound = true },
	coins = 12345,
	lives = 2,
	current_level = 6,
}

local success = sys.save(sys.get_save_file("my_cool_game", "save_state"), save_state)

As for your question on pprint() I think you’re missing something about how Lua tables are constructed. Somewhat simplified you could say that Lua tables can work either as a 1-indexed arrays or as key-value maps. This would be a 1-indexed array-like table:

local array  = { "foo", "bar" }

In this case print(array[1]) would print “foo” and print(array[2]) would print “bar” and pprint(array) would print:

{
  1 = foo,
  2 = bar,
}

Here’s an example of a key-value mapped table:

local map = { foo = "bar", key = "value" }

In this case print(map.foo or print(map["foo"]) would print “bar” and pprint(map) would print:

{
  key = value,
  foo = bar,
}

As you can see, in neither case a pprint() will print the name of the table itself. This is the expected result. Passing something as a parameter to a function call is a matter of passing the actual value, not the name of whatever variable this value might have been assigned to.

5 Likes

Oh, one more thing about Lua tables. They don’t have to be either indexed or keyed, they could just as easily be a mix:

local some_table = { "foo", "bar", key = "value" }

And the values don’t have to be all of the same type either. You can mix as much as you want:

local some_table = { 1, 2, 3, "foo", "bar", function() end, nil, { "some", "nested", "table" }}

and how can i change one of the values inside level_stars table? save_state.level_stars[1] = new value?

Yes, that’s exactly how you’d go about doing it. It’s just a bunch of nested tables and table access.

Any way to check if the saved file exists? To create the file only the first time that the player plays the game.

And how can i access this table from other script?

The documentation for sys.load() specifies that it returns “loaded lua table, which is empty if the file could not be found”. So, try to load the saved file and if you get back an empty table create it with some default values.

If you want to share some state between multiple scripts then you have a few options:

  1. Never keep this table in memory and always load and save it wherever you need it. This essentials means that you’re sharing the file and not the table. This has some disadvantages of course. The most obvious being that you have a lot of identical sys.load() and sys.save() calls in your code. If you need to make a change you need to change in multiple files.
  2. Load the table in a boot/loader/init script and load it into a global table. Modify this global table in the scripts that need to access the table. Save the table in the final() function of the script that loaded the table. The obvious drawback with this approach is that you’re storing the table as a global variable with all the disadvantages this entails.
  3. Create a Lua module to deal with loading, saving and manipulating the data. require() this module from wherever you need to access the data. This encapsulates the table nicely and allows you to change the how and where you get the save state from (maybe you want to add cloud saves or something in the future). This is my recommended approach.
2 Likes

OK, I’ll use the 3rd method. Thanks a lot for all the help!!

Can anyone give example of the option 3

Here’s one example: DefSave

1 Like