GaryCXJk

Veteran
Veteran
Joined
Dec 24, 2012
Messages
88
Reaction score
46
First Language
Dutch
Primarily Uses
Making every variable global is the worst thing you can do. There's a reason many jQuery plugin creators wrap everything inside a function, it's to avoid any issues regarding compatibility. One function will overwrite the other, but then another does the same, thus, you end up with a broken mess.

What Bootstrap does in its Javascript modules is, it stores everything in a separate variable that's private, then adds a method that sets the old method as the default method.

Take this for example:

// ALERT PLUGIN DEFINITION // ======================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.alert') if (!data) $this.data('bs.alert', (data = new Alert(this))) if (typeof option == 'string') data[option].call($this) }) } var old = $.fn.alert $.fn.alert = Plugin $.fn.alert.Constructor = Alert // ALERT NO CONFLICT // ================= $.fn.alert.noConflict = function () { $.fn.alert = old return this }What this does is, it sets the old method in a variable called old. When $('element').alert.noConflict() gets run, it sets the constructor back to the old one, and if I recall correctly, does so without setting it for any other element that uses the new method, but I could be wrong.
Another way is to store the old method in a submethod, like:

var oldMethod = MainObject.mainMethod;MainObject.mainMethod = function() {};MainObject.mainMethod.old = oldMethod;That way you don't needlessly expose everything that shouldn't be exposed.Like I said, it's bad practice to expose everything.
 

estriole

Veteran
Veteran
Joined
Jun 27, 2012
Messages
1,533
Reaction score
763
First Language
indonesian
I think, we meant different things here.

When you said "original function" I supposed you mean the, well, original Game_Event.prototype.initialize function from MV, in this case.

Not some function someone aliased somewhere else.

That doesn't work if it the first alias is private, of course.

That's why Yanfly doesn't make the functions private as they would be needed for plugin extensions as the example with the ItemUpgradeSlots plugin I made.
if a person alias Game_Event.prototype.initialize for the first time.......

the alias will become the "original" Game_Event.prototype.initialize (original function from MV without edit)

while Game_Event.prototype.initialize will "become" what they edit.

so i think when i said "original function"...it's indeed could be the original Game_Event.prototype.initialize function from MV

but also could be what people already  edit.

ex:

Original

Person A alias => Original +

Person B alias => Original ++

Person C alias => Original +++

we could somehow need to call Original, Original +, Original ++ depending on what compatibility patch we want to make.

so even it's what people already edit... we sometimes need to access it instead of losing it.

so by not be able to call that alias.... if the first person that alias original method use private variable...

that mean we LOST the original function from MV...

the problem is... i see some plugin maker alias method inside (function(){...})()

thus making the original method lost...

although... Hudell answer this particular problem in other thread... he said even we use (function(){...})()...

we can still STORE the original function and make it accessable....

for example: this code is not using hudell method:

var est_build_decor_Window_EventItem_includes = Window_EventItem.prototype.includes;Window_EventItem.prototype.includes = function(item) {    if($gameParty._decorType && item && $gameSystem.getDecorType(item)){       return $gameParty._decorType.some(function(t){           if(t.toUpperCase() == $gameSystem.getDecorType(item).toUpperCase()) {               return true;           }        return false;       });    }    return est_build_decor_Window_EventItem_includes(this,item);};to this using Hudell method:

(function() {Window_EventItem.prototype.est_build_decor_old_includes = Window_EventItem.prototype.includes;Window_EventItem.prototype.includes = function(item) {    if($gameParty._decorType && item && $gameSystem.getDecorType(item)){       return $gameParty._decorType.some(function(t){           if(t.toUpperCase() == $gameSystem.getDecorType(item).toUpperCase()) {               return true;           }        return false;       });    }    return Window_EventItem.prototype.est_build_decor_old_includes(this,item);};})();by storing it inside an existing function... (in ruby we can make new method inside a class that contain old method)

we can call Window_EventItem.prototype.est_build_decor_old_includes using above code

for original method. but still i don't see it's advantage vs using original var xxxx = function

because we also need to thing about namespace too so no one overwrite it.

(it even could be longer because prototype word is longer than var word)

the naming of var in above example can also be shortened by removing _

ex: var EstBuildDecorWindowEventItemIncludes)

so use what you think suit you better...
 
Last edited by a moderator:

GaryCXJk

Veteran
Veteran
Joined
Dec 24, 2012
Messages
88
Reaction score
46
First Language
Dutch
Primarily Uses
In such cases you'll really need to rethink how you'll implement your plugin. If you need the original method, you'll need to think about either reimplementing the old method or make it so it requires your users to place it before the other plugins.

Using the original method instead of the new one often breakd the original intent of the plugin you're trying to circumvent. Sometimes it's something small, but more often it's needed further down the line.

Either way, aliasing is bad practice anyway, as it breaks optimization.
 

Ryan's Replacement

Aspiring Developer
Member
Joined
Jun 2, 2014
Messages
27
Reaction score
1
First Language
English
Primarily Uses
I sort of know what's going in your template and understand how to change the title screen now. Thank you for that btw. But I've been looking some of the default plug-ins and have come up with the same question. 

Like I said, I sort of understand what's going on in the code but where are they finding all the variable names from the default source code? Is there a way to view that, because I feel like that would be a good way to learn how to make plug-ins. 

If anybody here would like to share how they learned to make plug-ins/scripts that would be greatly appreciated  :)
 

kiriseo

Veteran
Veteran
Joined
Oct 27, 2015
Messages
245
Reaction score
85
First Language
German
I sort of know what's going in your template and understand how to change the title screen now. Thank you for that btw. But I've been looking some of the default plug-ins and have come up with the same question. 

Like I said, I sort of understand what's going on in the code but where are they finding all the variable names from the default source code? Is there a way to view that, because I feel like that would be a good way to learn how to make plug-ins. 

If anybody here would like to share how they learned to make plug-ins/scripts that would be greatly appreciated  :)
In your project's js folder you'll find eight javascript files. In these files are the methods and variables MV uses.

But I would suggest to look at this thread and the files Zalerinian uploaded there.

http://forums.rpgmakerweb.com/index.php?/topic/47361-rmmv-split-source-files-for-plugin-development/

It's easier for beginners as they are split into smaller pieces with comments for their use BD
 

Ryan's Replacement

Aspiring Developer
Member
Joined
Jun 2, 2014
Messages
27
Reaction score
1
First Language
English
Primarily Uses

Corrupted Ralph

The World Breaker
Veteran
Joined
May 24, 2015
Messages
197
Reaction score
51
First Language
English
Primarily Uses
This will only cover the BASICS of plugin making.  I will add more to this when the video is up ( i.e. how to pull params from the user to use in your plugin)


A video will accommodate this in a little bit.  You will NOT become a level 99 Warlock after this... maybe. a level 5 Wizard?.


Anyways,


1.  Download my template


https://www.dropbox.com/s/23qz6k2st0fnjb1/template.js?dl=0


2. Download an IDE,  or a Text editor specifically for coding  ( I use Notepad ++)  (you can use regular note pad, but that's boring)


https://notepad-plus-plus.org/


3. Load my Template and read through my comments.  You can adjust code if you'd like.


Believe it or not,  this is actually a working plugin as well.  Load this to your plugins folder and turn


on your Text Drawing on your title screen.. see what happens!


* I will explain this below for the newer guys later tonight*  Please read through replies on this thread for errors or best practice.



//=============================================================================// Toms_Example Template// by Faytless / Thomas Pham// Date: 10/25/2015 //============================================================================= /*: * @plugindesc xxxxx // Describe your plugin * @author yyyy // your name goes here * * @param xxxxx //name of a parameter you want the user to edit * @desc yyyyy //short description of the parameter * @default zzzzz // set default value for the parameter */ // NOTE: THIS WILL NOT MAKE YOU A DARK WIZARD. HERE ARE SOME BASE FOR YOU TO LAY A FOUNDATION FOR PLUGINS! // NOTE: THIS WILL NOT MAKE YOU A DARK WIZARD. HERE ARE SOME BASE FOR YOU TO LAY A FOUNDATION FOR PLUGINS! // NOTE: THIS WILL NOT MAKE YOU A DARK WIZARD. HERE ARE SOME BASE FOR YOU TO LAY A FOUNDATION FOR PLUGINS! // NOTE: THIS WILL NOT MAKE YOU A DARK WIZARD. HERE ARE SOME BASE FOR YOU TO LAY A FOUNDATION FOR PLUGINS! // NOTE: THIS WILL NOT MAKE YOU A DARK WIZARD. HERE ARE SOME BASE FOR YOU TO LAY A FOUNDATION FOR PLUGINS! // NOTE: THIS WILL NOT MAKE YOU A DARK WIZARD. HERE ARE SOME BASE FOR YOU TO LAY A FOUNDATION FOR PLUGINS! // NOTE: THIS WILL NOT MAKE YOU A DARK WIZARD. HERE ARE SOME BASE FOR YOU TO LAY A FOUNDATION FOR PLUGINS! // NOTE: THIS WILL NOT MAKE YOU A DARK WIZARD. HERE ARE SOME BASE FOR YOU TO LAY A FOUNDATION FOR PLUGINS! // NOTE: THIS WILL NOT MAKE YOU A DARK WIZARD. HERE ARE SOME BASE FOR YOU TO LAY A FOUNDATION FOR PLUGINS! // NOTE: THIS WILL NOT MAKE YOU A DARK WIZARD. HERE ARE SOME BASE FOR YOU TO LAY A FOUNDATION FOR PLUGINS! // Declare your function // 1. change *** to your plug ins file name below.// You are telling RPG maker that this plugin exsists. (function() { var parameters = PluginManager.parameters('template'); // NOTE: THIS WILL NOT MAKE YOU A DARK WIZARD. HERE ARE SOME BASE FOR YOU TO LAY A FOUNDATION FOR PLUGINS!// Now find something you want to edit in the core plugins. You can// find them in the Project\www\js folder // 2. find the EXACT function you want to edit /* This function can be found in rpg_scenes.js Scene_Title.prototype.drawGameTitle = function() { var x = 20; var y = Graphics.height / 4; var maxWidth = Graphics.width - x * 2; var text = $dataSystem.gameTitle; this._gameTitleSprite.bitmap.outlineColor = 'black'; this._gameTitleSprite.bitmap.outlineWidth = 8; this._gameTitleSprite.bitmap.fontSize = 72; this._gameTitleSprite.bitmap.drawText(text, x, y, maxWidth, 48, 'center'); */ // You need to come up with a name for your modification while keeping // class name the same. // the name of the function I want to edit is called // Scene_Title.prototype.drawGameTitle // The name of my function will be called _Scene_Title_xxx //Follow for ease of use, follow the template below. // Start your var as _NAME_NAME_YOURCLASSNAME // Have it equal the function you are replacing var _Scene_Title_xxx = Scene_Title.prototype.drawGameTitle; // make your adjustments by adding code, or adjusting them below. // This is an exact copy of the code above, but with some of my adjustments // to some of the parameters. Later, I will show how you can call your parameters that the user adjusts // so your plugin has a little more control Scene_Title.prototype.drawGameTitle = function() { // _Scene_Title_xxx.call(this); //sometimes you have to call your function to get this to work. In this case you don't Ill explain why later. var x = 20; var y = Graphics.height / 4; var maxWidth = Graphics.width - x * 2; var text = $dataSystem.gameTitle; this._gameTitleSprite.bitmap.outlineColor = 'black'; this._gameTitleSprite.bitmap.outlineWidth = 8; this._gameTitleSprite.bitmap.fontSize = 200; this._gameTitleSprite.bitmap.drawText(text, 0,0 , maxWidth, 48, 'center'); } })(); // dont touch this.

NOOO!!!! it's a level 30 Wizard!
 

canfu

Warper
Member
Joined
Jan 28, 2016
Messages
1
Reaction score
1
First Language
english
Primarily Uses
Is there any intention of continuing this tutorial?
 

zharth

Veteran
Veteran
Joined
Feb 11, 2014
Messages
40
Reaction score
13
First Language
English
Primarily Uses
RMMV
Is there any intention of continuing this tutorial?



I'd like to second this question. To the OP: your first tutorial was great. I'd love to see more. In particular, right now I'm wondering how to go about working with user-adjusted parameters, which you hinted at.
 
Last edited by a moderator:

kioadipra

Warper
Member
Joined
Mar 3, 2016
Messages
2
Reaction score
1
First Language
English
Primarily Uses
Thanks!


Looking forward to the continuation of this tutorial. I hope you'll make it. heheh
 

blurymind

Veteran
Veteran
Joined
May 5, 2016
Messages
62
Reaction score
17
Primarily Uses
I am having trouble understanding the engine api. How do you debug this thing? Can we print messages to check things?  How do you debug? 
 

Rivendark

Villager
Member
Joined
May 17, 2016
Messages
5
Reaction score
0
Primarily Uses
"The absolute basics of plugin making" as the topic says. Here, as an addition, just a very simple plugin, that allows you to print to the console your own message.


With this you will learn how to use your parameters and how to debug.

View attachment SampleMessage.js
 

Nomi

Veteran
Veteran
Joined
Dec 16, 2014
Messages
160
Reaction score
51
First Language
German
"The absolute basics of plugin making" as the topic says.


True - but it also says that things ll be explained later.


// _Scene_Title_xxx.call(this);    //sometimes you have to call your function to get this to work.  In this case you don't Ill explain why later.

"this" would interest me a lot - I come across it so often and cant rly figure out why it has to be called. The this confused me quite often allrdy
 

Allcor

Warper
Member
Joined
Nov 9, 2016
Messages
1
Reaction score
0
First Language
Dutch
Primarily Uses
The way plugins are loaded is really confusing to me. If someone could continue this would make starting to create plugins a lot less daunting. 


I wanted just to add a variable to Game_System. Did not find out how saving works but i read the whole object is saved. So i wanted to add my own variable to Game_System.prototype.initialize in the 'correct' way. 

// _Scene_Title_xxx.call(this);    //sometimes you have to call your function to get this to work.  In this case you don't Ill explain why later.



Adding this line will run the original code. Is this a way to merge your code with the original? Seems like a good practice to reduce compatibility issues.


So would this work? 


/*:
*
*@plugindesc This plugin creates a extra game variable.
*
*@author Allcor
*
*@help
*
* Because sometimes you don't want to use a event variable.
*
*@param First
*@default 0
*
*@param Second
*@default 100
*
*/

(function() {
// the above must be in this format to work, parameters works like a hash, with watever you put behind '@param' being the key.
var parameters = PluginManager.parameters('template');
var a = Number(parameters['First']);
var b = Number(parameters['Second']);

// renaming the original function
var _Game_system_init = Game_System.prototype.initialize;

// re-defining same function with added lines
Game_System.prototype.initialize = function() {
_Game_system_init.call(this);
this._mySavedVariable = [a,b];
}

})();


Now to make that my reputation class :S
 

Willrune

Villager
Member
Joined
Sep 6, 2016
Messages
16
Reaction score
1
First Language
English
Primarily Uses
Yep! This methodology is known as a few things, but the name that seems to stick is "Immediately Invoked Function Expression", or IIFE (pronounced "iffy"). If you have a minute, you can check out Ben Alman's explanation for IIFEs here: http://benalman.com/news/2010/11/immediately-invoked-function-expression/


Anything done inside of that block will be scoped to that function only, so it gives us a safe space to perform our calculations before overriding or adding to behaviors of the game engine or some plugin.


This technique is used to save us from Global Variable Hell:o



Ben Alman is a good source of information on a number of JavaScript topics!


Something to keep in mind with IIFEs / closures is the risk of memory leaks if something is referenced but never used again. Mikol Graves dives into it a little more here: https://www.quora.com/Do-anonymous-Javascript-IIFEs-remain-in-the-memory-stack-after-they-are-used#answer_21585684


There was another link that could explain it better than me, but it has been so long, I can't seem to find it.  >_>
 
Last edited by a moderator:

L.W. Flouisa

NumeroHex
Veteran
Joined
Mar 31, 2012
Messages
198
Reaction score
48
First Language
English
Primarily Uses
RMMV
Sorry but I beg to differ about global variables. I've been programming in Ruby for three years. Global variables are the reason I'm able to have health and enemy health that doesn't automatically reset on initialization. It's the reason I'm able to assign tiles to a variable, or the user would automatically by reset at tile one!

I'm tired of continuing to here about no global variables. Globals are not bad, you just don't want to use them to much, and make sure you really want the whole program to access them.

Things like navigation could not work without global variables.

I might understand if you were saying use local variables if you don't want a specific variable to be changeable everywhere. But sometimes you just got to be able to change something across methods.

I'm going to keep using globals, with no intention of ever stopping.

Anyway, back to studying javascript format.^ ^
 

George Halstead

Veteran
Veteran
Joined
Mar 24, 2017
Messages
68
Reaction score
14
First Language
English
Primarily Uses
RMMV
Was going to give this a go, is the code still working for the plugin etc ?
 

CaptainRadish

Veteran
Veteran
Joined
Nov 10, 2015
Messages
47
Reaction score
62
First Language
English
Primarily Uses
N/A
I think I'll make a study of this as well... I'm an absolute beginner, but learning eventing has definitely made me more comfortable with the idea of trying JavaScript out.
 

GaniNix

Villager
Member
Joined
May 3, 2018
Messages
9
Reaction score
13
First Language
German / Thai
Primarily Uses
RMMV
Can you code with Javascript Editor? We learnt about it a little bit in the school.
 

KostasVs

Warper
Member
Joined
Jan 1, 2019
Messages
3
Reaction score
1
First Language
Greek
Primarily Uses
RMMV
For newcomers finding this page, allow me to add some information that you will find useful (as I did).

When writing plugins, there are two common tasks:
  • replacing an original function,
  • extending an original function.
1) Replacing an original function:
Code:
originalFunctionName = function(argument1, argument2, ...) {
    /* your code here... */
}
"originalFunctionName" is a function located somewhere in the game's JS files. The arguments (argument1, argument2, ...) should be the same as in the original function, to avoid errors.
Example use:
Code:
BattleManager.makeEscapeRatio = function() {
    // the original code sets escape ration to: 0.5 * $gameParty.agility() / $gameTroop.agility()
    // in this example we hard-code the ratio to 75%
    this._escapeRatio = 0.75;
};

2) Extending an original function:
Code:
var _functionAlias = originalFunctionName;
originalFunctionName = function(argument1, argument2, ...) {
    /* some code here... */
    _functionAlias.call(this, argument1, argument2, ...);
    /* some other code here... */
}
What this does is to first store the function "originalFunctionName" in a temporary function "_functionAlias", then replace the "originalFunctionName" with new code, but executing the original code somewhere inside the new code.

Example 1:
Code:
    var _Spriteset_Battle_createEnemies = Spriteset_Battle.prototype.createEnemies;
    Spriteset_Battle.prototype.createEnemies = function() {
        // execute original code
        _Spriteset_Battle_createEnemies.call(this);
        // print message to console
        console.log ("Total Enemies: " + $gameTroop.members().length);
    };
This script will print the number of enemies to the console when a battle starts. To see the console during Editor Test, press F8.

Example 2:
Code:
var _Sprite_Battler_setHome = Sprite_Battler.prototype.setHome;
Sprite_Battler.prototype.setHome = function(x, y) {
    // mirror the battler's image
    this.scale.x = -1;
    // mirror the battler's position (left <--> right)
    x = Graphics.boxWidth / 2 - (x - Graphics.boxWidth / 2);
    // execute original function (we pass the modified "x" value)
    _Sprite_Battler_setHome.call(this, x, y);
};
This will flip the image and position of the battlers, moving the player party to the left and enemies to the right. NOTE: if you want this for your game, you should also extend Sprite_Battler.prototype.startMove(x,y) to use "negative" x.​
 

Latest Threads

Latest Posts

Latest Profile Posts

Back to working on my games again after a long break from this.
Insight of the day: Technically you can do off path shortcuts in the forest, but maybe you shouldn't. Also: Weeds can grow taller than me.
Well...my husband went on a 5 day trip. He accidentally took my set of keys and the only phone charger we have right now (left my other one at the hospital). Hope y'all like me at least decently enough 'cause I'm about to be here a lot.
It’s nice when you can actually see your own progress. There was a time when the concept of arrays was so confusing. Now, I can use length, pop, push, shift, unshift, join, concat, slice, sort, and reduce. Granted I can’t do it from memory, but that still seems like progress. Fun with Arrays!
Wanted to turn this into a joke or something, but it turned out into something meta and sad.
badmeme.png

Forum statistics

Threads
131,547
Messages
1,220,941
Members
173,230
Latest member
eggy29
Top