Suggestion Issue: Savegame Location Settings


Pages: 1

Justin

  • Master Stencyler
  • *
July 16, 2020, 02:59:18 pm
Issues crop up from time to time with the default mechanism for saving games.

HTML5

Topic: HTML5 not creating permanent saves
Topic: HTML5 save/load does not work on some websites
Extension: Extra Save Blocks (HTML5 Save Fix)

iOS
Issue: Changing game name changes savedata path for iOS

We should provide a more user-friendly way of addressing these issues rather than requiring code blocks to be used. Not sure yet if that should be something in the UI, or more similar to rob1221's solution of specifying the path in a block.


Issue updated by Justin - July 16, 2020, 03:02:00 pm
  • Tags added: 4.1.0


Justin

  • Master Stencyler
  • *
July 19, 2020, 08:41:54 pm
Okay, after some time investigating, here's the current situation.

Stencyl saves and loads game attributes using the "save game" and "load game" blocks with no customization. The location that savedata is stored depends on the platform. On some platforms, and in some circumstances, it's possible for the path that savedata is stored at to change, leading to player saves being lost.

HTML5

HTML5 puts the save data into the domain's local storage at "${Browser.window.location.pathname}:mySave.sol".
This works when the game is always served from the exact same url.
If a single url were to serve multiple games, they would all write to the same local storage object.
If a single game were served from different urls, then the game would save to multiple local objects, and game saves could easily be "lost"
 - the url could change if a website's versioned API is updated (e.g. v2 -> v3)
 - the url could change if some other query parameters are passed through the url (?someParam=someValue)
 - there could just be multiple pages on the site where the game can be played
In short, the current default for HTML5 is very poor.

The existing workarounds for this are lime.app.Application.current.meta.set("localSavePath", "mygamename");, which changes the path to mygamename:mySave.sol.
There's also rob1221's engine extension, which does the same thing, but includes an argument in a custom block for the save path instead of storing it at localSavePath.

Flash

Flash puts the save data into a SharedObject for the SWF at "[SHARED_OBJECT_CONTAINER]/mySave.sol". For local files and for web content both, this is pretty platform specific, but either way has a pretty high chance of being lost if not careful. However, since the SharedObject method of saving game data should be pretty universal for Flash content, all websites that accept Flash games most likely account for this. Plus Flash is dying/dead, so it doesn't matter as much as the other platforms.

Native (Desktop + Mobile)

Native targets store games inside the "applicationStorageDirectory", which is retrieved by SDL_GetPrefPath(organization, application).
This means different things for each platform. Currently, the "organization" passed here is always "Stencyl", and the "application" is
always the game's filename.

Android:
   SDL gets the path from Context.getFilesDir()
   - this one ignores both organization and application. It's quite variable across different android devices and versions, so no example given.
     But assuming Android vendors do their job right, none of this should matter.
macOS / iOS:
   SDL gets the path from NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)[0]/$org/$app
   Example: /Library/Application Support/Stencyl/My Game/mySave.sol
Linux:
   If the XDG_DATA_HOME environment variable is set, SDL gets the path from $XDG_DATA_HOME/$org/$app
   Otherwise, SDL gets the path from $HOME/.local/share/$org/$app
   Example: /home/bob/.local/share/Stencyl/My Game/mySave.sol
Windows:
   SDL gets the path from ${SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, $org/$app)}
   Example: C:\\Users\\bob\\AppData\\Roaming\\Stencyl\\My Game\\mySave.sol

The problem with this, is that we default to using the game's "file name" for the second part. This is based on the name of the game in Stencyl, which may be changed quite often by developers across the development lifecycle of their games, and even between updates. This translates to lost player saves on all platforms (except Android, where game name is ignored). On macOS only, "file name" is actually taken from the "App Name" field instead of the Stencyl project name.

The existing workaround for problem number 2 is to use lime.app.Application.current.meta.set("file", "My Game");, specifying the "file name" your game had when it was first released.


Pages: 1

Details

  • Reported
    July 16, 2020, 02:59:18 pm
  • Updated
    July 21, 2020, 12:58:28 am

  • View Status
    Public
  • Type
    Suggestion
  • Status
    New
  • Priority
    Normal
  • Version
    (none)
  • Fixed in
    (none)
  • Assigned to
    (none)
  • Category
    (none)

Tags