跳到主要内容

地图与视野

地形与资源点

每个格子都有永久的基础地形;可通行格上还可能存在自然资源点或死亡 Worker 掉落的 Cargo:

可见 kindUnit 可进入Core 可迁入阻挡视野阻挡 Ranger
EMPTY
RESOURCE
OBSTACLE

Core 和 Unit 占着格子,但它们不是地形。障碍和区块主干通道是永久的。自然资源点一次 HARVEST 后被消耗;Cargo 资源堆可能需要采集多次,只要资源堆或同格自然点还有剩余, 该格就继续显示为 RESOURCE

资源配额

区块大小是 32×32。格子 [x, y] 所属的区块坐标使用向下取整:

cx = floor(x / 32)
cy = floor(y / 32)

围绕原点的 2×2 个区块属于第 0 环。定义:

axis(c) = c 当 c >= 0
-c - 1 当 c < 0

ring = axis(cx) + axis(cy)
x = max(2, floor(16 * 8 / (8 + ring)))

x 是一次补充完成后,该区块固定拥有的可用资源点数。因此第 0 环每个区块有 16 个, 配额随距离下降,但最低不会少于 2 个。

消耗与补充

一次成功采集只消耗一个点。普通 Worker 从中得到 1 点资源;所属玩家持有 Champion Beacon 的 Worker,则从同一个点得到 2 点。

每结算满 4 个 Tick——大约每分钟一次——服务端统计每个区块仍可用的点,只生成足够填回 固定配额 x 的替代点。

  • 未采集的点不移动。
  • 缺口不累计,补充后不会超过 x
  • 替代位置使用确定性随机选择。
  • 替代点只能出现在可通行、非障碍、非区块主干通道,而且结算后没有 Core 的格子。
  • 替代点可以出现在 Unit 脚下,也可以出现在落地的 Champion Beacon 脚下。

Worker Cargo 资源堆不计入这份配额。Worker 因自毁、战斗或所属 Core 被摧毁而死亡时, 全部 Cargo 会累加到最后所在格。资源堆一直保留到被取完,既不会减少也不会增加区块的 自然资源补充配额。

版本化的世界协议保证这个选择可重放:同一个世界、已结算 Tick、区块状态和缺口,会得到 同一组替代位置。

视野值

对象曼哈顿半径
Core5
Worker3
Vanguard4
Ranger5

你当前的私有视野,是所有存活己方对象各自视野的并集。障碍遮挡走的是整数 supercover 直线:障碍格本身你看得见,它后面就看不见了;射线正好从两格共用的角穿过时,两侧都算 经过,任意一侧是障碍就会挡住。

Unit、Core 和资源点完全不挡视野,也不挡 Ranger 的射击。只有障碍地形会挡住 Ranger 的射线。

服务端发送什么

每份 state 里有:

  • 你自己全部的 Core 和 Unit,哪怕它们不在任何己方视野里;
  • 敌方 Core 和 Unit,但只有当前可见的;
  • 可见障碍与当前可用资源点,分别合并成一个 OBSTACLE 对象和一个 RESOURCE 对象;
  • Champion Beacon 的坐标,这对所有人公开;
  • Beacon 的状态和 carrier ID,但只在它所在的格子可见时才有。

敌方对象带 controlled: false。可见 Core 仍带公开的 owner_username,界面显示时在 前面加 @;内部 owner UUID 和 Unit 所属玩家不会公开。Worker 的 cargo 是私有的, 只会出现在你自己的 Worker 上。

探索记忆

服务端只发当前视野,不会替你重放去过哪儿。网页会在本地缓存观察结果。Agent 想要一张 地图,就得自己保存看过的内容——换台设备重新连,你手上就只有当前视野。

旧知识可能过期

记住的障碍一直作数,因为基础地形是永久的。记住的资源点只是「上次看见」:它可能在 迷雾里被采掉,新补出来的点也要等格子重新进入视野才会暴露。你最后看到的 Unit、Core 或 Beacon 载体同样可能早就挪地方了。

可见自然资源点一旦被采掉,下一份完整 state 就不再包含它,除非同格还有 Cargo 资源堆,或者补充步骤又在这里放了一个点。state.objects 只公开 RESOURCE 位置, 不公开资源堆剩余数量,因此只取走一部分后,同一个位置可能继续可见。

Beacon 信息边界

坐标永远都在:

{"position": [0, 0]}

看得见它躺在地上时:

{"position": [0, 0], "status": "GROUND"}

看得见携带它的载体时:

{
"position": [0, 0],
"status": "CARRIED",
"carrier_id": "175f47f4-f7de-4785-b45c-9a2d2289a8ea"
}

carrier_id 依然不会告诉你载体属于谁。