如何在多玩家laggy环境下正确地使用武器冷却重装定时器?

我想在服务器上的两个客户端上以公平和可预测的方式处理武器冷却定时器。

情况:

  1. 多个客户端连接到服务器,这是做命中检测/物理
  2. 客户端连接服务器的延迟时间从50ms到500ms不等。
  3. 他们想要用相当长的重装/冷却时间来拍摄武器(假设精确到10秒)重要的是他们能够在接近冷却时间的时候拍摄这些武器,就像有些客户比其他人一样因为他们是“早”或其他“晚”),他们获得了显着的优势。
  4. 我需要显示剩余的时间来重新加载玩家的屏幕上
  5. 客户可能有时钟错误(坏时区等)

我目前正在做什么来处理延迟:

  1. 客户端收集历史logging中的服务器端状态,用服务器时间戳标记
  2. 客户评估他的时间与服务器时间的差异:

    behindServerTimeNs = (behindServerTimeNs + (System.nanoTime() - receivedState.getServerTimeNs())) / 2 
  3. 客户端将从服务器接收到的所有状态从当前时间延迟200毫秒,通过他认为他与服务器时间的时间差异(无论是由于时钟错误还是滞后)来调整。 如果他在计算时间的两侧都有服务器状态,他(通常是LERP)在它们之间进行插值,如果不是,那么他(LERP)就外推。

  4. 没有其他的客户端运动预测,例如,使他的车辆看起来更加敏感,到目前为止已经完成,但也许会在稍后添加

那么如何正确添加武器重装定时器?

我的第一个想法是,服务器向每个玩家发送每次世界状态更新完成重新加载的时间,然后客户端根据时钟差异进行调整,从而可以估计重新加载何时在客户端完成(也许也考虑到从客户端到服务器的拍摄信息的延迟也是如此),并且如果用户在此之后(或者甚至稍微之前?)捣碎“拍摄”button,则发送拍摄事件。

服务器会得到拍摄事件,并考虑到服务器接收时间的时间。 如果它不在重新加载时间附近,它会丢弃它,如果它已经过了重新加载的时间,就立即执行它,并保持它几个物理周期,直到重新加载完成,以防早期收到它。

这似乎有点复杂,我想知道它是否会起作用(例如ping不到的情况是否会降低更高的重装率),以及是否有更优雅的解决scheme来解决这个问题。

管理重载次数服务器端是否完全有必要? 通常最简单的方法是在公平性和响应性方面在客户端。 我不是专家,但我可以预测,目前的系统鼓励垃圾邮件,服务器必须检查每个请求是否有效,然后丢弃它,占用更多的处理能力。

用60ms的ping来建立一个客户端的基本模型(忽略处理时间等),我们得到:

 Client sends event at 0ms Server receives event at 30ms Server sends time back to client, arrives 60ms Client can shoot at 10030ms according to both server and client If ping constant and player clicks once when told shot is ready: Client clicks to shoot at 10030ms Message arrives at server 10060ms Server sends back timer for 20060ms If ping constant and player spams: Messages sent repeatedly to server between 30 and 10030ms Around 10030ms one of these messages arrives and is instantly accepted Server sends back timer of 20030ms If ping spikes to ~250ms: Spamming is not affected as much as one of the messages will get through Single click is delayed by another ~100ms 

这是一个公平的系统,只要每个人在重新加载结束时不断地点击,但是如果你要管理它的客户端,效果只会减缓时间,而不是重新加载时间本身(这会触发即刻)。 在上面的例子中,每次重新加载都会丢失几毫秒,直到完整的时间被丢失。

如果镜头发送到服务器,重新加载是本地的,那么镜头可能会晚点,但重新加载将始终准时。 慢/快时钟最初的问题可能仍然是一件事情。 根据你使用的语言/框架,可能有更好的时间衡量。 除此之外,我恐怕不能帮上忙。