Proof of Concept: Ruby in RMMV - A Simple HUD Demo

Chocobo

Villager
Member
Joined
Jan 18, 2016
Messages
29
Reaction score
48
First Language
German
Last weekend I came to stumble across the Opal project that allows Ruby code to be run in the browser by transpiling it into JS. I was hooked to find out if it can work in RMMV -- and by that I mean more than just a hello world program.

As a preamble:
There already was a thread with a demo of the RMMV running Ruby about 2 years ago. But the concept was different. It required the end user to have Ruby installed and set up and would only work on a computer. Also, the code wouldn't have been able to interact with the JS objects, so things like a HUD wouldn't have been possible.

This demo project is runnable on a computer, a web browser or a mobile device, without the user having to install anything. So the normal RMMV deployments all work. Furthermore, Opal's JS bridging allows for two-way Ruby/JS interaction.

Without further ado, here's a video of the running demo:

And here is the Ruby code of the two HUDs:
Code:
#==============================================================================
# ** Variable_HUD
#------------------------------------------------------------------------------
#  This class shows a HUD that displays a variable and an icon.
#==============================================================================

class Variable_HUD < Window_Base
   def initialize(iconID, varID)
    @iconID = iconID
    @varID = varID
    
    x = 816/2 - window_width/2
    
    # Calling the base constructor
    super! x, 0, window_width, window_height
    
    refresh
   end
  
   def window_width
     128
   end
 
   def window_height
     64
   end
 
   # Get the variable value
   def value
     $gameVariables._data[@varID] || 0
   end
 
   # Draw the contents
   def refresh
    self.contents.clear
    self.contents.fontSize = 24
    
    drawIcon(@iconID, 0, 0)
    self.contents.drawText(self.value, 0 + 36, 0, 32, 32, 'right')
   end

  # Display the window and attach to the scene
  def show
    $scene.hud = self
    $scene.hud.openness = 0
    $scene.addWindow(self)
    
    open!
  end
end

#==============================================================================
# ** Super_HUD
#------------------------------------------------------------------------------
#  This class shows a HUD that displays some random stuff.
#==============================================================================

class Super_HUD < Variable_HUD
  def initialize
    # Needed when a method from the JS base class should be overriden
      override :standardBackOpacity

    super 99, 100
    
    self.height = 100
  end
 
  # Methods from the Ruby base class can be overriden as usual
  def value
    @varID + rand(100)
  end
 
  def standardBackOpacity
    # Super calls can be made with _super attached to the base method
    o = standardBackOpacity_super
    return o / 2
  end
end

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

# Overriding the update method of Scene_Map.
# In JS -- too lazy right now to figure out the Ruby code :~)
%x{
    var mapUpdateVHUD = Scene_Map.prototype.update;
    Scene_Map.prototype.update = function()
    {
        $sceneMap = this;
        if (this.hud)
            this.hud.$refresh();
        
        mapUpdateVHUD.call(this);
    }
}
In the index.html, there are the following added script tags:
HTML:
        <script src="ruby/opal.js" onload="Opal.load('opal')"></script>
        <script src="ruby/native.js"></script>
        <script src="ruby/opal-parser.js" onload="Opal.load('opal-parser')"></script>
    
        <script type="text/javascript" src="js/libs/pixi.js"></script>
        <script type="text/javascript" src="js/libs/pixi-tilemap.js"></script>
        <script type="text/javascript" src="js/libs/pixi-picture.js"></script>
        <script type="text/javascript" src="js/libs/fpsmeter.js"></script>
        <script type="text/javascript" src="js/libs/lz-string.js"></script>
        <script type="text/javascript" src="js/libs/iphone-inline-video.browser.js"></script>
        <script type="text/javascript" src="js/rpg_core.js"></script>
        <script type="text/javascript" src="js/rpg_managers.js"></script>
        <script type="text/javascript" src="js/rpg_objects.js"></script>
        <script type="text/javascript" src="js/rpg_scenes.js"></script>
        <script type="text/javascript" src="js/rpg_sprites.js"></script>
        <script type="text/javascript" src="js/rpg_windows.js"></script>
        <script type="text/javascript" src="js/plugins.js"></script>
        
        <!-- Ruby files go here -->
        <script type="text/ruby" src="ruby/ruby-definitions.rb"></script>
        <script type="text/ruby" src="ruby/HUD.rb"></script>
        
        <script type="text/javascript" src="js/main.js"></script>
First, the Opal scripts. At the end, two Ruby files are included. The first one defines globals, helpers and some behaviors so that the HUD code can be written like it is. Also, the RMMV "script" command gets overwritten so that it evaluates Ruby code instead of JS code.

The Variable_HUD class inherits from the Window_Base JS class (bridging). Everything else is more or less just "normal HUD stuff", apart from the last lines. The syntax %x{...} lets you run JS code; there the update method is aliased and overriden (this should be doable in pure Ruby as well). Also note that the super call to the JS base class in Variable_HUD requires the special syntax with an appended exclamation marks. Lastly, note that if you want to override methods from the base JS class, you need to use a special override call (see Super_HUD constructor).
On a closing note, I want to mention that this should just serve as a proof of concept. Running Ruby code like this will be significantly slower than running the direct JS code. Also, there's probably a lot more work to do in order to be able to write bigger plugins.

You can find the demo project (< 2 mb) in the attachments.
 

Attachments

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Making my character able to jump around the map because I'm bored and I already did my childhood "I'm bored" punishment of doing dishes.
Actor2_7 added!

Stream is running late, but will begin shortly with some Darkest Dungeon!
More plugins coming this Wednesday, along with updates to our core engine!

Forum statistics

Threads
103,077
Messages
997,088
Members
134,543
Latest member
MrFujioka
Top