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?
Accessing Plugin Variables in Events
● ARCHIVED · READ-ONLY
-
-
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. -
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? -
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 -
If youre gonna use them for conditional branches, you can use them directly without setting them to game variables
The issue I run into here, is that I may want to do something in an event that depends on sayCode: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.Map.get('npc1') // say this key has a numerical value -
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. -
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. -
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?call on those values in game just as you would something like $gameVariables
So shall I store these in a JSON file then?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. -
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.
-
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?
-
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.
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.
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 -
I'm just a bit confused as to what an 'in-game call' would consist of.
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. -
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:this way, if they say affinity_get instead of just affinity, it should return the value instead.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; } };
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. -
Hm well I suppose I could manually create all the variables ahead of timeAs 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.
Apparently it is not, though I'm not quite sure why since it was completely at the top level of the file.Or like what frog suggested, you can just make affinityBook a global variable
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.this way, if they say affinity_get instead of just affinity, it should return the value instead.
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. -
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 -
Apparently it is not, though I'm not quite sure why since it was completely at the top level of the file.
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! ^_^ -
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.I think I'm correct in saying that MV automatically encapsulates each plugin in its own IIFE;
In the code for the PluginManager, it simply appends each .js plugin to the HTML:
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).SpoilerCode: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); };
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"
SpoilerCode:// 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; };