关于定时事件的MUD(游戏)设计概念问题

发布于 2024-08-30 22:54:37 字数 439 浏览 8 评论 0原文

我正在尝试构建一款 MUD(多人互动小说游戏),

我正处于设计/概念化阶段,但遇到了一个我无法提出解决方案的问题。希望有经验的程序员能给点建议。

这是我能解释的最好的问题。当玩家决定执行某项操作时,他会向服务器发送命令。然后,服务器处理该命令,确定是否可以执行该操作,然后执行该操作或响应一个无法执行该操作的原因。某个操作可能失败的原因之一是玩家正忙于做其他事情。例如,如果玩家在战斗中刚刚挥舞了一把巨大的大刀,他可能需要 3 秒才能重复此动作。如果玩家很快再次尝试挥杆,游戏将做出响应,指示他必须等待 x 秒才能执行此操作。现在,我可能可以毫不费力地设计这个。我遇到的问题是如何从人工智能生物中复制这种行为。服务器自行执行的所有事件(即不是对玩家所做的事情的立即反应)都必须对时间敏感。一些邪恶的怪物对你施了咒语,但必须等待 30 秒才能再次执行...我想我可能会将所有这些事件添加到某种事件队列中,但如何使该事件队列对时间敏感?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

金兰素衣 2024-09-06 22:54:37

MUD 操作通常在“滴答声”上执行,而不是立即执行 - 这允许有限的延迟影响,并且可以将怪物的命令插入队列并公平处理。

就我个人而言,我不喜欢这种方法,但几乎 99% 的 MUD 都使用它。您需要设计一个强大的命令队列和命令队列。事件队列可以处理AI和用户命令。然后,您可以将“虚拟延迟”添加到 AI 命令中,该命令可以是预定义的,也可以是所有用户延迟的平均值,或者您喜欢的任何内容。

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.

一绘本一梦想 2024-09-06 22:54:37

AI 是客户。

仅在最远的视图中它们才是“服务器的一部分”。它们实际上位于主游戏引擎之外。他们是没有人的专门客户。

人工智能客户端与服务器的接口与人类客户端相同。

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.

野の 2024-09-06 22:54:37

好吧,你的人工智能控制的实体有某种“我下一步要做什么?”方法对吧?只需让该方法返回“我很忙,继续做我正在做的事情”结果,而另一个操作正在进行中。

例如

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

等等。抱歉变量编码标准......;)

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... ;)

撞了怀 2024-09-06 22:54:37

您可以使用线程来处理特定类型的生物,并将所有实例放入某种类型的数组中。然后,线程只需重复应用逻辑来遍历列表。 DelayTimeStart 和 Delay 可以是父 Mob 类的属性,当线程执行循环时,它可以推迟处理 Mob 的任何有延迟时间的实例。

You could use threads to handle specific types of Mobs, and put all the instances into an array of some sort. Then, the thread simply goes through the list repeatedly applying logic. DelayTimeStart and Delay could be attributes of the parent Mob class, and when the thread goes through the loop, it can put off processing any instances of the Mob in which there is time remaining in the delay.

别想她 2024-09-06 22:54:37

一种基本方法是使用一个数据结构来表示邪恶怪物的法术实例,并在其上设置冷却计时器。当使用该力量时,会设置冷却时间(大概是由法术的主定义定义的秒数);尝试再次使用它将会失败,就像玩家的能力一样。这可以通过让队列检查冷却时间与事件队列集成,如果它尚未过期,则等待它过期,或中止操作,或根据需要重新安排操作。

A basic approach would be to have a data structure representing the evil monster's instance of its spell, with a cooldown timer on it. When the power is used, the cooldown is set (presumably to a number of seconds defined by the master definition of the spell); an attempt to use it again will fail just like with the player ability. This can be integrated with an event queue by having the queue check cooldown, and if it hasn't expired, to wait for it to expire, or abort the action, or reschedule the action, as appropriate.

风吹雨成花 2024-09-06 22:54:37

我将从 LPMud/LDMud 的角度为您提供答案。

MUD 中的每个玩家都是player.c 的一个实例。 Player.c继承自living.c。有生命的事物都有心跳。对于泥浆上的每个活体(或任何具有 heartbeat() 函数的物体),heartbeat 函数每 2 秒处理一次。计时事件通常不是基于秒来完成的,而是基于通过对象内的计数器经过的心跳数。

适用于你的问题的好消息是怪物也继承自living.c。这意味着,如果您的操作只能定期执行,那么这一切都可以根据已发生的滴答数在心跳内进行管理。

I'll provide you an answer from an LPMud/LDMud point of view.

Every player in the MUD is an instance of player.c. Player.c inherits from living.c. Things that are living have a heartbeat. The heartbeat function is processed once every 2 seconds for every living object on the mud (or anything that has a heartbeat() function). Timing events is not typically done based on seconds, but instead based on the number of heartbeats that have elapsed through counters within the object.

The wonderful news that applies to your question is that monsters also inherit from living.c. This means that if you had actions that can only be performed periodically this can all be managed within the heartbeat based on the number of ticks that have occurred.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文