View previous topic :: View next topic |
Author |
Message |
virusman
Joined: 30 Jan 2005 Posts: 1020 Location: Russia
|
Posted: Tue Jun 03, 2008 1:25 Post subject: NWNX Ruby |
|
|
I'm working on NWNX Ruby plugin that is going to have an embedded Ruby interpreter with a library of all NWScript functions that you can execute directly from Ruby code.
The latest sources are available on SVN:
http://nwn.virusman.ru/svn/nwnx2-linux/trunk/plugins/ruby/
It's not a fully working version yet.
Python version will be available as soon as I get most of the stuff working.
Last edited by virusman on Mon Jan 12, 2009 18:53; edited 1 time in total |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Wed Jun 04, 2008 16:39 Post subject: |
|
|
To anyone interested in this:
I am developing a toolkit based on nwnx_ruby that will allow efficient and beautiful module development if you are a persistent world developer.
http://roe.elv.es/
The project is, naturally, in it's earliest stages. I'd appreciate feedback and ideas of any kind; send them to me via mail (elven at swordcoast net) or just post here (*thread-hijack*). |
|
Back to top |
|
|
Mikel of Avalon
Joined: 29 Dec 2004 Posts: 72 Location: Germany
|
Posted: Thu Jun 05, 2008 9:32 Post subject: |
|
|
I'm very new to ruby - have you any link to get some information about ruby? _________________ Mikel of Avalon
Kalandur - Die vergessene Welt |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Thu Jun 05, 2008 11:14 Post subject: |
|
|
Mikel of Avalon wrote: | I'm very new to ruby - have you any link to get some information about ruby? |
Official book
more resources |
|
Back to top |
|
|
virusman
Joined: 30 Jan 2005 Posts: 1020 Location: Russia
|
Posted: Thu Jun 05, 2008 11:18 Post subject: |
|
|
Quote: | [04 Jun 08 02:16] * Azbest * hi v-man, could you name an example what you can achieve by processing the code in ruby?
[04 Jun 08 02:16] * Azbest * i have limited imagination here
[04 Jun 08 02:19] * virusman * you can do pretty much the same as in NWScript
[04 Jun 08 02:19] * virusman * and even more
[04 Jun 08 02:19] * virusman * Ruby is object-oriented, so you can write OOP wrappers around objects
[04 Jun 08 02:19] * virusman * you can easily access files, networking, etc.
[04 Jun 08 02:20] * virusman * you can generate Ruby scripts on the fly and execute them immediately
[04 Jun 08 02:20] * virusman * arrays, stacks, hashsets are also supported
[04 Jun 08 02:21] * virusman * you can use Ruby variables and arrays as an alternative to NWScript localvars
[04 Jun 08 02:21] * virusman * and much, much more |
|
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Thu Jun 05, 2008 11:38 Post subject: |
|
|
Ruby code is *much* cleaner and simpler than the rather crude NWScript equivalent.
I dare you (basic string processing): Split a string at arbitary whitespace, iterate over the results, and reverse each string you get, then return as a string. You've got 2 minutes, and one fencepost error will disqualify you. ;)
PS: str.split(/\s+/).map {|s| s.reverse }.join(' ') |
|
Back to top |
|
|
Makazasky
Joined: 27 Apr 2008 Posts: 21
|
Posted: Fri Jun 06, 2008 5:29 Post subject: |
|
|
sorry... im suspicious about this project
From what i checked, The Ruby script will be execute from a nwnx function, can the SetLocalString function handle 1000 lines of script ?
The script will be entirely interpret dynamically, Is it not going to have bad performance? |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Fri Jun 06, 2008 12:41 Post subject: |
|
|
Makazasky wrote: | From what i checked, The Ruby script will be execute from a nwnx function, can the SetLocalString function handle 1000 lines of script ? |
nwnx_ruby directly uses the nwscript VM to execute opcodes. In plain ruby, performance is exactly as good as native; there is no noticeable overhead involved.
As a far-off figurehead, I've benchmarked iterating, through nwnx_ruby, over (exactly) 100 items in a players' inventory, getting the object name and its basetype, and store them in a hash. 2 msec. This is on par with nwscript performance.
Writing a decent framework in ruby around it WILL affect performance, of course, but not insofar as that it is noticeable; and the advantages so far outweigh the theoretical performance hit that it is a moot point anyways. I say theoretical, because it will not result in lag for players (which is what everyone cares about).
There will be more educated benchmarks coming along as soon as someone that cares enough does them. :)
Edit:
You were asking about inlining ruby in nwscript. That is not the best usage for this project (though you certainly can do so). The point is to just delegate events to a ruby library (for example, "player enter"), and do all scripting there. (for example, NWScript.SendMessageToPC(NWScript.GetEnteringObject(), "Hi!")) |
|
Back to top |
|
|
Makazasky
Joined: 27 Apr 2008 Posts: 21
|
Posted: Fri Jun 06, 2008 17:19 Post subject: |
|
|
It shouds good but im still confuse how this plugin work
Is there a beta version already? |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
Posted: Fri Jun 06, 2008 18:41 Post subject: |
|
|
Makazasky wrote: | It shouds good but im still confuse how this plugin work :?
Is there a beta version already? |
You can check out the latest svn revision and compile it. There are a few features missing, like vectors and action handling, but it runs just fine. It is not a stable release, or even beta, though, and there is no documentation or guidance besides the actual source code. |
|
Back to top |
|
|
elven
Joined: 28 Jul 2006 Posts: 259 Location: Germany
|
|
Back to top |
|
|
JeffSheets
Joined: 04 Feb 2009 Posts: 18
|
Posted: Thu Feb 05, 2009 9:40 Post subject: Logged error info |
|
|
I wanted uncaught errors to actually be processed out to the log file, so I changed the following around line 110 in NWNXRuby.cpp in my copy.
Code: |
if (nError)
{
VALUE lasterr = rb_gv_get("$!");
VALUE klass = rb_class_path(CLASS_OF(lasterr));
VALUE message = rb_obj_as_string(lasterr);
Log(0,"Error: %s\n%s\n",RSTRING(klass)-ptr,RSTRING(message)-ptr);
return NULL;
}
|
Now all the bugs caused by my inexperience with Ruby will be easier to debug!
By the way... thanks to everyone who's ever worked on or contributed to NWNX. VERY nice software! |
|
Back to top |
|
|
JeffSheets
Joined: 04 Feb 2009 Posts: 18
|
Posted: Thu Feb 05, 2009 16:43 Post subject: |
|
|
Another change I made:
in ruby_int.c, function NWScript_GetLocalString:
Code: |
StackPopString(&sRetVal);
if (sRetVal)
return rb_str_new2(sRetVal);
return Qnil;
}
|
This makes the function return nil in ruby for local strings that do not exist (never created or recently deleted), instead of throwing an error. |
|
Back to top |
|
|
Fireboar
Joined: 17 Feb 2008 Posts: 323
|
Posted: Sat Feb 07, 2009 1:23 Post subject: Re: Logged error info |
|
|
JeffSheets wrote: | I wanted uncaught errors to actually be processed out to the log file, so I changed the following around line 110 in NWNXRuby.cpp in my copy.
Code: |
if (nError)
{
VALUE lasterr = rb_gv_get("$!");
VALUE klass = rb_class_path(CLASS_OF(lasterr));
VALUE message = rb_obj_as_string(lasterr);
Log(0,"Error: %s\n%s\n",RSTRING(klass)-ptr,RSTRING(message)-ptr);
return NULL;
}
|
Now all the bugs caused by my inexperience with Ruby will be easier to debug!
By the way... thanks to everyone who's ever worked on or contributed to NWNX. VERY nice software! |
This doesn't work with the current version.
I've just recently discovered the delights of nwnx_ruby. I'll certainly be giving this a thorough workout to see if it... er... works out. Nice plugin, potentially the best one yet. |
|
Back to top |
|
|
JeffSheets
Joined: 04 Feb 2009 Posts: 18
|
Posted: Sat Feb 07, 2009 2:56 Post subject: Re: Logged error info |
|
|
Fireboar wrote: | This doesn't work with the current version.
I've just recently discovered the delights of nwnx_ruby. I'll certainly be giving this a thorough workout to see if it... er... works out. Nice plugin, potentially the best one yet. |
You're right... so I use something like the following code for calling Ruby functions:
Code: | string RubyEval(string sCode) {
object oMod = GetModule();
sCode = "begin " + sCode + " rescue NWScript.SendMessageToPC($OBJECT_SELF,$!.class.to_s + ': ' + $!.message.to_s + '\n' + $!.backtrace.join('\n')) end";
SetLocalString(oMod,"NWNX!RUBY!EVAL",sCode);
return GetLocalString(oMod,"NWNX!RUBY!EVAL");
}
void RubyEvalVoid(string sCode) {
object oMod = GetModule();
sCode = "begin " + sCode + " rescue NWScript.SendMessageToPC($OBJECT_SELF,$!.class.to_s + ': ' + $!.message.to_s + '\n' + $!.backtrace.join('\n')) end";
SetLocalString(oMod,"NWNX!RUBY!EVAL",sCode);
}
|
End result is that anything that messes up in the preload script gets logged, and anything executed from NWScript gets sent to the pc. The Void version is included so you can AssignCommand the ruby call. Other Modifications to the code may be made to deal with the errors in more specific ways (My actual code colorizes some of the output).
I'm also thinking that tag based item programming may end up being even cooler with Ruby scripts... |
|
Back to top |
|
|
|