Drakkonis

Veteran
Veteran
Joined
Mar 5, 2021
Messages
159
Reaction score
138
First Language
English
Primarily Uses
RMMZ
Is there a way to grab a line from a .js file, perhaps as a string? I know I can get a string of a function's source code, but that's not what I'm after. I'd like to be able to load lines from the js file as strings whether they're functions or not. Most of what I'd want to be able to grab would be outside of functions, and I'd like to be able to include commented lines as well. Or failing that in general, at least be able to read the commented lines dealing with plugin params.

If curious about the use, I think it would make my Plugin Core's parameter conversion more intuitive, and I believe I'm gonna need it for my attempt to make MZ functions compatible with MV(reverse FOSSIL).

My searches thus far has only turned up how to grab a function's code or its passed arguments, so I'm not sure if what I'm after can be done without a LOT of work(obviously it can be done, the engine's plugin editor window can do it).

Thanks in advance!
 

Zevia

Veteran
Veteran
Joined
Aug 4, 2012
Messages
649
Reaction score
362
First Language
English
Primarily Uses
RMMV
You can use the fs module that comes with Node. It returns a Buffer, which you can turn into a String using the toString method, which you could then split on the newline character.

That would give you an Array where each element represents a line of code.

JavaScript:
const fs = require('fs');
const fileContents = fs.readFileSync('./js/plugins/MyPlugin.js').toString();
console.log(fileContents);

const lines = fileContents.split('\n');
console.log(lines);
 

Restart

Veteran
Veteran
Joined
Mar 15, 2019
Messages
797
Reaction score
642
First Language
English
Primarily Uses
RMMV
The game keeps plugin params around after loading, it's all stored in $plugins[pluginNumber].parameters

If you're doing a reverse fossil, you'll also probabl need to be able to identify the whole plugin list before the plugin code actually runs (in case you need to setup an inheritance injection in advance, or backup a function to bypass how a plugin redefines it). FOSSIL gets the name list this way:
Code:
Fossil.pluginNameList =  $plugins.map(a => a.name);

You're probably going to want to look in the PluginManager code in rmmv_managers.js for anything more elaborate, I don't think a lot of people poke around with this sort of meta-code.
 

Drakkonis

Veteran
Veteran
Joined
Mar 5, 2021
Messages
159
Reaction score
138
First Language
English
Primarily Uses
RMMZ
The game keeps plugin params around after loading, it's all stored in $plugins[pluginNumber].parameters

If you're doing a reverse fossil, you'll also probabl need to be able to identify the whole plugin list before the plugin code actually runs (in case you need to setup an inheritance injection in advance, or backup a function to bypass how a plugin redefines it). FOSSIL gets the name list this way:
Code:
Fossil.pluginNameList =  $plugins.map(a => a.name);

You're probably going to want to look in the PluginManager code in rmmv_managers.js for anything more elaborate, I don't think a lot of people poke around with this sort of meta-code.
It's not just the params themselves, it's the other information about them. For my Core, it converts the parameter strings to the actual variable types, it does so based on the content of the string, but that doesn't mean it's going to be as accurate as I'd like it to be. But if I can grab the other aspects of a param, like its type, it can be more reliable, since certain parameter types would NEED to be certain variable types, like the troop type always needs to be a number.

For the reverse FOSSIL(working title RetroPlug, trying to come up with a clever acronym so I can call it RETRO), I need to be able to grab plugin command information to make MV's plugin command function properly. MV's plugin command is a string with the command and all arguments in the same string, where MZ's plugin arguments are passed as an object. Therefore I need to be able to grab any args defined for the command in order to properly construct the object the function expects. I don't need the entire plugin list for this, as I'd also need to identify plugins as being for MV or MZ. Instead I'm tying it to the registerCommand function, since ONLY MZ plugins use that function. This also means I'm not processing a lot of data when I don't need to, since right now it's only needed for plugin commands. So if there are no plugin commands, I'm not wasting time parsing the file.

You can use the fs module that comes with Node. It returns a Buffer, which you can turn into a String using the toString method, which you could then split on the newline character.

That would give you an Array where each element represents a line of code.

JavaScript:
const fs = require('fs');
const fileContents = fs.readFileSync('./js/plugins/MyPlugin.js').toString();
console.log(fileContents);

const lines = fileContents.split('\n');
console.log(lines);

This is exactly what I needed! Thanks!
 

Restart

Veteran
Veteran
Joined
Mar 15, 2019
Messages
797
Reaction score
642
First Language
English
Primarily Uses
RMMV
Ah, sorry, I think I misunderstood what you were after.
 

Drakkonis

Veteran
Veteran
Joined
Mar 5, 2021
Messages
159
Reaction score
138
First Language
English
Primarily Uses
RMMZ
Ah, sorry, I think I misunderstood what you were after.
Yeah, I was a little vague in the intro post... but I was a little worried that people might be concerned about what I was after when I mentioned wanting a plugin that has any direct interaction with another plugin's code, even if it's just reading a comment block. But that data isn't directly declared anywhere else, and the way MZ's plugin commands get handled REQUIRE that information, so I needed it to make MZ plugin commands compatible at ALL. Luckily that stuff isn't(probably CAN'T be) obfuscated, or any plugin that obfuscated their comment blocks would have their commands unusable in MV right out of the gate, with no way to fix it without getting in contact with the original author.
 

Restart

Veteran
Veteran
Joined
Mar 15, 2019
Messages
797
Reaction score
642
First Language
English
Primarily Uses
RMMV
It's not just the params themselves, it's the other information about them. For my Core, it converts the parameter strings to the actual variable types, it does so based on the content of the string, but that doesn't mean it's going to be as accurate as I'd like it to be. But if I can grab the other aspects of a param, like its type, it can be more reliable, since certain parameter types would NEED to be certain variable types, like the troop type always needs to be a number.

For the reverse FOSSIL(working title RetroPlug, trying to come up with a clever acronym so I can call it RETRO)
Run Everything That Rpgmaker Offers: MZ, or RETROMZ?
 

Drakkonis

Veteran
Veteran
Joined
Mar 5, 2021
Messages
159
Reaction score
138
First Language
English
Primarily Uses
RMMZ
Run Everything That Rpgmaker Offers: MZ, or RETROMZ?
Given RPGMaker's history and the different scripting languages in its past, I think that's a bit misleading.

Kinda thinking Really Experimental Temporal Reliability Operations, at least while in development. Not sure the Really Experimental part would fit if it gets a large chunk of possible plugins working and I feel it's stable enough for a v1.0 release. The Temporal Reliability Operations I think I would want to keep in the final name, since this is basically allowing MV to use "tech from the future".

Got MZ plugin commands working, though they require the dev to have a bit of knowledge about the plugin they're trying to use... or at least the ability to read the script and understand what they're reading enough to find the commands and their arguments, so technically the point of this thread is now no longer necessary.

I think I'm actually about ready to put up a v.01 in-development post for this thing, though I want to run it through a few more plugin varieties first. I've not really USED MV, I mostly got it for the animation editor, its RTP, and to have access to its code to make plugins I make by request actually compatible with the engine its being requested for, which means my tactic of throwing a plugin at it until it breaks is still the fastest way for me to find the differences. If nothing else it'll let me find the stuff most commonly used in MZ plugins that MV can't natively do.

I should probably stop, this is going from a "I need to figure out how to do a thing for a plugin I'm making" thread to a "talk about the plugin I'm making that I made this thread to figure something out for" thread. lol
 

 Masked 

Assistant
Veteran
Joined
Oct 28, 2015
Messages
112
Reaction score
292
First Language
Portuguese
Primarily Uses
RMMZ
If you want to make something core-like (which I'm guessing you do, from what you've described), I'd suggest not using fs. It's part of Node, which means it only works when the game is run from NWJS, and probably won't work on mobile (definitely not on the web).

You should take a look at how the DataManager loads JSON files. You can do the same with JS files, just change the MIME type to application/javascript or something and handle onload accordingly.

Also, if you want something more advanced, take a look into acorn. It's (quoting the Github repo)"A tiny, fast JavaScript parser, written completely in JavaScript", and could probably be embedded into a plugin. With that you could parse the JS file and actually manipulate de AST to find/change what you want. It supports comments too, altough you would need to parse the annotations yourself (which isn't really that hard, a regex would probably do).
 

Drakkonis

Veteran
Veteran
Joined
Mar 5, 2021
Messages
159
Reaction score
138
First Language
English
Primarily Uses
RMMZ
If you want to make something core-like (which I'm guessing you do, from what you've described), I'd suggest not using fs. It's part of Node, which means it only works when the game is run from NWJS, and probably won't work on mobile (definitely not on the web).

You should take a look at how the DataManager loads JSON files. You can do the same with JS files, just change the MIME type to application/javascript or something and handle onload accordingly.

Also, if you want something more advanced, take a look into acorn. It's (quoting the Github repo)"A tiny, fast JavaScript parser, written completely in JavaScript", and could probably be embedded into a plugin. With that you could parse the JS file and actually manipulate de AST to find/change what you want. It supports comments too, altough you would need to parse the annotations yourself (which isn't really that hard, a regex would probably do).
The DataManager bit looks to be the simplest, so I'll probably try to figure that one out. I don't understand the usage of the XML request (I'm still technically learning javascript as I go, but I think I've got a lot of the basics down well enough for most things I want to do), so I'll probably wait on that until after I get the bones of this thing working. I'm ok with it being only compatible with pc installations in the meantime. Ideally I'd probably switch to it full-time so that it's compatible with any environment the games will run in, instead of having both and detecting what environment it's in. The only advantage I could see there is if the fs method is significantly faster, in which case it would be preferred where possible. I'll have to find a beefy plugin or collection of plugins to test that, but I imagine in most cases it won't make enough of a difference to matter.
 

Zevia

Veteran
Veteran
Joined
Aug 4, 2012
Messages
649
Reaction score
362
First Language
English
Primarily Uses
RMMV
If you want to make something core-like (which I'm guessing you do, from what you've described), I'd suggest not using fs. It's part of Node, which means it only works when the game is run from NWJS, and probably won't work on mobile (definitely not on the web).
@Drakkonis I haven't read too far into what you're trying to do, so I'm not weighing in on other options, but if you still wanted to import a file as a String and break it down by line as an Array, an alternative to using Node modules for non-NWJS environments could be to just make a request:

JavaScript:
fetch('./js/plugins/MyPlugin.js')
    .then(response => response.text())
    .then(text => console.log(text.split('\n')));

If you want something compatible with older browser environments, you can use something similar to what the DataManager does:

JavaScript:
const xhr = new XMLHttpRequest();
xhr.open('GET', './js/plugins/ZeviaArcGradient.js');
xhr.onload = function() {
    console.log(xhr.responseText.split('\n'));
};
xhr.send();
 

Latest Posts

Latest Profile Posts

Quite the versatile cast so far :p

chars.PNG

Edit: Sprites are made by Alexdraws and TheMightyPalm. I just edited them.
Degica Games Turn Komodo | RPG Maker News #77

Well, rats. Was really looking forward to trying out FPS Creator, but trying to install and set it up was pretty much impossible for my tiny brain to comprehend. So much for that, then.
Ah, home once more! I think I can safely work on my games now.
Let's hope power remains on for the day

Forum statistics

Threads
112,412
Messages
1,068,117
Members
146,062
Latest member
BuckyBattleBorn
Top