模型归属
参伍把职责分成三层。引擎负责必须确定、权威且可重放的部分;可选的扩展 crate 基于对外 API 提供通用领域机制,例如移动或法律;你的应用负责时代内容,以及赋予这些机制具体含义的各项决定。新增一条规则时,可以用这一页判断它该放在哪一层、代码应依赖哪个 crate。
查看图表源码
flowchart TB
App["你的应用<br/>时代内容、场景、<br/>事故、权限记录"]
Ext["扩展 crate<br/>canwu-movement、canwu-law、<br/>canwu-culture、canwu-society 等"]
Ref["参考整合包<br/>canwu-reference-world 等<br/>可替换的示例"]
Api["canwu-api<br/>对外 API"]
Engine["引擎与机制 crate<br/>canwu-core、canwu-event、canwu-sim、<br/>canwu-routing、canwu-transport 等"]
App --> Ext
App --> Api
Ext --> Api
Ref --> Api
Api --> Engine
箭头从一个 crate 指向它所依赖的 crate。引擎与机制 crate 从不依赖扩展、参考整合包或应用代码。
一条所有权规则
Section titled “一条所有权规则”通用引擎 crate 拥有确定性的模拟契约:状态、结算、证据、随机性、持久化和重放。扩展 crate 和参考整合包拥有具体的世界概念,例如军队、政府、领土、人物和信件,以及描述这些概念的事件载荷。
需要跨多个插件修改记录时,同样遵循这条规则。例如,文化目标退休时,法律记录可能仍在引用它,这时的维护操作要同时修改不同插件拥有的记录。内核检查参与者集合、记录版本和工作预算,并保证所有修改要么一起提交,要么都不提交。每个参与者只能修改本插件拥有其 schema 的记录,目标记录的所有者插件还必须提交对该记录的精确修改。插件通过 register_owner_authorized_maintenance_participant 登记为参与者,或通过 register_maintenance_dependency_resolver 登记为依赖解析者。这两种登记都保存在插件描述符中,调用方无法漏掉某个参与者。
下表列出常见的关注点,说明哪个 crate 拥有相应机制,以及哪些事项由你的应用决定。
| 关注点 | 所有者 | 由你的应用决定 |
|---|---|---|
| 人物生存与人身状态、运行时创建人物、撤回排队输入 | canwu-sim 核心状态与指令 |
人物何时死亡、被俘、获释或出现;撤回哪些输入 |
| 多所有者条件转移 | canwu-sim 转移清单、第 10 阶段暂存与第 11 阶段审计 |
每次转移的参与者、预期版本和含义 |
| 规则评估证据 | canwu-core 记录、canwu-sim 边界证据、canwu-api 视图读取 |
规则 ID 及各项的含义 |
| 决策谱系与席位继任 | canwu-decision 票据与控制者绑定 |
谁占据席位、继任者何时接任 |
| 委托动用资源 | canwu-resource 动用授权与 Granted 来源策略 |
谁可以授权给谁,以及权限证据记录 |
| 移动生命周期与运力池 | canwu-movement 运行时记录与插件;canwu-transport 记录与纯函数分配 |
事故、危险、敌对行为及其随机抽样,以及权限依据记录 |
| 受托承运人与承运人扣押 | canwu-correspondence |
委托背后的关系,以及把扣押消息转告发送者 |
| 真伪判定 | canwu-information 解读记录 |
伪造被识破的概率 |
| 加权、表决单元与征询程序阶段 | canwu-law 编译后的程序 |
席位权重、表决单元和平局规则 |
| 引擎内文化结算 | canwu-culture 的 CultureBoundaryPlugin 结算生命周期并产生变化;canwu-society 始终是 canwu.society:state 的唯一写入者 |
接触信号和文化定义 |
| 政策压力来源与 cohort 人口校准 | canwu-society |
人口校准所引用的外部存量记录 |
| 外部传播来源 | canwu-technology |
所引用的内容记录及其声明的可靠度 |
有两个移动相关的 crate 名字相近。canwu-reference-world 带有一个移动插件,用 order_movement_v1 命令移动示例世界中的军队和人物,属于可替换的示例代码;canwu-movement 则是面向 canwu-transport 记录的通用移动生命周期扩展,与参考世界无关。
通用事件契约
Section titled “通用事件契约”canwu-event 只包含通用事件契约:
| 类型 | 说明 |
|---|---|
SimEvent |
事件信封:身份、时间、受影响实体、摘要、原因和相关标识 |
EventKind |
类型标签加扁平化的结构字段。领域 crate 定义强类型载荷,并用 from_payload 和 decode_payload 转换。 |
CauseRef |
事件的原因:命令、父事件、边界或系统 |
EventAudience |
哪些角色相对视图可以看到事件;插件未声明时为 Private |
EventKindError |
载荷无法编码或解码时返回的错误 |
移动、军队到达、人物旅行、信件交付、报告派发、知识和调试字段等强类型载荷,都放在拥有它们的整合包中。运行时保留了私有的兼容载荷,用来严格校验旧的事件标签和字段。插件事件带有插件名和事件类型,可以通过 EventKind::plugin_identity 取出。事件如何记录和呈现,见事件系统。
历史:已退役的 canwu-world crate
Section titled “历史:已退役的 canwu-world crate”早期版本提供过一个 canwu-world crate,把一个示例世界放进了引擎的依赖图。它的十二个公开类型 MapPoint、Person、PersonTransitState、LetterStatus、LetterCargo、Government、Territory、Route、TransitState、Army、WorldSnapshot 和 WorldDiff,现在都在 canwu-reference-world 中。这个 crate 通过对外 API 提供它们,同时提供示例移动插件、脱离式投影和路由适配函数 planning_snapshot_from_world。canwu-routing 基于通用的 PlanningSnapshot 规划路线,不依赖示例世界。
canwu-sim 仍保留其中大部分类型的副本,并由 canwu-api 重新导出,供已弃用的 Canwu::world() 投影和旧式 Command::OrderMovement 路径使用。新代码应使用 canwu-reference-world 或自己的领域记录。逐个类型的归属理由见仓库中的世界与事件归属审计。