主题
动作与私有信息
合法动作是一等 API
legal_actions(pool, state, player) 返回当前状态下玩家可提交的完整 Vec<Action>。 服务端或宿主不应自行猜测动作掩码,也不应接受列表外参数后“尽量执行”。step 仍会在 提交时重验,防止候选产生后状态已变化。
主要动作包括:
- 换牌;
- 部署普通或带目标/抉择的单位;
- 移入前线、宣告攻击;
- 打出带目标/抉择的指令;
- 武装或在锁定前解除反制;
- 确认手牌、预报、库顶、生成卡和私有手牌选择;
- 结束回合。
目标统一使用 TargetRef:战场实体、手牌实例或牌区插入点。尚未实现的目标协议不会 被静默降级为另一个目标类型。
决策信封
MatchSession::decisions 为每个决策方返回:
| 字段 | 含义 |
|---|---|
actor | 当前有权提交动作的玩家 |
observation | 仅该玩家可见的状态 |
actions | 稳定顺序的合法动作 |
state | 生成该列表时的状态指纹 |
使用动作索引时必须同时回传 state。这能避免网络延迟或并发处理把旧索引映射到新动作。
结构性遮蔽
Observation 不是完整状态加若干“可见”布尔值,而是从数据形状上移除对手秘密:
- 对手未公开手牌只有数量;
- 对手武装的反制及真实隐藏花费不存在于观察结构;
- 未揭示隐蔽单位只有
FaceDown { owner },没有牌面字段; - 历史中的实例 ID 只能通过当前视角的白名单解引用;
- 未揭示隐蔽单位离场后,其身份不会因日志而重新泄露。
自己的手牌、资源、武装反制和已知身份则完整可见。
待选状态
效果需要后续玩家选择时,状态进入 PendingChoice。候选在首次结算时冻结,确认动作只 重验“属于冻结候选且仍在原区域”,不会重掷随机数。当前类型包括:
- 动态手牌目标;
- 预报的类别/卡面两段选择;
- 库顶揭示选一;
- 随机生成卡候选;
- 敌方隐藏手牌的临时私有候选。
私有候选只在选择者的 PendingChoiceView 中出现;另一方只看到来源和候选数量。临时 披露不会永久写入 card_seen。候选全部失效时效果按规则空放并恢复外层续算,避免死锁。
FIFO 与暂停续算
同一动作产生多个交互时按 FIFO 处理。暂停帧保存剩余效果、目标游标、绑定、事件负载和 随机状态;确认后从精确断点继续,不从效果开头重跑,也不重复支付或触发弃牌钩子。