Windows External Files issue

So I'm working on a project which requires the use of several external files. Basically it needs to load a random background accessible to players. Although even after a fair amount of sleep deprived reading It seems I still dont have a grasp on file_find_first. To add to this issue I'm also trying to use a single code for testing and publishing. So I also need to find a way to make the installer or game place these directories and files when it's not testing in temp location. Any thoughts?



if directory_exists(working_directory + "\backgrounds")
{
var i = 0;
var fileName = file_find_first(working_directory + "\backgrounds\" + "*.png",0);

while(fileName != '')
{
backgroundArray = fileName; //
fileName = file_find_next();
i += 1;
}

file_find_close();

randomize() //randomize random number generator (RNG)
randomBackground = irandom(array_length_1d(backgroundArray - 1)) //pick a random true number between 0 and the number of backgrounds; no decimal points
backgroundImage = background_add(backgroundArray[randomBackground],0,backgroundSmoothing) //set BGimage variable to the randomized number
background_assign(backgroundImage,bck_temp)
}
 

chamaeleon

Member
So I'm working on a project which requires the use of several external files. Basically it needs to load a random background accessible to players. Although even after a fair amount of sleep deprived reading It seems I still dont have a grasp on file_find_first. To add to this issue I'm also trying to use a single code for testing and publishing. So I also need to find a way to make the installer or game place these directories and files when it's not testing in temp location. Any thoughts?



if directory_exists(working_directory + "\backgrounds")
{
var i = 0;
var fileName = file_find_first(working_directory + "\backgrounds\" + "*.png",0);

while(fileName != '')
{
backgroundArray = fileName; //
fileName = file_find_next();
i += 1;
}

file_find_close();

randomize() //randomize random number generator (RNG)
randomBackground = irandom(array_length_1d(backgroundArray - 1)) //pick a random true number between 0 and the number of backgrounds; no decimal points
backgroundImage = background_add(backgroundArray[randomBackground],0,backgroundSmoothing) //set BGimage variable to the randomized number
background_assign(backgroundImage,bck_temp)
}
If that is in fact code you copied and pasted from your project, perhaps first you can try to actually store the filename in an array rather than assigning it to a variable.
Code:
backgroundArray[i] = fileName;
 

TsukaYuriko

🦑
Forum Staff
Moderator
As a general rule of thumb, remove working_directory and the leading backslash from your file paths. Path generation is automatic in Studio versions of GameMaker, and it is best left to itself by using relative file paths.
 

Lonewolff

Member
As a general rule of thumb, remove working_directory and the leading backslash from your file paths. Path generation is automatic in Studio versions of GameMaker, and it is best left to itself by using relative file paths.
Do you still need double backslashes in GMS2 like you did with 1.x? i.e. "\\some_folder\\some_asset.xxx"
 

TsukaYuriko

🦑
Forum Staff
Moderator
Generally, a single slash is sufficient, and you certainly don't need to use backslashes. Forward slashes are fine - this isn't following the rules of Microsoft's operating systems (anymore?). In fact, any amount of forward slashes is fine, as long as it's not 0.
To make this a bit easier to illustrate, I created a little snippet which tests a few different path setup combinations in a row and outputs the result. It can be found at the bottom of this post.

It also documents the ancient myth of whether working_directory is required, optional or detrimental to getting paths to work: In the version this test was performed, it does not change the results at all, but since the code works without it, there is no good reason to use it and add a potential error source in case this ever changes. There are a few outdated hints and warnings about this in the manual - the most up to date and close to reality one I could find was on the file system page:
NOTE: in general GameMaker Studio 2 will handle all this for you and you rarely need to use the working_directory built in variable.
The exception to not having to use two slash characters is specifically when you do use backslashes for whatever reason. Two backslashes are treated as a backslash escaping a backslash, producing a single backslash. In that case, you need to use two, as it will otherwise be treated as an escape character for the letter that follows after it, which screws up the file path. In fact, you can use any amount that is evenly divisible by two such as 2, 6 or 64, so if you ever felt like playing out this video in GML... you can.

Code:
test = "folder\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\test.txt";
result = (file_exists(test) ? "works" : "doesn't work");
show_debug_message(test + " " + result);
folder\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\test.txt works
(Disclaimer: Don't do that.)

This was tested on Studio 2.x, runtime version 2.2.1.291, Windows VM target.


Here are some examples of paths that don't work (and why):
Code:
Some examples of path formats that don't work
"folder\test.txt"       (backslash in the middle escapes "t")
"\folder\\test.txt"     (backslash at the start escapes "f")
"\\folder\\test.txt"    (backslashes correctly escaped but backslashes at the front are not allowed)
"/folder/test.txt"      (slashes at the front are invalid too)

Full test script, in case you want to verify this on your end:
Code:
var tests, i = 0;
tests[i++] = "folder/test.txt";
tests[i++] = "folder//test.txt";
tests[i++] = "folder///test.txt";
tests[i++] = "folder\test.txt";
tests[i++] = "folder\\test.txt";
tests[i++] = "folder\\\test.txt";
tests[i++] = "folder//\\//test.txt";
tests[i++] = "folder\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\test.txt";
tests[i++] = "folder\/test.txt";
tests[i++] = working_directory + "folder/test.txt";
tests[i++] = working_directory + "folder//test.txt";
tests[i++] = working_directory + "folder///test.txt";
tests[i++] = working_directory + "folder\test.txt";
tests[i++] = working_directory + "folder\\test.txt";
tests[i++] = working_directory + "folder\\\test.txt";
tests[i++] = working_directory + "folder//\\//test.txt";
tests[i++] = working_directory + "folder\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\test.txt";
tests[i++] = working_directory + "folder\/test.txt";

for (i = 0; i < array_length_1d(tests); i++)
{
   var result = (file_exists(tests[i]) ? "works" : "doesn't work");
   show_debug_message("Test " + string(i) + ": " + tests[i] + " " + string(result));
Test 0: folder/test.txt works
Test 1: folder//test.txt works
Test 2: folder///test.txt works
Test 3: folder est.txt doesn't work
Test 4: folder\test.txt works
Test 5: folder\ est.txt doesn't work
Test 6: folder//\test.txt works
Test 7: folder\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\test.txt works
Test 8: folder/test.txt works
Test 9: Y:\scratchpad3_72A98287_VM\folder/test.txt works
Test 10: Y:\scratchpad3_72A98287_VM\folder//test.txt works
Test 11: Y:\scratchpad3_72A98287_VM\folder///test.txt works
Test 12: Y:\scratchpad3_72A98287_VM\folder est.txt doesn't work
Test 13: Y:\scratchpad3_72A98287_VM\folder\test.txt works
Test 14: Y:\scratchpad3_72A98287_VM\folder\ est.txt doesn't work
Test 15: Y:\scratchpad3_72A98287_VM\folder//\test.txt works
Test 16: Y:\scratchpad3_72A98287_VM\folder\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\test.txt works
Test 17: Y:\scratchpad3_72A98287_VM\folder/test.txt works


As an added bonus, for the masochists:
This is valid code: tests[i++] = "V\/W\/VVV\/\/VW\/\/WVVW\/\/\/\/\/\/V\/\/\/Vest.txt";
Test 19: V//W/////WWV///VWWV//////W////////////Vest.txt works

Does that answer the question? ;P
 
Oh so I found out what was wrong with this the other day, the issue it when you are referring to a location with a \ in a json variable you must use \\ json is weird when being decoded by gms
 
Top