Author Topic: Mudlib Design Specs: pt1  (Read 4012 times)

Offline Sluggy

  • Friend
  • **
  • Posts: 91
    • View Profile
    • Stellarmass
Mudlib Design Specs: pt1
« on: January 29, 2013, 06:28:43 PM »
Since I've previously mentioned on another thread that I am going to start work on a new mudlib I've been scribbling lots of things down onto paper. Before I really get into the code I want at least a rough sketch of what it should look like once things are in a working order. Since then I've come across a few considerations that I figured might warrant other opinions. Since its likely that many of these 'considerations' might pop up I've decided to label each such thread with a part number- hence the 'pt 1' in the title.

Sefuns: Do people like them? I generally like the idea of common functions just being available without having to include special headers or accessing wrapper objects. However, there is something to be said about the organization of placing hundreds of function prototypes and #include statements into a single sefun object. And that something isn't very nice.

User Accounts: This one seems to have a lot of merit both ways and tends to spark quite a few arguments. How do people (both developers and players) feel about parent accounts that hold all of their separate characters? It seems like a bit of a security risk and many of my players actually argue that it would be less convenient than just having multiple passwords. Anyone else have a thought?

God Characters: My initial idea was to simply provide 'creator' accounts that did not have any 'physical' player avatar. However, it does seem that a lot of folks feel cheated by that. Players like 'seeing' their creators walking about and talking with them within the virtual world. And creators find it easier to simply upgrade an existing character rather than make a new account that seems to have fewer capabilities. I've read Crat's comments on this in regards to DS and I'm starting to come around to the idea.


Offline Camlorn

  • Friend
  • **
  • Posts: 76
    • View Profile
Re: Mudlib Design Specs: pt1
« Reply #1 on: January 30, 2013, 01:23:51 AM »
The comment about sefuns implies that you have picked a driver, and that will largely determine what you should do in that regard.  I'm looking now--I thought sefuns could also override efuns, but am not finding confirmation of that anywhere.  Regardless, sefuns make a good place to put security, as that should be a concern from the ground up.  Also, if your sefun object fails to compile, the mud will have extreme difficulties if it loads at all, and I can say (from experience) that it is easier to debug a running mud.  Depending on a few other things which I'm not going to verify right now, it may add significant overhead, but it probably does not (I can't remember if this is a dead souls facility or a driver facility, but am 99% leaning towards driver, which means no problem if implemented intelligently).  I, personally, would just consider sefuns to be part of the "standard library."  Note: if we are going to use sefuns, then at least 75% of users will not know that they are sefuns, and thus they need to be documented as you write them.  If you promise that you will document them later-you won't.

    I like accounts.  I also dislike accounts.  To be honest, you're asking questions that need a better picture of what the mudlib is going to be here.  If you want to do cool things like roleplaying points, accounts are a good thing: I've seen one mud that lets you share credits (bought with real money) and allows exchanging of bound items (not useable except by the character who picked them up) between characters on the same account.  You can have accounts without a master account menu: all characters on the same (verified--that's important) e-mail are in the same account.  This can do all sorts of things, limited only by the imagination of the developer.  I stole the e-mail idea from Alter Aeon, btw.

    99% of muds (99% because there's bound to be one I haven't seen) allow gods to be regular characters with an extended power set.  On a diku, this is good.  On an lpmud, this may or may not be good, depending on the discipline of the god.  On the one hand, this does indeed make it really easy--you always have a body.  On the other, if you divorce connections from bodies (see my earlier comments on dgd), the commands for gods can be put into the connection object instead of the body object, and now gods can have more than one body, perhaps with some sort of body saving facility.  The big one here, though: it's really tempting to use a god char as a test char for that new extra-buggy system, and now your god character is too bugged to be used as a god (which you kind of can't do on things that aren't lpc).  I almost never see a god walking around, unless an event is going on, and there's no need for a god to have a body to be able to talk on channels--and, tbh, body is a nebulous concept in this context anyway.  Again, up to you, as imho you can easily go either way.

    In my opinion, these shouldn't be the first questions you're asking.  Accounts can be added later.  If you don't like sefuns, or aren't sure, don't use them until you are, moving code there if you want them.  The first issue, and one I don't know how to answer, should be this: what is the difference between a player and a god?  Are there multiple levels of gods?  Define your god hierarchy.  And here's the issue I'm getting at, how is security going to work?  You can use the e-mails are accounts idea later, you can give or take away god bodies (they're objects, after all, and you can gut the body part out if you decide you don't like it)...but it's all no use if I can make the mud come crashing down with a snap of my lowest-level god fingers.  I do not know how to answer this question in the lpc context, as it is a hard question to answer, and typically relies on directory structure and a whole bunch of other stuff.  If there were a dead souls mud that had a huge playerbase, and if I were a god on it, I could probably eventually figure out a hole in that security system just by trying stuff, for example, but the point here is that I would have to try stuff...it would take me time, I probably would be noticed, and to be quite honest, there's a lot of things newbies might try that shouldn't be allowed.

Here's how I see the steps going, and you may have completed some of these:
-answer really, really broad questions.  What is the mud about? It's a mudlib, so you can maybe skip this.
-implement the minimal subset of features such that connecting can display a greeting and then disconnect you.
-implement the room.  Players log in (no passwords), get assigned that name, and get put in a room. They can walk around.  No admins yet, no account saving, but you can walk around.  When you quit, your player goes away forever--no saving.
-code your character as the only god at a low level, and make all the god tools, editors and such, so that you can code from something besides ftp.  Entering your name prompts for a super-not-secret password in the code.
-account saving, the ability to flag others as gods, and account authentication (accounts are users. if there is more than one char to an account is the question above, but characters are always on accounts, technically, even if the account is only ever allowed one char).
-implement at least some sort of security system.

    And then you get to design combat, and if you want oone account per user with multiple chars, and if you want gods to be characters that can fight or not...all that fun stuff.  But maybe I'm the pot calling the kettle black or whatever that saying is--maybe you've done all that.

    Just my thoughts.

Offline chaos

  • BFF
  • ***
  • Posts: 291
  • Job, school, social life, sleep. Pick 2.5.
    • View Profile
    • Lost Souls
Re: Mudlib Design Specs: pt1
« Reply #2 on: January 30, 2013, 02:24:10 AM »
FWIW, there's no law that says you have to have all your sefuns in the same .c file.  Mine are in 36 modules that are all inherited into the sefun object.

Not having an account system seems to me like promoting players to developer because they leveled up to a certain point in the game: a quaint archaism from the earliest, dumbest days of MUDs that has no place in any kind of modern or sensible practice.
« Last Edit: January 30, 2013, 02:26:38 AM by chaos »

Offline Nulvect

  • BFF
  • ***
  • Posts: 127
    • View Profile
Re: Mudlib Design Specs: pt1
« Reply #3 on: January 30, 2013, 04:54:35 AM »
Sefuns: These are good if used intelligently. In Fluffos they are handled by the driver I believe, and they can override normal efuns (with the ability to call the efun as efun::blah() as well). Do sort them out by type. Similar to chaos, my mud has a bunch of separate .c files where each file is a category of functions, and all those files are included into the main sefun file. Security is generally handled, in part, by sefuns, and is very important to think of at the beginning. There's no reason why you can't set up a standard library instead of or in addition to using sefuns and I think it's really your call. Less sefuns may reduce memory overhead for each object, but not necessarily.

User accounts: For the love of all that is holy, yes. Anyone arguing that having multiple passwords is more convenient has never been the one tasked with finding stray characters. Not to mention it makes it easier to identify who's who for rules enforcement and punishment. Require an email address too, then you have a guaranteed way to do password resets (it'll happen, it's inevitable). It's better for them, it's better for you.

God characters: I've never immed anywhere where imms didn't have a physical body. That said, I've seen plenty of imms mess themselves up by screwing around with their body specs and forgetting something. Like they're still an elf, but they have a centaur's body, something bugs out assuming they should have a left leg instead of a left forehoof, and they're completely bugged until someone else fixes them. I think I like the idea of imms not having bodies normally, but being able to create and destroy bodies for themselves as needed.

To come back around to security, might I recommend the following: groups defining specific permissions such as read/write access to different filesystem areas (build, lib, spells, etc), then a set of imm positions that contain those groups. You can create new positions and edit existing ones as needed and give them exactly the permissions you want. I've had to deal with trying to add or change imm levels before, and I've had to deal with creating security groups from scratch in a production environment, and I really think this would give the most flexibility while maintaining security.

Offline quixadhal

  • BFF
  • ***
  • Posts: 629
    • View Profile
    • WileyMUD
Re: Mudlib Design Specs: pt1
« Reply #4 on: January 30, 2013, 06:12:52 AM »
sefuns are always present and are generally required in most lpmuds.  They do indeed allow you to override the driver efuns with lpc coded versions.  In DGD, these are called kfuns, I believe.

Security on these is vital, since you ONLY want the core systems to be able to override an efun (or an sefun, for that matter).  The rest of your mudlib security will rely on them.

I like user accounts.  I'd prefer to see someone log into their user account and be shown a list of their existing characters they can play, or the option of making a new one (if allowed).  MMO players are used to shared bank spaces and whatnot, so this is a no-brainer these days.

God characters.  Well.... I think builders/admins/etc should log into an account which has no physical form, but should be able to become mortal (as an avatar) if they so desire.  Once mortal, they should NOT have access to any special commands or abilities except ONE command... the one that abandons their avatar and returns them to god form.

For security, I'm a big fan of ACL's.  Access Control Lists.  All things have an owner (whatever created them), and may have a group (builders, domain, etc), but quite often you want finer grained control and ACL's make that much simpler.  Many existing LPMUDs use this idea for domain control... you add several players to a domain, and now they have building permissions but only in that domain.  I'd extend the concept throughout.

While this is a bit far down the design tree from the start, a good idea (IMHO) is to consider the following hierarchy.

connection object -> user object -> character object -> body object

The connection object is what you get first, when you connect.  It will (eventually) handle logging in and out, and that's about it.  This would also handle snooping, and logging, if you implement that.

The user object is tied to a connection object, but on disconnect may persist so it can be reattached to another connection object (if the user disconnects without fully logging out).  This holds all the user data, email, password, characters, and permissions.

The character object is a game device, holding data about a specific character the user plays.  It holds all the stuff about their skills, levels, bank vaults, stuff-not-on-their-body, whatever.

The body object is the physical form of the character.  Normally, a character gets one body they pick when they start, but maybe they can shape-shift, or maybe they can possess others, or maybe they die and can't ressurect but have to reincarnate.  This holds their physical stats, their inventory, perhaps some abilities and skills specific to that form.

So, when Bob is playing Foo, a level 20 werewolf. He has a house with 20 gold and a spare sword, and he's currently wearing chain mail and wielding a sword, with 3 gold.

If he wolfs out, he gets a different body that's a wolf form.  It has no gear or money, but has some abilities his human form lacked.  Perhaps he can no longer cast or speak.  It's up to you to decide if his stuff stays on his old body and is restored when he returns to human form, or if it falls to the ground and his human form returns naked.  In either case, the stuff in his house and bank should not be affected.

Bob's character object holds his name (Foo), level (20) and his house deed and inventory.  His body (werewolf.human) holds his sword and 3 gold.  His new body (werewolf.wolf) holds nothing.

In the case of a god character, you could let them make a new one or convert an existing charcter, but the "god" option would only be available if the account is flagged for it.  Once done, their default "body" would be an insubstantial ghost which can be visible or invisible, but has no inventory and can't directly manipulate the game world.

How they create/spawn an avatar is up to you.  Maybe they can clone any mob and then possess them, or maybe they have a set avatar they create and which always represents their mortal form.  In any case, I think this makes it harder for them to just cheat, and because the avatar is just a regular mortal critter, the players know the rules.

Offline Sluggy

  • Friend
  • **
  • Posts: 91
    • View Profile
    • Stellarmass
Re: Mudlib Design Specs: pt1
« Reply #5 on: February 02, 2013, 01:31:43 AM »
Sorry, the 'sefuns' word is a specific term for MUDs but I was using it as a generalized shorthand for 'globally accessible utility functions that provide the capacity to mimic and/or override built-in driver functions (efuns) but are written at the mudlib level'. Basically I was asking if folks prefer just a loose collection of functions or if they like to have them grouped under a warpping object depending on their purpose. That all. XD

I have indeed though about security quite a bit but was planning on making a different thread since I still am working my way through DGD and am not sure how well it will work (I'm quickly learning that almost everything I knewabout FluffOS is going to be of limited use). As I said, this is still all paper-n-pencil stuff so far so I'm trying to make broad ideas that are mostly platform agnostic.

I've considered a basic layout that is likely similar to most mudlibs but with one major twist. Its a combination of ACls (Quix, I hadn't considered attaching the ACLs to every object, only directories. Which were you suggesting?) plus a directory stack underneath that. I was considering having three root folders for the mudlib: core, secure, and public. The public folder is where most of the game-specific code would end up as well as domains, creators' private work spaces, and shared mudlib code. ACLs would be most useful in this region. The second level is the secure folder, it has a nearly identical layout to the public folder but is used for central mechanics of the game, save data, permissions lists, etc. This region would be off limits to anyone not belonging to a particular group. So far this are pretty normal right? So here's the last and likely most controversial one: The core folder. It would contain the 'to-the-metal' mechanics that drive the mudlib as well as interface with the driver. This would not be accessible from within the mud. Crazy huh? But I figure there are a few good reasons for this 1) It's code that will rarely change. 2) On my mud there is only one other person I would trust to touch such and not without my supervision 3) This stuff is used by every major and minor system in the game so it would likely require a reboot anyway. 4) I'd want to test it fully offline before ever consider using it. 4) All of the above makes it ideal to simply use a code repo to clone / edit / test locally / and upload such code. Technology and resources for this are abundant these days so why not just do it that way? Heck, that's how the driver works anyway so is it that big a deal to extend it to some of the mudlib.

I'm perfectly willing to admit that I haven't thought this out all the way but I'm generally under the impression that I don't need to provide access to anything until proven otherwise. Any views, anecdotes, or examples that might make me reconsider?


On the topic of gods with bodies, I realized by reading your responses that I've answered my own question with my mudlib's core idea - components. Since the body will just be a hierarchy of components attached at runtime it's really not even worth worrying about I suppose XD


Offline quixadhal

  • BFF
  • ***
  • Posts: 629
    • View Profile
    • WileyMUD
Re: Mudlib Design Specs: pt1
« Reply #6 on: February 02, 2013, 08:46:48 AM »
Under DGD, I believe the place you'd want to put such things is the "auto" object, which is automatically inherited by every other object in the game, except the driver object itself (I think).

I would suggest putting ACL's on every object, however they could be inherited by the containing directory if you like.  That would allow you to override any specific file, or just set it on the directory and let children look up to find the right permissions.

While I'm on the subject though, don't think of it ONLY in terms of files and directories, but any object in the entire game.  You might well want to set an ACL on a virtual object, or a specific INSTANCE of an object, if they're persistent.

An example I could imagine is a builliten board.  While you may want the ACL on the file to allow any builder to clone one at will, you might want to lock specific instances of them to specific groups.  Like a domain chat room's board only being writable to members of the domain, or an admin board only allowing admins to write to it.  Perhaps you want boards in player areas that the players themselves can read and write to.

You can certainly do it other ways, but since you're designing from scratch... you should try to make as FEW systems as possible, and make them apply to as MANY things as you can.  That keeps things easy to debug and easy to learn.

For specifics, I've always liked the VAX/VMS permission system.  Read/Write/Execute/Delete, which can be set for any user or group.  Why seperate write and delete permissions?  First, because sometimes you want people to be able to modify things, but not remove them entirely -- as something else may depend on their existence.  Second, VMS also had automatic file versioning... so by default, if you edit a file, the old version is kept as filename.ext;ver.  So, if you allowed infinite versions, but no delete privs... you could always retrieve stuff even if someone nuked it.

Oh, one other thing.  Everything in an LPMUD mudlib is accessible from inside the mud.  It has to be.  Now, you can always ensure that some parts of it require root/system privs which no actual player/wizard/whatever has. :)

I also approve of the idea of using a repository.  I use git, myself.  If you want to get really snazzy, you could write LPC code to invoke some of the git commands, so people could edit things in-game and actually commit/rollback/etc directly from the game client.

If you do so, I suggest making a local git repository and making another one elsewhere which you can "push" copies to.  That way, you only push when you are in a known good state, and the public (or whomever may need to run a test server) can always grab from the push server, and it can serve as an off site backup for you.

Of course, you also have to decide if you want a public or private repository... if you want public, github works well.  If you want private though, you'll either need to set it up yourself or probably pay for it.  If you're very careful of how you design your mudlib's data layout, you could export PART of it as public, but most mudlibs don't consider that and end up with private/secure data mixed into places that are hard to excise.

Offline Camlorn

  • Friend
  • **
  • Posts: 76
    • View Profile
Re: Mudlib Design Specs: pt1
« Reply #7 on: February 02, 2013, 11:47:47 AM »
If I recall correctly, if you are using Dgd and the kernel mudlib, security is taken care of already.  I do not recall the specifics of this.  Also, do note that, in Dgd, the auto object is like java's Object class--it has no real magic going on.  It is inherited by everything, thus everything put in it is inherited by everything.  There may or may not be overhead when using sefuns in FluffOS, but there is when using Dgd's similar functionality.  Typically, the answer is to make inheritable libraries.

    I can't comment on security beyond "it needs to exist".  I'm by no means an expert in that area.  If uyou want to provide a convenient coding interface, though, it might be worth writing some sort of ftp server or client plugin that respects your security: using the ingame editors is a pain, and giving people ftp access will just make it such that you shouldn't have bothered with security in the first place.

    Finally, keep in mind that, unless you write *very* good documentation, programmers will need to be able to read that core code to figure out how to do anything beyond set_description.

Offline Sluggy

  • Friend
  • **
  • Posts: 91
    • View Profile
    • Stellarmass
Re: Mudlib Design Specs: pt1
« Reply #8 on: February 02, 2013, 01:51:57 PM »
@Camlorn: Don't worry about the documentation. I'm the kind of guy that can't write a function without providing autodoc info for every parameter. Heck, even my players get documentation http://stellarmass.space-madness.net/manuals/!

Since you brought up the topic of what this mudlib is about I figure I can answer that more clearly for the record. Components. That's it. I've used them, I like them, and I think they are an ideal construct for MUDs and games in general. But there don't seem to be any LP-based mudlibs that use them. I'd like to try to change that. Systems and features can be written using any technique you can imagine so I'm not so focused on anything beyond the bare bones right now. But I want it to use component-based design from the ground up. Since I just went through Melville and Phantasmal last night and discovered they are both public domain, I'm sure I'll be 'borrowing' bits and pieces for my purposes. I'd just like to wrap it up with components.  8)


@Quix:
Quote
Oh, one other thing.  Everything in an LPMUD mudlib is accessible from inside the mud.  It has to be.  Now, you can always ensure that some parts of it require root/system privs which no actual player/wizard/whatever has.
That's the plan. Does that seem too extreme?

Quote
I would suggest putting ACL's on every object
Ah, you've answered my next question then. I'm not too familiar with this sort of thing though. Obviously the info carried needs to be lightweight. Would you suggest group ids attached to each object and then keep the actual permissions for each group in a separate database?

Offline quixadhal

  • BFF
  • ***
  • Posts: 629
    • View Profile
    • WileyMUD
Re: Mudlib Design Specs: pt1
« Reply #9 on: February 02, 2013, 03:52:19 PM »
The kernellib does provide security, but nothing says you have to use the kernellib.  It does a LOT of work for you, but it also imposes a few restrictions that you may or may not be willing to live with.  Personally, I find the fixed named directories rather annoying.  It's easy to change, but then you can't easily upgrade when new bugfixes are released.

I would suggest just implementing ACL's on every object as a mapping.  By default, you may want to populate it only with the owner's permissions, and if you implement a default "group" for things to belong to, that group's permissions.  If the mapping is undefined/empty, look upwards to find permissions.

Traditional LPMUD security uses file pathnames as object identifiers (except for the occasional virtual object), so /d/foo/forest/path3.c could have an empty ACL, which you then have you look up the entry for /d/foo/forest, and then /d/foo (the domain).

Note that you can cache this... so you don't need to hit the filesystem for each of these things all the time.  In fact, you'd only need to do so once, if no data exists for that path in the cache.

Typically, you'd write a daemon for that.  It might be as simple as a big mapping which has entries for every file/object that's out there, and each entry is a mapping of the various ACL permissions.  Your API would just be a handful of functions to say "what's the permission list", "can i do X to this", and "add/revoke permission X from this".

If the entry exists for "thing", you just return the appropriate value.  If not, you calculate it based on whatever criteria you'd normally use... walking up the tree until you find a known thing, or if you make it all the way to the top, returning the default (likely just ([ "root", "rwxd" ]), or if(getuid() != "root") return false;).

That kind of thing... there are some gotchas, but they depend on the rest of your security model and what you allow in terms of masquarading and overloaded systems.  I think ACL's eliminate the need for much of the trickery that had to go on in the normal LPMUD systems, where you had to pretend to be other groups or users to get the right permissions to do things.

Offline Sluggy

  • Friend
  • **
  • Posts: 91
    • View Profile
    • Stellarmass
Re: Mudlib Design Specs: pt1
« Reply #10 on: February 02, 2013, 06:23:00 PM »
Ok so I'm getting a bit lost here. First, are you suggesting permissions data being stored for each object where 'object' is the code file, the blueprint object of a compiled file, or the individual instances of each object? I took it to mean instance but now I'm not so sure.

This system has some interesting properties when applied to a message-based component system as well. If each component has its own access rights there will be potentially many layers of access within a single user's hierarchy. Care will have to be taken that creators don't subvert components with more access by inheriting them and/or rerouting code through the messaging system thereby allowing components with less access to send data/commands to components with more access.

Offline Camlorn

  • Friend
  • **
  • Posts: 76
    • View Profile
Re: Mudlib Design Specs: pt1
« Reply #11 on: February 02, 2013, 10:12:43 PM »
Well, here's what I think...building off the above.  And I do recognize that I'm not qualified for security related stuff.  I'm disregarding how you store it, I'll come back to that in a minute.  Pretend we have a sensible way to query permissions.  I personally don't think groups are a good setup here, but I'm not an expert.  But here's what I would do, since I'm the one who made the point of this in the first place.

-If the object is in a special directory, it always has permission to do everything.  This is intended so that you can have demons and such that can do dangerous things.  No one but the owner has permission to modify this directory, as this code is trusted to be absolutely 100% safe, either by not being a security hole in any way ever or by checking permissions itself.  These objects are always assumed to have permission to do everything, and include things like the permissions managing code and the master.c file as well as, obviously, the code responsible for letting wizards dest objects (get around the permissions manager by desting the permissions demon, for example, or crash the mud by desting it...depends on what you do if that suddenly goes away).
-When an object is instantiated, its instance gets either (1) the permissions of the code that instantiated it or (2) if instantiated by a wizard, the permissions of the wizard.
-if at this point the object has permissions to do things that its file does not have permission to do, remove the permission entry for the object.
-If the object has the same permissions as the file, remove the permission entry.

    The last one is an optimization which may or may not be needed.  The third one lets you prevent code from doing things it could if given the permissions of the calling wizard.  I assume the first two are self-evident.   Look up permissions by (1) checking if it is in the special magical root directory, (2) checking if the instance has permissions, and (3) checking the permissions of the file.  Stop as soon as you have a match. If step 3 fails, give the object no permissions and alert the highest authority immediately, as that's either a bug or hack attempt.

    You could let the permissions entries be whatever, read/write/execute/delete, group names, doesn't really matter, so long as they have a hierarchy for point 3; if they do not, you're into untrusted directory land, and imho at that point just use the old model of directories are permissions and be done.

    Personally, I'd store this entire thing on one daemon as a mapping.  If in Dgd, I would store it as a mapping set up as a linked list of mappings, to deal with swapping; that particular setup, though, does have other implications on dgd about getting rid of objects if using persistence which I won't go into here, as I'm not clear on them myself.

    Can you define components?  It sounds like you want to make a mudlib with no defined theme, and components has a whole lot of meanings.  Just saying it's about components is really, really broad; do you mean plugins? Just that systems are separate?  You can't have the latter: combat will depend on rooms and mobs, for example, and everything will depend on time.  In my opinion, writing a mudlib with no defined theme is difficult to impossible; I have not seen that done.  I am not going to say that it is impossible, but if you do, you can't really implement a lot of core nontrivial systems and, for me anyway, if I have to do them myself I'll just go write my own mudlib.  Combat with swords is very different than ranged space battles, for example, so I'm kind of curious.

Offline Sluggy

  • Friend
  • **
  • Posts: 91
    • View Profile
    • Stellarmass
Re: Mudlib Design Specs: pt1
« Reply #12 on: February 03, 2013, 01:35:35 AM »
Hmm, I'm no security expert either but I mislike the idea of chopping down to a lower access level. I'd fee less prone if it were built up. Just, I'm not sure how to go about doing it. However, I agree on that third point - never allow an instance to have an access level higher that the directory/file from which it came. And the first point is basically what I was proposing with the 'core' directory.

On the topic of components. I mean specifically component-oriented design (also using a composite-pattern in this case). Favoring composition of objects over inheritance to apply features or behaviors to the core entity. A couple good resources that show its practical use can be found here:
 http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
http://gameprogrammingpatterns.com/component.html
I've used these techniques in non-mud related games with amazing success and I'd like to apply it to a mud now too.

Offline Camlorn

  • Friend
  • **
  • Posts: 76
    • View Profile
Re: Mudlib Design Specs: pt1
« Reply #13 on: February 03, 2013, 02:47:51 AM »
I just want to be clear.  These are the problems I see.  They are not an attack on you, they may not even be problems, but from where I am standing, this is what it looks like.  I may not have a complete understanding of components, but I think I do, and read both those articles.

Well, yes...that's interesting and basically looks like Scala traits, only with more ugliness, at least to me; Scala traits appears to be that without having to write the shell.  Anyhow.

    The problem is, you haven't told me anything about the game.  You seem to be desiring to write a mudlib that is just a mudlib.  This doesn't work.  Mudlibs *are* games.  They may be missing areas, but they *are* games.  That design pattern is already done in some mudlibs, though maybe not to the extent you would want it done, at least by my understanding.  If I have inheritables that do not collide, then I have components, and I can inherit both the sword inheritable and the mob inheritable if I wanted; I do not know of any mud that separates it to that extent, but there's nothing that stops that.  If I want to "own" the classes, not inherit them, then I'm looking at all sorts of boilerplate code, so just call inheriting owning.  You can divide things up, but I don't think it makes much sense to do so.  You've got the lookable component and the pickupable component and all that--how far do you want to go?  In a mud, there's typically three things: mobs, items, and rooms.  Players are a special case of mob, yes, but they aren't that special in some designs.  Both of those articles talk about "different domains", but that doesn't exist much in a mud.  The lookable component and the pickupable component are going to be part of *every* item, for example, and the saveable component is going to be part of, probably, absolutely everything.  There's maybe two or three domains that can be sensibly designed to rarely need to interact with each other, emphasis on rarely: saving, moving, and combat.  I can not immediately think of a way to decouple them to a sufficient extent to make this work: you don't want players quitting in combat, for example, or just walking away from a fight, and thus they're still tied together pretty tightly.

    Perhaps I'm misunderstanding the design pattern, but it sounds like you're just going to end up with a bunch of 10 or 20 line files, and good luck finding the one you need.  The big systems--combat, for example--have to be either pulled out or lumped together in one file; that is, it's big, no matter where you put it, component or otherwise.  I imagine if you want to get technical and use components, you can have a hittable component and an attacker component, but even that doesn't make much sense as they're coupled.  I imagine it is somehow possible to divide the mud in that way, but it doesn't seem like you'd gain much.

    If you wanted to be able to dynamically add and remove components at runtime, that's possible but will quickly become somewhat ugly in LPC.  Given the way lpc objects work, i.e. Daemons, I don't think this is so necessary, not as those articles present it.

    But back to my original point.  You're not going to be able to develop a credible mudlib without developing an actual mud, even if it isn't intended for players.  You have told me nothing about the genre of your mudlib, or the features that, from the perspective of a player, make it unique--if I'm the kind of person who wants someone else's mudlib, I'll probably see Coffeemud, go "Oo, it's got everything" and go use that instead; it's easy to build for, and I don't have to learn anything.  If you're developing a well-documented mudlib without the desire to run a mud, you're targetting the people who don't know much about running muds (particularly the group who does not realize that running a mud means programming), and that's the group you have to win.  I know this is taking the thread in a new direction--further away from the specs mentioned in the first post--but it is an important question.

Offline quixadhal

  • BFF
  • ***
  • Posts: 629
    • View Profile
    • WileyMUD
Re: Mudlib Design Specs: pt1
« Reply #14 on: February 03, 2013, 05:19:01 AM »
Just to clarify something about security.

I really HATE "special directories".  I think it's an outdated concept that's very hard to maintain, and frustrating to work around.  Older muds evolved that way because CPU was hard to come by, and memory was also limited, so it was easier to say "if it's under /sys, it has system privs".

Basically, your builder's permissions boil down to "can I read this?", "can I write here", "can I clone this?".  There are also similar permissions for users.  The user has no direct way to read/write/clone things, but they have a game interface with permissions... "can I use this?", "can I take this?", "can I destroy/modify this?".

In the bulletin board example, let's say the board code lives in /std/obj/bboard.c.  There are no particular permissions here.  Builder's can read it, clone it, but not modify or delete it.  Why?  Because whomever created bboard.c set the ACL to allow read/clone for any wizard.  Again, users can't manipulate files, so those permissions mean nothing to them.

So, newbie wizard Joe wants a board in his workroom.  He clones /std/obj/bboard and makes an instance.  He has permissions to his own workroom, and directory, and that's about it.  So, the system automatically sets the ACL on his instance to be Joe : rwed, wizards : r.

The board code saves data in ./save/bboard.o.  Joe writes on it, reads it, and invited Ted over to play with it.  Ted tries to write on it and can't.  Ted doesn't have permission to write to /w/Joe/save/bboard.o.  If you grant Ted permission (or all wizards), then evil wizard Quix used /bin/ed to hand-edit bboard.o and screw up the messages.  Clearly, that won't work.

If you grant the permissions on the directory, it's worse.  If you grant Ted himself permission to Joe's stuff, now he can mess with other data or modify Joe's code.  Also not good.

One solution is the way unix does things... you could have a setuid flag, which means that since the instance of the board object is owned by Joe, all code run by it runs as Joe, no matter what this_player() says.  So, the code in bboard.c has to use this_player() to determine who to post as, and which posts can be modified/deleted, but the actual object is Joe's, so it can write to Joe's data file.

From a simplistic point of view, when you call a function from a singleton object (/std/obj/bboard.c), it runs with YOUR permissions.  When you call it from a clone, it runs with the clone's permissions.

The only thing ACL's buy you is the ability to have more complex relationships, which can be very useful with large teams and evolved systems.  It frees you from having to make special directories that the code magically parses to find permissions, and centralizes things under one roof.

You still have to deal with the other headaches of what runs as what, and what does it need to be able to do. :)