Question about JS, Parameters and Plugin Command

Discussion in 'Learning Javascript' started by shrap_x, Dec 24, 2015.

  1. shrap_x

    shrap_x Villager Member

    Messages:
    20
    Likes Received:
    0
    First Language:
    English
    I am slowly building my understanding of the new JavaScript engine.

    I wrote a JS to modify the direction my followers are pointing when I stop moving.

    The JS works fine with a  parameter to allow me to turn this function on and off.

    What I would like to know is how I can programmatically set the parameter to on and off, so I can enable and disable this feature on demand.

    There appears to be no instructions in the manual on how to use the Plugin Commands event control. Is this what I need? If so, how do I use it?

    Otherwise, what shall I do?
     
    #1
  2. Iavra

    Iavra Veteran Veteran

    Messages:
    1,797
    Likes Received:
    856
    First Language:
    German
    If you want to provide a way to disable your plugin during runtime, i would use a switch to do this. Let the user define a switch id as plugin parameter and enable/disable your own functions, depending on if that switch is ON or OFF.
     
    Last edited by a moderator: Dec 24, 2015
    #2
  3. shrap_x

    shrap_x Villager Member

    Messages:
    20
    Likes Received:
    0
    First Language:
    English
    Using a defined switch: I thought about that but thought there might be a better way.

    I still want to understand what the Plugin command does, and how to use it.

    I will attempt to implement a switch. I can learn a bit doing that.

    A switch is great for a binary, but in the instance where I might want to pass a variable of a different type, or even a string, things change.

    That's why I want to figure out the science behind it.
     
    #3
  4. SilverDash

    SilverDash Veteran Veteran

    Messages:
    389
    Likes Received:
    151
    First Language:
    Dutch
    Primarily Uses:
    RMMV
    if (yourVariableOrCondition){  // <put your script here>}The above only works during game-start. You can not use that code to 'unload' a script. But this code can prevent your script from loading at all when RM concatenates the scripts.

    And lastly I don't see the point of unloading a script during runtime, I believe your design is bad. Just make your script do nothing if it should not be used instead of deleting all of it's functions/aliases/etc. For that we have if-checks.

    foo.randomizeFollowerFaceDir = function(){  if (!this.myScriptIsActive) { return; } // Do nothing if the script is not active  // your code here};Edit:

    Ah yes I may have misunderstood, you just want to use plugin commands.
     
    Last edited by a moderator: Dec 26, 2015
    #4
  5. shrap_x

    shrap_x Villager Member

    Messages:
    20
    Likes Received:
    0
    First Language:
    English
    I do not wish to unload the script. I think you misinterpreted my request.

    My request is two parts:

    1.) What is Plugin command and how does it work?

    2.) Can I/How do I change a parameter of a script programmatically during runtime?

    My script may do multiple things with multiple parameters, but I may want to change a parameter from true to false, for example, on they fly.

    If it cannot be done the way I am thinking that is fine. I can use a work around.

    I am trying to understand the most efficient way first, before writing more code.

    In my case, I wrote a script that makes the followers turn the direction of the main character when the main character stops moving. That way all the followers are looking in the same direction. I can, potentially, see an instance where I may want to disable that temporarily in an event. I am using a string parameter of true of false to control this, under the assumption the plugin is enabled.
     

    Lets say that I make a script that creates a menu, and I may want to change the menu name programmatically. I might define that in a script.

    I am trying to think how to make the script as versatile as possible, in case I want to share it. I could reference a switch and do it that way, but that has limited use. I was hoping there was a way to modify the parameter value like a variable.
     
    Last edited by a moderator: Dec 26, 2015
    #5
  6. Milena

    Milena The woman of many questions Veteran

    Messages:
    1,282
    Likes Received:
    106
    Location:
    Ireland
    First Language:
    Irish
    Primarily Uses:
    N/A
    Plugin Command is kind of a renewed script call commands. It allows you to do almost anything internally. If you want to know more about them, SomeRandomDude and Soulpour777 made a tutorial, which you might want to check here:
     
    #6
    crowhound likes this.
  7. shrap_x

    shrap_x Villager Member

    Messages:
    20
    Likes Received:
    0
    First Language:
    English
    /*:mad:plugindesc Modified follower system, with additonal features.@author shrap_x@param ~~ Direction ~~@param LeaderDirOnStop@desc Face same direction as the leader when not moving.@default true@help Customize the followers with new features.*****************************************************************************Revision 1,00* When player stops moving, followers turn to same direction as leader*///-----------------------------------------------------------------------------Game_Player.prototype.isStopping = function() { var parameters = PluginManager.parameters('!shrap_x_followers'); var dironstop = String(parameters['LeaderDirOnStop'] || 'true'); if (this._vehicleGettingOn || this._vehicleGettingOff) { return false; } var stopcheck = Game_Character.prototype.isStopping.call(this) if((stopcheck) && (dironstop == 'true')) { $gamePlayer.LeaderDirFollowers($gamePlayer.direction()); } return stopcheck;};Game_Player.prototype.LeaderDirFollowers = function(d) { this._followers.leaddir(d);};//-----------------------------------------------------------------------------Game_Followers.prototype.leaddir = function(d) { this.forEach(function(follower) { follower.setDirection(d); }, this);};That's interesting. I can see how I can use the plugin command to set a variable.

    So let me ask this:

    Right now I am treating my parameter values as locals. In every function I need to use I reference the parameter value to set a variable.

    I am guessing there is a more efficient way to do this, by accessing the parameters on game load and saving the variables as globals.

    Then I can use the plugincommand to change the value of the variable, without having to worry about the parameter.

    I think I shall look at this option. Can anyone recommend a good starting point?

    I attached my current example code.
     
    #7
  8. SilverDash

    SilverDash Veteran Veteran

    Messages:
    389
    Likes Received:
    151
    First Language:
    Dutch
    Primarily Uses:
    RMMV
    Look at how Yanfly does it.

    Or this is how I do it (pretty much the same):

    var Silv = Silv || {};Silv.Parameters = $plugins.filter(function(p) { return p.description.contains('<SilvMinimap>'); })[0].parameters; // note: requires <SilvMinimap> in the description of the js-file.Silv.Minimap = Silv.Minimap || {};Silv.Minimap.BorderWidth = parseInt(Silv.Parameters['Border Width']); // stores parameter in variable in global objectBut... wut... you load the parameter as a string instead of a bool. And you compare strings all the way down... You even have a string as the default value...

    var dironstop = String(parameters['LeaderDirOnStop'] || 'true');..(dironstop == 'true')Aside from it not being === but ==, WHY...
     
    Last edited by a moderator: Dec 27, 2015
    #8
  9. shrap_x

    shrap_x Villager Member

    Messages:
    20
    Likes Received:
    0
    First Language:
    English
    Well I did not know about the === operator until this morning, and having tested my above code it works with == as is, though I have not tried to test it with different variables than true/false.

    I am simply learning as I go. I never said it was optimal. The above is based on the examples I had looked at previously, which is why I am using a string.

    I do want to implement Boolean controls and variables.

    I plan to spend some time on it this weekend. Thanks for the advice.
     
    Last edited by a moderator: Dec 27, 2015
    #9
  10. SilverDash

    SilverDash Veteran Veteran

    Messages:
    389
    Likes Received:
    151
    First Language:
    Dutch
    Primarily Uses:
    RMMV
    Then those examples are made by some amateur and you should be careful not to follow such poorly made tutorials. But as a newbie to programming in general, it's probably impossible to tell what tutorials are good and which are not.
     
    old code:

    var dironstop = String(parameters['LeaderDirOnStop'] || 'true');..if (dironstop == 'true')somewhat better code (with still room left for improvements, like assigning and casting the parameter somewhere else and only once):

    var dironstop = parameters['LeaderDirOnStop'].toLowerCase() === 'true'; // ONLY do this ONCE in your script and not inside some loop or method that is called repeatedly..if (dironstop)I just found out that I also use == instead of === in some of my scripts :/... I fail lol.

    Also note that you can use spaces inside parameter names so instead of 'LeaderDirOnStop' you can use 'Leader Direction On Stop'

    Also the Plugin Command is processed by EACH Plugin that supports plugin-commands. So it's not 100% internal and not the most efficient method but it's the way RM wants us to do things I guess and it works. They should have done this better but oh well, it works. RM itself doesn't have exactly great code-designs imo.
     
    Last edited by a moderator: Dec 27, 2015
    #10
  11. shrap_x

    shrap_x Villager Member

    Messages:
    20
    Likes Received:
    0
    First Language:
    English
    //===========================================================================//Global Variable initializationvar $shrap_x_global = $shrap_x_global || {};$shrap_x_global.param = $shrap_x_global.param || {};//===========================================================================//shrap_x_followers$shrap_x_global.param = PluginManager.parameters('!shrap_x_followers');$shrap_x_global.param.follower_leaderdironstop = Boolean($shrap_x_global.param['LeaderDirOnStop']);I'm not a newbie at programming, but JavaScript I am fairly new too. I've done a lot of C and SQL.

    So I just need to learn a few tricks and syntax.

    I modified my code a bit. I created a .js file that will create global variables on project load.

    Here I read the parameters for my .js files in question.

    Next I am going to write a plugin command function for overwriting the values initially stored.

    That will do what I want to accomplish.

    But one last question:

    In my global function, how does RMMV handle traps if the parameters/js file does not exist? So that I can put the appropriate error check?
     
    #11
  12. Iavra

    Iavra Veteran Veteran

    Messages:
    1,797
    Likes Received:
    856
    First Language:
    German
    Umm...this will always evaluate to true, no matter the parameter value.
     
    #12
    SilverDash likes this.
  13. SilverDash

    SilverDash Veteran Veteran

    Messages:
    389
    Likes Received:
    151
    First Language:
    Dutch
    Primarily Uses:
    RMMV
    Oops :D . I'm making so many dumb mistakes today... I edited my post to fix that. Anyway this is how yanfly does it for boolean params:

    Yanfly.Param.BECAISelfTurn = eval(String(Yanfly.Parameters['AI Self Turns']));Not sure if the String() is required but the eval should work. Personally I prefer the

    .toLowerCase() === 'true';
    Code:
    $shrap_x_global.param.follower_leaderdironstop = Boolean($shrap_x_global.param['LeaderDirOnStop']);
    That won't work either because:

    var foo = Boolean('false');alert(foo); // shows truevar foo = !!'false';alert(foo); // shows trueSo you kinda have to make an === 'true' check or an eval to get it done right for your global.
     
    #13
  14. Iavra

    Iavra Veteran Veteran

    Messages:
    1,797
    Likes Received:
    856
    First Language:
    German
    String() isn't needed, because parameters are always given as strings (unless the scripter forgot to add the @param entry, but in this case the plugin should probably crash...). Personally, i also use ".toLowerCase() === 'true'".
     
    #14
  15. shrap_x

    shrap_x Villager Member

    Messages:
    20
    Likes Received:
    0
    First Language:
    English
    //===========================================================================//Global Variable initializationvar $shrap_x_global = $shrap_x_global || {};$shrap_x_global.param = $shrap_x_global.param || {};//===========================================================================//shrap_x_followers$shrap_x_global.param = PluginManager.parameters('!shrap_x_followers');$shrap_x_global.param.follower_leaderdironstop = eval(String($shrap_x_global.param['LeaderDirOnStop'].toLowerCase()));if ($shrap_x_global.param.follower_leaderdironstop === true) alert("true");else alert("false");Thanks. I modified my code and tested it. I have the appropriate global command with proven true/false recognition.

    I also have a working plugin command to change the variable to true/false so I can enable/disable the feature as needed.

    The only thing I need now is an error trap in case the plugin doesn't exist.

    I added some code as shown, and if I remove the plugin from my manager and rename the .js file, the alert never executes.

    I am still debating on making the complete code a release plugin for the community, but if I do what I want to do is use one .js file as a master/core file that will handle the plugin commands and the global variables and potentially reference multiple secondary .js files. 

    And if someone chooses not to load that particular plugin the interpreter should just ignore it.

    Right now it behaves more like the code is "lost" or ceases executing before the alert.
     
    Last edited by a moderator: Dec 27, 2015
    #15
  16. SilverDash

    SilverDash Veteran Veteran

    Messages:
    389
    Likes Received:
    151
    First Language:
    Dutch
    Primarily Uses:
    RMMV
    I personally dislike core-scripts unless you have like 20 public plugins or something alike. But that is personal. Also I wouldn't use a single core-file for handling parameters for all of your scripts for several reasons.

    The plugin-command will simply do nothing (or at least not crash) if the plugin that normally processes it is disabled. Imo everything you are "debating" is a no-go. It feels to me that you are trying to make something that was a must in Ace, but not in MV anymore.

    I would advise you to look at other major scripters and look how they implement it.

    This is my personal template for new plugins (note the absence of an anonymous function, Iavra would probably kill you if you do this :p . But you can add an anonymous function if you want. The Silv.AddAlias ensures that the aliases still remain public):

    //=============================================================================// Silv<scriptName>.js// Version: 1.00//=============================================================================/*: * @plugindesc v1.00 <description> <Silv<scriptName>> * @author Silver * * @param -- General -- * * @param foo * @desc foo * @default foo * * @help * * *-------------------------------------- * Version History: *-------------------------------------- * v.1.00 (day month 2015) * - First Release * */// Importedvar Imported = Imported || {};Imported.SILV_<scriptName> = 1.00;// #Parametersvar Silv = Silv || {};Silv.<scriptShortName> = Silv.<scriptShortName> || {};Silv.Parameters = $plugins.filter(function(p) { return p.description.contains('<Silv<scriptName>>'); })[0].parameters;// GeneralSilv.<scriptShortName>.foo = parseInt(Silv.Parameters['foo']); // Dependencies//if (!('<requiredScript>' in Imported) || (Imported.SILV_<requiredScript> < 1.00)) { throw new Error('ERROR: "Silvers <scriptName>" requires "Silvers <requiredScript>" v1.00 or higher. It must be placed above this plugin.'); }// AliasSilv.Alias = Silv.Alias || {};if (!Silv.AddAlias){    Silv.AddAlias = function(alias, original_method)    {        if (Silv.Alias[alias]) { throw new Error('Alias already exists: ' + alias); }        Silv.Alias[alias] = original_method;    };}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Utilities////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Your Code////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// This is the end of this awesome script!//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    I just use ctrl+f and replace the strings like <scriptName>. There is also a basic decency-check in it.

    Also it only uses a single SHARED-global-variable (Silv) between all of my scripts, not even the aliases are cluttering the global Window. They are nicely stored in Silv.Alias and are always checked for uniqueness. This helps me greatly with debugging and lessens the chances of compatibility issues.
     
    Last edited by a moderator: Dec 28, 2015
    #16
  17. shrap_x

    shrap_x Villager Member

    Messages:
    20
    Likes Received:
    0
    First Language:
    English
    var Imported = Imported || {};Imported.SILV_<scriptName> = 1.00;so if I follow the logic correctly, what you are doing is either "creating" a global set of variables or "preserving" the existing global set of variables and adding to it.

    That way you can define your globals for your current script file inside the current script file.

    The globals will be added to the whole, but will not overwrite or delete any competing script file variables. That makes sense.

    I think I could do something similar to that and make it work nicely.

    Every programmer has their own technique and flair.
     
    Last edited by a moderator: Dec 28, 2015
    #17
  18. SilverDash

    SilverDash Veteran Veteran

    Messages:
    389
    Likes Received:
    151
    First Language:
    Dutch
    Primarily Uses:
    RMMV
    I create a single global variable for all of my scripts called Silv. Silv is an object and I indeed add everything to this variable, including my aliases (so that other people may patch my scripts even when I use an anonymous function).

    Because I use

    var Silv = Silv || {};I indeed do not overwrite it for 'competing scripts'. Same goes for the Imported variable. Everyone uses it and adds his/her own script to it. Some with a boolean (blerg) and some with a string (yuk) and some with a float (yay) containing the version number.

    But imo my approach is the best. It allows version-checking as well as patching of scripts even though I use anonymous functions in some of my scripts (thanks to the Silv.Alias variable). So far people either chose between anonymous or non-anonymous). But I can handle both now, without cluttering the global namespace with my code. Therefore I believe (not sure though) that my approach is the cleanest, most compatible and easiest to debug design of them all.
     
    Last edited by a moderator: Dec 28, 2015
    #18
  19. estriole

    estriole Veteran Veteran

    Messages:
    1,030
    Likes Received:
    334
    First Language:
    indonesian
    I notice that you create global variable to store plugin parameter... just be careful if you plan on dynamically change the value... it will not saved to savefile when you save and load the game. It will reload the default value when you load the game.... Place it in Game_System as this._variablename instead..m

    It will automatically saved changes you made on the fly to savefile and when you load the game it will use the value you stored in save instead of default value in plugin parameter.

    I write from my phone btw. Sorry if it look bad in formatting.

    Hope this help.
     
    #19
  20. shrap_x

    shrap_x Villager Member

    Messages:
    20
    Likes Received:
    0
    First Language:
    English
    Thanks for the tips.

    @SilverDash, if I were to use and modify your template, do you require any credit?
     
    #20

Share This Page