screeps吧 关注:714贴子:637
  • 1回复贴,共1
求助

新人入坑求助~

只看楼主收藏回复

目前刚接触这个游戏几天,正在重构到任务驱动架构,这个过程中碰到一个很关键的卡点,如何得知一个任务是否已经完成呢,如harvest之类的持续任务可以不需要处理,可是像spawnCreep这样需要几ticks时间才能完成的任务,如何得知何时任务完成?
之前尝试过以下两种思路,但都失败了
1. task结构体携带一个函数每tick判断是否完成
2. task 结构体携带一个变量表示倒计时
思路1的核心问题在于screeps没有足够稳定的运行时内存,Memory会因为stringify导致丢失,global和运行时内存都会刷新,失败
思路2的问题在于复杂性和灵活性不足,spawnCreep的耗时可以通过spawn.spawning上的remainingTime得到,但如果我希望把升级rcl也作为一个task,这样的话就很难得知何时完成任务了
目前山穷水尽,求个大佬指点一下


IP属地:北京来自iPhone客户端1楼2023-09-10 02:30回复
    在《Screeps》中,要判断一个任务是否完成,特别是对于需要一定时间才能完成的动作(如 spawnCreep),确实存在一些挑战。不过,有几种可能的解决方案可以尝试:1. 使用消息队列或事件系统:你可以设置一个消息队列或事件系统来跟踪任务的进度和状态。例如,每当你开始一个新的任务时,你就在队列中添加一项。当任务结束时,你就从队列中删除这项。这样就可以通过检查队列的状态来判断任务是否已经完成。如果你想增加更多的复杂性,比如并行处理多个任务,那么你可能需要考虑更复杂的并发控制策略。2. 利用 Memory 的变化检测机制:Memory 对象的一个特性是它可以检测其内容的变化。这意味着你可以在你的 task 中维护一个对 Memory 中的某个值的引用,并在该值改变时做出响应。这可能并不适合所有的情况,但它在某些情况下可能会很有用。3. 使用自定义函数和API调用:你也可以考虑为你的任务创建一个自定义的 API 或者函数。这个函数可以在任务完成后被调用并更新相应的内存位置或者执行其他操作。虽然这样做可能需要额外的编程工作量,但它将给你的程序带来更大的灵活性和可扩展性。4. 计时器与倒计时:尽管你在思路二中提到了一些问题,但这并不意味着所有形式的计时器和倒计时都不可行。例如,你可以设定一个定时器,每当定时器触发一次,就表示任务又进行了一步。然后根据总的步骤数和你当前的步骤数比较就能知道任务是否完成了。这种方式的缺点是你的游戏的逻辑运行速度完全依赖于服务器的刷新率了。5. 全局变量标记法:可以为每个任务分配一个独特的全局布尔标志。当任务开始时将其设为 true,而当任务结束后设回 false。可以通过读取此全局变量的值来确定任务是否已完成。这种方法简单直接且易于实现,但是它可能会导致大量的全局变量被创建和使用,如果游戏规模扩大到一定程度可能会出现管理上的困难。6. 监听游戏事件:有些 Screeps API 可以用来监听特定的事件,比如 creep 的出生、死亡等。如果你的游戏具有这样的特性,那么你可以监听这些事件并根据事件的类型来判断任务是否完成。这种方式的好处是你不需要自己手动去追踪每一个任务的进度,而是由 Screeps 自己来告诉你;然而它的局限性在于并非所有的事件都可以用于此目的,而且即使能这么做也只适用于特定的任务种类。7. 计数器法:在一些简单的场景下,也可以使用计数器来完成类似的任务。例如每次 creep 移动一格就将计数器加一,一旦达到目标数量就认为任务完成。这种方法的适用范围有限制并且要求目标的明确性,但如果应用得当也能起到不错的效果。8. 依赖计划系统的设计模式:这是一种较为复杂但也更为强大的方法——让你的 AI 系统具备一种能力去制定和管理计划的能力。在这种模式下,"任务" 就是一系列的动作序列,AI 在任何时候都知道应该做什么以达成目标。"任务完成" 就变成了计划的某一部分已经被实施完毕的情况下的处理方式的问题了。这种做法能够应对各种复杂多变的游戏状况以及提供更高的游戏体验自由度。当然这也需要花费相对较多的开发时间和精力。总的来说,《Screeps》是一个非常深度化和复杂的游戏环境,因此并没有哪一种是万能的最佳方案可以使用。《Screeps》中的许多核心概念都需要开发者自行探索和理解,《Screeps》才会真正变得“活”起来!


    2楼2023-09-10 03:00
    回复