在RM中使用gem和bundle
2014 年 8 月 26 日
其实很多东西跟普通ruby使用gem和bundle是一样的,但是RM没有自带rubygems,因此有两种思路,一种是给RM嵌入一个rubygems,一种是利用另一个Ruby(也就是实际运行bundle的ruby.exe等)来发现require需要的文件和依赖关系。
下面以第二种思路为例,例子任务是使用iniparse这个gem来帮助RM里面读Game.ini。
注意:RPGMaker系列本身不支持载入.so文件,因此能用到的gems只能是纯Ruby形式的源文件组成的代码,这个文章与这个限制无关,也无意绕过这个限制。只是提供了另一种管理脚本插件的思路:借用rubygems。产生的gem目录也可以最后放在加密的rgssad(rgss2a/rgss3a)文件里面并用某种手段当做本地目录读出来,从而保证了加密保护游戏程序的语义,当然这里也不讨论对gem目录的加密和解包具体方法。
1. 首先像正常使用bundle一样在Game.exe目录下建立一个gemfile:
1 2 3 | source 'http://ruby.taobao.org' gem 'iniparse' |
2. 用bundle在工程目录安装所需的gems:
用cmd在工程目录下运行下列代码。
1 | bundle install --path gems |
3. 在RM的脚本编辑器中插入一段辅助代码,让require可以自动去找到我们指定的gem:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | def rb(code, args = nil) open "run.rb", "w" do |f| f.write " class Output def <<(obj) puts [Marshal.dump(obj)].pack('M') end end $output = Output.new " f.write code end system "ruby run.rb #{args}> list.txt" Marshal.load File.read('list.txt').unpack("M").first end module Kernel alias oreq require $:.concat rb %{ $output << $: } def require(a) u = rb %{$output << Gem.find_files(ARGV[0])}, a u.select(&FileTest.method(:file?)).any?{|req|oreq req} end Object::RUBY_VERSION = rb %{$output << RUBY_VERSION} require 'rubygems' alias require oreq end |
4. 这个时候在脚本编辑器之后可以插入使用的代码了,这里我们用的是RGSS3(RPG Maker VX Ace)的代码例子:
1 2 | require 'iniparse' msgbox IniParse.parse(File.read('Game.ini'))["Game"]["Scripts"] |
5. 最后,运行的方式是在cmd下运行下列代码,你也可以建立快捷方式:
1 | bundle exec "Game.exe console" |