04 Jan, 2011, drifton wrote in the 1st comment:
Votes: 0
so i'm planning on changing the input model of my mud so that i can have more control over the mobs and npcs

in my mud i have a base MudObject that i derive my other game objects from
currently i have Player, Item, World, Area, Room and Wilderness

as i was thinking about mobs and npc with the logical conclusion that they are very similar to players in how they interact with the world and how they are represented to the player as other players, this is leading me to want to create an Actor class that derives from MudObject and the Player, NPC, and Mobs would then derive from the actor class. then each class would have some kind of controller

this brings me to the question of how i should then organize the input controller

right now as it stands the the PlayerObject has a Reference to the client object, where the client is basically in control until the player logs into his character then the PlayerObject takes over control of the input polling the client reference for new lines and then passing those off to the command interpreter ect…

what ideas and suggestions does everyone have, i've just been working on it and banging my head against the wall, and i would prefer not to have to take a month long break until i'm struck with some random stroke of genius
05 Jan, 2011, plamzi wrote in the 2nd comment:
Votes: 0
I think you'll need to share more details about your codebase and your specific goals before anyone can help. What does "more control" mean?
05 Jan, 2011, drifton wrote in the 3rd comment:
Votes: 0
The code base is custom, written in the d programming language i know a lot of programming languages so an idea expressed in one language i can convert to another, i'm having trouble figuring out the path data should take to organize and pass the data around that is received from the client's socket, right now the client object handles the processing of protocols whether it needs to add, convert or reform data that is then sent/received over the socket

in addition to this when data is received from a client it can be setup to either poll the raw data or poll data on a per line basis

in the main loop
handle new connections
process clients
get input
process players
handle playerstate
if state wants input polls for input
change state after input if needed
send out buffer to clients that was generated during tick/pulse what ever you want to call it
rinse and repeat
05 Jan, 2011, RoFAdmin wrote in the 4th comment:
Votes: 0
my sentiments exactly Crayt. I wasn't sure if had just smoked to much today or something, but apparently not.

@drifton: I have no clue what you are asking.
05 Jan, 2011, Cratylus wrote in the 5th comment:
Votes: 0
RoFAdmin said:
my sentiments exactly Crayt. I wasn't sure if had just smoked to much today or something, but apparently not.

@drifton: I have no clue what you are asking.


Unfortunately my post keeps getting deleted. People will just have to wonder what you're replying to.

-Crat
http://lpmuds.net
05 Jan, 2011, chrisd wrote in the 6th comment:
Votes: 0
drifton said:
in the main loop
handle new connections
process clients
get input
process players
handle playerstate
if state wants input polls for input
change state after input if needed
send out buffer to clients that was generated during tick/pulse what ever you want to call it
rinse and repeat


This looks fine, to be honest. It sounds like you're wanting to reduce the differences between NPCs and Players, though, so I have a suggestion. Rather than "process players", make it "process characters" (both NPCs and Players) and handle "input" from both of them. Let's suppose that there's no difference between NPCs and Players except that the latter has a connection to a remote host. Check this out:

for ch in characters:
if not ch.brain:
continue
input_lines = ch.brain.process() # Perhaps: ["look", "say hello", "wield sword"]
for line in input_lines:
ch.handle_command(line)

Now in this example, ch.brain.process() returns a list of commands that the character has chosen to execute. In the case of a player, ch.brain is actually a wrapper for the connection, so ch.brain.process() retrieves whole lines of input from the connection and returns them as a list. In the case of an NPC, however, ch.brain might be None or it might be an object that generates and returns a list of commands for the NPC to execute when ch.brain.process() is called.

As for what happens in ch.handle_command(), it sounds like you have a command interpreter and so forth already complete. If you want more flexibility in this area, though, you could change the way your characters handle commands after retrieving them from the connection/brain. One way is to have a number of handlers that you can attach/detach from characters and pass input to all of these handlers in turn. In this way you can easily add and remove sets of commands to/from individual characters as needed.

Hope this gives you some food for thought - if you were after something more specific, go ahead and ask. :smirk:
05 Jan, 2011, plamzi wrote in the 7th comment:
Votes: 0
drifton said:
The code base is custom, written in the d programming language i know a lot of programming languages so an idea expressed in one language i can convert to another, i'm having trouble figuring out the path data should take to organize and pass the data around that is received from the client's socket, right now the client object handles the processing of protocols whether it needs to add, convert or reform data that is then sent/received over the socket

in addition to this when data is received from a client it can be setup to either poll the raw data or poll data on a per line basis

in the main loop
handle new connections
process clients
get input
process players
handle playerstate
if state wants input polls for input
change state after input if needed
send out buffer to clients that was generated during tick/pulse what ever you want to call it
rinse and repeat


Although you still haven't asked a clear question, I'm beginning to suspect you're thinking about how to support human input that actually controls npcs/mobiles. Let us know if that's the case. They say that phrasing the right question takes you half-way to an answer. This may be one of those cases.
05 Jan, 2011, drifton wrote in the 8th comment:
Votes: 0
@chrisd - > that is the type of system that i'm leaning towards, atm

@plamzi -> i am looking at how to control npc/mobs with the human input, i'm also trying to keep things fairly clean, though i am by no means a tidy person, my mind wanders a lot and it hard alot of the time for me to express my crazy little mind =p things that i think are obvious never turn out to be

also i'm trying to wrestle with the idea of what should own the client object
should the client object own the reference to the actor(npc/mob/player) or should it be the other way around where the actor owns the client reference
05 Jan, 2011, plamzi wrote in the 9th comment:
Votes: 0
drifton said:
@plamzi -> i am looking at how to control npc/mobs with the human input, i'm also trying to keep things fairly clean, though i am by no means a tidy person, my mind wanders a lot and it hard alot of the time for me to express my crazy little mind =p things that i think are obvious never turn out to be

also i'm trying to wrestle with the idea of what should own the client object
should the client object own the reference to the actor(npc/mob/player) or should it be the other way around where the actor owns the client reference


I think I understand your quandary. On the one hand, you need to start with a client object prior to a player logging in with a character. This indicates the client object outranks the actor object. On the other hand, a mobile/npc, which is also an actor, exists with or without an active client object, which *seems* to suggest the opposite.

For this problem, I'd say there's nothing wrong with reading the classics. The way a DikuMUD codebase handles the hierarchy (implicitly, in classless C) is it assumes that a client (descriptor) has to have a non-npc object in a playing state before it can become a controller of NPC's (via the switch command). This makes sense because you need to know that, say, an immo has sufficient powers to possess NPC's directly (as opposed to controlling them "from the outside"). After 'switching', the client has a child player object in a pseudo-linkless state, and whatever input waits at the socket is being interpreted into actions for the NPC being possessed. The real lesson here is that the client object rules, since it contains two pointers to "actors":

struct char_data *character; /* linked to char */
struct char_data *original; /* original char if switched */

At switch time, the character pointer "plugs" into an existing NPC actor, and the original pointer maintains the link with the actual player actor so a 'return' is possible. In other words, a DikuMUD NPC is an auto-spawned and re-spawned client-less character ready to be possessed, automated in the meantime.

Direct possession of NPC's seems to me to be a "messy" but also undisputedly convenient feature, especially for QM's. There's probably a way to get the same end result with less messiness and at the same time make it possible for one human QM to control multiple NPCS. For instance, you could have a client object that holds an array of actor pointers. If the primary actor pointer (always a non-NPC) is in the "NPC control" state at the time you poll the client for input, you can interpret the input as direct control over all the other active actor pointers (let's say five death knights galloping towards a player-defended city). You'd need a small set of immo commands to handle adding and removing of controlled NPC's to the array, but that should be trivial.
05 Jan, 2011, quixadhal wrote in the 10th comment:
Votes: 0
My only suggestion here is.. stop treating npc/mob/players as seperate things. They all function the same way in the game world, so make them share the same data structures and thus have (the potential for) the same abilities. If you do that, you only need to plug in either a socket/command-parser for control, or an AI routine; and either a save routine for state information, or not.

It will also make life easier down the road if you choose to do polymorph/possession/reincarnation or any other mechanic that has you swapping bodies or losing control of your character.
05 Jan, 2011, Sryth wrote in the 11th comment:
Votes: 0
Quote
My only suggestion here is.. stop treating npc/mob/players as seperate things. They all function the same way in the game world, so make them share the same data structures and thus have (the potential for) the same abilities. If you do that, you only need to plug in either a socket/command-parser for control, or an AI routine; and either a save routine for state information, or not.


I'll +1 Quixadhal here. It is more an object oriented way of looking at the mud, but you're using an object oriented language so it is easy enough once our human heads wrap around it.

Really…What's the difference between a npc, player, item, or room.

All have short and long descriptions? Yep.

All have attributes? Yep. They're different for each, but that's ok, I'd store attributes probably in a dictionary anyway.

All have action controls? Yep. an NPC has AI, a player has a brain. (Arguable sometimes, but hey.) An item and
room hopefully have AI in whatever form. Progs/triggers and such.

These are just a few examples. So really, the only difference we have so far between our objects is the AI/brain. (Note I referred to in-game items as "items" not objects.) Helper methods implemented on the brains that inherit the base object should be doing any differentiation work.

Now, with that done, you should be able to poll any "brain" object (with a common api between them of course) and have it respond appropriately whatever kind of thing it represents.
05 Jan, 2011, plamzi wrote in the 12th comment:
Votes: 0
I think the OP is quite clear on NPCs and players being near-identical from a coding viewpoint, as his very first post reveals:

drifton said:
as i was thinking about mobs and npc with the logical conclusion that they are very similar to players in how they interact with the world and how they are represented to the player as other players, this is leading me to want to create an Actor class that derives from MudObject and the Player, NPC, and Mobs would then derive from the actor class.


I believe his question has to do with how best to accommodate the differences between the two within the same object (Actor) and how best to handle Actors in the main loop.
0.0/12