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.

Gosu RGSS Player

So I was thinking in the shower (as you do), about RPG Maker.

RGSS, specifically. It's a nicely packaged set of Ruby scripts, which are ran by a C made program.

Now let's say we rewrote all of the hidden scripts and pasted them into the scripts.rxdata file. Would it then not be feasible to create a ruby program to run this file, as game.exe does?

My thought is basically one of expandability and user choice. If we did have this scenario, then a different Bitmap class could be created for say, Gosu, or SFML, or any other graphics library you can think of. The game could be encrypted with any form of encryption.

If this is the case, couple of questions:

1. What are the default scripts? (Or, have I missed any?)

Bitmap
Sprite
Plane
Viewport
Tilemap
Window
Color
Table
Tone
RPG::*
Audio
Graphics

(Seems a lot..)

2. Is there a method in Ruby to print out... well, there is, but I can't get it to work... method forms:

to_print = ""
methods = Object.methods
for i in 0..methods.size
to_print += methods + " " + Object.method[methods].parameters.join(", ") + "\n"
end
print to_print

Should work... well, in my mind should work. It doesn't.

Anyway, would simply be useful (and necessary, really) for recreating the hidden scripts.
 
All I can add is that there's a listing of the "hidden" scripts in the help file of each maker. It lists available methods and accessable variables, however obviously doesn't show any actual code.
 
None of the above listed "scripts" are actually scripts. They are all C classes, which are interfaced with Ruby, meaning they allow Ruby to make calls that actually fire C code, not Ruby code. Ruby alone really isn't powerful enough, or in close enough contact with the OS to run a game, therefore this is how it needs to be done. Sure, you could use about 5000 Win32API calls to different graphic rendering libraries and audio drivers, but Ruby cannot do these things on its own with the type of efficiency that is required.
 
I made a Gosu equivalent to the Input module a while ago. It's mostly self-contained, with two methods that just have to be called from the main Gosu Window instance.

Input module:
Ruby:
module Input

    UP, DOWN, LEFT, RIGHT = 8, 2, 4, 6

    A, B, C, X, Y, Z, L, R = 11, 12, 13, 14, 15, 16, 17, 18

    F5, F6, F7, F8, F9 = 21, 22, 23, 24, 25

    SHIFT, CTRL, ALT = 31, 32, 33

    MAPPING = {Gosu::KbUp => UP, Gosu::KbDown => DOWN, Gosu::KbLeft => LEFT, Gosu::KbRight => RIGHT,

                         Gosu::KbNumpad8 => UP, Gosu::KbNumpad2 => DOWN,

                         Gosu::KbNumpad4 => LEFT, Gosu::KbNumpad6 => RIGHT,

                         Gosu::KbZ => A, Gosu::KbX => B, Gosu::KbC => C,

                         Gosu::KbNumpad0 => B, Gosu::KbSpace => C, Gosu::KbReturn => C,

                         Gosu::KbEnter => C, Gosu::KbPageUp => L, Gosu::KbPageDown => R,

                         Gosu::KbA => X, Gosu::KbS => Y, Gosu::KbD => Z,

                         Gosu::KbQ => L, Gosu::KbW => L,

                         Gosu::KbF5 => F5, Gosu::KbF6 => F6, Gosu::KbF7 => F7, Gosu::KbF8 => F8, Gosu::KbF9 => F9,

                         Gosu::KbLeftShift => SHIFT, Gosu::KbLeftControl => CTRL, Gosu::KbLeftAlt => ALT

                        }

    @@key_state = {}

    @@key_state.default = -1

    def self.update

        @@key_state.each_pair do |key, value|

            next if value == -1

            @@key_state[key] += 1

            @@key_state[key] = 20 if value == 25

        end

    end

    def self.press?(id)

        return @@key_state[id] > 0

    end

    def self.trigger?(id)

        return @@key_state[id] == 1

    end

    def self.repeat?(id)

        return @@key_state[id] == 1 || @@key_state[id] == 24

    end

    def self.dir4

        return 2 if @@key_state[DOWN] > 0

        return 8 if @@key_state[UP] > 0

        return 4 if @@key_state[LEFT] > 0

        return 6 if @@key_state[RIGHT] > 0

        return 0

    end

    def self.dir8

        return 1 if @@key_state[DOWN] > 0 && @@key_state[LEFT] > 0

        return 3 if @@key_state[DOWN] > 0 && @@key_state[RIGHT] > 0

        return 2 if @@key_state[DOWN] > 0

        return 7 if @@key_state[UP] > 0 && @@key_state[LEFT] > 0

        return 9 if @@key_state[UP] > 0 && @@key_state[RIGHT] > 0

        return 8 if @@key_state[UP] > 0

        return 4 if @@key_state[LEFT] > 0

        return 6 if @@key_state[RIGHT] > 0

        return 0

    end

    def self.any?

        @@key_state.each_value do |value|

            return true if value != -1

        end

        return false

    end

    def self.down(id)

        key = MAPPING[id]

        if key

            @@key_state[key] = 0 if @@key_state[key] == -1

        end

    end

    def self.up(id)

        key = MAPPING[id]

        if key

            @@key_state[key] = -1

        end

    end

end

Gosu Window implementation:
Ruby:
class Main < Gosu::Window

    def button_down(id)

        Input.down(id)

    end

    def button_up(id)

        Input.up(id)

    end

end
 

e

Sponsor

It's slightly different than that. As mentioned above, all these classes are written in C and compiled into the DLL with their respective Ruby interfaces, usually for performance reasons (notably the graphics stuff). You could do the equivalent with Gosu, since it's a C++ lib with a Ruby interface; if well programmed, it would probably be faster, to be honest.
 

Zeriab

Sponsor

The RPG::* modules and classes does seem to be only written in RGSS. You can see their code in the help file, yes their functional code, not just the signature. (There is at least one error, so be careful about using it)
I think that the classes and modules who don't have their code shown in the help file are written in C with the only Ruby code being a simple wrapper. I don't actually know this, I'm just guessing.

*hugs*
 
I agree with zeriab, ive always heard that. I have rewritten RPG::Cache recently and had no isssues what so ever. granted i was doing simple stuff like:

[rgss]def self.title(filename)
  return @converter.create_bitmap(filename)
end
[/rgss]
 

e

Sponsor

Caching is actually easy; all it does is grab and keep a reference to a unique location in memory where the resource is stored, so that it will never be garbage collected (i.e. as long as there exists a reference to an object, it will not be purged). That's not very intensive in terms of CPU cycles. The Bitmap and Graphics portion are definitely, and perhaps even others I can't remember (i.e. accurate, high quality audio might be one of these)
 
you have the cache module in the help file
Ruby:
module RPG

  module Cache

    @cache = {}

    def self.load_bitmap(folder_name, filename, hue = 0)

      path = folder_name + filename

      if not @cache.include?(path) or @cache[path].disposed?

        if filename != ""

          @cache[path] = Bitmap.new(path)

        else

          @cache[path] = Bitmap.new(32, 32)

        end

      end

      if hue == 0

        @cache[path]

      else

        key = [path, hue]

        if not @cache.include?(key) or @cache[key].disposed?

          @cache[key] = @cache[path].clone

          @cache[key].hue_change(hue)

        end

        @cache[key]

      end

    end

    def self.animation(filename, hue)

      self.load_bitmap("Graphics/Animations/", filename, hue)

    end

    def self.autotile(filename)

      self.load_bitmap("Graphics/Autotiles/", filename)

    end

    def self.battleback(filename)

      self.load_bitmap("Graphics/Battlebacks/", filename)

    end

    def self.battler(filename, hue)

      self.load_bitmap("Graphics/Battlers/", filename, hue)

    end

    def self.character(filename, hue)

      self.load_bitmap("Graphics/Characters/", filename, hue)

    end

    def self.fog(filename, hue)

      self.load_bitmap("Graphics/Fogs/", filename, hue)

    end

    def self.gameover(filename)

      self.load_bitmap("Graphics/Gameovers/", filename)

    end

    def self.icon(filename)

      self.load_bitmap("Graphics/Icons/", filename)

    end

    def self.panorama(filename, hue)

      self.load_bitmap("Graphics/Panoramas/", filename, hue)

    end

    def self.picture(filename)

      self.load_bitmap("Graphics/Pictures/", filename)

    end

    def self.tileset(filename)

      self.load_bitmap("Graphics/Tilesets/", filename)

    end

    def self.title(filename)

      self.load_bitmap("Graphics/Titles/", filename)

    end

    def self.windowskin(filename)

      self.load_bitmap("Graphics/Windowskins/", filename)

    end

    def self.tile(filename, tile_id, hue)

      key = [filename, tile_id, hue]

      if not @cache.include?(key) or @cache[key].disposed?

        @cache[key] = Bitmap.new(32, 32)

        x = (tile_id - 384) % 8 * 32

        y = (tile_id - 384) / 8 * 32

        rect = Rect.new(x, y, 32, 32)

        @cache[key].blt(0, 0, self.tileset(filename), rect)

        @cache[key].hue_change(hue)

      end

      @cache[key]

    end

    def self.clear

      @cache = {}

      GC.start

    end

  end

end

 

Everything in the RPG:: module is pure ruby, the rest (Helpfile->Built-in Classes) is hardcoded in C.
 

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