Aloe Guvner

Walrus
Veteran
Joined
Sep 28, 2017
Messages
1,628
Reaction score
1,127
First Language
English
Primarily Uses
RMMV
Write a Plugin that reads Notetags - Beginner

Happy Tutorial Tuesday!

This tutorial will teach you how to read an actor's "race" (like Human, Goblin, Dwarf) from their notetag in the database, and display it in the Status Menu.

What should you know before getting started?

This is a beginner level tutorial, and almost everything will be explained in detail. That being said, it would help to have a basic understanding of the following concepts:
  • What a Javascript variable is
  • The sections of the database (Actor, Item, etc.)
  • The difference between assigning a value to a variable vs. checking for equality in a variable
    • i.e. `var myVar = 3` vs. `myVar === 3`
  • How to create folders and files on your computer
---------------------------------------------------------------
What will you learn?

You will learn how to:
  • Read basic notetag data
  • Alias a function
  • Create a new property on an actor
  • Write a script call that can be used in events
  • Create a plugin command
  • Slightly alter the Status Menu

---------------------------------------------------------------
Let's get started!

---------------------------------------------------------------​

RPG Maker MV version

This tutorial is written using modern Javascript standards (ES2015+) that are available in MV v1.6+. For old versions of MV, be sure to use the old Javascript code that is provided. Look out for the sections labelled {{Old MV}}.

If only one version of code is provided, it will work with any version.

---------------------------------------------------------------

Setup

This tutorial is best followed on a blank project with no plugins installed.
If your code isn't working, you will know it is a mistake that you made rather than an incompatibility with another scripter's code. After you have tested your plugin in a blank project, then you can integrate it with existing projects.

In order to write the code, you will need a text editor. Some recommendations are Notepad++, Visual Studio Code, Sublime Text, Atom, Brackets.

Start by creating a blank Javascript file (.js file) named whatever you would like.

---------------------------------------------------------------
Tutorial

This tutorial will teach you how to read an actor's "race" (like Human, Goblin, Dwarf) from their notetag in the database, and display it in the Status Menu.

1.)
Add the following text to Harold's notetag in the database:
Code:
<race:Human>

---------------------------------------------------------------

2.)
Run the game in test mode. On the Title screen, press F8 to open the console, and we will discover the 'meta' property that is on all database objects. In the console, type the following and press enter:
Code:
$dataActors[1]

Expand the data using the arrows, and you will see all of the data from the Database entry for Harold, including the "race" notetag you have added.

MetaNotetagConsole.png

How did this get there?

The RPG Maker MV developers added this `meta` property to make it easy to read notetag data.

---------------------------------------------------------------

3.)
Begin writing the plugin, specifically, the section to read the notetag data. In your .js file, write the following:

Code:
// Retain a reference to the original function
const Game_Actor_setup = Game_Actor.prototype.setup;

Replace `const` with `var`

This creates an alias of the existing `setup` function for actors. In Javascript, you can completely overwrite functions; so by doing this, we will keep a reference to the original function.

---------------------------------------------------------------

4.)
Below that, we will define our new actor `setup` function.

Code:
Game_Actor.prototype.setup = function (actorId) {
   // Call the original function
   Game_Actor_setup.call(this, actorId);
};

We call the original function so that the normal setup of the actors still happens.

---------------------------------------------------------------

5.)
Now we can add one more line to our `setup` function to read from the `meta` data that we examined in step 2.

Code:
Game_Actor.prototype.setup = function (actorId) {
   // Call the original function
   Game_Actor_setup.call(this, actorId);
   this.race = $dataActors[actorId].meta.race || null;
};

The actor now has a `race` property on it that is set to whatever was written in the notetag!

Let's stop for a quick Q & A about this.

---------------------------------------------------------------

Q & A - Round 1
Why did we go through the trouble of aliasing and calling the original function? Why not just copy the whole function from `rpg_objects.js` and add our line to the end?

We could have, and this would have produced an identical result.

However, by overwriting the `setup` function without keeping a reference to the original, we would have made our plugin incompatible with any other plugins that use the same `setup` function.

What is the difference between 'Game' Actor and 'Data' Actor? When do we use one or the other?

The 'Game' Actor is the living, changing actor. It represents all of the changeable data about the actor, such as HP, MP, and Level. This is saved/loaded to/from the savefiles.

The 'Data' actor is completely static data that is defined in the editor Database and stored in the /data/Actors.json file. This data is read fresh from the json file every time the game is booted.

What does `this` mean in Javascript?

`this` is a variable that represents the context that a function is invoked in. In our case, it refers to the actor that is currently getting setup, so it could be Harold, Therese, etc.
Here is a more thorough article explaining this concept.

What does the `||` operator do?

This is Javascript's `or` operator. We're using it to check whether the race notetag actually exists or not, and if it doesn't exist, then we set the value to `null`.

What is `null` and why use it?

`null` in Javascript is when the developer wants to explicitly declare that a variable/property has no value. We use it in this circumstance to avoid crashing the game if somebody didn't add a "race" notetag to the actor.

---------------------------------------------------------------

6.)
Now that "race" is added as a property on the actors, we can easily access it. As a quick example, we'll overwrite the `drawActorNickname` function in the Status screen to draw the actor's race instead of their nickname.

Code:
Window_Status.prototype.drawActorNickname = function (actor, x, y, width=270) {
   this.resetTextColor();
   // If the actor has a defined race, we'll draw it
   if (actor.race) {
      this.drawText(actor.race, x, y, width);
   }
};

Remove the `=270` from the function arguments and add this line as the first line of the function:
Code:
width = width || 270;

HaroldStatusScreen.png

Why include an "if" statement? What is it doing?

Remember before, how if there was no "race" notetag on the actor, we saved the "race" value as `null`?
This `if` conditional statement is checking whether the actor has a legitimate value for their race before drawing that text.

---------------------------------------------------------------

7.)
Create a script call that can change the race of the actor.

Perhaps a mysterious actor starts with a race of "???" and is revealed later, or they change races over the course of the story (Human --> Werewolf). We will create a function here that can be called to change an actor's race.

Code:
Game_Actor.prototype.changeRace = function (newRace) {
   this.race = newRace;
};

This function takes one input, or `argument` of the new race for the actor, and updates the actor's "race" property to the new value.

During the game, this function can now be called like this:
Code:
// Change the race of actor #1 (Harold) to 'Werewolf'
$gameActors.actor(1).changeRace('Werewolf')
Notice how the world 'Werewolf' had to be in quotes. This is because it is a string (text).

---------------------------------------------------------------
8.)
Create a plugin command that can change the race of the actor.

We start by aliasing a reference to the `pluginCommand` function.

Code:
// Retain a reference to the original function
const Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;

Replace `const` with `var`

Then, we overwrite the `pluginCommand` function but make sure to call the original function.

Code:
Game_Interpreter.prototype.pluginCommand = function (command, args) {
   Game_Interpreter_pluginCommand.call(this, command, args);
};

**It is very important to alias and call the original function. If you don't, you will break the plugin commands of all other plugins installed above this one in your projects.

---------------------------------------------------------------

9.)
Add the logic for our plugin command.

Plugin commands are structured like this:
Code:
command arg[0] arg[1] arg[2] arg[3] arg[4] ... arg[n]

So we decide that we will structure our command as:
  • command --> "ChangeRace"
  • arg[0] --> The actor ID to change
  • arg[1] --> The new race

Hey, what's with the square brackets? Is this a new type of variable?

The arguments are given to us in an 'array' format, which is like a list. Arrays are zero-indexed, which means the first item is considered to be a position 0.

We can now modify the function to use our logic.

Code:
Game_Interpreter.prototype.pluginCommand = function (command, args) {
   Game_Interpreter_pluginCommand.call(this, command, args);
   // If the plugin command is ours
   if (command.toLowerCase() === "changerace") {
      // Grab the arguments
      const id = parseInt(args[0]);
      const newRace = args[1];
      // Change the actor's race
      $gameActors.actor(id).changeRace(newRace);
   }
};

Replace `const` with `var`

Now, using a Plugin Command of:
Code:
ChangeRace 1 Werewolf

Harold's race will be changed to 'Werewolf'.

What is parseInt? Why didn't we have to include quotes in the race 'Werewolf' like before?

The arguments are given to us already in a string format, so we need to ensure any numbers are actually converted to numbers (int means integer).

What is `toLowerCase()`?

This is a function we can use on strings to convert all letters to lower case. It makes the plugin command more friendly, because it's no longer case-sensitive.

---------------------------------------------------------------

The final plugin that was created in this tutorial can be referenced here.
The tutorial in its original format is available here.
 
Last edited:

Archeia

Level 99 Demi-fiend
Staff member
Developer
Joined
Mar 1, 2012
Messages
15,273
Reaction score
15,699
First Language
Filipino
Primarily Uses
RMMZ
It looks fine to me but I think it'll disappear in Learning Javascript so I'll pin it.
 

mlogan

Global Moderators
Global Mod
Joined
Mar 18, 2012
Messages
15,946
Reaction score
8,865
First Language
English
Primarily Uses
RMMV
@Archeia If it would be better suited in tutorials, that's fine, I just felt since it was Javascript specific, it should go here. There are learning Javascript tutorials in this section as well.
 

Eliaquim

Hakuen Studio
Veteran
Joined
May 22, 2018
Messages
1,883
Reaction score
1,361
First Language
Portuguese - Br
Primarily Uses
RMMZ
THANKS A LOT ALOE.... i will learn from here!! ^^
 

bazrat

Pixel Game Maker MV
Veteran
Joined
Oct 15, 2018
Messages
241
Reaction score
179
First Language
English
Primarily Uses
Other
Man I have read tutorials, I have watched many videos, and I have tried to understand how plugin commands are implimented. You broke this down so well that I can actually understand what I am doing now. Thank you for this Aloe. This is a game changer for me!
 

Bridgeman

Veteran
Veteran
Joined
Aug 10, 2014
Messages
121
Reaction score
18
First Language
Dutch
I'm pretty sure I followed this tutorial to the letter, yet when I add my plugin into my game nothing shows up in the Parameters field of the plugin menu. Is it supposed to be that way, or am I doing something wrong?
 

Eliaquim

Hakuen Studio
Veteran
Joined
May 22, 2018
Messages
1,883
Reaction score
1,361
First Language
Portuguese - Br
Primarily Uses
RMMZ
@Bridgeman This tutorial will not insert any plugin parameters. I think you understand something wrong.
This is for a plugin to be able to read Actor note tags.
You can see the entire plugin made in this tutorial here.
 

palatkorn

Veteran
Veteran
Joined
Nov 1, 2019
Messages
267
Reaction score
194
First Language
thai
Primarily Uses
RMMV
I usually go in Search from examples that people created
But only a few people who write well describe this way. Thank you.
 

ThreeSixNine

Veteran
Veteran
Joined
Jan 22, 2019
Messages
276
Reaction score
236
First Language
English
Primarily Uses
RMMV
Yes! This is eactly what I need next! After reading hiddenones camping item tutorial, I have been playing around with custom notetags. Currently I am only using custom notetags to build arrays of items as sub categories and saving the arrays to their own game variable. Seeing how easy it will be to give myself the ability to modify the meta data opens the door to take this even further. After landing on storing arrays in a game variable, one thought that keeps popping up is creating some kind of reputation or relationship system.
 

Latest Threads

Latest Posts

Latest Profile Posts

#WIP Metal Tactics's TBS (2015 vs 2021)
VSt9pWc.png
ZXnpNYY.png
RPG Maker News #14 | Diffused Screen Effects, Unsellable Items, Ambient Synths, Adult Woman Set
If kids are going to be taught on computers and have access to the Internet, some basic knowledge of copyright should be a part of the grade school curriculum.
I have some news that I want to share - I've been accepted to university ^-^
I received some offers just over a month ago, but I wanted to make my choice and get things in place before sharing the news.
I'm super excited, and I'm very happy with my choice of program and school.
Yesterday I went to get some new jeans for my new job... and discovered I'm a plus size. I'm planning on dieting so I can get back to where I was before 2020. I decided on a Japanese food diet because the recipes I can cook at home are both low-calorie and delicious.

Forum statistics

Threads
110,513
Messages
1,053,858
Members
143,603
Latest member
arkauss
Top