---
title: "运行机制推测"
image: "https://wiki.wrightkit.dev/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://wiki.wrightkit.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 运行机制推测

注意：本文绝大部分内容均为主观推测​，因此正确性不做保证，仅供参考。

规则会同时在服务器与不同玩家的设备上运行。这保证了所有玩家的体验一致，但也导致了一些问题，例如服务器拥挤的情况下可能会感到不流畅，随机并不是真随机。

部分操作不会立刻生效，因为在OW中，命令的模拟（即实际运行命令）是周期性的，目前大致为16.6ms（60Hz）。又称每16.6ms是一个tick。例如，当你重生一名玩家后，立刻改变玩家的一些属性很可能无效。

所有能在屏幕上显示或能发出声音的东西，包括玩家、建筑、文字、图标、特效等，都可以被称作“实体”，但不包括HUD（广义的）部分。地图工坊仅能操作由地图工坊创建的实体，和一些实体的特定内容（例如访问玩家的部分状态）。地图工坊限制的实体数量，只包括由地图工坊创建的实体，并且所有玩家共享此上限。

## 运行过程

OW的地图工坊很可能是单线程运行的（指规则运行过程）如果没有发生阻塞（即等待动作），则当前的动作会一直运行下去，不会被其他规则打断。

根据我们的测试，我们推测OW的运行过程如下：

* 维护一个运行队列。
* 每个tick，进行：
	* 游戏本身的逻辑（如命中判定、移动模拟等）
		* 如果在此过程中，触发了事件（如“玩家造成伤害”等），则将其放入队列。
	* 等待队列是否有到达等待时间或条件不满足的
		* 到达等待时间：加入到执行队列中。
		* 条件不满足：根据动作处理。
	* 检查每个可用的持续事件的条件是否满足，如果满足就加入到执行队列中。
	* 更新部分带有“重新赋值”属性的实体、HUD。
* 按照运行队列执行。

## 优化建议

### 独立重复运算

目前所观察到的现象表明：持续事件的“条件”、带有“重新赋值”属性的实体、HUD，会在每个tick进行运算。因此，有多个规则使用了同样的运算时，例如：（规则1、规则2、规则3事件均为“持续 - 每名玩家”）

* 规则1：相距距离(事件玩家, 全局变量(A)) < 5
* 规则2：相距距离(事件玩家, 全局变量(A)) > 0
* 规则3：相距距离(事件玩家, 全局变量(A)) == 5

则可以写为：

* 规则A：
	* 事件：持续 - 每名玩家
	* 动作：
		* 设置玩家变量(事件玩家, B, 相距距离(事件玩家, 全局变量(A)))
		* 等待(0.016, 无视条件)
		* 循环
* 规则1：玩家变量(事件玩家, B) < 5
* 规则2：玩家变量(事件玩家, B) > 0
* 规则3：玩家变量(事件玩家, B) == 5

这样写有一个小问题：本来响应条件变化的时间不超过16.7ms，但现在则不超过33.3ms。但一般不会有太大负面作用。

另外，直接读取属性（如玩家是否按下按键、玩家的生命值、游戏时间等）的操作其实优化空间并不大，所以不需要单独独立出来。

### 模拟局部变量

目前所观察到的现象表明：若无“等待”动作，规则运行不会被中断。因此，单个规则中若有多个同样的运算时，例如：

* 根据条件跳过(相距距离(事件玩家, 全局变量(A)) < 5, 1)
* // xxx
* 根据条件跳过(相距距离(事件玩家, 全局变量(A)) > 10, 1)
* // xxx
* 根据条件跳过(相距距离(事件玩家, 全局变量(A)) > 20, 1)
* // xxx

则可以写为：

* 设置玩家变量(事件玩家, B, 相距距离(事件玩家, 全局变量(A)))
* 根据条件跳过(玩家变量(事件玩家, B) < 5, 1)
* // xxx
* 根据条件跳过(玩家变量(事件玩家, B) > 10, 1)
* // xxx
* 根据条件跳过(玩家变量(事件玩家, B) > 20, 1)
* // xxx

## 其他

* 因为运行机制，“等待”并不完全准确。一次等待时间，误差一般不超过16ms。

## “服务器意外关闭”的猜测

关于“服务器意外关闭”，我们有一些猜测，可能并不完全准确。

* “运行队列”可能到了某个上限
* 每个tick运行的时间超过了某个上限

## 参考资料

* [《守望先锋》架构设计与网络同步](https://gameinstitute.qq.com/community/detail/114516)
* [《守望先锋》中的网络脚本化的武器和技能系统](https://gameinstitute.qq.com/community/detail/114122)

另外感谢[竹子菌](https://space.bilibili.com/2418570)、[昭华](https://weibo.com/u/6571188444)的协助

Source: https://wiki.wrightkit.dev/zh/tutorial/core/index.mdx
