Faytless

Programmer who only gets Engineering jobs
Veteran
Joined
Jan 27, 2013
Messages
247
Reaction score
171
First Language
English
Primarily Uses
N/A
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

View attached files.

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.

Moving to Learning Javascript, & pinning

I think you should highlight the aliasing and calling of aliased methods more. First read through I didn't think you had it in there at all. This should be explained VERY well, and recommended as best practice, otherwise we're going to get a LOT of people writing plugins that just overwrite methods, which is going to give us a lot of incompatible plugins.
JavaScript:
//=============================================================================
// 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.
 

Attachments

  • Template.js
    4.3 KB · Views: 259
Last edited by a moderator:

Woratana

Veteran
Veteran
Joined
Jul 4, 2012
Messages
101
Reaction score
98
First Language
Thai
Primarily Uses
Great work ! :D

This will come in handy :)
 

fm2107

Veteran
Veteran
Joined
Jun 12, 2014
Messages
81
Reaction score
22
First Language
english
the syntax (function( ){ })( ); means its an anonymous function and will call itself when the executes that line? oh and on line 35 you mention change "***" what is that referring to? 

and ty for the post it helps a lot!
 
Last edited by a moderator:

babykgar

Villager
Member
Joined
Oct 19, 2015
Messages
14
Reaction score
1
First Language
English
the syntax (function( ){ })( ); means its an anonymous function and will call itself when the executes that line? 
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
 

Makeratore

Veteran
Veteran
Joined
Feb 9, 2014
Messages
249
Reaction score
96
First Language
Italian
Primarily Uses
RMMV
Nice, thank you for the guide! Please, continue it. ;)
 

Shaz

Keeper of the Nuts
Global Mod
Joined
Mar 2, 2012
Messages
45,993
Reaction score
16,810
First Language
English
Primarily Uses
RMMV
Moving to Learning Javascript, & pinning

I think you should highlight the aliasing and calling of aliased methods more.  First read through I didn't think you had it in there at all.  This should be explained VERY well, and recommended as best practice, otherwise we're going to get a LOT of people writing plugins that just overwrite methods, which is going to give us a lot of incompatible plugins.
 
Last edited by a moderator:

Faytless

Programmer who only gets Engineering jobs
Veteran
Joined
Jan 27, 2013
Messages
247
Reaction score
171
First Language
English
Primarily Uses
N/A
Moving to Learning Javascript, & pinning

I think you should highlight the aliasing and calling of aliased methods more.  First read through I didn't think you had it in there at all.  This should be explained VERY well, and recommended as best practice, otherwise we're going to get a LOT of people writing plugins that just overwrite methods, which is going to give us a lot of incompatible plugins.
Thanks,  you're aboslutly right --  I'll make the changes later tonight

I was planning on making a small series of videos talking about everything ^^;  I'll condense everything down to this thread when I have a moment.
 
Last edited by a moderator:

VHStapes

Game Designer
Veteran
Joined
May 25, 2014
Messages
57
Reaction score
7
First Language
English
I'm really excited about this! I know (I think) juuuust enough about Javascript to follow this and learn how to make some sweet plugins. This has already helped explain a lot. Thanks for all the hard work!
 

estriole

Veteran
Veteran
Joined
Jun 27, 2012
Messages
1,533
Reaction score
763
First Language
indonesian
first of all... i'm newbie in JS... i have some question...

i read on this article:

http://stackoverflow.com/questions/2421911/what-is-the-purpose-of-wrapping-whole-javascript-files-in-anonymous-functions-li

doing:

(function() {...code...})();is useful when we want to have private method / private function...

but if we don't have those private things... would it be better to write it without it...

any opinion???

another thing mentioned in that articles is polluting namespace... also variable inside it cannot be called from outside...

so if i do:

(function() {...var est_event_size_Game_System_initialize = Game_System.prototype.initialize;Game_System.prototype.initialize = function() {  est_event_size_Game_System_initialize.call(this);  this._est_custom_passage_map = {};};...})();what i want to ask:

1) when i create another script... can i use est_event_size_Game_System_initialize again as variable name for another alias?

since it's private variable thus not recognized by another plugin...

2)if i create another script... can i call est_event_size_Game_System_initialize.call(this);?

or i can only do that in the first script.

sorry for newbie question... the answer will be useful because when the plugin i write is still not much... i can still edit it for better performance.
 

kiriseo

Veteran
Veteran
Joined
Oct 27, 2015
Messages
245
Reaction score
85
First Language
German
what i want to ask:

1) when i create another script... can i use est_event_size_Game_System_initialize again as variable name for another alias?

since it's private variable thus not recognized by another plugin...

2)if i create another script... can i call est_event_size_Game_System_initialize.call(this);?

or i can only do that in the first script.

sorry for newbie question... the answer will be useful because when the plugin i write is still not much... i can still edit it for better performance.
I'm a newbie in js myself. But I think I've got the basics. If I'm completly off, than surely someone with more expertise will correct it :)

1) yes.

2) if you have another alias in the second script with the same name, why not?

est_event_size_Game_System_initialize.call(this); calls the function that you override with your alias.
 

VHStapes

Game Designer
Veteran
Joined
May 25, 2014
Messages
57
Reaction score
7
First Language
English
I've been trying to follow along with this template to make a menu. I'm starting small, and just trying to test things out at the moment and I've already hit a wall.

To start I just wanted to edit what the things in the command window do, pretty much just so I could tell that my code was actually doing something, which at this point doesn't seem to be working.

Here's what I have so far.

  (function() {  var parameters = PluginManager.parameters('vhsMenu'); var _Scene_Menu_vhsMenu = Scene_Menu.prototype.createCommandWindow; Scene_Menu.prototype.createCommandWindow = function() { _Scene_Menu_vhsMenu.call(this); this._commandWindow.setHandler('item', this.commandItem.bind(this)); this._commandWindow.setHandler('skill', this.commandPersonal.bind(this)); this._commandWindow.setHandler('equip', this.commandPersonal.bind(this)); this._commandWindow.setHandler('status', this.commandPersonal.bind(this)); this._commandWindow.setHandler('formation', this.commandFormation.bind(this)); this._commandWindow.setHandler('options', this.commandOptions.bind(this)); this._commandWindow.setHandler('save', this.commandSave.bind(this)); this._commandWindow.setHandler('gameEnd', this.commandSave.bind(this)); this._commandWindow.setHandler('cancel', this.popScene.bind(this)); this.addWindow(this._commandWindow);};It looks to me like I've done everything right, and that the Game End command should do the same thing as the Save command (which I know is pointless, I'm just trying stuff out).

Maybe menus are not a good place to start? Am I missing something insanely obvious?

Thanks guys.
 

Faytless

Programmer who only gets Engineering jobs
Veteran
Joined
Jan 27, 2013
Messages
247
Reaction score
171
First Language
English
Primarily Uses
N/A
(function() { var parameters = PluginManager.parameters('vhsMenu'); var _Scene_Menu_vhsMenu = Scene_Menu.prototype.createCommandWindow; Scene_Menu.prototype.createCommandWindow = function() { _Scene_Menu_vhsMenu.call(this); this._commandWindow.setHandler('item', this.commandItem.bind(this)); this._commandWindow.setHandler('skill', this.commandPersonal.bind(this)); this._commandWindow.setHandler('equip', this.commandPersonal.bind(this)); this._commandWindow.setHandler('status', this.commandPersonal.bind(this)); this._commandWindow.setHandler('formation', this.commandFormation.bind(this)); this._commandWindow.setHandler('options', this.commandOptions.bind(this)); this._commandWindow.setHandler('save', this.commandSave.bind(this)); this._commandWindow.setHandler('gameEnd', this.commandSave.bind(this)); this._commandWindow.setHandler('cancel', this.popScene.bind(this)); this.addWindow(this._commandWindow); }})();for got the   })(); .

keep in mind that this plugin is going to REPLACE the function

i havent had a chance to update this thread yet.  Let me know if you have any questions
 
Last edited by a moderator:

Makeratore

Veteran
Veteran
Joined
Feb 9, 2014
Messages
249
Reaction score
96
First Language
Italian
Primarily Uses
RMMV
Please, continue the tutorials!
 

VHStapes

Game Designer
Veteran
Joined
May 25, 2014
Messages
57
Reaction score
7
First Language
English
(function() { var parameters = PluginManager.parameters('vhsMenu'); var _Scene_Menu_vhsMenu = Scene_Menu.prototype.createCommandWindow; Scene_Menu.prototype.createCommandWindow = function() { _Scene_Menu_vhsMenu.call(this); this._commandWindow.setHandler('item', this.commandItem.bind(this)); this._commandWindow.setHandler('skill', this.commandPersonal.bind(this)); this._commandWindow.setHandler('equip', this.commandPersonal.bind(this)); this._commandWindow.setHandler('status', this.commandPersonal.bind(this)); this._commandWindow.setHandler('formation', this.commandFormation.bind(this)); this._commandWindow.setHandler('options', this.commandOptions.bind(this)); this._commandWindow.setHandler('save', this.commandSave.bind(this)); this._commandWindow.setHandler('gameEnd', this.commandSave.bind(this)); this._commandWindow.setHandler('cancel', this.popScene.bind(this)); this.addWindow(this._commandWindow); }})();for got the   })(); .

keep in mind that this plugin is going to REPLACE the function

i havent had a chance to update this thread yet.  Let me know if you have any questions
I actually had the })(); at the end of the script, I just forgot to paste it. I think the problem was actually an extra "};" in there, but regardless, following along with your code there fixed it! Now I can start messing with menu things, yay!

Please continue the tutorials! Thank you!
 
Last edited by a moderator:

GaryCXJk

Veteran
Veteran
Joined
Dec 24, 2012
Messages
88
Reaction score
46
First Language
Dutch
Primarily Uses
is useful when we want to have private method / private function...

but if we don't have those private things... would it be better to write it without it...

any opinion???
You generally always want to box off your code as much as possible to avoid any conflicts, only making things global if you know you need it.If you really need a global variable or function, use window as the main object. It allows you to have private variables while using them together with global ones. Or, you define the globals outside the function.

Code:
var doVelma;+function(w) {  var catchphrase = 'Jinkies!';  doVelma = function() {    catchphrase = 'Jinkies!';  }  window.doDaphne = function() {    catchphrase = 'Jeepers!';  }  w.getGhost = function() {    console.log(catchphrase);  }}(window);
As you can see I used the wrapper function in conjunction with a parameter, and I passed window as an argument, making w its shortcut.
 

estriole

Veteran
Veteran
Joined
Jun 27, 2012
Messages
1,533
Reaction score
763
First Language
indonesian
You generally always want to box off your code as much as possible to avoid any conflicts, only making things global if you know you need it.

If you really need a global variable or function, use window as the main object. It allows you to have private variables while using them together with global ones. Or, you define the globals outside the function.

var doVelma;+function(w) { var catchphrase = 'Jinkies!'; doVelma = function() { catchphrase = 'Jinkies!'; } window.doDaphne = function() { catchphrase = 'Jeepers!'; } w.getGhost = function() { console.log(catchphrase); }}(window);As you can see I used the wrapper function in conjunction with a parameter, and I passed window as an argument, making w its shortcut.
i decide to make ALL my alias global... since if it's private... then the 'original' function will be lost and cannot be accessed...

(correct me though if i'm wrong... and please tell me how to access that 'original' function)

just found some thing that need me to call 'original' method before aliased by yanfly in his message core plugin. and fortunately yanfly didn't make it private variable like lots of plugin maker here... so i can just call that original method to make my plugin compatible with yanfly's.
 

kiriseo

Veteran
Veteran
Joined
Oct 27, 2015
Messages
245
Reaction score
85
First Language
German
i decide to make ALL my alias global... since if it's private... then the 'original' function will be lost and cannot be accessed...

(correct me though if i'm wrong... and please tell me how to access that 'original' function)

just found some thing that need me to call 'original' method before aliased by yanfly in his message core plugin. and fortunately yanfly didn't make it private variable like lots of plugin maker here... so i can just call that original method to make my plugin compatible with yanfly's.
Ok, I'll correct you  :D

You can call the "original" function in a private alias in the same way as a global one.

yourAliasedFunction.call(this[, + needed argument]);

here's an example from the EnemyBook plugin:

var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand; Game_Interpreter.prototype.pluginCommand = function(command, args) { _Game_Interpreter_pluginCommand.call(this, command, args);If Yanfly had made them private, there would be no way to add on to the plugin like the ItemUpgradeSlots plugin for the ItemCore plugin. B)
 
Last edited by a moderator:

estriole

Veteran
Veteran
Joined
Jun 27, 2012
Messages
1,533
Reaction score
763
First Language
indonesian
Ok, I'll correct you  :D

You can call the "original" function in a private alias in the same way as a global one.

yourAliasedFunction.call(this[, + needed argument]);

here's an example from the EnemyBook plugin:

var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand; Game_Interpreter.prototype.pluginCommand = function(command, args) { _Game_Interpreter_pluginCommand.call(this, command, args);If Yanfly had made them private, there would be no way to add on to the plugin like the ItemUpgradeSlots plugin for the ItemCore plugin. B)
no... i mean something like this:

(function() {    var est_test = Game_Event.prototype.initialize    Game_Event.prototype.initialize = function(mapId, eventId) {        est_test.call(this,mapId,eventId);    };})();est_test become private variable...

then in ANOTHER plugin below the first one i write:

   var another_alias = Game_Event.prototype.initialize    Game_Event.prototype.initialize = function(mapId, eventId) {       if(somecondition here)       {          est_test.call(this,mapId,eventId);       }else{          another_alias.call(this,mapId,eventId)       }    };est_test is lost... (it's the original function before i alias it in first code) and in second plugin it throw errors...

another_alias will call the edited function... not the original one.

or like i said earlier... any way to access est_test from another plugin???

if i write it globally

    var est_test = Game_Event.prototype.initialize    Game_Event.prototype.initialize = function(mapId, eventId) {        est_test.call(this,mapId,eventId);    };second code above works fine...

the problem is i see some scripter wrapping their plugins with

(function() {})();would it be trouble for compatibility patch?

if you said no way we need original function before aliasing... the fact is we do sometimes...

this is taken from my plugin EST - AUTOCOLOR PLUS

before it has compatibility issues with yanfly message core... specifically the auto wrap part...

it's because before i auto color the text... i convert escape character so \n[1] will translate to Doraemon (if your actor doraemon).

and will be affected by the auto color... then the final result is thrown again to convert escape character to manage the coloring...

in yanfly... it broke the autowrap... so i need to call the original method before yanfly alias it for my first convert escape character...

if yanfly put it in function wrap like above... thus making the alias lost... then i cannot do that... and it won't be compatible easily.

Code:
var est_auto_text_color_Window_Base_convertEscapeCharacters =                             Window_Base.prototype.convertEscapeCharacters;Window_Base.prototype.convertEscapeCharacters = function(text) {  if (EST.AutoColor.OnlyUseInMessage && this.constructor != Window_Message)       return est_auto_text_color_Window_Base_convertEscapeCharacters.call(this,text);    var xtext = est_auto_text_color_Window_Base_convertEscapeCharacters.call(this,text);  if(Imported.YEP_MessageCore) xtext = Yanfly.Message.Window_Base_convertEscapeCharacters.call(this, text);    var word, use, regex;    for (key in $gameSystem._AC_setting)    {        regex = new RegExp("\\b("+String(key)+")\\b",'img');        xtext = xtext.replace(regex, function(x){            use = $gameSystem.AutoCorrectOk() ? key : x;            if ($gameSystem.AutoColorOk())                   return "\\c["+$gameSystem._AC_setting[key]+"]"+use+"\\c["+EST.AutoColor.ReturnColor+"]";            if (!$gameSystem.AutoColorOk()) return use;        });    }    if(EST.AutoColor.OtherTextColor.toUpperCase() === 'TRUE')               xtext = "\\c["+EST.AutoColor.ReturnColor+"]"+xtext+"\\c["+EST.AutoColor.ReturnColor+"]";    xtext = est_auto_text_color_Window_Base_convertEscapeCharacters.call(this,xtext);    return xtext;};
 
Last edited by a moderator:

kiriseo

Veteran
Veteran
Joined
Oct 27, 2015
Messages
245
Reaction score
85
First Language
German
no... i mean something like this:

(function() {    var est_test = Game_Event.prototype.initialize    Game_Event.prototype.initialize = function(mapId, eventId) {        est_test.call(this,mapId,eventId);    };})();est_test become private variable...

then in ANOTHER plugin below the first one i write:

   var another_alias = Game_Event.prototype.initialize    Game_Event.prototype.initialize = function(mapId, eventId) {       if(somecondition here)       {          est_test.call(this,mapId,eventId);       }else{          another_alias.call(this,mapId,eventId)       }    };est_test is lost... (it's the original function before i alias it in first code) and in second plugin it throw errors...

another_alias will call the edited function... not the original one.

or like i said earlier... any way to access est_test from another plugin???
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.
 

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,546
Messages
1,220,940
Members
173,230
Latest member
eggy29
Top