• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Asset - Extension Non-sandboxed filesystem access

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
upload_2017-3-7_17-16-57.png
Marketplace: https://marketplace.yoyogames.com/assets/5172/non-sandboxed-filesystem
Demo (itch.io): https://yellowafterlife.itch.io/gamemaker-nsfs
Documentation: http://yal.cc/r/17/nsfs/
Price: $3.99
Modules: Windows (is a DLL)

This extension offers quite a number of functions that allow the games to work with filesystem without "sandbox" restrictions, meaning that you can save to program' directory, read outside of AppData, and so on.

It also expands upon the built-in functions, offering more tools for working with directories, file attributes, and encoding.
Full list of supported functions got a little long so is now available in documentation.

While some functions are yet to be implemented, this can be bypassed by copying the given file/directory into the sandboxed directory and working with it via standard functions there.
 
Last edited:

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Worth it for that alone...


Do you reckon there's a way to do this for Mac & Linux builds as well? (I've no clue)
Yes - I'll be getting to that shortly. There are some differences between filesystem functionality works between Windows and Unix-based systems, but I do intend to cover majority of functions supported for Windows version.
 
S

Sam (Deleted User)

Guest
I feel kinda bad because I think I may be a part of the reason why YYG made it sandboxed to begin with. I used GameMaker Studio to make a game creation tool I called "Adventure Window"... It relied heavily on not being in a sandbox, and I'd imagine they don't like the idea of a product competing with theirs, that was made in theirs. lol.

Anyway, this is very useful. I recomend adding more platform support and a higher price tag. :)
 
R

renex

Guest
I'm probably buying this myself, I like my games to be easily user-moddable and the sandbox pisses me off.

I think I may be a part of the reason why YYG made it sandboxed to begin with.
I also had a complete file-based 3d fps/rpg engine at some point. Me and my friend actually decided to use 8.1 simply because of the file system limitations in studio, and eventually the project was abandoned due to 8.1 being largely obsolete and hard to work with. If Studio had no sandboxing, it would probably still be receiving work from us.
 
R

ryanmc.nz

Guest
Idea for YoYo: Make sandbox enabled by default, BUT:
- Have separate functions for non-sandboxed IO but simply make them not available unless you tick an option somewhere (also make the option have a nag about "make sure you test your file paths on every platform, YoYo is not responsible for miss-use of non-sandboxed file IO!").

This would at least allow your company to dismiss customers that haven't done their file paths correctly (if a support issue is about file IO, you can tell them to check this option..and even get a chuckle out of telling them to read the nag), and it would also allow me to test a project idea that's only a couple of lines of code without having to spend $4 on an extension that I might not even use :)
 
F

Falconsoft-Industries

Guest
I hate to say it but "someone nasty could create a virus using game maker with those functions" not that I would ever, I hate viruses.
 
A

amusudan

Guest
I hate to say it but "someone nasty could create a virus using game maker with those functions" not that I would ever, I hate viruses.
The same is true for any other engine that isn't sandboxed, and by-the-by I doubt anyone will be makign a virus in GM with other tools available.
 

Micah_DS

Member
Just building off of the above comment:
GameMaker would be very restricted if it got rid of everything that could be misused in some way. The tool doesn't need to change, but people's misuse of the tool is what would need changing - the tool isn't at fault when people misuse it. And if the tool is dumbed down, the people who would otherwise use it properly now find the tool less useful, and in some cases they even find that the tool is now incapable of doing the job they require.

I get where you're coming from @Falconsoft-Industries, and it's unfortunate there are some people out there who like creating harmful software, but it'd be an even more unfortunate situation to let a fear of that ruin a great tool like this.

On that note, I'll likely buy this in the future. I'll need it for a project in which I plan to allow the player to create custom content. A little sad it's Windows only atm, but I think I might be alright with that, I guess.. maybe.
 
R

ryanmc.nz

Guest
I hate to say it but "someone could stab a person with a screwdriver like this one" not that I would ever, I hate violence.
I hate to say it but "someone could drive over the speed limit with a car like this one" not that I would ever, I hate speeding.
All cars in the world are now restricted to the speed of a sloth.. even on race tracks.
 
Last edited by a moderator:
B

BPzeBanshee

Guest
Hello YellowAfterlife,

I tried out the demo and found some of the functions did not work correctly or return something other than expected values but otherwise worked correctly, listing as follows:
file_move_ns returns 0 but works
file_rename_ns returns 0 but works
directory_copy_ns returns 0 but works
directory_move_ns returns 0 but works
directory_rename_ns returns 0 but works
directory_delete_ns returns 0 (OK) and works, but inconsistent with file_delete_ns which returns 1 but successfully deletes
file_text_open_read_ns crashes the app, even trying to open textfiles made with the file_text_open_write_ns function

I'm familiar with the normal convention of returning 0 for successful scripts in most languages but that doesn't seem to be consistently applied across the commands here. I'm considering this for replacing GMFileSystem which in my experience has had issues running on some machines especially old XP machines and newer machines that lack whatever runtimes it needs (which from preliminary tests this thing blows those issues right out of the water) but I want to be sure the functions work and return consistent error codes before going ahead with the purchase.
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Hello YellowAfterlife,

I tried out the demo and found some of the functions did not work correctly or return something other than expected values but otherwise worked correctly, listing as follows:
file_move_ns returns 0 but works
file_rename_ns returns 0 but works
directory_copy_ns returns 0 but works
directory_move_ns returns 0 but works
directory_rename_ns returns 0 but works
directory_delete_ns returns 0 (OK) and works, but inconsistent with file_delete_ns which returns 1 but successfully deletes
file_text_open_read_ns crashes the app, even trying to open textfiles made with the file_text_open_write_ns function

I'm familiar with the normal convention of returning 0 for successful scripts in most languages but that doesn't seem to be consistently applied across the commands here. I'm considering this for replacing GMFileSystem which in my experience has had issues running on some machines especially old XP machines and newer machines that lack whatever runtimes it needs (which from preliminary tests this thing blows those issues right out of the water) but I want to be sure the functions work and return consistent error codes before going ahead with the purchase.
Ah indeed. Currently the functions mostly return whatever WinAPI returns, which in some cases is status code (non-zero is error that can be looked up on MSDN) and bool in others (actual error code being then obtained via a context-specific function). A bit of a mess really. I can make the functions all return true/false and have a separate function that returns the error code for when false was returned.
 
B

BPzeBanshee

Guest
I suppose that makes sense, it's just with the demo I had no context with which to understand the return values - I imagine script code comments would be sufficient for me personally but I'll leave the rest to your judgement.

With file_text_open_read_ns, am I doing something wrong there or is that crashing for you as well? That's probably the biggest deal breaker for me but at least workaroundable via file_copy_ns and using GM's own file_text_open_read I guess.
 

DukeSoft

Member
This is so weird. You have to make an extension to overcome a "feature" YoYoGames built in themselves. Not to blame you, YellowAfterLife, but why in heavens name does GM do this sandboxing stuff? Its really annoying.

Ontopic question; any idea on when the Mac / linux versions will be coming?
 

Mike

nobody important
GMC Elder
Fundamentally so that you don't care what OS you're running on. When reading files from windows, they come from a simple folder, when reading from Android the come from a ZIP, when reading from HTML5 they come from a URL, when reading from console they can come from, hell....anywhere those whacky console guys decide.

This is even more true of saving. on windows you can't save to program files - where you normally install things, so it's redirected. On Android, you can't save to the ZIP, so again redirected, HTML goes to local storage, console goes to save "slots" - they almost all differ.

So next time you complain that you can't save to "c:\temp\mygame.dat" remember that when you do finally decide to put it on another platform, you won't have to worry about the fact nothing has c:\ except windows, and all these "funny" locations are handled for you.

In GM8.x days the number of test programs from users we had that saved to absolute file locations was mind boggling (not to mention a little concerning that noobs could save to sensitive areas), now no one has to worry about it.
We didn't do it for the fun of it.

You can of course use get_open_filename() and get_save_filename() to load and save from anywhere the user decides to load/save from.
 

DukeSoft

Member
Fundamentally so that you don't care what OS you're running on.
Ah, okey, then I guess I misunderstood the intention. I actually thought it was to keep GM games off the anti-virus scanners.

You can of course use get_open_filename() and get_save_filename() to load and save from anywhere the user decides to load/save from.
True, allthough this is kind of annoying in fullscreen games - the window opens up below the game - and you have to alt+tab. I would make my own file explorer in the game, but I also can not save or read outside of the games' directories without using these functions. So in essence GM is now forcing me create (or use) an extension that would allow me to these things, for every platform. Where before, I only had to write GML, for - in my case - the most important platform.

But well, at least we have the extensions which will allow for us to do what we want. I can understand that you went with the sandbox solution instead of writing GML handles for the storage on each and every platform.
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Ontopic question; any idea on when the Mac / linux versions will be coming?
Will likely start working on that after I publish the Lua extension and finish some more contract work - to date the extension made approximately $20 (post-store-fees, pre-taxes), which does not provide extensive justification for prioritizing it over other tasks.
 

Mike

nobody important
GMC Elder
True, allthough this is kind of annoying in fullscreen games - the window opens up below the game - and you have to alt+tab. I would make my own file explorer in the game, but I also can not save or read outside of the games' directories without using these functions. So in essence GM is now forcing me create (or use) an extension that would allow me to these things, for every platform. Where before, I only had to write GML, for - in my case - the most important platform.
Again, this wouldn't work on consoles...on mobile... on HTML5. GMS is a cross platform tool, and one of it's primary aims is to make it as seamless as possible to move between platforms. If you had to do mountins of work in order to load a file every time you switched platform, it would have failed miserably in it. Sometimes extra work is avoidable, but it's not with the file system.

But if someone really wants it - for whatever reason, then you have extensions. But it's a double edged sword.
 

JeffJ

Member
Wouldn't it be possible to add a range of non-sandboxed filehandling functions, separate from the sandboxed ones? With a big fat disclaimer in the documentation stating that using them is at your own disclosure, and it is your job to figure out how to handle paths on each target. That way, we at least have the option for every platform, provided we do our own research. We also still have the speed and convenience of the already existing functions.
 

Mike

nobody important
GMC Elder
Not something we're looking to do - sorry. There are already extensions that do this for windows, and for cross platform if we did this, we'd only be adding more support issues for ourselves in the long run anyway.

No one reads the docs.... :(

If it's in an extension, then it comes with a natural boundary that helps enforce the issues involved - and I'm all for that.
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Uploaded a new version.
  • Added functions: file_find_attributes, file_find_size, file_get_size.
  • Documentation is now available online and included with the asset (see GMZ).
  • Most functions now return strictly true/false; full error code is stored in nsfs_status (see doc).
  • Fixed buffer_load_ns returning -1 for valid-but-empty files.
  • The demo no longer uses overly generic resource names.
This also saves from having to import the actual extension from included files (was a mishap with the initial release).
 
B

BPzeBanshee

Guest
Good to see you're still working on this YellowAfterlife!

However one of the original bugs I reported is still present - file_text_open_read_ns seems to crash in the demo, even when opening up files made successfully with the demo's own file_text_open_write_ns. Does this work for anyone else?
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Good to see you're still working on this YellowAfterlife!

However one of the original bugs I reported is still present - file_text_open_read_ns seems to crash in the demo, even when opening up files made successfully with the demo's own file_text_open_write_ns. Does this work for anyone else?
Sorry for that, I forgot to recompile the demo before uploading. Was just a typo (non-_ns function call for file_text_eof). Is now fixed.
 
P

PandaPenguin

Guest
hey @YellowAfterlife , awesome that you made this extension

I consider buying it because many of my game testers reported problems when saving/loading with built in paths (due to varying windows UAC settings I guess) so I want to make my game "portable" and save/load from wherever the player put the game.exe
only thing I would like to know now before I buy it: will it work with GMS2 ??
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
hey @YellowAfterlife , awesome that you made this extension

I consider buying it because many of my game testers reported problems when saving/loading with built in paths (due to varying windows UAC settings I guess) so I want to make my game "portable" and save/load from wherever the player put the game.exe
only thing I would like to know now before I buy it: will it work with GMS2 ??
It does - imports and works without any additional steps.
 
P

PandaPenguin

Guest
It does - imports and works without any additional steps.
works like a charm indeed, excellent! :bunny:

EDIT:

while it was very easy to use the extension to read from non-sandboxed locations I somehow could not figure out how to write....

It's probably something very obvious and easy but I can't find it and am probably overlooking something here :D

please advise, @YellowAfterlife
 
Last edited by a moderator:

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
works like a charm indeed, excellent! :bunny:

EDIT:

while it was very easy to use the extension to read from non-sandboxed locations I somehow could not figure out how to write....

It's probably something very obvious and easy but I can't find it and am probably overlooking something here :D

please advise, @YellowAfterlife
Write what in particular? You'd use file_text_open_write_ns for writing text files, or buffer_save_ns for saving buffers, or file_copy_ns to copy files. If path is not absolute, files will end up next to the game's executable.
 
P

PandaPenguin

Guest
Write what in particular? You'd use file_text_open_write_ns for writing text files, or buffer_save_ns for saving buffers, or file_copy_ns to copy files. If path is not absolute, files will end up next to the game's executable.
well, ini files and sprites in particular (as PNG)....
I guess the ini-files I can handle with file_text_open_write_ns?

EDIT:
well ini-files not really, text file would do as it's only used to store ds_map strings

but I have zip-files that get temporary extracted and the contained png files added into the game on runtime.... and that part is the biggest source of problems when the users UAC gets in the way...
 
Last edited by a moderator:

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
well, ini files and sprites in particular (as PNG)....
I guess the ini-files I can handle with file_text_open_write_ns?
For INI files you would usually copy them to sandbox to work with them and copy them back. I'd generally suggest against using built-in INI functions though due to a bunch of flaws with them (see here).
For loading/saving sprites you would also copy the files around - GM does not expose it's internal functions for loading assets.
 
P

PandaPenguin

Guest
For loading/saving sprites you would also copy the files around - GM does not expose it's internal functions for loading assets.
ok, well there is the problem then... the UAC would already prevent the extraction to the %appdata% so I would have nothing to copy around :/

hmm I had thought I can bypass the need to use the %appdata% in the first place with your extension
but hey thats my fault now for not checking all functionalities first :p enjoy the beer money
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
ok, well there is the problem then... the UAC would already prevent the extraction to the %appdata% so I would have nothing to copy around :/

hmm I had thought I can bypass the need to use the %appdata% in the first place with your extension
but hey thats my fault now for not checking all functionalities first :p enjoy the beer money
It doesn't have to be appdata directory, you can also use the temp directory or even program directory (if it's only for loading).
 
P

PandaPenguin

Guest
It doesn't have to be appdata directory, you can also use the temp directory or even program directory (if it's only for loading).
well working_directory and temp_directory both are in the appdata and both get affected by UAC ....

oh and sry for hijacking your thread with my problems now.... gonna stop here^^
 
J

johnny-o

Guest
Is there a method to allow a user to select multiple files for import?
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Is there a method to allow a user to select multiple files for import?
If you mean whether it has something like get_open_filename but with ability to pick multiple files, it doesn't, though you could implement your own dialogs via file_find_ functions. I may look into adding file dialogs in future, but I want to make Mac/Linux extensions sometime soon, and I'm guessing that there's a good reason to why built-in file dialog functions don't work on those.
 
D

Dropda

Guest
I wanted to know, is it possible to use this extension to load external .ogg files (Not included files) and use audio_create_stream with them?
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
I wanted to know, is it possible to use this extension to load external .ogg files (Not included files) and use audio_create_stream with them?
GameMaker does not provide any sort of functionality that could be used to directly load audio form external directories without making your own audio engine, but it is possible to use the extension to copy audio files to somewhere where audio_create_stream can load them (temp directory / game directory / sandboxed save directory)
 
D

Dropda

Guest
to somewhere where audio_create_stream can load them (temp directory / game directory / sandboxed save directory)
I was thinking about this, but I feel like even after reading about the file system's documentation I still haven't fully grasped it.

All those 3 locations are different* ( Are they? ) but how can I find about them during runtime?
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
I was thinking about this, but I feel like even after reading about the file system's documentation I still haven't fully grasped it.

All those 3 locations are different* ( Are they? ) but how can I find about them during runtime?
Paths are stored in temp_directory, working_directory (or was it program_directory?), and game_save_id accordingly.
For things anyhow persistent you would want to use game_save_id.
temp_directory may be cleaned by OS/user between game sessions, hence the name.
Executable directory is more convenient if you want the end user to be able to find the files easily or just keep all data in that directory (not writable without extensions though)
 
S

Sam (Deleted User)

Guest
Paths are stored in temp_directory, working_directory (or was it program_directory?)
The third one is working_directory, I believe. program_directory will be different from working_directory when you are test running a game from the IDE, or as a compiled executable - it is also a different location - if you are building for Mac or Linux.
 
Hello!
I recently bought this extension and I got to say it's really a must have! Thanks a lot!
But I think I found a bug and I'm not sure how to report it (didn't want to put it in the review).

I tried to add a simple 64x64 sprite like this
Code:
var file = "C:\\a.png"
var sprite = sprite_add_ns(file, 1, false, false, 0, 0)
show_debug_message("Sprite: " + string(sprite))
show_debug_message("Error: " + string(nsfs_status))
show_debug_message("File: " + string(file_exists_ns(file)))
The result was:
Code:
Sprite: -1
Error: 3
File: 1
So there should be nothing wrong with path which the error message implies (3 = ERROR_PATH_NOT_FOUND).
I know I can use the workaround with file_copy_ns() but since this is a function that is included I thought you might wanna take a look at it.

Thanks again!
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Hello!
I recently bought this extension and I got to say it's really a must have! Thanks a lot!
But I think I found a bug and I'm not sure how to report it (didn't want to put it in the review).

I tried to add a simple 64x64 sprite like this
Code:
var file = "C:\\a.png"
var sprite = sprite_add_ns(file, 1, false, false, 0, 0)
show_debug_message("Sprite: " + string(sprite))
show_debug_message("Error: " + string(nsfs_status))
show_debug_message("File: " + string(file_exists_ns(file)))
The result was:
Code:
Sprite: -1
Error: 3
File: 1
So there should be nothing wrong with path which the error message implies (3 = ERROR_PATH_NOT_FOUND).
I know I can use the workaround with file_copy_ns() but since this is a function that is included I thought you might wanna take a look at it.

Thanks again!
Hello, does your game do any operations that would result in appdata directory being created prior to this being done? There remain to be some issues with nsfs not creating directories automatically when copying/creating files (as this requires a little more care), which can yield "path not found"
 
Hello, does your game do any operations that would result in appdata directory being created prior to this being done? There remain to be some issues with nsfs not creating directories automatically when copying/creating files (as this requires a little more care), which can yield "path not found"
It does not but I tested it and that fixed the problem!
I ran the following code once (commented it out on the next run) and now the problem is gone.
Code:
var f = file_text_open_write("a")
file_text_close(f)
file_delete(f)
Thanks!
 
Last edited:
E

Emes

Guest
Hi @YellowAfterlife,
could you upgrade your extension to GM version 2.1.5.322 beacuse 2 funtions display errors and make impossible to complie application, pls hurry.
Script: sprite_add_ns at line 11 : unknown function or script sprite_add
Script: sprite_replace_ns at line 12 : unknown function or script sprite_replace
 
Last edited by a moderator:

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Hi @YellowAfterlife,
could you upgrade your extension to GM version 2.1.5.322 beacuse 2 funtions display errors and make impossible to complie application, pls hurry.
Script: sprite_add_ns at line 11 : unknown function or script sprite_add
Script: sprite_replace_ns at line 12 : unknown function or script sprite_replace
The extension definitely works on 2.1.5.322, are you on the trial version or something? That's the only case that I know that causes sprite_add/sprite_replace functions to not be there.

You could manually open the .gml file inside extension and comment those two out (at cost of not having the functions), but I'd suggest to re-login and/or re-install GMS2 if it's so unusually cursed.
 
E

Emes

Guest
The extension definitely works on 2.1.5.322, are you on the trial version or something? That's the only case that I know that causes sprite_add/sprite_replace functions to not be there.

You could manually open the .gml file inside extension and comment those two out (at cost of not having the functions), but I'd suggest to re-login and/or re-install GMS2 if it's so unusually cursed.
Nevermind, It works, thanks :D
 
Top