views:

142

answers:

3

I'm trying my hand at building a MUD (multiplayer interactive-fiction game)

I'm in the design/conceptualizing phase and I've run into a problem that I can't come up with a solution for. I'm hoping some more experienced programmers will have some advice.

Here's the problem as best I can explain it. When the player decides to perform an action he sends a command to the server. the server then processes the command, determines whether or not the action can be performed, and either does it or responds with a reason as to why it could not be done. One reason that an action might fail is that the player is busy doing something else. For instance, if a player is mid-fight and has just swung a massive broadsword, it might take 3 seconds before he can repeat this action. If the player attempts to swing again to soon, the game will respond indicating that he must wait x seconds before doing that. Now, this I can probably design without much trouble. The problem I'm having is how I can replicate this behavior from AI creatures. All of the events that are being performed by the server ON ITS OWN, aka not as an immediate reaction to something a player has done, will have to be time sensitive. Some evil monster has cast a spell on you but must wait 30 seconds before doing it again... I think I'll probably be adding all these events to some kind of event queue, but how can I make that event queue time sensitive?

+3  A: 

MUDs actions are usually performed on 'ticks' rather than immediately - this allows for limited affect of latency and for monster's commands to be inserted in the queue and processed fairly.

Personally, I don't like this approach, but pretty much 99% of MUDs use it. You need to design a robust command queue & event queue which can handle both AI and user commands. You can then add "virtual latency" to AI commands which may be predefined or an average of all users latency, or whatever you like.

I've developed a MUD from scratch and enjoy the concept so if you would like to discuss it further feel free [email protected]

Steven Jackson
+2  A: 

Well your AI-controlled entities have some sort of "what am I going to do next?" method, right? Just have that method return "I'm busy, keep doing what I was doing" result while another action is underway.

E.g.

class ToughGuy(AI):
   Action_Idle, Action_BroadswordSwing, Action_CastingMagic = range(3)

   MagicRange = 10
   MagicTime = 8
   MeleeRange = 4
   MeleeTime = 2

   def __init__(self):
      self.action = ToughGuy.Action_Idle
      self.actiontimer = 0

   def Update(self, timestep):
      if self.actiontimer <= 0:
         self.action = ToughGuy.ActionIdle
      else
         self.actiontimer -= timestep

      if self.action == ToughGuy.Action_Idle:
         global player # don't do this
         if self.AmIFacing(player):
            distance = DistanceBetween(self, player)
            if distance < ToughGuy.MeleeRange:
               self.action = ToughGuy.Action_BroadswordSwing
               self.actiontimer = ToughGuy.MeleeTime
            elif distance < ToughGuy.MagicRange:
               self.action = ToughGuy.Action_CastingMagic
               self.actiontimer = ToughGuy.MagicTime

etc. Sorry for the variable coding standards... ;)

dash-tom-bang
A: 

AI's are clients.

They're "part of the server" only in the most distant view. They're actually outside the main game engine. They're specialized clients with no human being.

An AI client has the same interface with the server that a human's client would.

S.Lott
That isn't how they should be implemented, it would cause huge and unecessery overheads. He means AI in the sense of NPC AI, they are part of the server.
Steven Jackson
AI makes me think to an actual AI that acts like a player through a player-like interface, like S.Lott says. I guess the OP wanted to say "mobs".
Lo'oris
@Steven Jackson: "Huge Overheads"? Really? How so? The computation must be done anyway, so it can't involve any more CPU. The connection can be a "localhost" network connection which is simply a shared buffer. What overheads are you talking about? Can you be specific? I can't see any. What am I missing?
S.Lott
Huge is relative. I don't mean the computation itself, you'd be converting logic into human-readable text just to be converted into logic again - why? You're proxying the AI through the network code just to be executed where it should be in the first place. Lo'oris you are correct that the OP should have specified mobs. It's not unheard of for a MUD to have 10,000+ mobs (NPCs).
Steven Jackson
@Steven Jackson: "human-readable text"? Why? Why not calls from the AI to the same methods the human interface uses after handling GUI's and parsing and all that front-end stuff an AI doesn't need. This is the Web Services philosophy. Human front-end and web services use the same underlying API's to do the same things. Why doesn't that apply here?
S.Lott
Because it's a MUD, unless stated otherwise you can assume it operates over Telnet and that all inputs are human readable.
Steven Jackson
@Steven Jackson: Why assume "it operates over Telnet and that all inputs are human readable"? That seems to be a fairly silly assumption. It makes the AI's harder to write (as evidenced by the question). Why not have a multi-layered architecture? Why assume a bad architecture when it's relatively easy to have an architecture that exposes a machine-friendly interface layer?
S.Lott
http://en.wikipedia.org/wiki/MUD this is the topic. Your AI/protocol suggestions make sense for a custom implementation, but I'm not assuming it's telnet based because I'm in love with the protocol. It's just how almost all MUDs operate.
Steven Jackson
@Steven Jackson: "It's just how almost all MUDs operate" While that may be true, how do you know it applies to this question?
S.Lott