Accessing Plugin Variables in Events

Discussion in 'Javascript/Plugin Support' started by aeshthetic, Aug 9, 2018.

  1. aeshthetic

    aeshthetic Villager Member

    Messages:
    9
    Likes Received:
    0
    First Language:
    English
    Primarily Uses:
    RMMV
    Hello! Hopefully this is the right section for this post:

    I'm writing a simple plugin that defines a Map and modifies the map entries via pluginCommand. I'm wondering how I could access the values in the map during an event if, say, I want to create a conditional that requires a certain value in the map to be higher than 50. From what I can tell, I'm going to need to use $gameVariables instead of my own in-script objects to keep track of things that events need access to. If this is the case, how can I find out whether a variable of a certain name exists?
     
    #1
  2. MushroomCake28

    MushroomCake28 KAMO Studio Veteran

    Messages:
    1,547
    Likes Received:
    2,781
    Location:
    Montreal, Canada
    First Language:
    English
    Primarily Uses:
    RMMV
    Wait... what? Is that object you want to access part of Game_Map? If so, you know you could just access by script call with $gameMap.getYourObject();

    Same with a conditional branch. The only problem is with the conditions for an event page. For that I'm afraid you don't have good options, but still options non the less:
    1) Transfer the value of your variable/object into a game variable and set that variable as the event page condition.
    2) Have a parallel event with a conditional branch that checks the value of your variable/object, and if it is the desired value, it sets a self switch that triggers the next event page.
     
    #2
  3. aeshthetic

    aeshthetic Villager Member

    Messages:
    9
    Likes Received:
    0
    First Language:
    English
    Primarily Uses:
    RMMV
    If by 'that object' you're referring to the Map implementation I linked, no it's not. What I linked is a standard library implementation of the map data structure, which I wanted to use to store key value pairs. However it seems like if I want to look-up values from an event... well it seems that's impossible. As you've put it for me, I don't have good options but I still have options none the less.

    What you've described makes sense, but how can I figure out whether a certain variable of a certain name already exists in my script so that I know to look up it's value as opposed to creating a new one?
     
    #3
  4. Engr. Adiktuzmiko

    Engr. Adiktuzmiko Chemical Engineer, Game Developer, Using BlinkBoy' Veteran

    Messages:
    14,407
    Likes Received:
    2,822
    Location:
    Philippines
    First Language:
    Tagalog
    If ur using that directly, a script call with

    Map.prototype.get(key)

    should return to you the value associated with that key

    Map.prototype.has(key)

    should return to you if a key already has a value associated with it, so you can know if its used or not

    If youre gonna use them for conditional branches, you can use them directly without setting them to game variables

    PS: Im not sure though if you need the .prototype part
     
    #4
  5. aeshthetic

    aeshthetic Villager Member

    Messages:
    9
    Likes Received:
    0
    First Language:
    English
    Primarily Uses:
    RMMV
    The issue I run into here, is that I may want to do something in an event that depends on say
    Code:
    Map.get('npc1') // say this key has a numerical value
    being greater than 50. The only code that has access to the map is my script's code, so the event can't access that number. In order to allow it access, I'm assuming I'll have to store Map.get('npc1') in one of the $gameVariables. I'm okay with this, but I wonder how to ensure that the variable I'm creating hasn't already been created in the past so that I can update the variables or create new ones accordingly.
     
    #5
  6. aeshthetic

    aeshthetic Villager Member

    Messages:
    9
    Likes Received:
    0
    First Language:
    English
    Primarily Uses:
    RMMV
    I apologize for not doing this earlier, but here's the current code for my script:
    Code:
    let demoInterpreter = Game_Interpreter.prototype.pluginCommand;
    
    let affinityBook = new Map()
    
    let affinity = (amount, character) => {
      if (affinityBook.has(character)) {
        affinityBook.set(character, affinityBook.get(character) + amount);
      } else {
        affinityBook.set(character, 0 + amount);
      }
    }
    
    Game_Interpreter.prototype.pluginCommand = function(command, args) {
      demoInterpreter.apply(this);
    
      switch (command) {
        case "affinity":
          affinity(args[1], args[0]);
          break;
        default:
          break;
      }
    };
    my affinity function looks up and modifies the map entry corresponding to the character parameter, which is fine. The thing is, I need to be able to access the data in the map in my events, not just in my script.
     
    #6
  7. Frogboy

    Frogboy I'm not weak to fire Veteran

    Messages:
    1,630
    Likes Received:
    2,017
    Location:
    North Carolina, U.S.
    First Language:
    English
    Primarily Uses:
    RMMV
    You can make your own in-script object and reference that in the exact same way you would for the ones that the base game engine builds. You could define, say...

    Code:
    var $myPluginMap = {}; 
    ... store whatever plugin parameters you need in there and call on those values in game just as you would something like $gameVariables. If you change these values in-game, they will reset when you leave the game and come back unless you save and load your custom object.

    Or maybe I misunderstand what you're asking.
     
    #7
  8. aeshthetic

    aeshthetic Villager Member

    Messages:
    9
    Likes Received:
    0
    First Language:
    English
    Primarily Uses:
    RMMV
    This might be what I need, but I'm not quite sure yet.
    I don't know how one would do this, can you elaborate?

    So shall I store these in a JSON file then?
     
    #8
  9. Frogboy

    Frogboy I'm not weak to fire Veteran

    Messages:
    1,630
    Likes Received:
    2,017
    Location:
    North Carolina, U.S.
    First Language:
    English
    Primarily Uses:
    RMMV
    From your code you posted (sorry, didn't see this before my post), I think you can reference affinityBook as your object. You could also set another variable like $affinityBook if you wanted but I don't think it'll be necessary unless defining it with let instead of var restricts the scope from an in-game call. You can then call any method that this Map object contains.
     
    #9
  10. aeshthetic

    aeshthetic Villager Member

    Messages:
    9
    Likes Received:
    0
    First Language:
    English
    Primarily Uses:
    RMMV
    I'm just a bit confused as to what an 'in-game call' would consist of. How do I reference an object in my script/plugin from anywhere else?
     
    #10
  11. Engr. Adiktuzmiko

    Engr. Adiktuzmiko Chemical Engineer, Game Developer, Using BlinkBoy' Veteran

    Messages:
    14,407
    Likes Received:
    2,822
    Location:
    Philippines
    First Language:
    Tagalog
    If the Map js file is listed as a plugin in your game, the event should be able to reference it via the calls I posted. Else, you will use those calls in your plugin instead, probably in a plugin method that you will then call via the event

    or if you do it like frogs in which you create a variable called $myPluginMap, you can use that very variable in the event.

    As the developer of that game, you should know already if the $gameVariable ur gonna use is already in use or not coz ur the one using them.

    Anyway, you can always use $gameVariables.value(id) to see if that variable has a value, if its nil (or maybe Null I forgot which one JS uses), then it has never been used
     
    Last edited: Aug 9, 2018
    #11
  12. Frogboy

    Frogboy I'm not weak to fire Veteran

    Messages:
    1,630
    Likes Received:
    2,017
    Location:
    North Carolina, U.S.
    First Language:
    English
    Primarily Uses:
    RMMV
    A call from an Event. I assumed you were talking about an Event that runs in-game and needs to reference your plugin code. So the Script... command or any box that accepts script.
     
    #12
  13. Engr. Adiktuzmiko

    Engr. Adiktuzmiko Chemical Engineer, Game Developer, Using BlinkBoy' Veteran

    Messages:
    14,407
    Likes Received:
    2,822
    Location:
    Philippines
    First Language:
    Tagalog
    TBH, unless ur using them as page conditions, I'd just make a new plugin command in your plugin that returns the value of Map.get(key) directly. You already made a plugin command for setting the values, so you should already know how to make them anyway. Or edit your plugin command so that it can return a value too depending on the ''command" given
    Code:
    Game_Interpreter.prototype.pluginCommand = function(command, args) {
      demoInterpreter.apply(this);
    
      switch (command) {
       case "affinity":
         affinity(args[1], args[0]);
         break;
       case "affinity_get":
         affinityBook.get(args[0]);
         break;
       default:
         break;
      }
    };
    
    this way, if they say affinity_get instead of just affinity, it should return the value instead.

    Or like what frog suggested, you can just make affinityBook a global variable (if it isnt already) and use it directly in the events. Since its defined outside of another object, it should be accessible via the events directly

    You can actually try if its accessible via this call

    console.log(affinityBook.get(key))

    in a script call event command (its together with the plugincommand event command) in maybe an action triggered event or something

    and check if it prints something in the console when you run it, it should return an error if affinityBook isn't accessible.
     
    Last edited: Aug 9, 2018
    #13
  14. aeshthetic

    aeshthetic Villager Member

    Messages:
    9
    Likes Received:
    0
    First Language:
    English
    Primarily Uses:
    RMMV
    Hm well I suppose I could manually create all the variables ahead of time

    Apparently it is not, though I'm not quite sure why since it was completely at the top level of the file.

    It seems as though my only options here are to either have this information stored in a variable or accessible via script, because plugin command isn't an option as a condition for a conditional branch.

    In the end I think it's probably a better idea to manually create variables to store each NPC's affinity value, since I need this data to be persistent.

    I apologize for going in circles when the solution was so simple '^^ thank you guys for your help, I appreciate it a lot.
     
    #14
  15. Engr. Adiktuzmiko

    Engr. Adiktuzmiko Chemical Engineer, Game Developer, Using BlinkBoy' Veteran

    Messages:
    14,407
    Likes Received:
    2,822
    Location:
    Philippines
    First Language:
    Tagalog
    You can always make a function instead of a plugin command, that way you can call it via script calls.. or you know you can actually call the plugin command via a script call if you follow how Game_Interpreter calls it.

    But if u do need it to be saved with the save file for changes, you need to also edit the saving function to include it. Or as you decided, just use game variables
     
    #15
  16. caethyril

    caethyril ^_^ Veteran

    Messages:
    957
    Likes Received:
    596
    Location:
    UK
    First Language:
    English
    Primarily Uses:
    RMMV
    I think I'm correct in saying that MV automatically encapsulates each plugin in its own IIFE; let is scoped exclusively to the current block. Like @Frogboy suggests, use var for a global variable. [Edit: Or not (see following post). :kaoswt:]

    But yes, using $gameVariables also gets around having to add extra data to the save files and all that. Much neater all round! ^_^
     
    Last edited: Aug 10, 2018
    #16
    Frogboy likes this.
  17. Aloe Guvner

    Aloe Guvner Walrus Veteran

    Messages:
    1,456
    Likes Received:
    931
    Location:
    USA
    First Language:
    English
    Primarily Uses:
    RMMV
    Sorry, but this isn't true. Many people (myself included) choose to write their plugins as an IIFE to protect variables, but other plugin writers (such as Yanfly) create a global namespace for their variables.

    In the code for the PluginManager, it simply appends each .js plugin to the HTML:
    Code:
    PluginManager.loadScript = function(name) {
        var url = this._path + name;
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = url;
        script.async = false;
        script.onerror = this.onError.bind(this);
        script._url = url;
        document.body.appendChild(script);
    };
    There's no difference between "let", "const", and "var" for defining global variables, if the variables are declared in the global scope. (You can try all 3 in the console of whichever browser you're viewing this page with).

    A Script call (Event Command), however, does encapsulate variables in function scope, specifically within the scope of command355(). If you wanted to declare a global variable within a Script call Event Command, you would have to explicitly declare it with the Window object, i.e. "window.myVar = 3"
    Code:
    // Script
    Game_Interpreter.prototype.command355 = function() {
        var script = this.currentCommand().parameters[0] + '\n';
        while (this.nextEventCode() === 655) {
            this._index++;
            script += this.currentCommand().parameters[0] + '\n';
        }
        eval(script);
        return true;
    };
     
    #17
    caethyril and Frogboy like this.

Share This Page