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.
 
Thanks a lot!

Is there a command (function?) that returns the total number of elements the skill has? If I can divide rate_total by the number instead of 2, it would be possible to make an average out of 3 or more elements.
Edit: Hm, nevermind, I can do this with a local variable.
 
skyscrapper13":1fd77mha said:
Thanks a lot!

Is there a command (function?) that returns the total number of elements the skill has? If I can divide rate_total by the number instead of 2, it would be possible to make an average out of 3 or more elements.
Edit: Hm, nevermind, I can do this with a local variable.

If I remember correctly, you would do the following:

[rgss]def elements_max_rate(element_set)
  return 100 if element_set.empty?
  rate_total
  for i in element_set
    rate_total += element_rate(i)
  end
  return (rate_total/element_set.size)
end
[/rgss]

It was actually rather silly of etheon to do it that way. Anyway, the one part I changed divides rate_total by the number of elements in element_set, instead of just dividing it by 2.
 
My apologies if this has been asked before or if it's in the wrong place.

I'm writing my game in portuguese, so I had to translate many of the usual menu parameters like hp, mp, equipment,etc... And to accommodate some of the bigger words, RMXP reduces the font width/size, and the word looks cramped and ugly.

I've managed to solve this problem for the equipment and experience parameters by modifying the width value (obvious solution):
Code:
self.contents.draw_text(320, 48, [b]80[/b], 32, "Experiência")

But when it comes to HP/MP, changing the width value only increases the space between the values and the word "hp" itself.


So my question is: Which values do I change to modify the font size/width of the word "hp" on the status screen.
 
Cremno":t7tjzgvf said:
It's not the logical operator or - it's the Array#| method. That method returns a new array by joining two arrays and removing duplicates.
The cause of using this method is that an actor can't be poisoned two times :wink: . E.g.:
[ruby]current_actor_states = %w(Poisoned Paralyzed Sleeping)
states_to_assign = %w(Sleeping Poisoned Blind)
p current_actor_states + states_to_assign  # actor is poisoned and sleeping two times
p current_actor_states | states_to_assign  # he's not poisoned and sleeping two times
[/ruby]But remember that also Fixnum, FalseClass and other classes can have this operator defined and each can have different effects. Read the help (you have to serach manually because of the | character) or the Ruby Documentation, etc.

Btw the line you mean is the same as following:[ruby]used = (used | i.skill_effect(@actor, @skill))
[/ruby]
You are completelly wrong.

RGSS' Scene_Skill script:
[ruby]if @target_window.index == -1
  # Apply skill use effects to entire party
  used = false
  for i in $game_party.actors
    used |= i.skill_effect(@actor, @skill)
  end
end
 
[/ruby]
This will check if using the skill "@skill" will cause any effect on the current characters on the party. It's the boolean operator or, as I previously stated. "used" will be true if the skill causes effect. <img src=\"{SMILIES_PATH}/WinkingEmoteAnim.gif\" alt=\":wink:\" title=\";)\" />

There are no arrays here, so why are you speaking about an Array method?
Indeed, the class Array has a special implementation to the || operator, and it'll work as the "union" math function. It's basically "or" applied to values on two sets.

Cremno, do you really think that I don't know what I'm talking about?... o_O

@Beecheese:
I don't think I've understood what you mean. Where are you changing HP/MP width? It should work just fine.
Anyway, the code you're looking for is the Window_Base draw_actor_hp method:
[ruby]self.contents.draw_text(x, y, 32, 32, $data_system.words.hp)
[/ruby]
Change it as you like. For example, this should work fine:
[ruby]self.contents.draw_text(x, y, 80, 32, $data_system.words.hp)
[/ruby]
But you might have to change the "width" value. At the Window_Status class, you'll find:
[ruby]draw_actor_hp(@actor, 96, 112, 172)
draw_actor_sp(@actor, 96, 144, 172)
[/ruby]
The last value, "172", is the width value. If the HP/MP text is overlaying the numbers, try increasing this value. 220 will probably be enough. :thumb:


SEE YA!!!!!
 
LegacyCrono":rma7c791 said:
Cremno":rma7c791 said:
It's not the logical operator or - it's the Array#| method. That method returns a new array by joining two arrays and removing duplicates.
The cause of using this method is that an actor can't be poisoned two times :wink: . E.g.:
[ruby]current_actor_states = %w(Poisoned Paralyzed Sleeping)
states_to_assign = %w(Sleeping Poisoned Blind)
p current_actor_states + states_to_assign  # actor is poisoned and sleeping two times
p current_actor_states | states_to_assign  # he's not poisoned and sleeping two times
[/ruby]But remember that also Fixnum, FalseClass and other classes can have this operator defined and each can have different effects. Read the help (you have to serach manually because of the | character) or the Ruby Documentation, etc.

Btw the line you mean is the same as following:[ruby]used = (used | i.skill_effect(@actor, @skill))
[/ruby]
You are completelly wrong.

RGSS' Scene_Skill script:
[ruby]if @target_window.index == -1
  # Apply skill use effects to entire party
  used = false
  for i in $game_party.actors
    used |= i.skill_effect(@actor, @skill)
  end
end
 
[/ruby]
This will check if using the skill "@skill" will cause any effect on the current characters on the party. It's the boolean operator or, as I previously stated. "used" will be true if the skill causes effect.

There are no arrays here, so why are you speaking about an Array method?
Indeed, the class Array has a special implementation to the || operator, and it'll work as the "union" math function. It's basically "or" applied to values on two sets.

Cremno, do you really think that I don't know what I'm talking about?... o_O

Chill pickle. There's more than 1 way to skin a cat, and you both came up with methods on how to do it. I don't think Cermno was saying you were wrong, but saying there was an another way to do it. There was really no reason for any that in your post.
 
Thanks for the help.

Also, asking for an opinion: I have two arrays that will be used in every battle in the game.
Is there a "better" place to set them? I put it at the initialization of battle, but I was thinking about setting them at the beginning of the game or loading of the game, since they stay unchanged forever...
It's a really lame question, only I don't know if there's a factor involved I don't know of =P
 
If they are going to be the same for every battle, make them a constant. Setting the instance means you are making objects every time battle is started, where as making them constants, you only have to make them once (as long as you aren't setting the constant to be equal to variables or something).

Code:
class Scene_Battle

  Constant_1 = value

  Constant_2 = value

end

All there is to it.
 
As Sephy said, make them Constants.

But let me point you something, if you ever find it necessary. When you create the Constants inside the Scene_Battle class, you usually won't use those on another class. But you still can! So, for example, if you had Constant_1 and Constant_2 at Scene_Battle and will have to use those values at Window_Skills, you can call the constant values by:
[ruby]Scene_Battle::Constant_1
Scene_Battle::Constant_2
[/ruby]

But if you're using it only at Scene_Battle, you'll not have to do that. :wink:


SEE YA!!!!!
 
I have a question. I'm not sure if this has been answered, but I can't seem to find where if it has. I've seen in some scripts the term "*ARGS" being used. What exactly is its purpose? When and why would I use it?
 

Wichu

Member

Putting * in front of a method argument which is an array will pass each value in the array as a separate argument. For example:

class.method(a,b,c)

is the same as

array=[a,b,c]
class.method(*array)

In method definitions, it works in reverse, converting several arguments passed into an array.
It's useful for things such as aliasing, letting you pass the arguments to the original method without having to worry about how many there were. For example, say you use:

def method(a,b,c)
#do stuff here
end

alias old_method method
def method(a,b,c)
#do something new here
old_method(a,b,c)
end

Now, say you change it to take a fourth argument. You'd have to edit the aliased method, too. However, you could use this to avoid that problem:

alias old_method method
def method(*args)
#do something new here
old_method(*args)
end

If any more experienced scripters disagree, feel free to correct me.
 

e

Sponsor

Basically:

[rgss]def method(*args)
  # args is now an array of arguments; it's what we refer to as a variadic function, that is, a function/method which has no finite number of arguments
  # Basically, there could be 0 to thousands of arguments, so that you could do:
  method()
  method(1, 2, 3)
  method("hello")
  method(1,2,3,4,5,6,7,8,9,10,11,12,13)
  # You get the point
end
[/rgss]

So, as I explained in the comments, *args transforms your function/method into a variadic one; it shouldn't be used unless you explicitly want a function which can take any number of arguments. It's bad practice to use it when you know that the function cannot take more than, say, 4 arguments.

It will also be used to supplement for the lack of multiple function declarations with different method signatures. In most static languages, you can usually define two functions with the same names, but different signatures (that is, different arguments/return values). In Ruby, you can't, so you use *args and try to treat all possible cases.
 
Ok, I've stared at this long enough. It locks up when I set $game_system.energy_bar to false from an event.

Code:
 

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

# ** Game_Party

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

#  This class handles the party. It includes information on amount of gold 

#  and items. Refer to "$game_party" for the instance of this class.

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

 

class Game_Party

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

  # * Public Instance Variables

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

  attr_reader   :energy                   # party energy level

  attr_reader   :max_energy

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

  # * Object Initialization

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

  alias topdod_init initialize

  def initialize

    @max_energy = 200

    @energy = 100 #@max_energy

    topdod_init

  end

  def increase_energy(amount)

    @energy = [@energy + amount, @max_energy].min

  end

  def decrease_energy(amount)

    @energy = [@energy - amount, 0].max

  end

end

 

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

# ** Spriteset_Map

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

#  This class brings together map screen sprites, tilemaps, etc.

#  It's used within the Scene_Map class.

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

 

class Spriteset_Map

  alias topdod_init initialize

  alias topdod_dispose dispose

  alias topdod_update update

  def initialize

    @energy_bar = Sprite_Energy_Bar.new

    topdod_init

  end

  def dispose

    topdod_dispose

    @energy_bar.dispose

  end

  def update

    topdod_update

    @energy_bar.update

  end

end

 

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

# ** Game_System

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

#  This class handles data surrounding the system. Backround music, etc.

#  is managed here as well. Refer to "$game_system" for the instance of 

#  this class.

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

 

class Game_System

  attr_accessor :energy_bar   # true if energy bar is on

  alias energy_bar_init initialize

  def initialize

    @energy_bar = true

    energy_bar_init

  end

end

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

# ** Sprite_Energy_Bar

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

#  This sprite is used to display the energy bar.

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

 

class Sprite_Energy_Bar < Sprite

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

  # * Object Initialization

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

  def initialize

    super

    self.bitmap = Bitmap.new(120, 24)

    self.bitmap.font.name = "Arial"

    self.bitmap.font.size = 22

    self.x = 640 - self.bitmap.width

    self.y = 0

    self.z = 500

    @energy = 0

    @max_energy = $game_party.max_energy

    update

  end

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

  # * Dispose

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

  def dispose

    if self.bitmap != nil

      self.bitmap.dispose

    end

    super

  end

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

  # * Frame Update

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

  def update

    super

    # Set energy bar to visible if working

    self.visible = $game_system.energy_bar

    # If energy bar needs to be redrawn

    if self.visible

      if @energy != $game_party.energy

        @energy = $game_party.energy

        # Clear window contents

        self.bitmap.clear

        # Draw energy bar

        self.bitmap.font.color.set(255, 255, 255)

        self.bitmap.draw_text(self.bitmap.rect, "E")

        full = @energy * 100 / @max_energy

        black = Color.new(0,0,0)

        green = Color.new(0,255,0)

        self.bitmap.fill_rect(18, 8, 102, 8, black)

        self.bitmap.fill_rect(19, 9, full, 6, green)

      end

    end

  end

end

 

I gotta just be not seeing something...
 

e

Sponsor

It only locks up when you set it from an event?

I get the same problem whenever I set anything from $game_system (any property or attr_accessor item) to false. Setting to true doesn't seem to bother them, but it locks up when I set it to false. Go figure.

My work around was to set $game_system.energy_bar to nil. That seems to work.
 
This is the strangest error, but I have an idea what's going on.
Setting "$game_system.energy_bar = false" is causing the script event command to return false... which is making it not move its index.

[rgss] 
# From Interpreter 1
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
...
...
...
      # If return value is false when trying to execute event command
      if execute_command == false
        return
      end
      # Advance index
      @index += 1 # This never happens because it keeps returning first
    end
  end
[/rgss]

I don't actually know why it works like that, but we have something to go from. At the least you know your code isn't wrong, it's something with how the Interpreter works. It also only seems to occur if the script event command is only one line, and that line evaluates to false. (Make one with just false, or 1 == 0 or something and it'll do the same thing)

Anyway to get it working just put another line in the script command so it's not one line.
 
I didn't even think to try that Eth, thanks.

Yeti, good eye. I was looking at that section of Interpreter just yesterday, and still didn't catch it.

Now I just hope I remember next time it bite's me! :scruff:

Thanks guys
 
@Brewmeister:
This topic is not to help you fixing your own scripts. It's to give information on the standard RGSS scripts. :blank:
But here's a solution to your problem. After changing the value, make it return true. Preety simple... It'll look like this:
[rgss]$game_system.energy_bar = false
return true
[/rgss]
...And problem solved! :wink:

SEE YA!!!!!
 

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