The Dawn Of Time
The Official Forums for the Dawn Of Time Mud Codebase
 
Log in Register FAQ Memberlist Search The Dawn Of Time Forum Index Goto the Official Dawn Website

Alternate to Mprogs : Pscripts

 
Post new topic   Reply to topic    The Dawn Of Time Forum Index » Snippets
View previous topic :: View next topic  
Author Message
Blackout



Joined: 16 Aug 2003
Posts: 26

PostPosted: Sat Aug 07, 2010 5:21 am    Post subject: Alternate to Mprogs : Pscripts Reply with quote

I have never liked mprogs. They do alright for some things, but as any experienced coder knows, there is just a -lot- that they cannot do. I have started developing something for my own mud which will take the place of mprogs. I call it 'pscripts' (The Dawn derivative is called Rewoven Pattern, and the system is Pattern Scripts). Basically, it's a system built around Lua (which I'm not terribly familiar with, but has all the perks I wanted). I intend to use a system similar to triggers (Hooks) that puts most of the pressure of figuring out if a trigger is valid on the script, not the mud.
Obviously I'm early into it, but I've got it sofar to the point where it is capable of taking a block written into a mprog vnum, using it as a Lua chunk and outputting messages to the server or echoing into the mud. I'm optimistic about the whole experience. I'm curious if anyone else might want a copy of whatever I end up with when I'm done. Use of my future snippet will likely require Lua 5.1 or newer installed on your server/computer and a few steps to add necessary files into your projects.
Below is a list of the features that I'm after:

--Temporary and Persistent Variable Support
--Complex Evaluation
--Arithematic Support
--Complex Trigger requirements
--Read/Write Access to Object, Character, Mob, Affect Data
--Timed/Conditional Pausing Support

If folks appear interested, I'll try to drop by updates as I develop further.



_________________
"I could really get around to hating you if I didn't procrastinate so much."

The Third Turning Mud -- Wheel of Time Reimagined
tangent.dune.net 5600
Shaitan, Owner/Head Implementor
Back to top
View user's profile Send private message Send e-mail
Blackout



Joined: 16 Aug 2003
Posts: 26

PostPosted: Sun Oct 17, 2010 2:50 am    Post subject: Final Update Reply with quote

Welp, judging by the replies to this thread, I'm guessing most folks were not interested. I won't bother releasing this snippet to the general public as a result but a final update:

I did complete this project and create an effective and working alternative to mprogs capable of doing complex arithematic, logical evaluations, string manipulation and evaluation, and variable support. The main engine runs off of lua 5.1+ and is positively zippy. I'm still working on expanding to be as efficient and powerful as it can be, but despite being fairly new to lua, in my preliminary evaluations it's capable of blowing the roof off of anything a mprog can do. I could feasibly create new commands that have arguments, new spells and skills and even exceed anything a spec function could do with the limited implementation I've developed sofar.

Good stuff.



_________________
"I could really get around to hating you if I didn't procrastinate so much."

The Third Turning Mud -- Wheel of Time Reimagined
tangent.dune.net 5600
Shaitan, Owner/Head Implementor
Back to top
View user's profile Send private message Send e-mail
Kalahn
Codebase Developer


Joined: 18 Jan 2003
Posts: 710
Location: New Zealand

PostPosted: Sun Oct 17, 2010 8:00 pm    Post subject: Reply with quote

Things are pretty quiet here these days, so I wouldn't take it personally.

A number of years back I had planned to embed a script language, initially tcl (I changed using '{' as the colour code prefix to '`' in prep for this. Later in time I believed if ever got around to embedding a language, it would be python. The thing is, as time went on, my available time got less and less, so I never got around to it. These days though, If I was planning on embedding a scripting a language it would either be python or lua.

It is interesting to note that Civ 5 embeds lua as its script language, where as they used python in Civ 4.

I have no doubt you can do some pretty nice things once you get a real language within the environment.

I have a few questions about your implementation, I appreciate it is a work in progress, so interested in your thoughts about some of these even if you haven't tackled them yet:
    1. You mentioned in your original post you mentioned times/conditional pausing support. Did you manage to achieve anything along these lines?
    2. How involved would a patch be to implement into the dawn release? (assuming you keep the bulk of the LUA embedding code in dedicated files - how many mods to the core dawn source is involved?).
    3. Is it a complete replacement for mobprogs/mudprogs, or just an alternative scripting engine?
    4. Are you using the same triggering mechanism/options etc?
    5. Can you call other LUA functions?
    6. Can LUA functions call existing mudprogs?
    7. Do you support object progs?
    8. How deep is your embedding? Room/area progs (other than an invisible mob)? Hooking into things like char_update(), weather_update() etc?
    9. What is your variable support like? are you able to determine where variables are persisted? i.e. saved on a pfile, saved on a pet, on an object etc? Any concept of scope?
    10. Are you exposing any mud internal data structures to LUA yet? e.g. could you script doing a short description change by directly manipulating the players short description?

Definately interested to hear more.

Cheers,

- Kal


Back to top
View user's profile Send private message Visit poster's website
Blackout



Joined: 16 Aug 2003
Posts: 26

PostPosted: Mon Oct 18, 2010 12:32 am    Post subject: Reply with quote

Wonderful to hear from you Kalahn -- I'll try to share information on it. It's still in its natal stages so I'm daily optimizing/reorganizing/adding to it, but it's fully functional and that's what matters I think:)

1) Not yet, but I have thought of a way that I'm pretty sure will work. Took a lot of study on lua yields and if it doesn't work with lua 5.1, according to the design notes on lua 5.2, 5.2 should be capable of overcoming the one stopgap.

2) Easy as sin. It is infact in a dedicated set of header/cpp files right now aside from the trigger calls, a few hook tables/defines for OLC editors and some function declarations. Each trigger (called a hook in my implementation) requires placement in the pertinent functions to be checked, but otherwise it handles locating hooks in the room/mob/obj, etc etc.

3) Currently it's an alternate on my mud while I switch it out, but it is intended to completely replace mobprogs/mudprogs when I finish. Currently I've added into the mpedit system the ability to set prog or script types on them and changed the mprog system to check to make sure scripts being attached/run/etc are of the proper type for the engine they are being directed to.

4. As you can guess from earlier, the mechanism is very similar -- the options themselves are more condensed in implementation because the script itself can handle identifying specific criteria, for instance a say hook does not need the key phrase, it reacts to all says and the script figures out if the say has the right criteria and acts appropriately.

5. Oh yes, I actually created a new system resource file of pscripts.lua which is secretly called to begin each lua thread and handles setting up tables, metatables and the methods required for interfacing between mud and lua data.
From the scripter's POV the system seems to be pretty seemlessly interacting with the code, the one major exception is that the get/set functions built into each datatype table take a string argument to identify variables on the data they deal with -- IE: ch:SetStat( "hp", 500). Any coder would recognize more is going on behind the scenes, but all in all, pretty strong.
In reality pscripts.lua is setting up functions in each datatype table that call exposer functions to specific mud routines. For instance, ch:SetStat( "hp", 500) calls an exposed function Mud_SetVariable( data_type, data_pointer, variable_name, value ) with the call : Mud_SetVariable( CHAR_DATA, ch.data, "hp", 500), and Mud_SetVariable handles identifying the type of data, typecasting the pointer ch.data back into a char_data, and callign the function that actually gets/sets information. The getter/setter currently works much like save.cpp loading routines do -- identifying the variable name via keys which also provide the function with the methods to deal with the information. When a new variable is to be exposed to lua, you just add a key and, if the data is complex to deal with, write a custom function similar to GIO to cope with special cases.

6. Because it's working through specialized C functions exposed to the lua engine, I can say with very little reservation that there isn't much the system -can't- do in your mud, including doing such obscenely cool things as creating a spell and setting its information based on things you say. I could easily write a script hooked to a mob's says that allowed a player to enter a room, say the proper phrases, and have their says converted into a brand new spell in game similar to what we might make with createspell and sedit. I imagine if I allowed spells to call a script instead of a C function, I could probably go a step further and allow a player to dictate the entire shebang. Lots of potential.

7. I can feasibly support anything progs. The system doesn't care what is calling it or what context it is being used in, the script is given the power to evaluate on a situation-by-situation basis once its hook has been checked, identified and matched.

8. See previous. If a hook function is added that handles figuring out when to call a script and what to pass it, the script can handle everything past that.

9. Lua is self-contained for variables created within the script. I developed a linked list approach to exporting variables in specific situations, and lua has methods to check for them and import them into the script as needed. When lua is done with them or needs to update the mud side, it will need to call a getter/setter to do it, but considering how much further it all is than mprogs, I'd be ashamed to gripe about it.

10. To give you an idea of what it can do, I added recently to my mud a script hooked to a newbie mob's precommand hook for a quest. Within that script, it has two 'commands' that can be executed - list and exchange. list creates a list similar to a shop list, but of things the mob will sell in exchange for parts that nearby mobs sometimes drop as they die. Bring him the requisite parts and exchange <#> and the script calls a C function on my mud that generates a balanced random item, the script tells this function to generate at level 15 piece of eq for the appropriate wear location which is passed back to the script. The script stores this in a lua variable 'piece', it then goes through and restrings the piece using some of those inline->getter/setter functions I described earlier, and gives the player the piece.

An example of that script segment looks like this:
Code:

function MakePiece( lvl, type, spot, keywords, short, long, desc )
   piece = RandomObject( 15, type, spot )
   piece:SetStat( "name", keywords)
   piece:SetStat( "short", short)
   piece:SetStat( "long", long)
   extra_desc = MakeEdData(keywords, desc)
   piece:AddEd(extra_desc)
   return piece
end

....(later)...

keywords = "sharktooth necklace"
short = "a sharktooth necklace"
long = "a sharktooth necklace litters the ground."
desc = "This necklace is an incredible piece of jewelry. Truly marvelous."
piece = MakePiece( 15, "armor", "neck", keywords, short, long, desc)
ToChar(piece, actor)
actor:Say("Cherish this necklace, it's a pride and joy of mine.")
actor:Act("give " .. Refer(piece) .. Refer(ch))

(Refer btw provides, based on datatype and a C call for information, a reference string, such as as a #uid or vnum)
That function is in the individual script, just for this mob to use. I can create functions like that on the fly and optimize my scripts considerably.

And to be honest, this is only this messy and explicit because I'm so raw new with lua. If I were more confident with tables, I could easy create an array of tables in the script that held all of the exchange numbers/keyword/short/long/desc/actor statements for each item and just drew them from that instead of making me manually spell them out.

I'm very proud of this project and I say without reservation its potential uses eclipses my fledgeling abilities to draw upon them currently.

Cheers back, my friend:)



_________________
"I could really get around to hating you if I didn't procrastinate so much."

The Third Turning Mud -- Wheel of Time Reimagined
tangent.dune.net 5600
Shaitan, Owner/Head Implementor
Back to top
View user's profile Send private message Send e-mail
Kalahn
Codebase Developer


Joined: 18 Jan 2003
Posts: 710
Location: New Zealand

PostPosted: Mon Oct 18, 2010 7:22 pm    Post subject: Reply with quote

Sounding really good.

The mudprog engine because it is so basic, and has very limited access to the internals of the mud while not ideal for the most part, it does mean from a security point of view things are simplier.

How is security addressed in your implementation?
i.e. do you intentionally not create the ability to not edit potentially senstive areas? e.g. advancing levels - so a prog can't imp the area editor?

How hard would it be to do something that broke the mud?
e.g. any infinite loop protection?
execution limits etc

Are you watching out for memory leaks when working with strings? e.g. when replacing a short description your centralised string code logically does the same as replace_string() instead of ch->short_descr=str_dup("new string") etc?

- Kal


Back to top
View user's profile Send private message Visit poster's website
Blackout



Joined: 16 Aug 2003
Posts: 26

PostPosted: Mon Oct 18, 2010 9:27 pm    Post subject: Reply with quote

Security was surprisingly easy to deal with. I created a setting in mpedit which allows you to set a script security level - normal, imm, admin, high, unrestricted. Each setting has a minimum level to set them to such, and the exposer functions on the C side automatically generate script errors if the lua script attempts to access something beyond the security level set on the script. Likewise, when one script calls another, the lower of the two security levels they possess are what the child script inherits. So, even if you call another script with a higher security level, you can't 'backdoor' your way into accessing higher level mud data.

As far as things like execution limits and looping, lua handles most of that itself. There are a few methods of crashing the mud through misaccessing of improperly error-handled functions (mea culpa) but, it's a learning experience and I've since been adding the error handlers required to catch the ones in lua I didn't realize could be problematic, such as (table):fun(args) passes a self variable which (table).fun(args) does not, creating fun if the lua function its calling depends on self and doesn't exception handle a miscall. One tricky problem I had initially was how to protect system-defined data from being overwritten without the mud being able to tell.
Lua, because it's completely dynamic with variables, doesn't have any true system of macros, protected variables or really effective levels of discretion. I could overwrite the Lua structure that holds the char_data information in my pscript and while it wouldn't mess up other pscripts (each has their own constructors and threads) or the mud (lua's functions deal with C data via pointers and accessors, not direct access) it would generate some spectacularly silly script errors.
What I finally decided to do was create a mud-side linked list of outstanding pscripts (pscripts that are running or were running and called more recent pscripts in the process).
Basically Script A is created and added to the list, and then run.
In the course of Script A, it makes a call to Script B,
Script A is pushed back on the linked list and Script B takes the front.
This way when something is protected like with the security levels I listed before, I can make comparisons between the pointers they're passing me as pointers to specific mud data and what the pscript_data on that linked-list stack says it -should- be passing me pointers from and catch someone trying to do something devious like trying to manually defraud pointer addresses or pull a switcheroo on things. Sofar this appears to catch the tricks I've understood enough Lua to try against it.

Yeah, I actually use replace_string in the getter/setters to deal with avoiding excessive string leaks. To be honest, I am sure I'm missing chances to optimize that further. I have to constantly tell myself 'baby steps'Smile Lua internally handles all of its own garbage collection, which was one of the reasons I really ran to it. No need for me to tell it how to allocate memory or when to free things or what outstanding memory it has. It handles a (from what the guides explain) fairly complex table tracking every last bit in use by Lua and at appropriate times, managing the table to avoid creating leakage. Wiser men than me appear to believe that aside from some very complex table manipulation of the memory addresses, lua's garbage collection is interally nearly impregnable. Good stuff there.



_________________
"I could really get around to hating you if I didn't procrastinate so much."

The Third Turning Mud -- Wheel of Time Reimagined
tangent.dune.net 5600
Shaitan, Owner/Head Implementor
Back to top
View user's profile Send private message Send e-mail
Sarjenka



Joined: 10 Aug 2019
Posts: 1
Location: Berea, Ohio

PostPosted: Sat Aug 10, 2019 6:11 am    Post subject: Reply with quote

Good afternoon! It's know it's been almost nine years since you've posted this... but I'm very interested in using it and I'd like to know more about how it works. Could you email me directly? My first name is "sarjenka", my middle initial is ".", my last name is "aeristan" and my address is "at GMail". Thank you!


Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    The Dawn Of Time Forum Index » Snippets All times are GMT + 13 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001-2005 phpBB Group
Theme created by Vjacheslav Trushkin