20 Oct, 2009, JohnnyStarr wrote in the 1st comment:
Votes: 0
So, I'm trying to figure out a good way to go about the whole PC / NPC
thing in my Ruby project. I've thought about the benefits of having a super
class called Character, and then have a Player class and a Mob or NPC class.
You could load up Character with all the stats that PCs and NPCs both have,
and then customize them both. Now, this is great for data members, but what
about methods? I would like to take the approach of creating a Command 'Module'
as a Mixin, but I havent decided whether i want to Mixin Command with Character,
or Player. See, an NPC could use the same command "Move" but using "send"
wouldn't apply because an NPC wouldnt have a Descriptor (at least not unless it
was under control by an Immort).

Should I develop a Module for Character commands, and then have a special Module
for Player commands, and mixin Character commands with Character, and Player commands
with Player?

Sorry if this was long-winded, but this stuff is a bit new to me ;)
20 Oct, 2009, David Haley wrote in the 2nd comment:
Votes: 0
I don't think that commands should be mixed in. Turns out that we've had this conversation before; see this thread, posts 31-42.

I'm skeptical of most uses of mix-ins; I think people tend to use them just because it sounds cool but are just using language features and syntax instead of solving some kind of abstraction problem – actually, sometimes they are IMO worsening the abstraction.

Now, it can make perfect sense to have a Character that you subclass into NPCs and PCs. Something to think about is whether you really even need that; a character can have input and output handlers, where an NPC instance of a Character would have null output (or maybe point it to some AI!) and AI input; a player's I/O would be tied to the socket.

Or, if you want to take the subclass approach, just have the NPC's 'send' method be a black hole that takes input and does nothing.

But, note that the method I suggested is more flexible, and more easily adaptable to a mob being controlled by an imm: you don't have to special-case the above black hole. Instead, you merely add the imm's socket to the I/O of the Character. You could even have several sockets controlling the same character! (What fun…! :wink:) This is more realistic than it sounds: when you snoop a player, what you're doing, really, is adding your socket to their output handling, with some prefixing thrown in to indicate that the line is coming from their output, not yours.
20 Oct, 2009, Asylumius wrote in the 3rd comment:
Votes: 0
My drunk ass replied to the wrong thing in the wrong place.
20 Oct, 2009, JohnnyStarr wrote in the 4th comment:
Votes: 0
@david.
LOL, we did indeed have this conversation.
I like that idea about the control. Maybe you could have a list of each mob under your control, then have a special command that finds
the characters you control like:

$> clist
$> you are controlling:
$> 1] hassan
$> 2] gollum
$> 3] frodo

$> c1 dance
$> … makes hassan dance …
$> c3 kill gollum
$> … makes frodo begin to fight gollum …
20 Oct, 2009, JohnnyStarr wrote in the 5th comment:
Votes: 0
Asylumius said:
My drunk ass replied to the wrong thing in the wrong place.

haha, don't get beer on your keyboard!
21 Oct, 2009, Erok wrote in the 6th comment:
Votes: 0
Didn't look at the thread, but the approach that's worked well for me so far is to assign commands to one or more permission groups. Currently I just have npc, pc, and admin, where, intuitively, npc's have npc permission, pc's have npc and pc permission, and admin's have npc, pc, and admin permissions.

It functions as a hierarchy currently, so isn't any better/worse than level based permissions, but I expect to eventually have different groups of admin commands based on role, and possibly pc commands based on class, but the code isn't that far along yet.
21 Oct, 2009, Runter wrote in the 7th comment:
Votes: 0
To share some of my own experiences with Ruby: I've found less of a need to use inheritance directly in Ruby because of open classes. (Proof of this to some extent is the fact that Ruby doesn't support multiple inheritance.) You too may look for less time consuming solutions with mix ins for smaller projects. I'll leave it to the Mudbytes rogue scholars to explain why proven convention is poor design, but for empiricists like myself we have seen solid results and are having more fun than ever using flimflam like mix-ins.


edit: I have a few more thoughts on the idea in general. I don't like separating the PC from the NPC structures. The obvious reason some codebases in the past have done it is not for ease of development but for saving resources. My solution so far on my Ruby project has been to have a class called Actor and I mix-in functionality for AI systems on the fly. Otherwise an actor will behave just as a disconnected PC would. I've found this to be a useful way of doing it since it separates structure from behavior.
21 Oct, 2009, Tyche wrote in the 8th comment:
Votes: 0
Runter said:
To share some of my own experiences with Ruby: I've found less of a need to use inheritance directly in Ruby because of open classes. (Proof of this to some extent is the fact that Ruby doesn't support multiple inheritance.) You too may look for less time consuming solutions with mix ins for smaller projects. I'll leave it to the Mudbytes rogue scholars to explain why proven convention is poor design, but for empiricists like myself we have seen solid results and are having more fun than ever using flimflam like mix-ins.


Maybe because Ruby also exhibits strong characteristics of prototypical object-oriented languages; where in practice design is often less about "is a" relationships, than about "acts like a" relationships. Extending objects through mix-ins is just simpler, although delegation is certainly an option.

In any case, there's at least two philosophies in the mud world on "commands". In Dikus, and (R|S)ocketMud commands are defined on the actor. While one might suggest that some of these are written in C, aren't object-oriented anyway and really don't define methods on classes, there is still the classical function signature where all commands require Character as an actor. Other muds like MOO and COOL define commands (verbs) on the objects and not the actor. There's greater flexibility in decentralizing commands that way, but there is greater chance of a creating incoherent commands.

My only strong opinion on this is Diku's level-based security system is a very very dumb idea.
That is dual using level as both character progression and administrative security is lame.
21 Oct, 2009, KaVir wrote in the 9th comment:
Votes: 0
Tyche said:
My only strong opinion on this is Diku's level-based security system is a very very dumb idea. That is dual using level as both character progression and administrative security is lame.

Combining the security system with progression levels didn't bother me that much to be honest, as it's fairly usual for admin to be higher level than players anyway.

I was never particularly fond of having a linear command structure though. I believe some Diku derivatives added a way to assign specific commands to particularly admin, which is an improvement (at least for muds which have staff hierarchies), but I also found it annoying for players to see dozens of commands they could never use because their class didn't have access to them.
24 Oct, 2009, JohnnyStarr wrote in the 10th comment:
Votes: 0
Ruby's ducktyping and reflection capabilities are fantastic.
I have adopted Runter's idea of using an @actor variable. instead of worrying about what class the @actor is, it checks to see if:
@actor.responds_to?(:method)
This way, you can assign any object to actor, which could open the door for cool things like "ship", "mech" and other alternate command interfaces. very nifty.
24 Oct, 2009, David Haley wrote in the 11th comment:
Votes: 0
Duck-typing is your friend, until it isn't. It's extremely nice for smallish systems, or systems that you have total control over. It can make life more complicated in large systems especially with several developers, because you no longer have the compiler looking over your back making sure you're not doing something dumb.

An adage that I'm fond of is to have loose typing internally in modules, and strong (static) typing across module borders. Unfortunately this is not something that many languages can get you.

What does this mean for you? Well, you should certainly go ahead and use this stuff to start. Just keep in mind that the looser things get, the easier it is to write more code but also the easier it is to shoot yourself in the foot in potentially very subtle ways.
24 Oct, 2009, Runter wrote in the 12th comment:
Votes: 0
I think I don't necessarily disagree with what David said above. However, I would like to present the other side of this argument and perhaps shield some of you from this cold water which may otherwise turn you off on duck-typing.

That being said, people using strong typing exclusively shoot themselves in the foot as well. Well, Maybe not DH. He's pretty much a pro, but this certainly rings true in the common languages of choice for MUDs on these forums.

Honestly, I haven't shot myself in the foot once while using Ruby because of weak typing that I can remember. Nothing that wasn't easily remedied or didn't take long to put to paper in the first place. I think the idea that duck-typing necessarily leads to poor or dubious development isn't absolutely true.

And I think what was said first was more true than what was later amended–
Quote
It's extremely nice for smallish systems, or systems that you have total control over. It can make life more complicated in large systems especially with several developers, because you no longer have the compiler looking over your back making sure you're not doing something dumb.


Then:
Quote
What does this mean for you? Well, you should certainly go ahead and use this stuff to start. Just keep in mind that the looser things get, the easier it is to write more code but also the easier it is to shoot yourself in the foot in potentially very subtle ways.


What I think it actually means for You, the aforementioned small hobbyist-despot developer, is quicker development, entertaining time spent on your hobby, and productivity with minimal foot-shootage. That's been a trifecta I've enjoyed so far in my hobbyist life.

P.S. Star, It's nice to see you delving into Ruby. I think you'll find the Ruby community is quite strong even around MUDs. If you need any help with anything Ruby specific I'm more than glad to help.
24 Oct, 2009, David Haley wrote in the 13th comment:
Votes: 0
I think Runter understood me this way already, but just to be clear, I absolutely agree that you should not shy away from these techniques. They can make life very easy as you get started and let you spend more time writing code, rather than producing ceremony and laying down scaffolding for the compiler. You should be aware of how you can shoot yourself in the foot, and then just be careful, but you shouldn't avoid it entirely just because it's possible to shoot yourself in the foot.
24 Oct, 2009, Tyche wrote in the 14th comment:
Votes: 0
There ain't no static typing in Ruby.
There ain't no static typing in Ruby.
There ain't no static typing in Ruby.
0.0/14