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.
 
oops, bit of a slip-up there, I forgot to add a bit, the code should look like
Code:
$data_weapons[$game_actors[actor ID].weapon_id].function
OR
Code:
$data_weapons[$game_party.actors[actor ID].weapon_id].function

The second one will let you get the info for your party members, but in the second case 0 represents the 1st character in your party. Hope that helps XD

EDIT: Also note, this code will throw an error if the member in question has no weapon equipped.
 
The Interpreter uses this code:
Code:
  def command_231
    # Get picture number
    number = @parameters[0] + ($game_temp.in_battle ? 50 : 0)
    # If appointment method is [direct appointment]
    if @parameters[3] == 0
      x = @parameters[4]
      y = @parameters[5]
    # If appointment method is [appoint with variables]
    else
      x = $game_variables[@parameters[4]]
      y = $game_variables[@parameters[5]]
    end
    # Show picture
    $game_screen.pictures[number].show(@parameters[1], @parameters[2],
      x, y, @parameters[6], @parameters[7], @parameters[8], @parameters[9])
    # Continue
    return true
  end
By the look of this, you can see which parameters that does what. You should be able to use a method of the like(add to Game_Event if using):
Code:
  def animate_pictures
    for p in @event.pages
      for command in p.list
        if command.code == 231
          animate_picture(command.parameters)
        end
      end
    end
  end
Please note that the 'animate_picture' method would be your own method in this case.
Since you did not specify what exactly your animation is supposed to do, I will not get into detail. I assume, however, you do not want to just move the pictures around, as that can be done through eventing.

To call the code above, however, use:
Code:
$game_map.events[id].animate_pictures
OR to use it for 'this event' inside a call script for instance:
Code:
event=$game_map.interpreter.get_character(0)
event.animate_pictures

Hope this helps.
 
FireRaven":vbwsfo5q said:
The Interpreter uses this code:
Code:
  def command_231
    # Get picture number
    number = @parameters[0] + ($game_temp.in_battle ? 50 : 0)
    # If appointment method is [direct appointment]
    if @parameters[3] == 0
      x = @parameters[4]
      y = @parameters[5]
    # If appointment method is [appoint with variables]
    else
      x = $game_variables[@parameters[4]]
      y = $game_variables[@parameters[5]]
    end
    # Show picture
    $game_screen.pictures[number].show(@parameters[1], @parameters[2],
      x, y, @parameters[6], @parameters[7], @parameters[8], @parameters[9])
    # Continue
    return true
  end
By the look of this, you can see which parameters that does what. You should be able to use a method of the like(add to Game_Event if using):
Code:
  def animate_pictures
    for p in @event.pages
      for command in p.list
        if command.code == 231
          animate_picture(command.parameters)
        end
      end
    end
  end
Please note that the 'animate_picture' method would be your own method in this case.
Since you did not specify what exactly your animation is supposed to do, I will not get into detail. I assume, however, you do not want to just move the pictures around, as that can be done through eventing.

To call the code above, however, use:
Code:
$game_map.events[id].animate_pictures
OR to use it for 'this event' inside a call script for instance:
Code:
event=$game_map.interpreter.get_character(0)
event.animate_pictures

Hope this helps.

I'm not getting some of the info-- I've successfully called in the number of the picture, but that didn't do me any good- I need that to reference the name of the file, and the position of the picture, so I can call in the next set of frames...

What I'm attempting to create with all this can be found here.
 

Zeriab

Sponsor

Making a script command "wait" some time before executing is a bit advanced since you have to write some script which counts the amount of frames passed and calling the script command when the wanted amount of frames has passed.

If it is a method you want to call after a while then you can try to use the scheduler I have just cooked up: (It still needs some polishing, but seems to work)
Code:
class Scheduler
  ##
  # Class methods
  ##
  @@instance = nil
  
  ##
  # Singleton retrieval (Just the principal, it is not a real singleton)
  #
  def self.retrieve
    @@instance = Scheduler.new if @@instance.nil?
    return @@instance
  end
  
  ##
  # Class method for adding a call
  #
  def self.add_call(*args)
    self.retrieve.add_call(*args)
  end
  
  ##
  # Class method for updating the instance
  #
  def self.update
    self.retrieve.update
  end
  
  ##
  # Instance methods
  ##
  
  ##
  # Initialization
  #
  def initialize
    @timeline = Timeline.new
    @ticks = 0
  end
  
  ##
  # Add a method to call with arguments.
  #
  def add_call(wait, method, *args)
    # Must wait at least 1 frame
    if wait > 0 && method.is_a?(Method)
      # Calculate the absolute tick
      tick = @ticks + wait
      # Add the method call to the time line
      @timeline.add(tick, method, args)
    end
  end
  
  ##
  # Update once every frame
  #
  def update
    @ticks += 1
    @timeline.each!(@ticks) do |command|
      command[0].call(*command[1])
    end
  end
  
  private
  ##
  # An internal wrapper class for the Hash to ease its use in the Schedular class
  # Represents a time line where there can be any amount of calls at any tick
  #
  class Timeline
    ##
    # Initialization
    #
    def initialize
      @data = {}
    end
    ##
    # Add command call at tick
    #
    def add(tick, method, args)
      @data[tick] = [] unless @data[tick].is_a?(Array)
      @data[tick] << [method, args]
    end
    ##
    # Retrieve every command from a specific tick
    #
    def each(tick)
      tick_data = @data[tick]
      if tick_data.is_a?(Array)
        for command in tick_data
          yield command
        end
      end
    end
    ##
    # Destructive each! deletes the commands at the tick afterwards
    #
    def each!(tick, &block)
      each(tick, &block)
      @data[tick] = []
    end
  end
end

##
# Graphics module
#
module Graphics
  class << self
    ##
    # Aliases Graphics.update
    #
    unless self.method_defined?(:zeriab_scheduler_graphics_update)
      alias_method(:zeriab_scheduler_graphics_update, :update)
    end
    def update(*args)
      zeriab_scheduler_graphics_update(*args)
      Scheduler.update
    end
  end
end

Scheduler.add_call(300, method("p"), 'it works!', 'indeed it does!')
If you look in the bottom you can see that I have altered the Graphics.update to update the Scheduler every time Graphics.update is called.
At the very bottom you can see an example of how to use it.

The syntax is Scheduler.add_call(frames_to_wait, method, *arguments)
The tricky bit is how to get the method you want. Use the method method for that.
Code:
obj = MyObject.new
obj.method("my_method") # This is how you can get the method
Notice also that if you use arguments like $game_variables[2] then the value used is whatever the variable is when the method call is added to the scheduler and not when the method is called.

*hugs*
- Zeriab
 
@HellRazor:
Actually, a pause is easy.
Code:
for tick in 0...60
  Graphics.update
  Input.update
end
This will pause the game for 60 frames (2 seconds in RMXP, and 1 second in RMVX).

SEE YA!!!!!
 

Zeriab

Sponsor

That will halt the execution of everything for 60 frames, which is 1.5 seconds in RMXP and 1 second in RMVX.
If that is what you want then you might as well just do this: (For waits less than 8 seconds)
Code:
sleep 1.5
 
    WOW you guys are amazing thanks for the fast replies! this is the best post ever so far really helps...but i'm not clearly in my question (as always) so sorry...i'm meaning halt the execution of one command, not the game... like : execute command one time, wait x seconds, run command again, wait x seconds, run again... where x is a random number between 0 and 100 for sample...
 

Zeriab

Sponsor

I thought it was like that. Hence my first post being directed at that problem ^_^
I am assuming the random number is between 0 exclusive and 100 inclusive. (1, 2, 3, ... , 99, 100)
You can perfectly fine use Scheduler for what you want. I would suggest you use two methods. One that does what you want and another that takes care of the random time between the calls. It could look something like this:
Code:
def my_method
  # Do your stuff
end

def generate_my_method_call
  x = rand(100) + 1
  Scheduler.add_call(x, method('my_method'))
  Scheduler.add_call(x, method('generate_my_method_call'))
end

You can make it more sophisticated like let the variance being affected by variables, making the call loop stop by turning a switch ON (or OFF)
To start the example just have a script call with this: (the event command)
Code:
generate_my_method_call

*hugs*
- Zeriab
 
I'm noob at scripting so i'm getting this error :
uninitialized constant Game_Character::Scheduler

EDIT: where i put the Class_Scheduler thing? thanks

EDIT2: hey i'm starting to get Scheduler to work...its simply to put class Scheduler in my script...but it need hard modification to work like i want but this relly help me learn how to start in the right way  :straightthumb:

EDIT3: Zeriab i want x to aways change his value to random numbers and  x = rand(100) + 1 aways add one maybe because this i'm getting the plus and plus lag and bug and it is affecting all instances of my player i'm want scheduler to affect only the idle instance...sorry dont know if i explain it right  :down:
 

Wichu

Member

Just a quick question, I'm sure I've seen it answered somewhere, but I forgot where :S

Anyway, on the F1 menu, you can change whether it plays BGM / ME and BGS / SE, right?
How can you check that in a script?
 
@Wichu: I don't think you can do that, since it's not meant to be modified or anything. Those functions should be located somewhere between the actual game you see running and the interpreter, aka not the area were you could do anything with RGSS. You might be able to do it someway though, for example with a custom DLL file or even without one, like some people managed to workaround the F12 reset function...
Either way, I don't recommend either of those, for the simple reason that the F1 menu is supposed to be an option menu for the player, so changing anything related to that or having events in your game being affected by those settings would be counterproductive really.
 
Wichu":1l6rod2f said:
Just a quick question, I'm sure I've seen it answered somewhere, but I forgot where :S

Anyway, on the F1 menu, you can change whether it plays BGM / ME and BGS / SE, right?
How can you check that in a script?
I never tried it, but you could try reading windows registry (check last post here), on my machine these settings are in HKEY_CURRENT_USER/Software/Enterbrain/RGSS/
 
I create a script, which draws a window with the windowskin (like the Menu, without commands etc, just the  window with X=Blahblah and Y= Blahblah) and the values X and Y (and Opacity? I don't know if that's possible^^).
And then I want to write a text in the window that will be displayed, if I call it from somewhere.

Means:
In an event, I call this scirpt and an window will be shown with my written text in it.
 

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