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.
 
gameguy27":3upxlpwd said:
Line 69
Code:
super(0, 64 + file_index * 138, 640, 240)    
Change the 0 and the 64 + file_index * 138 to whatever
X = 0
Y = 64 + file_index * 138

Sigh, still no effect, sorry. I tried changing the X and it moved the save file image's position. When I try changing Y, nothing happens.
 
kiralim":lps7a6qg said:
gameguy27":lps7a6qg said:
Line 69
Code:
super(0, 64 + file_index * 138, 640, 240)    
Change the 0 and the 64 + file_index * 138 to whatever
X = 0
Y = 64 + file_index * 138

Sigh, still no effect, sorry. I tried changing the X and it moved the save file image's position. When I try changing Y, nothing happens.

Okay I looked through the script again and heres the Y it should work
Lines 169-171
Code:
    

@savefile_windows[0].y = 40    # This is for the first window

@savefile_windows[1].y= 105    # This is for the second window

@savefile_windows[2].y= 170    # This is for the third window

 
 
gameguy27":25a6vmdr said:
kiralim":25a6vmdr said:
gameguy27":25a6vmdr said:
Line 69
Code:
super(0, 64 + file_index * 138, 640, 240)    
Change the 0 and the 64 + file_index * 138 to whatever
X = 0
Y = 64 + file_index * 138

Sigh, still no effect, sorry. I tried changing the X and it moved the save file image's position. When I try changing Y, nothing happens.

Okay I looked through the script again and heres the Y it should work
Lines 169-171
Code:
    

@savefile_windows[0].y = 40    # This is for the first window

@savefile_windows[1].y= 105    # This is for the second window

@savefile_windows[2].y= 170    # This is for the third window

 

Nope that's the coordinates for the Save File image, not for the "Which file would you like to save?" text.
 
Oh ok well I'll look at it and I'll alter it until I get it kiralim. I like helping people if I can so keep a watch for I will figure it out.

Mind posting where you got it so I can have the image files? lol

EDIT: So you're not wanting to change the Save File's Image correct? You want to change the position of the Where would you like to save window right? Thats where I was confused.
Go to line 161
Code:
@help_window.opacity = 0
then add below it
Code:
@helpwindow.x = Whatever

@help_window.y = whatever

I hope thats what you were looking for. If not I'll keep trying
 
Kiralim, if you're using Moghunter's script you should make a topic to ask that or, even better, ask at the Moghunter Save File script. This topic is for the standard scripts only! :wink:
Anyway, here's what you should do:
~ Search on the scripts for "@help_window = Window_Help.new";
~ Below this line, put "@help_window.x = <number>" and "@help_window.y = <number>";
~ Done.

SEE YA!!!!!
 
I have a question concerning the Marhsal module. I get how it is used, with the dump and load methods. But when I look it up, the examples have it only dumping or loading one class. Where in the RGSS (at least for RMXP, haven't really done much with RMVX) it is able to dump and load multiple classes.

So my question is...how does it know which to load? Is it simply based on the order in which it was dumped, or does it somehow know where to put what class? Any help would be appreciated. :D
 

khmp

Sponsor

Think of Marshal's dump and load behavior as a line of people. Person1 enters a line, Person2 enters a line, Person1 exits line, Person2 exits line. The first thing you dump is the first thing that loads. First in first out. You can see this behavior if you look at Scene_File's write_save_data and read_save_data methods. Objects are dumped in the same order they are loaded. Most likely when the file is being written, and each individual class is serialized, it makes a marker describing the object size/deserialization process. However that's only my assumption I don't know much about the innards.

How does it know which one to load? Well keep in mind there are no defined types. Meaning you can't declare a variable of type integer. A variable assumes a type during assignment. Because of that Marshal doesn't need to know which class to load. It continues to read from the stream until it has reached the end of the file. It is your duty to remember the save/load order.

I tried to be verbose to cover most of it. If you still have a question let us know. Also below is a little code snippet demonstrating the work. The code can be placed right above main for a quick test if you wanted.

Code:
file = File.open('test.sec', 'wb')

Marshal.dump('test string', file)

Marshal.dump('this is a waste of a file', file)

file.close

 

file = File.open('test.sec', 'rb')

string1 = Marshal.load(file)

string2 = Marshal.load(file)

file.close

 

p string1, # 'test string'

  string2   # 'this is a waste of a file'

 

File.delete('test.sec')
 
The proper and common way to make a new object that must be saved/loaded with the rest of the game's session data, you must alias these following methods, and create/save/load these objects after the origional method alias. Here's an example...

Code:
#===============================================================================

# ** Scene_Title

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

 

class Scene_Title

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

  # * Alias Listings

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

  alias_method :cms_scntitle_commandnewgame, :command_new_game

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

  # * Command : New Game

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

  def command_new_game

    cms_scntitle_commandnewgame

    $game_menu = CMS.new

  end

end

 

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

# ** Scene_Save

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

 

class Scene_Save < Scene_File

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

  # * Alias Listings

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

  alias_method :cms_scnsave_writesavedata, :write_save_data

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

  # * Write Save Data

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

  def write_save_data(file)

    cms_scnsave_writesavedata(file)

    Marshal.dump($game_menu, file)

  end

end

 

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

# ** Scene_Load

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

 

class Scene_Load < Scene_File

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

  # * Alias Listings

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

  alias_method :cms_scnload_readsavedata, :read_save_data

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

  # * Read Save Data

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

  def read_save_data(file)

    cms_scnload_readsavedata(file)

    $game_menu = Marshal.load(file)

  end

end

Naturally, putting these 3 class mods grouped together (and not individually floating around wherever in your scripts list) is going to enforce the FIFO (first in, first out) as said above.

Good luck with it :smoke:
 

ChasW

Member

I ran into some trouble adding some debugging to equipping items onto actors within the default scripts, which has led me to some confusion on Events.

I was attempting to just go through some of the code and put in some prints to see how it functions when I ran into what appeared to be odd behavior from my perspective. Here's the code I changed in Game_Actor.

[rgss] 
  def equip(equip_type, id)
    case equip_type
    when 0  # Weapon
      if id == 0 or $game_party.weapon_number(id) > 0
        $game_party.gain_weapon(@weapon_id, 1)
        # TEST DEBUGGING
        print "New Weapon ID: %d" %id
        print "Old Weapon ID: %d" %@weapon_id
        # END TESTING
        @weapon_id = id
        $game_party.lose_weapon(id, 1)
      end
 
[/rgss]

The problem is, it keeps going and going and going. It will say "New Weapon ID: 1" "Old Weapon ID: 2" "New Weapon ID: 2" "Old Weapon ID: 1" over and over and over, never stopping. I have to Alt+F4 it. I tracked this back all the way to Scene_Equip line 20: def main. It looks like it is just an infinite loop in which it refreshes the page forever. That means it constantly calls equip repeatedly (@actor.equip line 106 of Scene_Equip). That would explain the behavior I saw when trying to watch the code quoted above.

So, my question is why is it done this way? I would have thought that it would have waited for a user fired Event based on a keypress at which time it would run Game_Actor.equip. Ruby is an O-O language, and the likes of Observer Patters and Events are fairly ubiquitous (I think, at least). Is this a programming choice? Is there a reason for it? Is this a Ruby thing? Is this what I can expect throughout the default scripts?
 
You are correct. They are calling 'refresh' with every update. It should only be called when the individual windows need to be refreshed.

Try changing the update method in Scene_Equip to

Code:
 

  def update

    # Update windows

    @left_window.update

    @right_window.update

    @item_window.update

    ## Only refresh when the right window cursor (index) moves

    if @equip_index != @right_window.index

      refresh

      @equip_index = @right_window.index

    end

    # If right window is active: call update_right

    if @right_window.active

      update_right

      return

    end

    # If item window is active: call update_item

    if @item_window.active

      update_item

      return

    end

  end

 
 
I just need feedback on this script I started working on. Its an Item Rarity script.

itemrarities.png


I need feedback on it and anything I could possible do to it.
 
I just need feedback on this script I started working on.
You missed the point of this topic. No feedback is given here.
If you need help with the default scripts, this is the place. But don't even bother posting here if you want people to download and comment your stuff.


SEE YA!!!!!
 
Curious, why might be I getting this error

Script 'Window_Base' line 172: NoMethodError occured.
undefined method 'name' for nil:NilClass

for this line in the window_base class.

self.draw_shadow(x, y, 120, 32, actor.name)

I don't get why it's not working personally cause actor.name is a variable of the Game_Actor class and actor is being sent to it but ya..

Trying to basically recreate the menu system so it's not making a new scene for the options of the menus (Item works fine but status/equip/skills of course require the send of actors so it must be something with that). If you need me to post more code just let me know.

Edit: nvm, I figured it out XD lol took me a bit though
 
I have a cms in my game where the faceset shown relies on actor id
however in my game I have character actor's graphic changing often
thus this system doesn't work for me,
rather I want it to rely on character graphic (the walking one seen on the map) filename
but I don't know which variable to use...

it uses @actor to determine which faceset to use and
@actor = actor

Which variable should I use instead of actor
(which according to Game_Actor refers to the actor id)
so that it refers to character graphic filename?
 
Hello :)

Wow, I haven't had to ask anything in a long time, but I was recently messing and experimenting with $game_map.passable? method and I've always been curious what this value is exactly and how it works, why its used, etc...

0x0f

When I use 'p' or 'print' to view the value, it says '15' so... I don't understand why that number? I mean, passability is based off of 8 directions, right? So what does the 0x0f or 15 come from?

When I look at this line, it confuses me what its purpose is...

# If obstacle bit is set in all directions
elsif @passages[event.tile_id] & 0x0f == 0x0f


That basically translates to me like...

# If obstacle bit is set in all directions
elsif @passages[event.tile_id] & 15 == 15


0x0f == 0x0f and 15 == 15 will always return true, right? Or does this 'bianary' number change or what? Thanks ahead of time for anybody who can clear that up for me.

@Velocir_X : This topic is for general Ruby/RGSS and RGSS2 questions, ie questions about default scripts and not custom scripts, if I'm not mistaken. Unless you're talking about VX, you might want to make your own support topic with the code for the CMS and especially the parts that you made to deal with facesets. If I have time I'll drop in and try to help you out.

If you want, I have a scriptlette (which needs to be updated) from my CMS which I use to handle face graphics, with a settings module so you can define things like what to look for in the filename when referencing a faceset.

Most people who do their own 'faceset' script for XP would reference it like @actor.character_name + "_face", ie Fighter 01's faceset would be "001-Fighter01_face" for the filename. If it doesn't exist, then use a rescue statement so it doesn't crash the game... please make topic, I'll try to help you more if I have time today.
 
@Velocir_X : This topic is for general Ruby/RGSS and RGSS2 questions, ie questions about default scripts and not custom scripts, if I'm not mistaken. Unless you're talking about VX, you might want to make your own support topic with the code for the CMS and especially the parts that you made to deal with facesets. If I have time I'll drop in and try to help you out.

If you want, I have a scriptlette (which needs to be updated) from my CMS which I use to handle face graphics, with a settings module so you can define things like what to look for in the filename when referencing a faceset.

Most people who do their own 'faceset' script for XP would reference it like @actor.character_name + "_face", ie Fighter 01's faceset would be "001-Fighter01_face" for the filename. If it doesn't exist, then use a rescue statement so it doesn't crash the game... please make topic, I'll try to help you more if I have time today.
Actually it is a custom script - Caldaron's Animated 1 Hero CMS
viewtopic.php?t=10326.msg111971

And I tried actor.character_name, it doesn't work
I get a random 10 digit variable name that is required ?????

The part of the script in question
class Menu_Graphic < Window_Base
#--------------------------------------------------------------------------
def initialize(actor)
@actor = actor
super(240, -256, 160, 224, 128)
self.contents = Bitmap.new(width - 32, height - 32)
refresh
end
#--------------------------------------------------------------------------
def refresh
self.contents.clear
draw_actor_menu_graphic(@actor, 64, 96)
end
#--------------------------------------------------------------------------
end

I would of put this on the cms's thread but that would be necroposting :(

EDIT: Nvm I was looking at the wrong place should of looked at the draw_actor_menu_graphic method :P
 
I'm having a problem editing original RGSS2:

Code:
 #--------------------------------------------------------------------------

  # * Get Character Graphic

  #     filename : Filename

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

  def self.character(filename)

    load_bitmap("Graphics/Characters/", filename)

  end

When I add 'hue' at the end of the array, the hue bar does not show up in the editor... Why is that? The commands above it has the 'hue' in their arrays above this segment... so I thought maybe the hue bar would show up, allowing me to edit hue values...
 
Kain Nobel":1lc559fo said:
Hello :)

Wow, I haven't had to ask anything in a long time, but I was recently messing and experimenting with $game_map.passable? method and I've always been curious what this value is exactly and how it works, why its used, etc...

0x0f

When I use 'p' or 'print' to view the value, it says '15' so... I don't understand why that number? I mean, passability is based off of 8 directions, right? So what does the 0x0f or 15 come from?

When I look at this line, it confuses me what its purpose is...

# If obstacle bit is set in all directions
elsif @passages[event.tile_id] & 0x0f == 0x0f


That basically translates to me like...

# If obstacle bit is set in all directions
elsif @passages[event.tile_id] & 15 == 15


0x0f == 0x0f and 15 == 15 will always return true, right? Or does this 'bianary' number change or what? Thanks ahead of time for anybody who can clear that up for me.

I can't answer fully, but I can help some and maybe you can figure it out from there/someone else can help with the rest. Anyway.

0xNUMBER means it's a hexadecimal number. 15 in hex is F. It's written with the 0x in front so it can be differentiated from decimal numbers (0F is clearly a hex number but, for example, 0x300 in decimal is 768; if you just wrote 300, how would it know which you meant?). I don't know the reason 0x is what's used, but whatever.
And as far as I can tell, for the code you were looking at
[rgss]# If obstacle bit is set in all directions
elsif @passages[event.tile_id] & 0x0f == 0x0f
[/rgss]
the order of operation here is
[rgss]# If obstacle bit is set in all directions
elsif ((@passages[event.tile_id] & 0x0f) == 0x0f)
[/rgss]

However, I don't know how the binary and operator works, so I'm not sure what it's checking. :/

EDIT

I'm thinking... the @passages[event.tile_id] gets the passability for the tile, which is 4 bits for each direction. So if they're all set to 1, that's 1111, which is 0x0F/15 in binary. I'm guessing the "& 0x0F" actually would return the exact same thing as the original number, except converted to hex instead of in decimal or whatever it starts as. I don't see why they would do it that way, but it kinda makes sense.
 

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