11 Oct, 2010, Mudder wrote in the 1st comment:
Votes: 0
KaVir said:
It was one of the things I factored into GW2 when I was designing it from the ground up - the whole Thing/Brain relationship makes it incredibly easy for players to control objects. But retroactively changing an established codebase to work like that would be a huge job.


My question is on implementing something like this. I haven't actually changed this part of a system yet and I'm not exactly how to work certain things.

I'm working with tinymudserver and at the moment I have a class tPlayer. It holds
class tPlayer
{
private:
int s; // socket they connected on
int port; // port they connected on

string outbuf; // pending output
string inbuf; // pending input
string address; // address player is from

public:
tConnectionStates connstate; /* connection state */
string prompt; // the current prompt
string promptchoice;
string playername; // player name
string password; // their password
int badPasswordCount; // password guessing attempts
int room; // what room they are in
bool closing; // true if they are about to leave us

etc, etc.


Now, if I wanted to start a brain/thing/body type relationship I would make the current class tplayer inherit at the bottom of it all? I'm not sure how else I could have a class that contains all the above (which is necessary for a player).

I want to have mobs that are essentially the exact same as players, treated the same. I read about players taking control over mobs then returning. I like that a lot and would like to have a system that allows this - but I think I need to solve the above first and figure this junk out. :grinning:
11 Oct, 2010, Scandum wrote in the 2nd comment:
Votes: 0
What would make the most sense to me is to have socket info, player info, and character info. These would be three separate classes. When a player takes over an NPC it would swap its normal character object with an NPC character object, the socket and player objects don't need to know the difference, other than how to return control back to the original body.

There's probably a proper OO way to go about it.
11 Oct, 2010, jurdendurden wrote in the 3rd comment:
Votes: 0
I think it really depends on far down you want to encapsulate things. You could branch it out forever depending on the things you want available in your mud. I started writing a big paragraph on how I would do it then I realized it was just one way of many you could do it, and it really depends on the features you want in game. How many things do you want your NPCs to be able to do, obtain (housing? ships?), use, perform, react to, turn into (severed heads, animals, whatev), etc.

On the other hand this does break it down into two simple classes: player and character. Whatever you want players ONLY to be assigned, put in here, and have each player class inherit the character class.


Edit: On a side note… not sure how Kavir does it, but I had the idea while writing this of doing "mind_flags". Basically just a list of assignable flags; sentient, construct, charmed, animal, plant, and more depending on what you'd want to do with it.
11 Oct, 2010, David Haley wrote in the 4th comment:
Votes: 0
It's not really that hard to do this even if you don't want to use some kind of fancy encapsulation. The important thing is to not treat different kinds of characters specially. If any kind of character can be given commands to interpret from a socket input stream, then just make sure that there's a link between those socket streams and the corresponding character object(s). Note that a single stream could, in principle, output to several characters! Anyhow, you don't need to implement some kind of "AI Brain" if you don't want to get that fancy. Just assume that if there's a socket attached to a character, it's a player; if there isn't, it's an NPC.

Fancier schemes will help you decouple this even further. For example, you might in fact want one socket to control several characters, as said above. If you use the simple scheme, output will get jumbled up and be hard to parse unless you add handling to character objects to be aware of the nature of the socket behind them. This is ok if you don't do too much of it and want to keep things simple, but will limit you later on.

As to the thing/body distinction – I much prefer to be specific and call it a 'mind', not just 'thing' – you need that if one "in-game mind" can meaningfully hop from body to body, maintaining some kind of state along the way. For example, you might shape-shift from a wizard to some other creature, obtaining a new body (with new physical stats) but holding on to your mental aspects (like knowledge acquired previously). Note that the mind/body distinction made here is rather different from the 'input source'/'controlled entity' distinction made earlier. You have a mind that wanders around the world controlling some body. But it is the input source that tells that drives that mind's activity.
11 Oct, 2010, KaVir wrote in the 5th comment:
Votes: 0
Mudder said:
Now, if I wanted to start a brain/thing/body type relationship I would make the current class tplayer inherit at the bottom of it all? I'm not sure how else I could have a class that contains all the above (which is necessary for a player).

You appear to have everything bundled into one class. You'd need to break it up.

My approach has two base classes, Thing and Brain. From Thing I derive Creature, World, etc. From Brain I derive HumanBrain, MobileBrain, etc. A Thing may have a Brain, and vice versa. The HumanBrain will always have a Socket object, which contains the player connection data.

When you first connect, the mud creates a Socket object, which immediately creates a HumanBrain for itself. When you log into the game, the mud creates a Creature object and connects it to your HumanBrain. If you drop your connection, your HumanBrain is destroyed - a "link dead" character is therefore defined as a Creature without a Brain. If you reconnect, a new HumanBrain is created, and is then connected to your previous Creature object.
13 Oct, 2010, JohnnyStarr wrote in the 6th comment:
Votes: 0
My approach is to consider any character to have a "controller" object. The controller could be an input stream, AI, or even some sort of
proxy that takes input from some other character (like a mind trick type of thingy). Of course, this is in Ruby so if you were doing this in C / C++
I'm sure there is a statically typed way to do it (ie: union or some C like trickery).

Anyway, I view at as this: Depending on the type of logic your game has (be it sci-fi / fantasy) it may make sense for a "chair" to be controlled,
a "shuttlecraft" or even a "dagger". All of which are not "characters". Ideally, you would add a "controller" or "mind" or "brain" to anything that makes
sense to have one. This way, you broaden your controllability to just about anything. This of course may complicate things a bit, possibly too much for
your idea, or it may simplify things depending on how far you go with it.
19 Oct, 2010, balakoth wrote in the 7th comment:
Votes: 0
Anyway you could elaborate on your methods Kavir?

I guess the order in which you are attaching your derived classes is confusing to me.

Socket, gets a brain attached (human), then a creature gets attached to that (Im assuming your normal stats, name, descriptions etc). But for your mobiles you are attaching a Mobile brain to a what.. a Thing? and then a creature to the mobile brain?

I have been thinking of how to go about a better approach to doing inheritance and making things more fluid. I guess im just a bit confused on how you'd allow these things to access the same commands (lets say from a command interp) etc. Are you just doing more in depth checks inside your various functions for these sorts of things, or do they happen more fluidly because of the derived types. Are your base functions then simply organized under lets say.. the base Brain class? (for example lets say your move function) so no matter what a brain has the ability to move the creature thats attached to it?

Also, do you have a player list, and a creature list? One that holds things with sockets and one that doesnt. I was trying to figure out the more fluid way to do this, without checking so many things for simple tasks, but apparently I have cooked my brain simply working on all this Vt100 stuff to see clearly :(

Merc clearly keeps it all in one list, and then simply loops through checking to see if it has a desc (socket data) and or pcdata (if its a player). But this seems.. clunky at the very least.

Enlighten us all good sir.
19 Oct, 2010, David Haley wrote in the 8th comment:
Votes: 0
balakoth said:
Merc clearly keeps it all in one list, and then simply loops through checking to see if it has a desc (socket data) and or pcdata (if its a player). But this seems.. clunky at the very least.

It's clunky depending on what you're doing with it. If you only loop over all players at the same time as you loop over all characters, for example when you need to update all characters, regardless of their status as players, but also do something special with players, then it's not really so bad. If you need to do operations that are only relevant to players (or to non-players), at times when you do not care about also doing things to all characters, then yes, it's wasteful.
19 Oct, 2010, KaVir wrote in the 9th comment:
Votes: 0
balakoth said:
Socket, gets a brain attached (human), then a creature gets attached to that (Im assuming your normal stats, name, descriptions etc). But for your mobiles you are attaching a Mobile brain to a what.. a Thing? and then a creature to the mobile brain?

Thing (like Brain) is a base class, you don't actually have an instance of one. But because the connection is established in the base class, that means that any type of Brain can be connected to any type of Thing. Thus a player and a mob are both represented by a Creature object (a type of Thing), but one has a HumanBrain while the other has a MobileBrain.

balakoth said:
I have been thinking of how to go about a better approach to doing inheritance and making things more fluid. I guess im just a bit confused on how you'd allow these things to access the same commands (lets say from a command interp) etc.

The command parser is a separate module. In retrospect I could probably have made it part of the Brain base class, but I originally copied it from Gladiator Pits just to get something up and running, and it sort of stuck. I also wasn't sure if I might later want link-dead characters to be able to execute commands, so I think I prefer it this way.

balakoth said:
Also, do you have a player list, and a creature list? One that holds things with sockets and one that doesnt.

No, I have a Thing list and a Brain list.
19 Oct, 2010, balakoth wrote in the 10th comment:
Votes: 0
So what is the difference between a mobilebrain and a human brain for you then? (Im assuming your mobiles use the same combat system as your players do so maybe it houses any kind of mechanics for it to fight that way via its own processes.

Id love to be a fly on the wall of you code one day :P While ive always thought about different ways to do things, not many people are open tehse days to sharing information about a 5 + year project, and for some reason I keep going back and redoing things because I think of some other way to do it…

So thanks for the information that you are sharing ;) Much appreciated
19 Oct, 2010, KaVir wrote in the 11th comment:
Votes: 0
balakoth said:
So what is the difference between a mobilebrain and a human brain for you then? (Im assuming your mobiles use the same combat system as your players do so maybe it houses any kind of mechanics for it to fight that way via its own processes.

The main difference is that the HumanBrain has a Socket object, while the MobileBrain has AI behaviour. Of course the mud doesn't usually care about that - it just sends data to the brain, and receives data from the brain. But if a player doesn't type anything, they won't fight.
20 Oct, 2010, Mudder wrote in the 12th comment:
Votes: 0
KaVir said:
Thus a player and a mob are both represented by a Creature object (a type of Thing), but one has a HumanBrain while the other has a MobileBrain.


I, too, am having trouble wrapping my head around this. It's likely just my unfamiliarity in working with classes. I avoided posting until I could refresh in my book and try out a little code but I haven't had time yet.

My question is with the above quite. I assumed from your earlier posts that you simply kept track of both the HumanBrain data and the Creature data. So now I take it that the creature data is in fact a new class that takes the data from the earlier two to create it's new data type. Yes? That seems a lot simpler actually, typing it out is helping me.

Also, I agree with balakoth. Thanks for taking time to help – and to everyone else that does the same. David Haley comes to mind.

While I may not post all the time, I read every single post here (unless it's protocol things I hardly understand) and even though I know answers to some of the newbie questions asked (or not), it helps to read over the different answers people give. So thank you community!
20 Oct, 2010, Rudha wrote in the 13th comment:
Votes: 0
Essentially as I understand it, a "HumanBrain" is a dummy brain that just sends the commands that the server receives from the socket to the character, whilst a "MobileBrain" has an artificial intelligence associated with it.

NakedMud doesn't make this distinction, which was something that put a few wrinkles in the cloth when I went earlier today to start on working out some artificial intelligence, though thankfully it does have a ch.sock() sub-object that you can test for the existence of.

Maya/Rudha

[edit:] Yes, Im aware that it also has a ch.is_pc boolean property, however it doesn't seem to work as designed. Its set true if you have a socket, but doesn't seem to be created if there isnt a socket, I've run into some errors thrown about non-existance of the property in that situation.
20 Oct, 2010, David Haley wrote in the 14th comment:
Votes: 0
Mudder said:
I, too, am having trouble wrapping my head around this. It's likely just my unfamiliarity in working with classes. I avoided posting until I could refresh in my book and try out a little code but I haven't had time yet.

My question is with the above quite. I assumed from your earlier posts that you simply kept track of both the HumanBrain data and the Creature data. So now I take it that the creature data is in fact a new class that takes the data from the earlier two to create it's new data type. Yes? That seems a lot simpler actually, typing it out is helping me.

One thing that helps me sometimes is to try to avoid thinking about code until I really have to, and to first think about things on a conceptual level. It can be hard to understand both the concept you're trying to implement and the details of your language's OOP system. So keeping those separate can help you get your head around the concept at least, before you eventually (and necessarily, unfortunately :wink:) have to implement it.

That said: yes, the various components would be made separate. This allows you to mix and match them as you like. It lets you on-the-fly swap out a "human brain" and swap in a "mob brain" for a given character – even a player character! You could do all kinds of neat things with that, such as letting your original body continue to fight while your typing controls some body elsewhere.

So before you start thinking about the syntax for writing classes, I would suggest drawing out on papers the various components you have in front of you and which one is responsible for which action. You can do this even with standard ROM/Merc/SMAUG data structures, by the way: categorize the member variables by general responsibility. Some are very clearly related to the physical creature running around in the MUD world. Others are very clearly related to how a player controls a character over a socket. Yet others could be categorized as some kind of "mind" attached to a presence in the world, separate from the body that it happens to occupy.

The point is that laying these things out in front of you and defining responsibilities will make it easier to see what objects you'll need in the end of the day. In fact, you might find that the classes emerge naturally from the separate responsibility circles you have drawn. You might also find that it doesn't really make sense to make one class per responsibility and that some can be merged. In the end of the day, you need a clear conceptual understanding of what you're trying to achieve in order to more productively start applying the language syntax to the problem.

A question that you will run into is what, exactly, you are sending these brain thingies. It's pretty obvious that the human brain sends commands typed by the player and the AI brain sends commands generated by, uh, the AI. But the interesting question here for the AI is: how exactly is it making these decisions? On the basis of what information?

Raw data isn't very nice for humans, and formatted data isn't very useful to an AI routine – it would have to pick it apart to get back to the raw data. But raw data is the starting point for formatted data, so you might consider sending all brains this raw data (possibly with formatting hints) and leave it up to the brain to decide what to do with them. The human version might format it into text and send it over the connection; the AI version would look at it and decide if it needed to react in some way.

Speaking earlier about separating responsibilities, this here is an example where you might see another responsibility emerging: the "data formatter" that translates raw data into some format that the brain understands. You might or might not decide to not make this an explicitly separate object; you might prefer to embed the functionality directly into the human brain object. I think this might be enough for now, though, so I'll leave that as an open question. :smile:
21 Oct, 2010, Runter wrote in the 15th comment:
Votes: 0
Some advice I would give is consider exactly what you want to accomplish. Sometimes complex models aren't the easiest route. Not that what is being discussed here is that complex. What is far more interesting is how your npcs decision making process works. How those decisions are deployed is a relatively small problem. So I guess my advice would be to keep it simple and implement it in steps. Small milestones help to keep development sane and tested throughout.
21 Oct, 2010, balakoth wrote in the 16th comment:
Votes: 0
WHile I understand what Kavir is doing, Im just curious on how he goes about checking and accessing these different concepts.

To Mudder, the easiest part to understand is the base class idea. His THING class is pretty much the basis of most entities on the mud.. for example I could assume Thing class holds a Name, Short Description, Description, Location, and possibly a flag variable. Then his creature would derive from this class so that all creatures had this same thing.. also an object class could also derive from the Thing class so it also had these variables.

Only way ive thought to approach it is to have a base entity class (like kavirs thing class) which holds that same info, once you create a creature (which would be derived from a THING) you could simply have a BRAIN * creatureBrain = new MobileBrain, or new HumanBrain… the issue im having t rouble wrapping my head around is, since Brain is simply a base class (that you derive from) how do you (Kavir) keep that in a list that is all as one.. or do you keep a seperate brain list for MobileBrains and HumanBrains. Since brain is just a base class, you would still have to have both variables of HumanBrain * hbrain, and MobileBrain *mbrain inside your creature class… if one or the other is simply for a creature you know what it is?

For my case if I went along the same route, then youd be checking in some way if its a Human or Mobile and just pass the Creature Class to a command interp… but with that certain commands would take some extra code in case a human or mobile wanted to use it. That or you created seperate commands that only a HumanBrain or MobileBrain could use (though that could become redundant code wise if there were some commands that related to both, simply using overloading in your command interpeter Execute(MobileBrain *actor) or Execute(HumanBrain *actor)


Just rambling but maybe someone can clue in if thats even a good approach. I think both Mudder and I would like to have our mobiles be as accessable to functions in the mud as a player would (Let them change the terrain of a MUD, access say talk tell commands fluidly, or heck even use the builder commands)

Maybe im wrong about your side of things Mudder, but thats where Im going with this hehe.
21 Oct, 2010, Rudha wrote in the 17th comment:
Votes: 0
There's absolutely nothing but common sense and your MUDs individual restrictions preventing NPCs from executing player commands. In NakedMud you can use ch.act() to make a NPC do anything a player can (provided the NPC is in the appropriate usergroup). I can't say I remember the restrictions of CircleMUD, but as I remember it, you were pretty limited when you were using mobpos in CM.

Maya/Rudha
21 Oct, 2010, KaVir wrote in the 18th comment:
Votes: 0
balakoth said:
the issue im having t rouble wrapping my head around is, since Brain is simply a base class (that you derive from) how do you (Kavir) keep that in a list that is all as one.. or do you keep a seperate brain list for MobileBrains and HumanBrains.

I just keep one list of Brains. The Brain is an abstract base class, so I can't instantiate it, but I can still have pointers to it.

balakoth said:
Since brain is just a base class, you would still have to have both variables of HumanBrain * hbrain, and MobileBrain *mbrain inside your creature class…

Nope, just a Brain * in the Thing class (and vice versa).
21 Oct, 2010, Scandum wrote in the 19th comment:
Votes: 0
What seems the most logical to me is to have a player socket, and replace the player socket with an AI module for mobs, as the mud shouldn't care if commands come from human input or some AI module. So to call something a 'player brain' is counter intuitive.

It seems weird to me to not clearly separate character and player data, though one could get away with the memory overhead on a MUD where there are only a few NPCs loaded into memory at a time.
21 Oct, 2010, KaVir wrote in the 20th comment:
Votes: 0
Scandum said:
What seems the most logical to me is to have a player socket, and replace the player socket with an AI module for mobs, as the mud shouldn't care if commands come from human input or some AI module.

That is what I do - the Brain provides the common interface, so that the Thing can send and receive data to and from the Brain, regardless of whether it's using a socket or an AI module.
0.0/30