FileSystem workflow is quite uncomfortable for more advanced uses.

0 favourites
  • 9 posts
From the Asset Store
With this template you will learn how to use the GooglePlay Games native plugin
  • I used to use NW.js for file operations, but recently tried out FileSystem so that I can support WebView2.

    Technically, there's nothing that's not doable with FileSystem, but the workflow felt cumbersome.

    - 'List contents' has to be run before 'Has file/folder' can be done.

    - You have to 'List contents' even for known directories like "<documents>"

    - 'Has file/folder' cannot be done with a folder path afaik, you have to 'List contents' again if you want a subfolder.

    - To read any file, you need another event, 'On file operation complete'

    - You can't send any data with the read file operation, nor get the name or location of the file. The only data available is FileSystem.FileText

    - If the FileTag of the file operation is varying or unknown, you need to use 'On any file operation complete' and then compare the FileTag. I found the workaround of setting the FileTag to something like...

    "readFile " & fileName & " " & fileDir

    ...to be a good way to send data with the request, then I can get these values with tokenat(FileSystem.FileTag, n, " ")

    The reason I need more data with read file operations is because I have worked on a few games with level editors, and on a recent one, user levels are saved in a location and the player can make as many as they want. Since I don't know how many levels they may have, loading these levels into the in-game UI becomes a little more complicated. I've also experimented with making games moddable, where levels might be loaded from lots of JSON files and assets.

    In any case where the amount of files is unknown, it becomes more annoying to work with FileSystem.

    NW.js's workflow was very compact and easy in comparison, even ignoring the fact that it's synchronous.

  • I agree with much of this!

    I am 4+ years into a project, with NWJS events scattered everywhere. I attempted to design my project to keep file operations inside common functions, but that failed over time and file actions are peppered across the project. I foresee it being a journey to replace all nwjs events, but of course this would be much more easier if FileSystem was not Async (or had option to choose from async or not), as this could be a near-direct-replacement easily if actions and such were not async.

    However, async isn't inherently "bad", but it's certainly not easy to "move over" to in a current project, and requires different forms of design/thinking when planning your systems due to async. Doable, but a lot of effort and can be a lot more advanced to design. I would disagree if it was the case that "It should have always been async, therefore going forward it will only be async", I think choice and options are good, I do agree that it's ideal to use async, but it's not "easy" per say compared to non-async, so having the choice feels far more desirable - I can see myself using both async/non-async for different systems in my project. Let the devs realise that "non-async with big file operations may freeze your game", but this may be rare/non-existent for most devs, as small file operations would occur most of the time, plus I doubt beginners would be attempting filesystem operations with huge files as their first projects and can be pointed to the other option when they ask for help. Choice is good!

    I am also a "advanced level editor" kind of person - Only needing access to a folder in "Documents", but lots of paths, folders, subfolders etc.

    I explored filesystem in past, but haven't recently (although was ramping up with excitement with seeing updates and seemed to be parity occurring between nwjs and filesystem plugin).

    I believe that filesystem/webview adoption could work out better if there was exact parity AND something else tempting (random example: what if file-system allowed zipping/unzipping - Something new and desirable to make people "want" to move to WebView2). In current form, I foresee "Lots of work to move to filesystem, to then use webview2, which has murmurs of issues occurring". Whereas, if extra features were offered for WebView2 that are desirable and cannot be achieved in NWJS, then that may sway many devs into using WebView2, even if there's a different set of bugs to deal with. I'm not aware/creative enough to think of possible features, the ZIP one would be amazing (there's old third party one, ironically NOT async and locks-up game when using and breaks on Worker Mode), and personally a ZIP feature, even if just for Windows only and not Mac/Linux, would immediately motivate me to move to WebView and rewrite all my NWJs events to handle async, without a doubt in my mind. This is a not-so-subtle suggestion but I promise I'm not trying to be cheeky, I think ZIP stuff relates to the topic, as advanced users of file operations may wish to zip level editor files and such to make it easier to distribute mods/levels/custom content, rather than utilising 3rd party software or asking players to zip it themselves. Then players can drop files onto the game, WebView unzips wherever we wish, boom, done, mod support! If "ZIP" stuff or other features could be a general HTML5 implementation, then WebView could still have features to benefit from it, maybe allowing "If you open your WebView EXE with a file parameter, then pass the file paths into the game if it's already open, or open the game with the paths", allowing devs to make custom file extensions for their "mod" files (AFAIK NWJS does not support this as of now, can't open NWJS EXE with a file path and feed this into the game, nor detect if game is already open when trying to open EXE with filepaths and feed paths into running game).

    One thing I like about FileSystem is that it "auto-creates a folder structure", if you enter Documents/Test/A/B/C/, it creates each folder instantly, that's a great benefit!

    In fairness of WebView2, although again, not certain, but, perhaps it is viable in it's current state - So long as you can indeed "list contents", even if many times, then collecting an array of paths is doable (Not sure how easy it is to then revisit a path and such, much like NWJS being instant/easy).

    I think the export option should have a "Bundle with WebView2 Version", much like NWJS does - I immediately have 0 interest in an auto-updating WebView2 system - I hate to imagine waking up one day, and game on steam dies on many computers due to a WebView2 update. Sure, this could happen with any windows update, but it would make WebView2 games stand out when all other Steam games are fine, basically rendering "only C3 games" breaking on Steam. I have 0 interest looking into a "Manual" solution to bundle WebView2 versions and such, the convenience of the build service offering all versions of NWJS is extremely helpful and easy - And I'm a long term user, I can imagine beginners wanting the easy route more than me!

    I am mixed on how to determine whether to move to WebView2 or not, and do have fright from NWJS getting stuck on a LTS version (as I always use beta), but of course I don't foresee NWJS disappearing if WebView2 hasn't reached a close parity (which it is certainly approaching).

    EDIT: How far can WebView exports be expanded upon with plugins, in sense that, if there were hard-limits with FileSystem API and it "must" be async, "must" list files before checking they exist, and "must" have certain rules in place, could a Scirra-made C++ extension bypass some of this?

    This could allow for parity with NWJS plugin, and perhaps other desirable features for benefiting a WebView export, like setting menu bar options and such (much like the nwjs plugin has)?

    I recognise the desire to keep all file operations under 1 plugin, and it's a fair philosophy to follow, but if it dampens potential for specific exports, that would be a shame. We know that FileSystem plugin doesn't work for Android as of now, but if there was a way to have an alternative method for Android filesystem access and it was in demand, I'd predict Scirra would support this anyway, even if temporary.

    Maybe the FileSystem plugin could detect that it is a WebView export and utilise the C++ extensions without the user's knowledge. I would even take a "WebView" plugin that has it's own set of FileSystem actions and such, much like NWJS currently does - Even if this is a step back at compacting all file operations into 1 plugin, I think this is a excellent way to keep parity, allow choice for devs.

    I know it may be a back-n-forth with the history of WebView, where there was already a unique plugin for file system stuff, which is now removed, which may then return, BUT it could aid with eliminating NWJS, get more on board, wouldn't affect anyone that currently uses FileSystem plugin and their async systems will continue to work, and could open extra doors/features for WebView exports to make it desirable to move to WebView2, overall encouraging devs to want to move to WebView, rather than that they have to move.

    WebView2 clearly is the best path forwards and gives Scirra the most control they have ever had over desktop exports - I feel the excitement, and it's close to being a no-brainer to switch over to.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I'm afraid the File System plugin must use async operations. It is not possible to use synchronous file system operations either in the browser or in our desktop wrappers.

    We went through a similar process years ago with the WebStorage plugin, which used to use a synchronous browser storage API, which then got replaced with the Local Storage plugin which is asynchronous (and uses IndexedDB internally). Yes, async logic can be harder to work with, but it's necessary. We've also made various improvements over the years to better handle it, like with 'Wait for previous actions to complete', async functions in event sheets, and so on. People also then adapted how they use storage - rather than lots of individual keys, a popular option now is just to use a Dictionary with multiple keys and save/load it all in one go, which is much easier to deal with.

    You used to even be able to do things like synchronous network requests - nobody seriously considers that now, and it's widely seen as a mistake, and a terrible idea to keep using it. Storage usually responds quicker than the network, but IIRC I've seen data showing there's a long tail of devices where storage is shockingly slow - perhaps it's ancient hardware, perhaps it's failing, perhaps the system is busy in the background, but I do think it's naive to assume "storage always responds quickly and so synchronous is fine". All modern software uses asynchronous access for the network and most uses asynchronous access for storage - it's the best way, and, well, in this case outside of NW.js it's the only way. So my main point is this is the modern and proper way of doing it anyway.

    To address a few of the other points:

    - You have to 'List contents' even for known directories like "<documents>"

    Why would the app know what's on disk without checking?

    - 'Has file/folder' cannot be done with a folder path afaik, you have to 'List contents' again if you want a subfolder.

    I guess it could work recursively, but then that is potentially a very slow operation if it is going to end up reading through a lot of folders. That kind of thing definitely cannot be synchronous.

    - To read any file, you need another event, 'On file operation complete'

    That's just like with AJAX requests. You can also use the 'Wait for previous actions to complete' action and then read the data in the next action after that.

    I think the export option should have a "Bundle with WebView2 Version"

    It does - see the docs on fixed distribution modes.

  • I don't mind FileSystem having async operations much. It does lengthen workflow, but I'm surprised NW.js wasn't async anyways.

    Why would the app know what's on disk without checking?

    I dunno, but NW.js seems to know. All I need is a folder path and it can read a file from it. NWjs.ReadFile(dir)

    Outside of sync/async, is that something WebView2 just isn't capable of for technical reasons?

    I guess it could work recursively, but then that is potentially a very slow operation if it is going to end up reading through a lot of folders. That kind of thing definitely cannot be synchronous.

    I would love the option. Maybe a toggle?

    Lastly, I would still like the FileTag workaround I found to be not necessary. You didn't really address the difficulty in using FileSystem with an unknown/customizable amount of files.

  • Call me silly but I don't fully trust "Wait for previous actions to complete" I almost always use the trigger conditions. Feels more robust to me, can't explain it. There were some bugs with "wait for previous" when it was introduced iirc, maybe that's why. It does come in handy in some cases though.

  • Since that's the subject, I'd use some directions... i need to:

    1) open a specific folder to pick a file for opening -> "Documents/GameName/" & var1 (the name of a folder created for the specific game you're playing)

    2) open one of the files listed (it's an image)

    I've tried following the manual, but i can't get to grasp it, NW was so straightforward!

  • Call me silly but I don't fully trust "Wait for previous actions to complete" I almost always use the trigger conditions.

    Yeah, I also do not consider using "Wait for prev." to be an option. It will always wait for previous actions, but it was recently discovered that it also waits for actions outside of the event's scope.

  • Danwood - you also posted that question here, please don't cross-post your question in other threads (see the Forum & Community guidelines).

    Back on the topic of using File System, this week's beta r418 includes some improvements to try to make it easier to use: it now has expressions to get the folder path and picker tag in triggers, which should help identify which file the trigger is for. You can now also use 'List contents' recursively to list files and folders including all subfolders, which should mean you can just list contents for the root directory of your game's data and then be able to easily access the full existing folder structure. Hopefully that all makes it easier to use for more complex cases. As I mentioned we can't go back to synchronous, but if there are any other changes we could make like this to help, then let me know.

  • I saw the improvements, I think they'll help a lot! I'm still not a fan of the workflow of having to 'list contents' first, but I think the recursive option will be a huge help in how many times it realistically has to be called.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)