TheGentlemanLoser

"And when we fall, we will fall together..."
Veteran
Joined
Dec 30, 2020
Messages
308
Reaction score
354
First Language
English
Primarily Uses
RMMV
Hey so I basically want to create a plugin where a single key press will call the equip scene for the main character, because the game has only one character and because it's using the Chrono Engine it feels very weird to me that you can press Q to quick-select an item to equip and W to quick select a skill to equip but if you want to change your equipped weapon you have to press escape to open the menu then hit equip then hit the character before you can do that, and then you're still like two or three more keystrokes away from getting back to the map screen. The seemingly neverending FPS binge I started a few weeks ago compels me to add that it would be more than acceptable to have a button press auto-switch the weapon the main character has equipped to the "next" weapon, but that sounds like it'd be (a lot?) more complicated**.

Now, I assume that this functionality--press button (I saw someone call it "polling the button" recently, is that the correct technical term?), thing happen--should be pretty basic and fundamental and not super complicated, because it's essentially a single if statement (if the button is being pressed) that then calls an existing scene (equip screen), I'm not creating a new scene or even modifying an existing scene, but the fact that I DO NOT ACTUALLY KNOW ANY JAVASCRIPT *makes this assumption absolutely worthless. Also I don't know how many problems all the YEP scripts I'm using are going to cause.

Still, I thought this time around I'd try to ask how to do it rather than beg someone to do it for me like usual. But I am requesting very low level instructions, assume I know almost nothing* and won't be far off.

(This is for my game Retroshock.)

thanks!
loser

* I don't literally know ABSOLUTELY NOTHING but that's closer to the truth than saying I know a thing or two; I wrote a simple game in javascript for a programming class way back in college but that was at least 13 years ago and I've long since smoked away all of those memories, when it comes to RMMV I've configurated and slightly modified some very complex plugins (that are only fully and properly documented literally in portuguese) and changed a line or two here or there to get existing plugins to work/work better with each other, but I have never even tried to write my own script.
** I could almost certainly event this but it'd be kind of kludgy and also I wouldn't learn anything doing it.
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
3,768
Reaction score
2,897
First Language
English
Primarily Uses
RMMZ
What key do you want to use for this?
 

TheGentlemanLoser

"And when we fall, we will fall together..."
Veteran
Joined
Dec 30, 2020
Messages
308
Reaction score
354
First Language
English
Primarily Uses
RMMV
E? That'd be sorta symmetrical since chrono engine is A to attack, S to skill D to device, so the player's hand will be in that general area anyway.
 

Eliaquim

Hakuen Studio
Veteran
Joined
May 22, 2018
Messages
2,223
Reaction score
1,720
First Language
Portuguese - Br
Primarily Uses
RMMZ
Hi there!

Well, that is very simple to do, don't worry! Let's take it to step by step:

1 - You need to add to the key mapper object, the keyboard key you want to use to call the equipment scene. For that, you will need the js key code and a custom name for this code.
Input.keyMapper[[URL='https://keycode.info/']jscode[/URL]] = "keyName"
"keyName" can be any name you want, you will use this name in the if statement.

2 - You need to find where you can put the if statement that will check if the key is pressed
You can use it directly on the Scene_Map.update. But I would go using this one because the menu is checked here too:

JavaScript:
Scene_Map.prototype.updateScene = function() {
    this.checkGameover();
    if (!SceneManager.isSceneChanging()) {
        this.updateTransferPlayer();
    }
    if (!SceneManager.isSceneChanging()) {
        this.updateEncounter();
    }
    if (!SceneManager.isSceneChanging()) {
        this.updateCallMenu();
    }
    if (!SceneManager.isSceneChanging()) {
        this.updateCallDebug();
    }
};

So you can Alias this function to add more code to it without destroying the original one:

JavaScript:
var Scene_Map_updateScene = Scene_Map.prototype.updateScene // Add the original function into a variable
Scene_Map.prototype.updateScene = function() {
Scene_Map.prototype.updateScene.call(this) // Call the original function stored in the variable
    if (!SceneManager.isSceneChanging()) {
        this.updateCallEquipScene() // New function to call the equip scene
    }
};

Building the updateCallEquipScene function

JavaScript:
Scene_Map.prototype.updateCallEquipScene= function() {
 if(Input.isTriggered("keyName"){
      SceneManager.push(Scene_Equip) // call the scene
}

You can make that on a new .js file and add it as a plugin in your plugin manager.

Hope I didn't miss anything! Let us know your progress ^^
 

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
2,829
Reaction score
2,164
First Language
EN
Primarily Uses
RMMZ
Input.keyMapper[[URL='https://keycode.info/']jscode[/URL]] = "keyName"
Not sure what happened here, but the keycode for E is 69, so you'd want something like:
JavaScript:
Input.keyMapper[69] = "keyname"

JavaScript:
var Scene_Map_updateScene = Scene_Map.prototype.updateScene // Add the original function into a variable
Scene_Map.prototype.updateScene = function() {
Scene_Map.prototype.updateScene.call(this) // Call the original function stored in the variable
    if (!SceneManager.isSceneChanging()) {
        this.updateCallEquipScene() // New function to call the equip scene
    }
};
Looks like you have a typo here:
JavaScript:
Scene_Map.prototype.updateScene.call(this)
Suggested replacement:
JavaScript:
Scene_Map_updateScene.call(this)

The rest looks OK~ :kaophew:
[Edit: nope, still some syntax errors left, see Traverse's follow-up post.]
 
Last edited:

TheGentlemanLoser

"And when we fall, we will fall together..."
Veteran
Joined
Dec 30, 2020
Messages
308
Reaction score
354
First Language
English
Primarily Uses
RMMV
Hey guys, thanks so much! I'm trying to get this to work so I'll update this as I go.

Looks like you have a typo here:
JavaScript:
Scene_Map.prototype.updateScene.call(this)
Suggested replacement:
JavaScript:
Scene_Map_updateScene.call(this)

The rest looks OK~ :kaophew:

What specifically is the difference in this context I mean I know it's the word prototype but what is the word prototype doing there?

Not sure what happened here, but the keycode for E is 69

Well then it's definitely gotta be E :uwink:

-EDIT=
Okay as of RN this is what I have in the plugin (which is activated in the plugin manager, I added it to the bottom of the plugin list below everything else)

JavaScript:
/*:
* @plugindesc When E key is pressed, call Equip Scene.
*/
Input.keyMapper[69] = "E"

Scene_Map.prototype.updateScene = function() {
    this.checkGameover();
    if (!SceneManager.isSceneChanging()) {
        this.updateTransferPlayer();
    }
    if (!SceneManager.isSceneChanging()) {
        this.updateEncounter();
    }
    if (!SceneManager.isSceneChanging()) {
        this.updateCallMenu();
    }
    if (!SceneManager.isSceneChanging()) {
        this.updateCallDebug();
    }
};

var Scene_Map_updateScene = Scene_Map.prototype.updateScene // Add the original function into a variable
Scene_Map.prototype.updateScene = function() {
Scene_Map_updateScene.call(this) // Call the original function stored in the variable
    if (!SceneManager.isSceneChanging()) {
        this.updateCallEquipScene() // New function to call the equip scene
    }
};

Scene_Map.prototype.updateCallEquipScene= function() {
if(Input.isTriggered("E"){
      SceneManager.push(Scene_Equip) // call the scene
}

I made @caethryll's corrections to @Eliaquim's code and corrected some errors I'd introduced myself.

Right now nothing is happening (which isn't the worst thing, it didn't explode my project lol!), i.e. when I press E on the map screen nothing happens.

I've noticed that most scripts I have start with similar boilerplate, something along the lines of this

JavaScript:
var Imported = Imported || {} ;
var TH = TH || {};
Imported.ActorBattleCommands = 1;
TH.ActorBattleCommands = TH.ActorBattleCommands || {};

or this

JavaScript:
var Imported = Imported || {} ;
var TH = TH || {};
Imported.ActorBattleCommands = 1;
TH.ActorBattleCommands = TH.ActorBattleCommands || {};

or something similar.

Does my scriptlet need something like that?

Also this is probably getting ahead of my ability to comprehend things but is 'prototype' what 'aliases' something?
 
Last edited:

Traverse

Veteran
Veteran
Joined
Jul 3, 2014
Messages
193
Reaction score
125
First Language
English
Primarily Uses
Does my scriptlet need something like that?

No.

Your scriptlet needs to be written without the mistakes in the syntax.

Specifically in this bit:
JavaScript:
Scene_Map.prototype.updateCallEquipScene= function() {
if(Input.isTriggered("E"){
      SceneManager.push(Scene_Equip) // call the scene
}

You're missing a closing parenthesis and a closing curly bracket.
JavaScript:
Scene_Map.prototype.updateCallEquipScene = function() {
    if ( Input.isTriggered("E") ) {    // Was missing the second ")"
      SceneManager.push(Scene_Equip); // call the scene
    };
}; // Missing the closing bracket.

There's a reason why code often has indentation for the separate clauses, it makes it easier to tell when you are missing a closing bracket somewhere (unless it's Python code - in which case the indentations are not just optional, but actually necessary for the code to work at all).

Common practice is also to put a semicolon at the end of each statement too. There are cases where an explicit semicolon at the end of a line is actually necessary to avoid bugs, usually if the next line of code starts with a parenthesis, as that will otherwise get interpreted as part of the previous line.
 
Last edited:

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
2,829
Reaction score
2,164
First Language
EN
Primarily Uses
RMMZ
Right now nothing is happening (which isn't the worst thing, it didn't explode my project lol!), i.e. when I press E on the map screen nothing happens.
See Traverse's post, there are some more typos to correct. Errors like that prevent the script from loading, which explains why nothing is happening! You can press F8 during test (or F12 if the game crashes on boot) to view the console, where detailed error messages (amongst other things) will appear.

Also, do not include the default updateScene code in your plugin: the whole point is to reference its existing definition, which may have been altered by plugins loaded before this one (or a core script update).

For clarity:
JavaScript:
(function() {  // IIFE for scope.
'use strict';  // Optional! Use strict-mode code evaluation within this IIFE.

  Input.keyMapper[69] = 'E';  // extend keymapper

  var _Scene_Map_updateScene = Scene_Map.prototype.updateScene;  // store original method in local var
  Scene_Map.prototype.updateScene = function() {    // override method
    _Scene_Map_updateScene.apply(this, arguments);  // call original method...
    if (!SceneManager.isSceneChanging()) this.updateCallEquip();  // ...then do this
  };

  Scene_Map.prototype.updateCallEquip = function() {  // define new method
    if (Input.isTriggered('E')) SceneManager.push(Scene_Equip);
  };

})();
Relevant technical links:

For the purposes of highlighting syntax errors like mismatched brackets, you may find it helpful to use a code editor. For JavaScript, I currently use Visual Studio Code:

Also this is probably getting ahead of my ability to comprehend things but is 'prototype' what 'aliases' something?
prototype is a keyword JavaScript uses to implement its inheritance model. It can be thought of as a more flexible implementation of classes, since each JS "class" is an object in its own right. More details:
"Aliasing" is done purely via object pointers. The method identifier Scene_Map.prototype.updateScene originally points to a function object in memory, let's call it A. The alias is performed by:
  1. Making a new reference to A and storing that in a variable;
  2. Creating a new function, B;
  3. Pointing the Scene_Map.prototype.updateScene identifier at the new function B
This allows the new method to include a reference to the original one, e.g. via call or apply.
 

Eliaquim

Hakuen Studio
Veteran
Joined
May 22, 2018
Messages
2,223
Reaction score
1,720
First Language
Portuguese - Br
Primarily Uses
RMMZ
Not sure what happened here, but the keycode for E is 69, so you'd want something like:
JavaScript:
Input.keyMapper[69] = "keyname"


Looks like you have a typo here:
JavaScript:
Scene_Map.prototype.updateScene.call(this)
Suggested replacement:
JavaScript:
Scene_Map_updateScene.call(this)

The rest looks OK~ :kaophew:
[Edit: nope, still some syntax errors left, see Traverse's follow-up post.]
God I was typing in the phone and in the preview all looks fine, but now that I see, is total mess xD Thanks!
This is the site to get the javascript keycode
 

TheGentlemanLoser

"And when we fall, we will fall together..."
Veteran
Joined
Dec 30, 2020
Messages
308
Reaction score
354
First Language
English
Primarily Uses
RMMV
Thanks guys! Let me give it another spin!

Holee **** it works! How about that. I just fixed the typos that @Traverse pointed out, I didn't paste in the code that @caethryll provided.

I'm using Notepad++ btw. It might be highlighting syntax errors in a way I'm not noticing or it might have an option to highlight syntax errors I've failed to turn on. I'm far from an expert user but I do like the app, kinda sorta know my way around it okay.

I tried to read and understand the article on IIFE and I think my brain is bleeding and I now have some kind of technical ignorance based edema...it tosses out phrases like

  1. The first is the anonymous function with lexical scope enclosed within the Grouping Operator (). This prevents accessing variables within the IIFE idiom as well as polluting the global scope.

and I can feel my tiny smoothbrain hemorrhaging as it tries to make these words have meaning.

basic (I think) questions/comments

  1. For some reason I had been under the impression that if there was a syntax error like a mismatched or missing bracket the entire game would crash on startup, as opposed to the plugin not working (this is part of the reason for my fear of messing with the javascript at all), just because I've seen the "syntax error" message on startup crash a few times.
  2. How can a variable contain a function? Unfortunately almost my entire knowledge of what a variable even is comes from 18-19 years of experience with the RPG Maker series of programs so this is hurting my brain trying to understand. I thought a variable stored either a number (not necessarily an integer) or a string. What in javascript IS a variable? I realize I could google this or look it up in the web reference provided but I feel like an actual person might be able to dumb it down a bit so I can understand it.
  3. "Also, do not include the default updateScene code in your plugin: the whole point is to reference its existing definition, which may have been altered by plugins loaded before this one (or a core script update)."
I thought that might be the case but I included it in the plugin because I thought that was what @Eliaquim wanted me to do. :uswt2:
 
Last edited:

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
2,829
Reaction score
2,164
First Language
EN
Primarily Uses
RMMZ
An IIFE is basically just a function that runs as soon as it is defined. Like any other function, local variables (e.g. var cake) defined inside it are not accessible outside that function. In other words, the "scope" of these local variables is limited to the IIFE.

The global scope is accessible from any part of the game; "polluting the global scope" means defining variables as global when they do not need to be.

Enclosing your plugin code in an IIFE is one way to keep your plugin's variables safe from the rest of the game code, e.g. other people's plugins. Alternatively (or as well) you can define a namespace for all your plugin's stuff, like in this example you quoted earlier:
JavaScript:
var Imported = Imported || {};
var TH = TH || {};
Imported.ActorBattleCommands = 1;
TH.ActorBattleCommands = TH.ActorBattleCommands || {};
  • If it doesn't already exist, define a global variable called Imported equal to {}, i.e. an object with no properties. This is an "import namespace", more on this in a moment.

  • Same thing again except this one's called TH. This is the "author namespace", i.e. all their plugins store data under this object. With just one global variable, the odds of a naming conflict are much lower but many things can still be made globally accessible, since properties of an object share the scope of that object.

  • Set the ActorBattleCommands property of the Imported object equal to 1. Other plugins can use this to quickly check whether this plugin is loaded and if so what version it is.

  • Set the ActorBattleCommands property of the TH object equal to an empty object if it doesn't already exist. This will be used as a "plugin namespace", i.e. all variables for this plugin will be defined as properties of TH.ActorBattleCommands.
Note that this is just another coding style, albeit a common one for MV/MZ plugins. :kaohi:

For your numbered points:
  1. When a plugin fails to load, it will fail "silently" and print its error to the console. You can view the console by pressing F8 during test. (Or F12 if the game crashes during boot.)
    The plugins are loaded asynchronously via the PluginManager.loadScript method (rpg_managers.js), using XHR (a.k.a. XMLHttpRequest). XHR provides an onError callback which the core scripts use to silently log plugin load errors to the console. More details on XHR here if you're up for it:

  2. In JavaScript, everything is either a primitive value (e.g. number, string, boolean) or an object. A function is just a specific kind of object, and objects can be assigned to variables. (Technically the object is defined in memory and assigning it to a variable actually assigns a pointer to that object.)

  3. I believe @Eliaquim was only providing the updateScene core script excerpt as an example~
 

Latest Threads

Latest Posts

Latest Profile Posts

I typically ask this on my normal social media channels, but figured there may be good replies here. Anyone got any good horror movie recommendations? I've seen a lot, but I always love getting suggestions! Bonus points if you know which service it is streaming on (in the US) - bring on the spOoooOky!
 After a few distractions (and my annual rough second week of October), I’m getting back on track with my OMGC project.
 Am I overcomplicating it? Yes. Am I going to tone it down? Almost certainly not.
 At least the dialogue stuff is almost done. I need to do the map itself, and then all that’s left is combat.
 Getting there!
Creating 3D CGs for Cutscenes. :kaosalute:

I keep wanting to post every song I make for the game and have to hold back on that because at this rate, I'll have spoiled all the really good stuff lol..
DerniBorges wrote on TSR's profile.
Is there any way this plugin works with the big character, and the QSprite plugin? Using RTP chars, everything works fine, but the big ones, with QSprite, it's like that in the image, it doesn't reflect right. And there is, in the settings, an option to fix it. Thanks.
bug2.png

Forum statistics

Threads
115,903
Messages
1,093,844
Members
151,152
Latest member
soryumi
Top