Page 1 of 1

Autosave Map

Posted: Mon Mar 08, 2021 7:01 pm
by visionok
Having lost a fair bit of mapping on a couple of occasions I decided to create a timer to autosave the map. The code itself is pretty much as per the wiki manual, I just changed the filename format to match the files that mudlet creates on closing profile.
Code: [show] | [select all] lua
local map_name = getTime(true, "yyyy-MM-dd#hh-mm-ss") .. "map"
local savedok = saveMap(getMudletHomeDir().."/map/" .. map_name .. ".dat")
local cmd
if not savedok then
  cmd = "Failed to autosave map\n" 
  echo(cmd)
  -- playAlert(cmd)
else
  cmd = "Map autosaved \n" 
  echo(cmd)
  -- playAlert(cmd)
end
I must add that mudlet itself has been very stable (no crashes so far), both those occasions were my fault. The first one I accidently deleted a whole group of stuff and there didn't seem to be any way to undo so I closed mudlet and didn't save profile. The second occasion I accidently created an infinite while-loop which locked up mudlet tight (the emergency stop button had no effect), so I had to kill mudlet.

Re: Autosave Map

Posted: Mon Mar 08, 2021 7:15 pm
by Zaphob
Why not expand upon this thread and share my take on the map autosaving script in here as well for comparison:

Code: Select all

mapper = mapper or {}
if not mapper.modifiedSinceBackup then
  echoM("Map was not modified. Skipping backup.")
-- elseif not mapper.connectedToGame then
--   echoM("Not connected. No backup necessary.")
-- BUT may have been changed anyway, then logged out without backup, so backup should happen anyway!
else

    mapper.backupVersion = mapper.backupVersion or 0
    mapper.backupVersion = (mapper.backupVersion + 1) % 5
    
    local fileName = getMudletHomeDir() .. "/map/backup" .. mapper.backupVersion .. ".dat"
    saveMap(fileName)
    echoM("Map backed up as: \n" .. fileName)
    
    mapper.modifiedSinceBackup = false

end

-- sysExitEvent
--    Raised when Mudlet is shutting down the profile 
--      a good event to hook onto for saving all of your data.
Just copy/paste this in a timer and set the duration as you see fit, maybe one hour or so.

Features include:
- Do not save if map was not changed since last backup at all
- Backup to more than one file, just in case something went wrong earlier (default is to keep 5 versions)

To check for updates, add a new line in all your functions that edit map data (create new rooms or areas, etc.) like this:

Code: Select all

mapper.modifiedSinceBackup = true
Also you need two simple scripts hooking into the sysDisconnectionEvent etc. and toggle the bool checked above

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE MudletPackage>
<MudletPackage version="1.001">
	<ScriptPackage>
		<ScriptGroup isActive="yes" isFolder="yes">
			<name>mapper.connectedToGame</name>
			<packageName></packageName>
			<script></script>
			<eventHandlerList />
			<Script isActive="yes" isFolder="no">
				<name>connected</name>
				<packageName></packageName>
				<script>function connected()
  mapper.connectedToGame = true
end</script>
				<eventHandlerList>
					<string>sysConnectionEvent</string>
				</eventHandlerList>
			</Script>
			<Script isActive="yes" isFolder="no">
				<name>disconnected</name>
				<packageName></packageName>
				<script>function disconnected()
  mapper.connectedToGame = false
end
</script>
				<eventHandlerList>
					<string>sysDisconnectionEvent</string>
				</eventHandlerList>
			</Script>
		</ScriptGroup>
	</ScriptPackage>
</MudletPackage>
These are the actual two scripts in a folder, you can just copy/paste the whole shebang into the scripts editor tree and be done.

Let me know how it works for you, or if somebody has another different approach to saving maps, feel free to share your style, too! :mrgreen:

edit: Included mapper table definition and updating modifiedSinceBackup

Re: Autosave Map

Posted: Tue Mar 09, 2021 10:44 am
by visionok
Interesting, I was going to implement "save only when map has changed" but using the simple condition of whether the number of mapped rooms has changed. But then I didn't bother since the save operation is quick and unobtrusive plus disk space is cheap.

However I'm curious to know how you check whether the map has changed. When I display(mapper) it returns nil, so I guess mapper is specific to your setup?

Re: Autosave Map

Posted: Tue Mar 09, 2021 1:09 pm
by Zaphob
Oh yes, I must have missed that. It's declared in another script and you can basically use an empty table in its place by putting this up front:

Code: Select all

mapper = mapper or {}
I was testing for changes, because I did not want 5 same versions saved to disk, eliminating the possiblity to go back before the very last changes.

Therefore, each of my mapper script's function that edits map data, has a line added as well just saying

Code: Select all

mapper.modifiedSinceBackup = true
It's not 100% fool proof, as I may move or edit rooms via mouse on mapper still, and it would not be counted as an actual change. But running around while mapping new areas will definitively not get lost anymore! :mrgreen: