Saving/Reloading Map After User Changes

I’m attempting to allow the user to modify a map, save this and reload the edited map upon reboot of the app. I’m following Dyson’s earlier suggestion of saving the table returned by getMap() as a json string and reloading this instead of the default map file.

The only problem I’m facing is with the new lighting system; it’s been awhile since I last updated MTE - so the new lighting system is completely new to me.

The problem I’m facing is that when loadMap() reached the following code with the edited json file:

[lua]

if not storageToggle then
  if map.properties.lightLayerFalloff then
   map.properties.lightLayerFalloff = json.decode(map.properties.lightLayerFalloff)
  else
   map.properties.lightLayerFalloff = {0, 0, 0}
  end
  if map.properties.lightLevelFalloff then
   map.properties.lightLevelFalloff = json.decode(map.properties.lightLevelFalloff)
  else
   map.properties.lightLevelFalloff = {255, 255, 255}
  end
end

[/lua]

The problem seems to be that with the edited json file map.properties.lightLayerFalloff is already a table and so the json.decode() call fails. I have added a type check in each statement to see whether the variable is alreaddy a table that appears to overcome the issue, but just wanted to make sure there wasn’t a “better” way and/if whether this is going to cause any issues down the line.

Like I said it’s been awhile since I stepped through MTE, so any help would be appreciated.

Hello SegaBoy,

A slightly simpler solution would be to change “if not storageToggle then” to “if not map.modified then” 

Thanks Dyson - like I said it’s been awhile since I updated MTE, when I last checked there didn’t appear to be any features for saving changes to a map - can I assume that the map property you mentioned above (map.modified) suggests there is now built in functionality? I don’t want to be reinventing the wheel if it’s already there - particularly because it could cause further issues with MTE down the line?

By the way - noticed you’re now an Enterprise subscriber - hope the good guys at CL gave that to you in acknowledgement of the awesome work you’re doing with MTE :slight_smile:

Yes, the folks at Corona SDK have been very generous. It’s great to know they find what I’m doing to be so valuable!

Map.modified is just a flag put in the map table so MTE can tell the difference between a map loaded fresh from its original file and a map either previously stored in memory or saved to a new file in the way you’ve described. It uses the flag to avoid doing work already done, like incrementing through an original file’s one-dimensional layer data to convert it to two-dimensional data.

But, on the subject of built in functionality, how do you think a function call to save a map should look? I’m thinking something slimple like saveMap(path, directory) should be sufficient, but I haven’t given it much thought yet. It really would do more or less what you have to do yourself: create a path to a file, encode json data, and save the file in the directory specified.

Good news - we all consider your work valuable.

I was contemplating adding the functionality into MTE myself - at the moment I’ve got everything outside (I have a Game_Map class that has a handle to MTE), but thought if I can get it all working might be a nice addition - I guess if you’ve got a loadMap, saveMap kinda goes hand-in-hand.

I use a very simple approach that I believe you recommended - at a very early stage in my project I have three tile layers (water, soil, grass), and allow the user to “dig” these and shape the terrain using updateTile(). When the user exits the app I simply call getMap(), jsonify it and save it to disk. Upon startup I check to see whether the file exists and if so load this version, otherwise load the default file.

It’s early days however this provides the basic functionality I’m after - not sure whether there are many other use-cases beyond that?

I did some work on this today. The function I’ve come up with is saveMap(map, file, directory). Every argument is optional. If map is nil, the currently active map is saved. If file is nil, the file defaults to the filename of the map. If directory is nil, the file is saved in DocumentsDirectory. Simple approaches do tend to be more flexible.

Hello SegaBoy,

A slightly simpler solution would be to change “if not storageToggle then” to “if not map.modified then” 

Thanks Dyson - like I said it’s been awhile since I updated MTE, when I last checked there didn’t appear to be any features for saving changes to a map - can I assume that the map property you mentioned above (map.modified) suggests there is now built in functionality? I don’t want to be reinventing the wheel if it’s already there - particularly because it could cause further issues with MTE down the line?

By the way - noticed you’re now an Enterprise subscriber - hope the good guys at CL gave that to you in acknowledgement of the awesome work you’re doing with MTE :slight_smile:

Yes, the folks at Corona SDK have been very generous. It’s great to know they find what I’m doing to be so valuable!

Map.modified is just a flag put in the map table so MTE can tell the difference between a map loaded fresh from its original file and a map either previously stored in memory or saved to a new file in the way you’ve described. It uses the flag to avoid doing work already done, like incrementing through an original file’s one-dimensional layer data to convert it to two-dimensional data.

But, on the subject of built in functionality, how do you think a function call to save a map should look? I’m thinking something slimple like saveMap(path, directory) should be sufficient, but I haven’t given it much thought yet. It really would do more or less what you have to do yourself: create a path to a file, encode json data, and save the file in the directory specified.

Good news - we all consider your work valuable.

I was contemplating adding the functionality into MTE myself - at the moment I’ve got everything outside (I have a Game_Map class that has a handle to MTE), but thought if I can get it all working might be a nice addition - I guess if you’ve got a loadMap, saveMap kinda goes hand-in-hand.

I use a very simple approach that I believe you recommended - at a very early stage in my project I have three tile layers (water, soil, grass), and allow the user to “dig” these and shape the terrain using updateTile(). When the user exits the app I simply call getMap(), jsonify it and save it to disk. Upon startup I check to see whether the file exists and if so load this version, otherwise load the default file.

It’s early days however this provides the basic functionality I’m after - not sure whether there are many other use-cases beyond that?

I did some work on this today. The function I’ve come up with is saveMap(map, file, directory). Every argument is optional. If map is nil, the currently active map is saved. If file is nil, the file defaults to the filename of the map. If directory is nil, the file is saved in DocumentsDirectory. Simple approaches do tend to be more flexible.