Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Alright guys, I'm making a script...

Okay, I really would like to learn scripting. I'm not planning on learning how to become a master, making full 3D systems and complicated menu and battle systems, just enough so that I can fix my own script problems and make some basic scripts that are just spiced up versions of the RTP scripts.

I have a specific script in mind that I would like to make, and I think it would be pretty easy because I can already imagine it would require the basics of scripting.

I would like to make a script that can be called in an event, so it would be like scene = Scene_???.new. You know what I mean. The script would be a window that appears with a list of items that I specify and, when the player presses 'C' (or Spacebar/Enter) on the items after selecting them with a selector, it adds that item to your inventory. It's much like in Oblivion when you click on a chest and that window appears with the contents of the chest appears and you can choose which ones you want to take.

NOW, this isn't a script request. I just want help making this myself, and all I want to know from you scripting veterans is which existing script do I want THIS script to derive from? (Like, what do I put after the '<'?) I will be updating this frequently if any questions pop up.

Thanks!
 

Jason

Awesome Bro

Code:
 

  def initialize(x, y, width, height)

    super(x, y, width, height)

    @item_max = 1

    @column_max = 1

    @index = -1

  end

 

That's taken straight from Window_Selectable, meaning if you use it as a parent script to your new window (Y'know, borrow the attributes from it), you'll still be able to create the window, using the super class anyway.

What you do, is create the windows and scene in seperate scripts, and in the scene, you'd add the windows like this;

Code:
 

@help_window = Window_Help.new

@item_window = Window_Item.new

 

That's taken from Scene_Item

Hope that's easy enough to follow, lol.
 
Oh, I see. So one script would have all the selecting attributes, another would handle the database items, and the last would handle the actual window? Also, would I have to make one big script, like in Scene_Item, where it calls all three of those at the beginning?
 

Jason

Awesome Bro

Well no not really, I mean, would this scene only have one window, which would show a list of items, that you select, and are added to your inventory ?

If so, you'd just need two scripts, one of them would be a window, while the other would be the scene;

The window would contain the actual window itself;

Code:
 

  def initialize

    super(x, y, width, height)

    self.contents = Bitmap.new(width - 32, height - 32)

    refresh

  end

 

As well as the contents obviously.. I'm sure you could easily borrow from Window_Item, such as the refresh and draw item methods. Although I'm not 100% on how to add which items you want to be shown in the window, I assume that'd have to be done with a call script using an array, you'll have to speak with someone else such as Brew for that (I can't handle arrays just yet, lol).

And for the scene, your best bet would be to use Scene_Item as a reference, or if that's too troublesome, see if some of the more experienced scripters could help you, as I'm not 100% on everything just yet, although I know enough to get me along, and I keep learning from the default scripts, lol. (Unless what I'm trying to do isn't included in any of the scripts, then I turn to the forums)
 
jъГìsт":uehl4aiy said:
would this scene only have one window, which would show a list of items, that you select, and are added to your inventory ?
Yeah, pretty much. It's basically a Scene_Item that stores a bunch of specified items. It would show the descriptions of the items as well, so I guess that would be another window as part of the scene I'm creating. The description window would be easy to do because it's the exact same thing as in Scene_Item.

Anyway, I guess I'll wait for Brew for the arrays part, but thanks a lot for your help so far. I got the gist of it. I'll learn someday lol, slowly but surely.
 
Another class that would be handy to look at is Window_Command. Basically, you'll want a window like Window_Item, except, instead of generating the items based on what the party has, you'll want it to accept an array of items, sorta like Window_Command does. You'll have to set up your scene to accept this array as well, so it can pass it on to the window.

So when you call your scene, it would be $scene = Scene_NAME.new([item1, item2, item3])
(the square brackets [] create the array of items. You can have however many you want)
 
Ah, okay. Window_Command. So, is there a type of code that calls an array? If I'm understanding you correctly, I have to do something to combine the functions of both Window_Command and Window_Item so that the window in the scene I'm creating carries the functions of both possessing items AND allowing them to be selected? How would I combine it like so?
 
I meant more refer to both scripts and see how they do things to get an idea for the window you have to create. (The actual window you create would probably be best inheriting from Window_Selectable). I've found the best way to learn to script is to look at the base scripts and learn and see how they do things.

As far as arrays, square brackets are used for the built-in ruby array class.
so....
Code:
@data = []  #this defines your array

@data[0] = "text!" #this adds the string "text!" to the first slot of the array

@data2 = ['a', 'b', 'c'] # you can also define and add elements to an array at the same time.

# in the above case, a is added to slot 0, b to slot 1 and c to slot 2
 
Okay, quick question. After putting the derivation, would I use def initialize or def main? I never really noticed what either of them are for.

Window_Command, which is derived from Window_Selectable, uses def initialize(width, commands). Since the script I'm making derives from Window_Selectable, would I use def initialize(width, commands)?

Also, after that part, should the script focus on making the window or should I focus on functions that require Window_Selectable?
 
Initialize is the function that is called when you first create an object of that class. Main is only ever used in Scene classes. The main at the very bottom of the script editor calls $scene.main and that's where everything sorta starts.

When a class inherits another class, it gains all of the functions of it's superclass. So by going class Window_YourNewWindow < Window_Selectable, YourNewWindow already has all the functions Window_Selectable had. So it has a index= and help_window=. And because Window_Base is a superclass of Window_Selectable, YourNewWindow also has all the functions of Window_Base.

When you look at the first line in initialize in Window_Command, you'll notice it calls "super(0, 0, width, commands.size * 32 + 32)" This is calling Window_Selectable's initialize function (which requires 4 variables: x, y, width, and height) The variables that Window_Command requires (width and commands) is something that is new to this class because they were needed for the new functionality of the window. In the case of your window, you'll really only need commands (or items I suppose) as a variable, since I imagine everything else will be staying the same every time this window is used.

Oh, and by calling super in the initialize function, you've technically made your window =D

Hopefully this is all making sense. I'm trying to explain the reasoning behind everything to help you understand scripting more.
 
Oh man, you are very helpful! And I also noticed that Window_Item is a derivative of Window_Selectable, which would make even more sense for me to use Window_Selectable. So after I make the window from super, would I now create the variable for handling the items in the array? I think I remember from Ccoa's tutorial a while back that the '@' symbol handles exclusive variables, ones that are only considered in the class that they lie in, right?
And '$' would be for all classes.
 
Yup, that's correct.
No symbol means it is a local variable: you'll only be able to use it in that method. It's basically a temporary variable you'd use in calculations and such. A common use would be something like bitmap = RPG::Cache.icon(item.icon_name) where that bitmap is being transferred onto the bitmap (the function is blt by the way) shortly after, so there's no reason to keep the variable after that.

@ is a private class variable: it's accessible anywhere in that class, but only that class, unless you write a method, or have a method automatically defined through attr_reader or attr_accessor.

$ is a global variable: any class can access and modify it. These are a bit of a system hog though, so only use one if you really really have to. Generally you wouldn't create one in this simple type of script you're trying to make. You might refer to one though, such as $game_party to add the item.

ALL_CAPS defined at the top of a class outside of functions is a constant variable: accessible only in that class, this is a variable that can not change. It's mostly used for settings and such.

And yup, defining your items variable would be a good next step. It will be very similar to the Window_Command method.
Code:
   @item_max = commands.size

    @commands = commands
only with different variable names and such.
 
Okay, so this is what I have so far:

Code:
class Window_Chest < Window_Selectable

 

 def initialize

  super(x, y, width, height)

  @item_max = 1

  @column_max = 1

  @index = -1

 end

 

 @data = []

 @item_max = commands.size

  @commands = commands

Something's telling me that everything is out of order. Also, the "super(x, y, width, height)" looks a little buggy as well because I think I need to actually use that formula.

If everything is up to par though, would I have to now add the items to the party? If so, how?
 
Yeah, there's quite a bit wrong with that. I'll try and address them from top to bottom.

First off, your initialize method isn't accepting any variables. You're going to need it to accept one variable like so: def initialize(items) I'll get to the point of this in a second.

You are right in that you need actual numbers in the super call, at least in this case. If you had your function accepting more variables (def initialize(x,y,width,height,items)) then you could use it as you have it now. Instead, if for example you wanted the window the size of the screen, you'd want to call super(0, 0, 640, 480)

The three lines immediately following the super (5-7) are redundant and serve no purpose. By calling super, these exact lines are done in Window_Selectables initialize method.

The three lines at the bottom (10-12) would most likely cause an error when you compile. With very few special exceptions, all code needs to be defined within functions. So those lines need to be up before the end of the initialize function.

And aside from being in the wrong place, those three lines are also not quite right. Because you are copying the incoming variable (that I mentioned you needed above), you don't need to initialize the data variable. And also, even if you had needed to, they'd need to be the same name. In what you did, you started as @data, then called it @commands later.

And finally, you need to 'end' a class just like a function :) You might not have gotten to that point, but I've had many a script not compile because I forgot an end (or a semi-colon... *shakes fist at c++*)

You don't have to look at the below if you don't want to, but the actual initialize method should look like so:
Code:
#==============================================================================

# ** Window_Chest

#------------------------------------------------------------------------------

#  This window displays a choice of items to pick from in a chest

#==============================================================================

 

class Window_Chest < Window_Selectable

  #--------------------------------------------------------------------------

  # * Object Initialization

  #     items       : list of items to pick from

  #--------------------------------------------------------------------------

  def initialize(items)

    super(0, 0, 640, 480)

    @item_max = items.size

    @items = items

    self.index = 0

    refresh

  end

end
Commenting (all the text after the # symbols) is not necessary per say, but it's good coding practice so you can remember what you did later. Oh, and I set the index to 0 because for the purposes of your script, you want the selection box to be visible right off the start. Also refresh (which we will have to define next) is called right after wards to draw the items visible in the window.

The actual handling of adding the items would be best placed in the scene class. There's a view more things this window needs yet before that though.
 
Oh wow, I did miss a lot. lol I Knew I was missing some stuff, I just had no idea what. When I was reading your post, when you mentioned the "index" part, I wondering what exactly it is/is for.

And about the Refresh part, is that where you would dispose or would it be a sort of thing that updates the script every time the selector moves?
 
The index is where the cursor current is. When it's set to -1, the cursor doesn't show. For the most part, this will be updated automatically if the window is active.

Refresh clears the window (usually just self.contents.clear) then redraws all the contents. So basically it would draw the list of items. The most efficient way to do this, is to have a separate function draw_item, that you call once for every item. An example from Window_Item
Code:
      for i in 0...@item_max

        draw_item(i)

      end
Then the draw_item would be fairly similar to Window_Item, except you will have 1 column, not 2, and I doubt you care how many of the item the party currently has.

And as I'm looking at the refresh method in Window_Item, I come to a realization. I imagine you'd probably want more then just items in chests? You'd want weapon and armor as well? In this case, how you're going to have to call the scene will be slightly different, though we can worry about that later when we get to it.
 
O_O I completely forgot about Weapons and Armor.
I was also looking at Window_Item's Refresh, and it looked to me that it's pretty much the exact same thing that I need in my Window. It defined the array (@data = []), adds items to the party, and pretty much everything I'm trying to do in my script. At the bottom though, where it mentions "bitmap", does that mean it's making a picture? Not sure why it needs to do that.

After Refresh, it does Draw Item and then deals with the Help window, so maybe I could either just use this in my script exactly the way it is, or maybe edit it a little (I don't know what I'd need to edit though lol).
 
Window_Item is actually more complicated then you need. Your array of items is already defined. It's in the variable @items from the initialize method. What window_item is doing, is creating an array from what the party already has. It doesn't actually add anything to the parties items. (and you don't want your script to yet either... that comes when the player decides which one they want)

As far as the bitmap, every window actually contains a bitmap. It's called contents. ((I think the windowskin is a separate bitmap as well, but that's besides the point)) The reason the script is defining the bitmap, is because at the beginning of the refresh method, it disposes it. This is so that in the case of Window_Item, the contents bitmap can be of variable height. If the party loses or gains an item, the heights is going to be different, and thus gets redefined.

For the case of your script, this is not necessary. The same thing can be done with a self.contents.clear at the beginning of the refresh method. Though this does remind me, I forgot one line in the initialize method. Right after the super call, you'll going to need self.contents = Bitmap.new(width - 32, height - 32)

And like I said above, draw_item will be similar, except you'll want it in one column instead of two.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top