file path problem when reading and writing files

rsjg

Villager
Member
Joined
Nov 12, 2018
Messages
6
Reaction score
1
First Language
English
Primarily Uses
RMMV
TLDR: I think NWJS's working directory isn't being set properly... maybe.

I'm working on something that reads and writes files and ran into some odd behaviour. For example:

Code:
//=============================================================================
// filePath.js
//=============================================================================

/*:
 * @plugindesc     tests behaviour when writing a file
 * @author     RSJG
 *
 * @help     Yes please.
 */

{
    fs = require("fs");


    function getPath(unformattedPath) {
        let path = "/" + unformattedPath + "/";
      
       //reg-ex magic here

        console.log("file path is: " + path); //"file path is: /testpath/""
        return path;
    }

    function writeFile(path, name, data){

        let wPath = (path === "") ? "" : getPath(path);
        fs.writeFileSync(wPath + name, data);
    }


    const Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;

    Game_Interpreter.prototype.pluginCommand = function (command, args) {
        Game_Interpreter_pluginCommand.call(this, command, args);


        if (command.toLowerCase() === "writetest") {
            writeFile("testpath","testfile2.txt","Hello Path + File!");
        }

        if (command.toLowerCase() === "writetestnp") {
            writeFile("","testfile1.txt","Hello File!");
        }
    }

};
Which is a simple plugin which gives commands to either writes a file to a fixed name on a fixed path (WriteTest), or with no path (WriteTestNP).

With no path it writes to the project folder as you would expect. But with a path it tries to write to "c:\testpath\testfile.txt".

Seemed easy enough to fix. Just change "let path = "/" + unformattedPath + "/";" to remove the first forward slash.

But the thing is I found this example and it had the same problem when I ran it:
https://forums.rpgmakerweb.com/index.php?threads/node-js-making-directories.80143/

Which makes me think the cause of the odd behaviour is probably on my end and my "fix" is going to cause problems down the line. The obvious answer is that the NWJS working directory is for some reason is not set correctly to the project folder. But then removing the forward slash shouldn't help.

I feel like I'm running in circles on this. Anyone have any idea what's going on?
 

Poryg

Dark Lord of the Castle of Javascreeps
Veteran
Joined
Mar 23, 2017
Messages
4,125
Reaction score
10,640
First Language
Czech
Primarily Uses
RMMV
Yes. This is C++ (to some extent). If you want to write to project path, you need to add a dot at the front of the filepath. So not
let path = "/" + unformattedPath + "/";

but
let path = "./" + unformattedPath + "/";

The reason it is done like this is, some people want to be able to use temp directories, if for no other reason.
 

Aloe Guvner

Walrus
Veteran
Joined
Sep 28, 2017
Messages
1,628
Reaction score
1,115
First Language
English
Primarily Uses
RMMV
In your first case, you're writing to the path:
Code:
/testpath/testfile2.txt
When you start a file path with a forward slash, it's the root directory (if you use windows, it instead refers to the letter of your drive like c:/)
Other symbols such as "~/" indicate the home directory, "./" indicate the current directory, and "../" indicate a level up. This isn't specific to node or NW.js or any programming language, this is directory notation in general.

Here's an example explanation, but there should be a lot of additional explanation for this out there.
 

rsjg

Villager
Member
Joined
Nov 12, 2018
Messages
6
Reaction score
1
First Language
English
Primarily Uses
RMMV
Thanks for the quick reply.

That's an improvement on removing the slash. It's definitely the safer option. Thanks!

But regarding that example I linked, I'm still curious. I have to assume it worked when it was posted. is the behaviour different as a result of something that's changed in RMMV?
 

Aloe Guvner

Walrus
Veteran
Joined
Sep 28, 2017
Messages
1,628
Reaction score
1,115
First Language
English
Primarily Uses
RMMV
I have to assume it worked when it was posted. is the behaviour different as a result of something that's changed in RMMV?
No, as I said, the way that directories work doesn't have anything to do with Node or NW.js or any programming language.

In the example that you shared, they are creating the absolute path in the "createPath" function. Because they use the absolute path (rather than a relative path), they can define the path from the root directory.
 

rsjg

Villager
Member
Joined
Nov 12, 2018
Messages
6
Reaction score
1
First Language
English
Primarily Uses
RMMV
I think I see why the example doesn't work. It looks like it's expecting window.location.pathname to provide the absolute path, but it contains "/index.html". The reg-ex scrubs that and the assignment effectively becomes var path = relativePath . Which I don't think is the intended result.
 

Aloe Guvner

Walrus
Veteran
Joined
Sep 28, 2017
Messages
1,628
Reaction score
1,115
First Language
English
Primarily Uses
RMMV
It's possible that the behavior of that "window.location.pathname" variable could have changed, so I partially take back what I said earlier. The behavior of how directories work is still the same, but depending on the version of NW.js, that specific variable might have contained something different than it used to. The "window" object is present in all front-end browsers, so you can open the dev tools of the browser that you are looking at this website with (F12 in Chrome for Windows, for example) and see what it outputs. For me, on this site, "window.location.pathname" says "/index.php", so not a very useful variable. B)

Instead, I encourage you to check out the process variable, which is a Node object, and you will be able to access the absolute path through that. (hint: Look in rpg_manager.js at the StorageManager class, which controls how the save files are saved. There is a helper function that gets the absolute file path).
 

Poryg

Dark Lord of the Castle of Javascreeps
Veteran
Joined
Mar 23, 2017
Messages
4,125
Reaction score
10,640
First Language
Czech
Primarily Uses
RMMV
From NWjs version 0.23 onwards any offline locations are encrypted. So you won't see C:/gameCompanyFolder/gameFolder/index.html, but
neidhkskhfidhurjjndlivhmeidhkaojcmeojcnir/index.html
in window.location. This is a security measure that prevents the app from nstively tracking where it has been installed. Of course it doesn't influence the functionslity in any way, it just makes using window/location entirely useless.
Nevertheless, the difference is that fs is a c++ module, so it functions differently from classic html.

Classic html has no access to your filesystem. Therefore its relative and absolute path is the same - the folder where index.html is located. As such you can load for example images through html using "/img/characters/People1.png" without issue. However, the purpose of the fs module was always to unlock access to pretty much all hard drive - even program files if you launch it with admin privileges. It wouldn't make any sense for the fs module to ask window.location.pathname for relative path by default as it would have made navigating the file system a ton more difficult.
 

rsjg

Villager
Member
Joined
Nov 12, 2018
Messages
6
Reaction score
1
First Language
English
Primarily Uses
RMMV
It's pretty interesting for legacy purposes. I may be missing something, but I'm not really seeing the downside of working with the relative path.

Though I'm still going to have to go back to the drawing board for I/O as I'd rather have something more portable than fs. Looking into how RMMV handles it natively probably is the way to go.
 

Poryg

Dark Lord of the Castle of Javascreeps
Veteran
Joined
Mar 23, 2017
Messages
4,125
Reaction score
10,640
First Language
Czech
Primarily Uses
RMMV
Feel free to use XMLHTTPRequests. But please, DON'T handle it as default MV does. It creates so brutal bottleneck by loading and redrawing it's beyond terrible. If javascript, use asynchronous javascript.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

He mad, but he cute :kaopride:

Our latest feature is an interview with... me?!

People4_2 (Capelet off and on) added!

Just beat the last of us 2 last night and starting jedi: fallen order right now, both use unreal engine & when I say i knew 80% of jedi's buttons right away because they were the same buttons as TLOU2 its ridiculous, even the same narrow hallway crawl and barely-made-it jump they do. Unreal Engine is just big budget RPG Maker the way they make games nearly identical at its core lol.
Can someone recommend some fun story-heavy RPGs to me? Coming up with good gameplay is a nightmare! I was thinking of making some gameplay platforming-based, but that doesn't work well in RPG form*. I also was thinking of removing battles, but that would be too much like OneShot. I don't even know how to make good puzzles!

Forum statistics

Threads
106,036
Messages
1,018,461
Members
137,821
Latest member
Capterson
Top