|
|||||||
This is a discussion on "Which scripting language?" in the Top Mud Sites MUD Coding forum : Hello, Long time listener, first time caller. I am in the process of developing a MUD server in C++, and I am looking for a way to allow builders to script objects with 'events'. That is to say if a character walks into a room it triggers a scripted method named say 'EnterRoom' on the room, other characters and any items that may be lying about, with said character as an argument to this method. I am quite capable of creating a lexer/parser myself, but I am wondering if there is an existing scripting language I can embed that ... |
|
You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so please, join our MUD community today! If you have any problems with the registration process or your account login, please contact us. If you are a registered member of the old TMS forums, please click here
|
![]() |
|
|
LinkBack | Thread Tools |
|
|
#1 |
|
New Member
Join Date: Nov 2003
Posts: 7
![]() |
Hello,
Long time listener, first time caller. I am in the process of developing a MUD server in C++, and I am looking for a way to allow builders to script objects with 'events'. That is to say if a character walks into a room it triggers a scripted method named say 'EnterRoom' on the room, other characters and any items that may be lying about, with said character as an argument to this method. I am quite capable of creating a lexer/parser myself, but I am wondering if there is an existing scripting language I can embed that will do the work for me? I have looked briefly at LUA and RUBY. It was not imediatly obvious how to achieve this in LUA, and I could not find that much information on embedding RUBY. The requirements are: * Each object (character/room/item etc.) needs to have its own script. * The script needs to access and create variables that are either local to its object or global to the world. * The script needs to be somehow 'aware' of the object it is scripting. * The script needs to be able to manipulate other objects somehow. Basically, much like a collection of method calls added on to the C++ object. I did a quick search and found a lot of good advice. However, to clarify, I suppose I am asking for more specific advice on how to set up these languages to achieve what I want. I strongly suspect someone before me has tried/achieved this. I look forward to your sage-like advice, Thanks! |
|
|
|
|
|
#2 |
|
New Member
Join Date: Jul 2002
Location: Canada
Posts: 17
![]() |
<shamelessPlug>
You mean something like this: http://www.wocmud.org/Carnage/docume.../documentID/24 http://www.wocmud.org/Carnage/docume.../documentID/25 </shamelessPlug> I'd say the joy was in writing it. And it's completely sandboxed and under my control. Before I wrote it I considered embedding PHP but then I figured that would be more of a hassle, and also I wanted my legacy easyact scripts to be compatible... so I started from scratch. In retrospect now that I've done it, there are things I can do I don't think would have been easy to do with PHP since I can fully control a running context from within a function (kill it, pause it, jump to an arbitrary code segment). As it stands though, it sucks my time like a black hole. |
|
|
|
|
|
#3 | |||
|
Senior Member
|
My public domain codebase, Aetas, has embedded Ruby for scripting. It performs admirably for every purpose you list.
Embedding Ruby is not too hard. I'll respond to your requirements in turn with how I implemented it in Ruby. Quote:
Quote:
I do not have variables that are global to the world; but if I did, I would be using the same system of properties. I'd merely implement them on the global 'Game' class instead of a specific object. Quote:
[code] class Element ... def cmdSay (args) return if args.empty? msg = "<#{name}> #{args}\n" room.broadcast(msg) room.sendevent(EVENT_TEXT, self, args, args) end ...[/quote] Since the 'say' command executes within the context of 'Element' (my toplevel entity), the 'room' in this method refers to the room in which the Element resides. So it functions rather naturally. Although this sorta feels like an advertisement, my codebase implements exactly what you're asking, so feel free to check it out and post any questions you might have. |
|||
|
|
|
|
|
#4 |
|
Senior Member
|
I was just chastised for leaving out an essential part of our say command. Behold the power of Ruby!
[code] class Element def dumbass (msg, &code) if get("dumbass") then send(msg) dumbasses = get("dumbass").to_s dumbasses.split(",").each { |dname| person = Game.find_player dname person.send(msg) if person } else yield end end def cmdSay (args) return if args.empty? msg = "<#{name}> #{args}\n" dumbass(msg) { room.broadcast(msg) room.sendevent(EVENT_TEXT, self, args, args) } end[/quote] Had some players getting too annoying, so we implemented a property for making messages they send only send to themselves or their little friends =). All without a reboot, btw. |
|
|
|
|
|
#5 |
|
New Member
Join Date: Jul 2002
Location: Canada
Posts: 17
![]() |
Heheh we create objects for dumbass players where we override (we can create also) a command
or in the case of the following snippet all communication commands... this is also loadable at run time, but prevents having exception handling in the command itself (which can also be scripted): [code] custom_command_act parameters; whisper talk say tell reply gtell yell commune ooc ask emote ' " ; , protect { if( !%eqpdObj( @actor, @this ) ) { #%runCommand( @actor, @command ' ' @arguments ) return } endif #@action = 1d20 if( @action == 1 ) { echoto char @actor You pull at your hair frantically. echoto notc @actor %getName( @actor ) pulls at \ %sexPossess( @actor ) hair frantically. } elseif( @action == 2 ) { echoto char @actor \ A loud gratuitous burp expounds from your stomach. echoto notc @actor \ A loud gratuitous burp expounds from %getName( @actor )'s stomach. } else { echoto char @actor \ An overwhelming feeling of stoopidity takes grasp of your being. } endif } endprotect [/quote] Behold the power of BlobbieScript |
|
|
|
|
|
#6 |
|
New Member
Join Date: Nov 2003
Posts: 7
![]() |
Thankyou very much! I took a quick look and both of those systems look like they could be extremely helpful. I'll take a closer look over the course of the next week or so.
Here's another poser, related to my first question: Another approach I am considering is writing the server entirely in an interpreted language like perl or ruby. I was wondering if anyone knows if it is possible to create an instance of a class which has basic functionality, then loading a script into that particular instance. What would be even more helpful is if it would override existing methods. In more detail: -> A class 'room' is defined. -> The class definition contains a method 'DropItem' which defines the default behaviour for dropping an item into that room. -> An instance of a room is created. -> A script is loaded into this instance that redefines 'DropItem' for this room and this room only. I don't know if this is possible, but I had a look through some documentation and perl's 'eval' looks interesting. I should note that I am not concerned about security at this point. This approach interests me for a few reasons: Less work, regular expressions (which I presume would come in handy in a text enviroment) and learning a new language (I am not familiar with perl/ruby/etc.). |
|
|
|
|
|
#7 | |
|
New Member
Join Date: Jul 2002
Location: Canada
Posts: 17
![]() |
Quote:
eval support, could do what you propose. For instance let's take the following (PHP style since I never bothered getting very acquainted with Perl class Room { function doDrop( $params ) { if( !is_null( $this->overrides['doDrop'] ) ) { return eval( $this->overrides['doDrop'] ) } // Do normal doDrop processing. ... } } As you can see by declaring an override script which is assigned to the specific instance of the room then you can essentially override normal processing for an individual room. Cheers, Blobule. |
|
|
|
|
|
|
#8 | |
|
Senior Member
|
Quote:
|
|
|
|
|
|
|
#9 |
|
New Member
Join Date: Nov 2003
Posts: 7
![]() |
Thanks again.
I guess I am too used to more static languages. I am extremely tempted to write the entire server in Ruby now. No more fiddling with templated lists... Easy scripting... No garbage collection to code... Not too far from C++... More besides. The pull is strong. |
|
|
|
|
|
#10 |
|
New Member
Join Date: Nov 2003
Posts: 7
![]() |
OK... I'm thinking about something like this:
[code] class Room def DropItem(item) blah end end ... eval "class ScriptedRoom_#{@room_id} < Room #{@roomscript} end" eval "a = ScriptedRoom_#{@room_id}.new" .... [/quote] If I put the script in a database, I could potentially redefine the behaviour of any object through a website. Dangerous perhaps, but fun! |
|
|
|
![]() |
| Thread Tools | |
Which scripting language? - Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| What language? | Aeran | MUD Coding | 9 | 04-27-2007 04:11 PM |
| Scripting | gutterzombie | MUD Builders and Areas | 6 | 01-28-2004 01:30 PM |
| Internal Scripting Languages | xanes | Advanced MUD Concepts | 10 | 05-19-2003 05:12 PM |
| Embedding scripting languages | Artovil | Advanced MUD Concepts | 6 | 09-13-2002 02:01 AM |
| shell scripting | Emit | MUD Coding | 3 | 05-26-2002 02:48 PM |
|
|