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.

Special Support - A great place to learn to Script

Everyone wants to learn to script, but no one really knows where to start. In my honest opinion, the best place to learn is just by reading the default scripts. I learned to script with the japanese RMXP, so I didn't have English comments at my disposal, so everyone of the new generation has that upperhand. Anyways, what I think the best thing to do to learn to script is read the default scripts, and understand each line.

So what I am offering here is support for anyone trying to learn to script. If there is a line of code you don't understand, ask me here. If there is something you want to know, like where in the script editor does something happen, ask here.
  • Ask about a certain line of code : What it means, does, etc.
  • Ask where the coding is for a certain function
PLEASE DO NOT ASK SOMETHING OTHER THAN EXISTING CODE, OR WHERE IN THE DEFAULT SCRIPTS TO FIND A CERTAIN BLOCK OF CODE. Your post will be deleted.

This is a Trial and Error topic. Hopefully, it can lead to more a use full FAQ for beginners.
 

khmp

Sponsor

Serenade":20jq6kda said:
I don't understand the entire for loop in general. And uh, is sephiroth still posting in this thing?

Yeah sorry you instead get me. :tongue: Is the question how they work or what they are used for? I'll try to cover all of that to avoid a back and forth conversation.

A loop is used to roll up a pattern of behavior to ease the creation of an object or objects. If you're looking through code and see a pattern occurring three or more times. It's quite possible that the code can be executed in a loop and shortened.

The types of "for loop"s you can utilize:
Code:
for element in Range
  # loop code
end

for element in Array/Hash etc.
  # loop code
end

The top "for loop" uses a Range type variable to dictate how many times the loop should run. In almost every case you would want the Range to start at 0 and go to N. Where N is any number larger than zero. A Range has two shorthand representations. First one is called an "Inclusive Range" because it includes every element including the last element. For example placing 0..5 in place of the word "Range" in the top "for loop" will tell the loop to run six times. However you can make it an "Exclusive Range" which uses three periods instead of two between the min and max. Using the top example again, if we have 0...5 in place of the word "Range". The loop will execute five times.

In the bottom example of a "for loop" we use an element to iterate through a container object(Array,Hash) of sorts. It's very cool to see how dynamic and flexible it is to mold around these objects but I digress. When the loop starts it grabs the first object inside the Array/Hash and stores it inside "element". But it is only a copy, the actual container object is not affected in this case. It continues to do this incrementally until it has reached the last element.

Code:
# Create an array holding our stuff
stuff = [0, 1, 2, 3, 4]
for element in stuff
  element += 1
end
p stuff # Will print "[0, 1, 2, 3, 4]"

What if you wanted to directly manipulate the data inside the array? You would use the first example like the following:

Code:
# Create an array holding our stuff
stuff = [0, 1, 2, 3, 4]
for index in 0...stuff.size
  stuff[index] += 1
end
p stuff # Will print "[1, 2, 3, 4, 5]"

I hope that helps.
 

Zeriab

Sponsor

Code:
for element in Range
  # loop code
end

for element in Array/Hash etc.
  # loop code
end
They are not really different types of for loops

The for loop in Ruby works like this:
Code:
for object in collection
  # loop code
end

The range 0...5 (exclusive 5) can be conceived as the collection of the numbers 0, 1, 2, 3, 4.
If you wonder what you can use as a collection the general rule of thump is any class which includes the Enumerable mixin

Let us take an example from khmp's post:
Code:
# Create an array holding our stuff
stuff = [0, 1, 2, 3, 4]
for index in 0...stuff.size
  stuff[index] += 1
end
p stuff # Will print "[1, 2, 3, 4, 5]"

We can translate that to: (With no loss of functionality)
Code:
# Create an array holding our stuff
collection1 = [0, 1, 2, 3, 4]
collection2 = 0...collection1.size
for index in collection2
  collection1[index] += 1
end
p collection1 # Will print "[1, 2, 3, 4, 5]"

Basically, we are working with 2 collections.
Naturally using 2 collections is slower than using 1 collection and if you don't need to know where the object is in a collection you should not use a range.

I hope this shed some more light over for loops instead of making it more confusing ^^

*hugs*
- Zeriab
 

e

Sponsor

If you're using a collection though, why would you use the for loop when you can do a each or each_index with a block?

Code:
[1,2,3,4,5].each do |value|
puts value
end

Or even shorter example :

Code:
[1,2,3,4,5].each { |value| puts value }
 

khmp

Sponsor

etheon":3bbn0n8l said:
If you're using a collection though, why would you use the for loop when you can do a each or each_index with a block?

Code:
[1,2,3,4,5].each do |value|
puts value
end

Or even shorter example :

Code:
[1,2,3,4,5].each { |value| puts value }

He asked for a "for loop" introduction, as poorly as mine was. :lol: But they're tons of different ways you could create looping behavior in Ruby.
 

Zeriab

Sponsor

It's a matter of taste more than functionality.

I have a Java background, where there is a similar construction:
Code:
for (Object object : collection) {
  // loop code
}

I use the for loop simple because it is more familiar to the Java syntax.
Performance wise I found there was no significant between using a for loop and a .each (I tested using some arrays as collections)

@khmp: Np, I'm glad I was able to help ^^
On a side note you may have some fun creating your own iterators.
Let me give you an example:
Code:
def WHILE(condition)
  if condition
    yield
    retry
  end
end

i = 0
WHILE(i < 3) { p i; i += 1}
I think what the code does should be obvious ^^
I capitalized WHILE because there already exists a while function in Ruby.

*hugs*
- Zeriab
 

khmp

Sponsor

etheon":j124rpzm said:
Oh. Maybe I should've read a couple more posts XD

I was just puzzled as to why people use for loops for collections.

Sometimes I use them when I am trying to get some kind of patterned layout. Although its just as easy to create you're own counter some people could use the for loops which is automatically updated.

Code:
@a_options = []
for i in 0...4
  # Make a new sprite first
  @a_options << Sprite.new

  # Load the bitmap for the newly created sprite
  @a_options[i].bitmap = Bitmap.new(128, 32)
  # Set the position of the item.

  @a_options[i].x = 50 + # Initial X
                    (10 * i) # Offset

  @a_options[i].y = 240 + # Initial Y
                    (@a_options[i].bitmap.height * i) + # Offset
                    (5 * i) # Option Spacing
end

Coming from a class in C/C++ for loops are primarily the only kind of loop taught other than while/do while. So I use them out of familiarity as well. I do appreciate the ".each" though. I try to use them when I don't need some kind of index based math.
 

e

Sponsor

Then you have each_index! :tongue:
Plus, .each is still usable with Ranges. It's there for pretty much any type that can be turned into a collection. And it fits perfectly with Ruby's philosophy of "duck typing". So stop making up excuses and .each your scripts! :tongue:
 
Well, an overview into "each" and "each_index":

"for" equivalent to "@myarray.each { |val| do_something }":
Code:
for val in @myarray
  do_something
end

"for" equivalent to "@myarray.each_index { |val| do_something }":
Code:
for val in 0...@myarray.size
  do_something
end

Hope you understood. :)
SEE YA!!!!
 
Hi, I'm just beginning to learn and I wanted to ask how do you change actors using a script?
I'm trying to make a Digivolution script that acts just like in Digimon World X where there is a menu of choosing which Digimon you want to digivolve.

Anyways, I have this code:
Code:
when 0 #evolve
      $game_system.se_play($data_system.decision_se)
      if $game_actors[2] != $evolution[i].character

I do not know if it is right, but it is for choosing the evolve command from a menu. I wanted to make it so that if the second game actor (which is the main Digimon actor) is the same as the evolution's character actor, it would become that actor, otherwise the evolve option would not be selectable.  I hope that made some sense, anyway, I'm just beginning to script...
 

khmp

Sponsor

Sakura Martinez":302vtwbm said:
Hi, I'm just beginning to learn and I wanted to ask how do you change actors using a script?
I'm trying to make a Digivolution script that acts just like in Digimon World X where there is a menu of choosing which Digimon you want to digivolve.

Anyways, I have this code:
Code:
when 0 #evolve
      $game_system.se_play($data_system.decision_se)
      if $game_actors[2] != $evolution[i].character

I do not know if it is right, but it is for choosing the evolve command from a menu. I wanted to make it so that if the second game actor (which is the main Digimon actor) is the same as the evolution's character actor, it would become that actor, otherwise the evolve option would not be selectable.  I hope that made some sense, anyway, I'm just beginning to script...

I'm afraid that is more a topic for RGSS support than Special Support. This topic's original intent was to clear up ambiguity or confusion on the default code that comes with RMXP rather than help with custom code. As you can see it has gone off on a rather lengthy tangent. Its time to reign in and focus for all of us.
 
I didn't know that it would have to be on RGSS Support since i was only asking on how to change actors using scripting methods and just explained where I was using it for.  Sorry if I posted wrongly.
 
I have problem learning RGSS

I'm trying to figure out the 'big picture' to make basic custom menu..
But unfortunately, it seems all tuts only giving the specific detail without explaining the big picture of it.

About the 'big picture' I mean.. the outline.. the steps.. sorry, english is my second language.. I just doesn't know how to explain it >.<

So, if anybody understand what I mean, please tell me the big picture of making custom menu screen.


Okay, another question.

Code:
@window_a1=Window_a1.new

As far as I know variables only store value. So what does Window_a1.new do to the variable @window_a1 here?
 
Variables actually stores a pointer, that is the address of something into the computer RAM.
What it is depends of the variable type. Integers corresponds to numbers, strings to a set of characters and objects (as Window_a1.new) corresponds to an instance of a class. Think in a class as a genre of object. So, a "Slime" object is an instance of the Monster class.
In Ruby, integers and strings are also objects, as they have their own class (check the help file for some methods of those). Considering that, Ruby has no "value", only objects - what, in my opov, is really better than ordinary "values" (that are known as primitive types).

I didn't understand what you mean with 'big picture'. But making CMS are simply changing the Scene_Menu to your own purposes... You should understand what windows and scenes represents into the RGSS scenary, but they're very self-explanatory. Further, you then need to understand the XY coordinates, the Window class properties and methods and how to eficiently working with it. Maybe it sounds rather complicated too much, but trust me, it isn't. ^^

SEE YA!!!!!
 
Thanks, It brighten me a bit :)

so assigning Window_a1.new to a variable allows the variable to do the methods of Window_a1 class. Am I right?

I've tried something like this :
Code:
class Window_a1 < Window_Base
  def initialize
    super(0, 0, 440, 120)
    self.contents = Bitmap.new(width - 32, height - 32)
  end
  
  def write
    self.contents.draw_text(0,0, 440, 32, "hello")
  end
end

class Testing
  def initialize
    @window_a1 = Window_a1.new
    @window_a1.write
  end
end

Then i set up an event and put Testing.new script. It works just as I expected.

But then I change the code into this :
Code:
class Window_a1 < Window_Base
  def initialize
    super(0, 0, 440, 120)
    self.contents = Bitmap.new(width - 32, height - 32)
  end
  
  def write(text)  # I change it here
    self.contents.draw_text(0,0, 440, 32, text)  # I change it here
  end
end

class Testing
  def initialize
    @window_a1 = Window_a1.new
    @window_a1.write(hello) # I change it here
  end
end

but error occured when I tested it.

Whats wrong with the code?



And another one,
Code:
  def index=(index)

What does '=(index)' mean?
 

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