question about handling JSON

Hi guys! Today I’m going to explain the way I’m handling the json files and I have a question.

Let’s go to the point

I have an small external module, 75 lines of code, that contains images references, basic functions that I will use and the game settings.

This is the way I’m saving data in json files:

--data.lua ---------------------------------------------------------------- --save game settings local json = require("json") local loadsave = require( "loadsave" ) local gameSettings = {} gameSettings = (loadsave.loadTable("gameSettings.json") or {}) M.currentLevel    = (gameSettings.levelNumber or "1") M.numOfLives      = (gameSettings.livesNumber or 3) M.musicStatus     = (gameSettings.musicPlaying or "on") M.updateSettings = function()   gameSettings.levelNumber     = M.currentLevel   gameSettings.livesNumber     = M.numOfLives gameSettings.musicPlaying    = M.musicStatus   loadsave.saveTable(gameSettings, "gameSettings.json") end M.printSettings = function()   print("GAME SETTINGS ==\n", json.prettify( gameSettings ) ) end

In my levels I update the information of the variables, for example, every time a level is completed in that function I do this.

local function levelCompleted(event)      --reset lives in JSON      data.numOfLives = 3      print("Resetting lives", data.numOfLives )      data.updateSettings() end

Now, in some data like the number of lives in the previous example everything is going well, but in some occasions, like for example, with the music on or off, the only way to maintain the value is to make a summary of the values in the scene:show and update those values every time the scene is displayed.

-- show() function scene:show( event )  local sceneGroup = self.view  local phase = event.phase  if ( phase == "will" ) then   -- Code here runs when the scene is still off screen (but is about to come on screen)      elseif ( phase == "did" ) then   -- Code here runs when the scene is entirely on screen    print( "Current scene = Level 3" )         data.currentLevel    = "3"     data.numOfLives      = gameSettings.livesNumber     data.musicStatus     = gameSettings.musicPlaying     data.updateSettings() data.printSettings() end end

and in this way I have not had any errors, like for example the music stays off or on as I select it in the game menu. Practically the whole game has the same logic to save and read data from the json files.

Question:

Is it necessary to rewrite the values to the json file, for example, as I am doing in the scene:show, or simply write only what I need to add to the table or replace existing values?

I have to say that I use composer and every time I finish a level or change of scene I destroy the previous scene.

Thanks in advance

DoDi

To save data to json you do have to provide all of the data you want to save, as your are doing now.  

However if you want to only write code for variables that change, I’d suggest having a module which controls the json data entirely and has functions to retrieve an entry or replace it. 

Very crude example:

--jsonManager.lua local jsonManager = {} local jsonData = json.decode(initialLoadOfYourJsonStuff()) local function saveData() someFunctionForSavingData(jsonData) end function jsonManager:get(variableName, defaultValue) --provide a default value, if this variableName does not exist in json data then return the defaultValue return jsonData[variableName] or defaultValue end function jsonManager:set(variableName, newValue) jsonData[variableName] = newValue saveData() end return jsonManager

--scene1.lua local jsonManager = require("jsonManager") --will get "currentLevel" from json data, or return 1 if "currentLevel" does not exist local levelNumber = jsonManager:get("currentLevel", 1) --will get "numOfLives" from json data, or return 3 if "numOfLives" does not exist local currentLives = jsonManager:get("numOfLives", 3) local function endGame() --set the value of "numOfLives" in json data to the current value of the currentLives variable jsonManager:set("numOfLives", currentLives) end

So now you only have to call jsonManager:set() for variables that you want to change, and any other variables will remain as they are. 

The key to all of this is that there is only a single lua file which truly reads/saves the json data, and then just passes it to other files and takes requests to save new data.

To save data to json you do have to provide all of the data you want to save, as your are doing now.  

However if you want to only write code for variables that change, I’d suggest having a module which controls the json data entirely and has functions to retrieve an entry or replace it. 

Very crude example:

--jsonManager.lua local jsonManager = {} local jsonData = json.decode(initialLoadOfYourJsonStuff()) local function saveData() someFunctionForSavingData(jsonData) end function jsonManager:get(variableName, defaultValue) --provide a default value, if this variableName does not exist in json data then return the defaultValue return jsonData[variableName] or defaultValue end function jsonManager:set(variableName, newValue) jsonData[variableName] = newValue saveData() end return jsonManager

--scene1.lua local jsonManager = require("jsonManager") --will get "currentLevel" from json data, or return 1 if "currentLevel" does not exist local levelNumber = jsonManager:get("currentLevel", 1) --will get "numOfLives" from json data, or return 3 if "numOfLives" does not exist local currentLives = jsonManager:get("numOfLives", 3) local function endGame() --set the value of "numOfLives" in json data to the current value of the currentLives variable jsonManager:set("numOfLives", currentLives) end

So now you only have to call jsonManager:set() for variables that you want to change, and any other variables will remain as they are. 

The key to all of this is that there is only a single lua file which truly reads/saves the json data, and then just passes it to other files and takes requests to save new data.