I myself absolutely suck(ed) at making scripts Plug and Play/user-friendly, and making it easy for people to implement a script/resource of mine. A perfect example of that is my old generation 7 project.
I saw someone suggest a tutorial on how best to make Plug and Play scripts, so let's get started.
- 1.) Classes can be overwritten and added to from elsewhere.
Let's say you want to add an attr_accessor to the PokeBattle_Trainer class ($Trainer is an instance of that). What you could do is to tell people to locate the script section the class is in and add it there. That's not at all efficient, however. You can "open" the class in a different section and simply add the attr_accessor in there. In this example, we want to add an attr_accessor :quests to our PokeBattle_Trainer class. Our original class is in a conveniently named section called "PokeBattle_Trainer". We'll make a new section and write the following:
This will simply add the getter/setter to the class without removing anything. If the accessor already exists in the class, it will be overwritten. If not, it will simply be added.Code:class PokeBattle_Trainer attr_accessor :quests end
Ruby has a very convenient keyword called alias. It allows you to rename methods during runtime without actually changing the code you write. The method can still be called, but you'll have to call whatever you renamed the method to. An alias follow one, basic format:
old_name is the method you want to rename, and new_name is the name the method will get.Code:alias new_name old_name
Aliasing is often used when you need to add code at the start or end of the method. You can alias methods in the main scope (not in a class or module), but you can also alias methods in a class (most common), and even in a module (less common and a bit harder). Here's an example of how to alias a method in the main scope:
It works pretty much the exact same way for classes:Code:def my_method # This is our method p "Hello world!" # It prints "Hello world!" end my_method # We call our method above alias old_my_method my_method # We rename our method above to old_my_method def my_method # We overwrite our method p "I have been aliased!" # We do something different old_my_method # We run our initial method end my_method # We call our aliased method
We'll now do the exact same, but for a module:Code:class Test # Initializing a new class def my_method # Creating a new method p "This is the first method!" end end myTestClass = Test.new # Creating an instance of our class myTestClass.my_method # Calling the method we just created class Test # Opening the class back up alias my_old_method my_method # Renaming our method to my_old_method def my_method # Overwriting our method p "This is the overwritten method!" my_old_method # Calling our old method end end myTestClass.my_method # Calling our method again
As you can see, we can't just alias in the main module itself. We have to do class << ClassName and do the aliasing in there.Code:module Test # Initializing a new class def self.my_method # Creating a new method p "This is the first method!" end end Test.my_method # Calling the method we just created module Test # Opening the module back up class << Test # Aliasing inside modules happens here alias my_old_method my_method # Renaming our method to my_old_method end def self.my_method # Overwriting our method p "This is the overwritten method!" my_old_method # Calling our old method end end Test.my_method # Calling our method again
As you can only add code above or below by using alias, you may sometimes want to copy some code from the original method. Don't go too overboard with this though, as the user can have changed the method (which would overwrite their changes)!
3.) New methods and classes don't always need to be in one specific section.
This is dead obvious, yet I failed at this myself at one point. If you add a new method that is related to the content in one section, it does not need to be in that section. For example, I made a new method for drawing text at one point and told users to put it in a section called "Messages". This is only adding to confusion, as putting it in there is not even necessary. My resource would be the only one making use of the method, so it could just go inside the script of my resource. That's something you should think about.
- Constants and instance variables in one place.
Let's say you're making a resource. It's a good habit to work with constants at the top of your class, or instance variables (@variable) at the top of whatever method initializes the class/sets up the module.
Some examples of things you may want to make constants or instance variables:
Those are just some examples; if you deem something important or neat, consider making it easily changeable.
- Coordinates for sprites or other important things
- Text color
- Sound effect names/volumes
- Paths to files
- If you have moving elements (for transitions), move speed
- If you have animating sprites, how often they animate (e.g. every X frames)
Here's an example:
Code:class MyUI SPRITE_PATH = "Graphics/Pictures/my_graphic" SPRITE_X = 255 SPRITE_Y = 0 def initialize @viewport = Viewport.new(0, 0, Graphics.width, Graphics.height) @sprite = Sprite.new @sprite.bitmap = BitmapCache.load_bitmap(SPRITE_PATH) @sprite.x = SPRITE_X @sprite.y = SPRITE_Y end end
COMMENT your code
You'll have likely heard it hundreds of times and chances are, you've got a great argument against doing so, too. Think from the perspective of who will be using your resource or else, though. Often times, people will want to do minor or major adjustments. By commenting here and there, you can be a big help to those people (which is what your aim is anyway when you're making a public resource, right?)
Of course, commenting every line or every few lines is ridiculous. It would be a good practice to comment method calls that do important things that people might want to change (messages, positions of certain sprites/elements). Aside from the method calls, consider commenting what arguments your methods take. A big complaint which I myself have myself with some methods in Essentials is the lack of "documentation" on a method. For example, if a method has (*args) and you actively use that in the method (args, args, args, etc.), the user has no way of knowing what everything stands for. That's all the more reason to want to document that, as it would really annoy people.
Of course, I speak as a relatively new programmer, and these are just some things I've encountered or found to work.