PDA

View Full Version : MUD's


DustyPorViva
01-06-2008, 09:17 PM
I think it's time I've learned how to work with MUD databases/scripts... and I'm looking for someone to teach me. You can reach me whichever way possible, but I suppose an IM would be the best way to teach(and what I'd prefer). If you're willing to sit down with me and teach me the basics of how to work with MUD's and .ini's, go ahead and initiate here or in an IM. After that I will most likely always refer back to you for questions.
Thanks in advance!

Chompy
01-06-2008, 09:30 PM
Well, there's different ways to make MUD's, but Inverness have taught me alot of what I can of MUDs :o

Well, for Ini files..

Make a wnpc or somewhere to store this script (To make custom objects):

function onCreated()
{
this.scriptlogmissingfunctions = false;
this.types = NULL;
// Files
maketype("IniFile", 0, {"file_ini"});
}
public function maketype(typename, super, classes)
{
temp.i = 0;

if (makevar("T" @ typename) != null) {
makevar("T" @ typename).destroy();
}
this.(@ "type_" @ typename) = new TStaticVar("T" @ typename);
if (super.type() == 2) {
this.(@ "type_" @ typename).joinedclasses = super.joinedclasses;
}
for (i: classes) {
this.(@ "type_" @ typename).join(i);
}
if (this.types.index("T" @ typename) < 0) {
this.types.add("T" @ typename);
}
}

And I usually put this in a class name that I used when creating the TIniFile custom object above:

("file_ini" as used above)

// Loads an INI File into the object.
public function load(filename) {
// Declaring the temp variables
temp.file = 0;
temp.i = 0;
temp.key = 0;
temp.e = 0;
temp.var = 0;
temp.val = 0;

// Load all the lines from the file.
file.loadlines(filename);
// Stop the loading if the file has no lines.
if (file.size() < 1) {
return;
}
for (i = 0; i < file.size(); i ++) {
// If the line starts with a semi-colon, skip it. (For comments)
if (file[i].starts(";"))
continue;
// Checking if the line is an INI section header (key)
if (!file[i].starts("[") && !file[i].ends("]")) {
// Check to see if a section has been found, can't load variables without one.
if (key == null)
continue;
// Get the position of the equal sign on the line.
e = file[i].pos("=");
// Skip the line if it doesn't exist
if (e < 0)
continue;
// If the line starts with an equal sign, append to last variable loaded.
// This is good for long multi-line amounts of text.
if (e == 0 && var != null) {
val = file[i].substring(1, -1);
this.(@ key).(@ var) @= val;
}
// If the equal sign isn't at the beginning, set a variable in the right section
// <varname>=<value>
else {
var = file[i].substring(0, e);
val = file[i].substring(e+1, -1);
this.(@ key).(@ var) = val;
}
}
else {
// Set the INI section.
key = file[i].substring(1, file[i].length() - 2);
}
}
}
// Saves this object as an INI file
public function save(filename) {
// Declaring temp variables, and getting dynamic variables in the object
temp.output = 0;
temp.i = 0;
temp.e = 0;
temp.keys = this.getdynamicvarnames();
temp.vars = 0;

for (i = 0; i < keys.size(); i ++) {
// If the dynamic variable is actually a value, skip it
if (this.(@ keys[i]).type() != -1)
continue;
// Write the section header
output.add("[" @ keys[i] @ "]");
// Get the dynamic variables for the section
vars = this.(@ keys[i]).getdynamicvarnames();
for (e = 0; e < vars.size(); e ++) {
// Add a line for the variable if its not zero.
if (this.(@ keys[i]).(@ vars[e]) != null) {
output.add(vars[e] @ "=" @ this.(@ keys[i]).(@ vars[e]));
}
}
}
// write the lines
output.savelines(filename, 0);
}
// Clears all values for a certain INI section.
public function clearkey(keyname) {
temp.i = 0;
temp.vars = 0;

// Stop the function if its an actual object.
if (this.(@ keyname).type() != -1)
return;
vars = this.(@ keyname).getdynamicvarnames();
for (i = 0; i < vars.size(); i ++) {
this.(@ keyname).(@ vars[i]) = null;
}
}
// Copies variables from an INI section to an object (like object.loadvars())
public function copyvars(keyname, object) {
// Stop the function if 'object' isn't an actual object.
if (object.type() != 2)
return;
// Stop the function if this.keyname is an object.
if (this.(@ keyname).type() != -1)
return;
for (temp.i: this.(@ keyname).getdynamicvarnames()) {
object.(@ i) = this.(@ keyname).(@ i);
}
}


Then you can load an ini file by doing:


function onCreated() {
temp.foo = new TIniFile();
temp.foo.load("mud/test.ini");

echo(temp.foo.section1.var1); // readed -> object.section.var
// output = value1
}


And "mud/test.ini"


[section1]
var1=value1
var2=value2


All credits to Inverness though :p

And I would suggest you to check out his two mudlibs that he released, it's worth learning from :)

DustyPorViva
01-06-2008, 10:25 PM
Well I plan on going through and making the ini objects manually... I just needed to know how to load data from them. Thanks!

Kyranki
01-07-2008, 12:34 AM
Dusty, you still make the ini objects from scratch when using what Chompy posted here...it's just a database of sorts with which instances of objects can be copied from.

So what Chompy has there joins the class to blank object and you copy in script like so...


temp.file = new TIniFile();
temp.file.load("filepath");

Inverness
01-07-2008, 11:24 AM
My maketype function was just to see if I could replicate object instancing like how its built-in.

It would probably be more manageable to do something like:

temp.file = new TStaticVar();
temp.file.joinedclasses = serverr.classes_inifile;
temp.file.load("stuff");

That should prevent you from having to worry about the base object being uncreated as the time your script runs. It would also allow you to update the class list for a type without going to change the script that creates it.

Also one can define public function objecttype().

I'd really like if there was a function onJoined() you could define just for classes that would be run the instant the class is joined and before the next class is joined. I'd also like a function onLeaving() that would be run when an object leaves the class; including when the object is destroyed. Graal would wait until onJoin() or onLeave() are completed before continuing();

Example:

//A random weapon
function onCreated() {
temp.obj = 0;

obj = new TStaticVar();
obj.joinedclasses = {"class1", "class2", "class3"};
// onJoined is called in order starting with first class in list, graal waits while these are finished.
obj.stuff(); // you do your stuff
obj.destroy();
// onLeaving is called starting with class3 and moving to class1 then when they're all complete, the object is destroyed.
}
// onCreated() would be called in the object if it still existed or no sleep() had been used in the above function.

Well I plan on going through and making the ini objects manually... I just needed to know how to load data from them. Thanks!I just use loadlines() and parse the lines.
And I would suggest you to check out his two mudlibs that he released, it's worth learning from :)I don't really like those, too overdone, its better just to have a universal MudObject that has all the features and has a single save file per object.

I currently don't even use an object for each item anymore as arrays are easier to handle, though I may change that if I find a performance difference.

Chompy
01-07-2008, 10:40 PM
I currently don't even use an object for each item anymore as arrays are easier to handle, though I may change that if I find a performance difference.

Still a way to learn how to make MUDs :p

Inverness
01-08-2008, 03:44 AM
Still a way to learn how to make MUDs :pBest to learn with the better way.

Chompy
01-08-2008, 04:24 PM
Best to learn with the better way.

True, but learning something is better then nothing :p

Anyways, Dusty, how's it going with the MUD?

DustyPorViva
01-08-2008, 05:40 PM
Great! I had a talk with Andrew and I've started from scratch. Instead of worrying about indexing each item on the server in a database, I've instead appended timevar2 onto the player's clientr.var for the weapon, and added it into the data. That way the only way to create a duplicate weapon would be if the the same weapon is created in the very same second. Also eliminates the need for indexing. When the item is dropped, it'll drop its unique index with it. I want to create something more advanced than just a timevar2 ID... but since it's being stored in a clientr.var, I'm trying to keep the size down... :/ If Stefan would fix the RC bugs that wouldn't be a problem.

Chompy
01-08-2008, 05:59 PM
Great! I had a talk with Andrew and I've started from scratch. Instead of worrying about indexing each item on the server in a database, I've instead appended timevar2 onto the player's clientr.var for the weapon, and added it into the data. That way the only way to create a duplicate weapon would be if the the same weapon is created in the very same second. Also eliminates the need for indexing. When the item is dropped, it'll drop its unique index with it. I want to create something more advanced than just a timevar2 ID... but since it's being stored in a clientr.var, I'm trying to keep the size down... :/ If Stefan would fix the RC bugs that wouldn't be a problem.

What rc bugs? :o

And it's good to hear that it's going great :)

DustyPorViva
01-08-2008, 06:04 PM
Setting attr's in RC with long clientr.vars will cut the longer clientr.vars if they exceed a certain character limit.

Chompy
01-08-2008, 06:24 PM
Setting attr's in RC with long clientr.vars will cut the longer clientr.vars if they exceed a certain character limit.

Ah,, the stupid 255 chars limit? I've made several posts about it :(
To bad that Stefan didn't do anything about it back then..

Inverness
01-08-2008, 07:29 PM
I simply used a serverr.muditemcounter integer to give items IDs. However I just index items per object like you would in an array. I suggest you just do it like that unless you have a reason why every item in existence needs its own ID.

Fancy IDing systems are just a hassle.