跳转到内容

架构总览

引擎如何分层、一条命令会经历什么、每个 crate 负责什么。

参伍是一个无界面历史模拟引擎,自身不带渲染器和界面。上层应用(游戏、研究工具、 调试客户端或 AI 智能体)把它当作 Rust 库链接进来,通过提交命令改变世界,通过快照、 事件和角色相对视图读取世界。实时世界状态只由引擎的运行时持有,也只在结算命令和调度 工作时发生变化。

选择某一层可以查看其中的 crate;切换到“跟随一条命令”,可以一步步看到一条命令从提交到 重放的全过程。

  1. 对外 API 边界 · 这条线以上的代码只使用 canwu-api

  2. 引擎内部 · 只能经由 canwu-api 访问

上层应用

负责渲染、输入、现实时间、账号与历史内容。它依赖 canwu-api,注册需要的插件,提交命令并读取结果。

仓库中的参考客户端

  • canwu-debug基于对外 API 与参考整合包的桌面调试客户端(egui)

领域插件

模拟领域扩展以模拟插件的形式提供可复用规则,它们都建立在 canwu-api 之上。按需注册,也可以自己编写。参考内容包提供数据,参考整合包把这些部件组合成可以直接运行、也可以复制改造的小型世界。

模拟领域扩展(已发布到 crates.io)

参考内容包

参考整合包(仅在仓库中,未发布)

编写自己的插件 →

canwu-api

应用依赖的引擎 crate,扩展 crate 也建立在它之上。其中的 Canwu 类型负责创建和推进模拟运行、接收命令、返回独立快照和角色相对视图,并支持存档、派生分支与重放。下层 crate 中需要的类型都由它重新导出。

主要调用

接入参伍 →

canwu-sim

持有权威状态。它把收到的命令放入输入队列,运行调度工作,并以边界为单位结算到期工作:边界是某个模拟时间点上的一次整体结算,按 14 个固定阶段运行;任何一步失败,整个边界回滚。它还记录存档和重放所需的证据与哈希。应用只通过 canwu-api 访问它。

crate

  • canwu-sim运行时、调度、结算、插件、持久化、哈希与重放
边界如何结算 →

模型与机制

插件和应用经由 canwu-api 使用的数据类型:发生了什么以及原因、每个角色知道什么、待定的决策,以及路线与运输记录。运行时本身使用其中的事件、知识和决策类型。

crate

事件与因果 →

基础层

类型化 ID、确定性随机数、schema 元数据与模拟时间运算。其他所有 crate 都建立在这两个 crate 之上。

crate

  • canwu-core稳定 ID、确定性随机数与 schema 基础类型
  • canwu-time模拟时间与带溢出检查的时长运算
可重放的随机性 →
  1. 第 1 步,共 7 步

    构造命令

    客户端构造一个类型化命令。在 starter 示例中,参考世界把 MovementCommand 包装成命令信封。

    let envelope = order_movement(Issuer::Actor(commander), &command)?;
  2. 第 2 步,共 7 步

    排入队列

    enqueue_command 把请求按到期时间放入输入队列,并返回回执。原样重发同一请求会得到同一张回执;同一请求 ID 配不同内容会失败。此时世界状态还没有变化。

    canwu.enqueue_command(due_at, priority, CommandRequest::new(id, revision, envelope))?;
  3. 第 3 步,共 7 步

    推进时间

    advance_canonical 推进模拟时间。每一批到期的工作都在一个边界中结算。

    canwu.advance_canonical(SimDuration::hours(19))?;
  4. 第 4 步,共 7 步

    结算边界

    引擎检查签发者的权限、命令所基于的修订版本以及预期时间,被拒绝的命令连同原因一起记录。随后插件系统按 14 个固定阶段运行并提出变更,这些变更一起提交,或一起回滚。

    14 个结算阶段 →
  5. 第 5 步,共 7 步

    记录结果

    提交的变更生成带有因果与受众的事件。角色知识与报告随之更新,重放日志也多记录一个边界。

  6. 第 6 步,共 7 步

    读取结果

    玩家或智能体通过 viewer_for_actor 读取,只能看到该角色知道的内容。受信任的上层应用工具还可以用 events() 列出事件,用 explain() 查询原因。

    let viewer = canwu.viewer_for_actor(actor)?;
    安全读取状态 →
  7. 第 7 步,共 7 步

    存档与重放

    snapshot_json 保存模拟运行,replay_journal 返回它记录的全部输入。replay_from_journal 根据这些输入重建运行;检查点哈希相同,说明重放完全一致。

    let replayed = Canwu::replay_from_journal(&[&plugin], &canwu.replay_journal())?;
    assert_eq!(replayed.checkpoint_hash(), canwu.checkpoint_hash());
    存档、重放与派生分支 →
每一层只使用本层和下方各层。选择某一层可查看其中的 crate;切换到“跟随一条命令”后,可用箭头逐步查看。
  • 上层应用依赖 canwu-api,并注册自己需要的插件。
  • 领域插件是建立在 canwu-api 之上的可选 crate。第一方扩展能调用的接口与你自己编写的 插件完全相同,因此任何一个都可以替换。
  • canwu-api 是受支持的对外 API,下层 crate 中需要用到的类型都由它重新导出。
  • canwu-sim 是 canwu-api 背后的私有运行时,负责实时状态、输入队列、调度、 结算、持久化与重放。
  • 模型与机制(canwu-event、canwu-knowledge、canwu-decision、 canwu-routing、canwu-transport)定义共用的数据类型,由 canwu-api 重新导出。
  • 基础层(canwu-core、canwu-time)提供 ID、确定性随机数和模拟时间。

下图展示各 crate 在 Cargo.toml 中声明的直接依赖:A → B 表示 A 依赖 B,外部依赖和 开发依赖未列出。依赖图默认放大到 250%;可以用按钮或在图内滚动鼠标滚轮,在 50% 到 600% 之间缩放,拖动画布即可平移。

参伍全部 workspace crate 之间的直接依赖;箭头从使用者指向它依赖的 crate. 查看依赖图源码.
查看依赖图源码
flowchart TB
  subgraph Tools["工具"]
      Debug["canwu-debug"]
  end

  subgraph Extensions["扩展"]
      Correspondence["canwu-correspondence"]
      Information["canwu-information"]
      Society["canwu-society"]
      Culture["canwu-culture"]
      Law["canwu-law"]
      Technology["canwu-technology"]
      History["canwu-history-research"]
      Fiscal["canwu-fiscal"]
      Resource["canwu-resource"]
      Production["canwu-production"]
      Military["canwu-military"]
      Movement["canwu-movement"]
  end

  subgraph Examples["示例"]
      MingFiscal["canwu-ming-fiscal"]
      EconomyContent["canwu-economy-reference-content"]
      MingReference["canwu-ming-fiscal-reference"]
      ForceSupply["canwu-force-supply-reference"]
      EconomyReference["canwu-economy-reference"]
      ReferenceWorld["canwu-reference-world"]
      MilitaryContent["canwu-military-reference-content"]
      MilitaryReference["canwu-military-reference"]
  end

  subgraph PublicApi["对外 API"]
      Api["canwu-api"]
  end

  subgraph RuntimeMechanisms["运行时与机制"]
      Sim["canwu-sim"]
      Transport["canwu-transport"]
      Routing["canwu-routing"]
  end

  subgraph Models["模型"]
      Decision["canwu-decision"]
      Event["canwu-event"]
      Knowledge["canwu-knowledge"]
  end

  subgraph Foundation["基础"]
      Core["canwu-core"]
      Time["canwu-time"]
  end

  Debug --> Api
  Debug --> MingReference
  Correspondence --> Api
  Correspondence --> Information
  Information --> Api
  Society --> Api
  Culture --> Society
  Culture --> Api
  Law --> Api
  Technology --> Api
  History --> Api
  History --> Technology
  Fiscal --> Api
  Resource --> Api
  Production --> Api
  Production --> Resource
  Production --> Technology
  Military --> Api
  Movement --> Api
  MingFiscal --> Api
  MingFiscal --> Fiscal
  EconomyContent --> Api
  EconomyContent --> Production
  EconomyContent --> Resource
  EconomyContent --> Technology
  MingReference --> Api
  MingReference --> Fiscal
  MingReference --> MingFiscal
  MingReference --> ReferenceWorld
  ForceSupply --> Api
  ForceSupply --> EconomyContent
  ForceSupply --> Resource
  EconomyReference --> Api
  EconomyReference --> EconomyContent
  EconomyReference --> ForceSupply
  EconomyReference --> Production
  EconomyReference --> ReferenceWorld
  EconomyReference --> Resource
  EconomyReference --> Technology
  ReferenceWorld --> Api
  MilitaryContent --> Api
  MilitaryContent --> Military
  MilitaryReference --> Api
  MilitaryReference --> Military
  MilitaryReference --> MilitaryContent
  MilitaryReference --> ReferenceWorld
  Debug --> ReferenceWorld

  Api --> Core
  Api --> Decision
  Api --> Event
  Api --> Knowledge
  Api --> Routing
  Api --> Sim
  Api --> Time
  Api --> Transport

  Sim --> Core
  Sim --> Decision
  Sim --> Event
  Sim --> Knowledge
  Sim --> Time

  Transport --> Core
  Transport --> Routing
  Transport --> Time

  Routing --> Core
  Routing --> Time

  Decision --> Core
  Decision --> Time
  Event --> Core
  Event --> Time
  Knowledge --> Core
  Knowledge --> Time
  1. 状态只通过命令改变。 客户端提交命令,插件在边界系统中提交变更提议。运行时 验证两者,并在结算边界中统一提交。
  2. 每次运行都可复现。 时间、调度工作、系统顺序和随机抽样 都遵循固定规则,所以按日志重放会得到相同的检查点哈希。
  3. 知识属于角色。 运行时把真值与每个角色所知分开保存。玩家和智能体通过 角色相对视图读取。
  4. 历史连同原因一起记录。 每个事件都保存起因、受众和 相关标识,因此可以向引擎查询某件事为什么发生。

特定时代的规则不写进引擎内核,而是放在 canwu-api 之上,分为四种形式:

类型 提供什么 例子
模拟领域扩展 以模拟插件形式提供的可复用机制 canwu-resource、canwu-movement
参考内容包 供扩展使用、带出处的版本化数据 canwu-ming-fiscal
参考整合包 组合扩展与内容的小型可运行世界 canwu-economy-reference
入门套件 可以复制后修改的可运行示例 canwu-reference-world 中的 starter 示例
从参伍引擎到模拟领域扩展、参考内容包、参考整合包和上层应用. 查看图表源码.
查看图表源码
flowchart TB
  Engine["canwu-api + canwu-sim"] --> Domain["模拟领域扩展"]
  Domain --> Pack["参考内容包"]
  Domain --> Integration["参考整合包"]
  Pack --> Integration
  Integration --> Starter["入门套件"]
  Starter -. "复制后修改" .-> App["你的游戏或研究工具"]
  Domain -. "直接注册" .-> App
  Pack -. "直接复用" .-> App

下面几个例子说明职责如何划分:

  • 移动。 canwu-transport 只保存记录:命令、运输执行、行程修订、交接、预订和运力池。 canwu-movement 是运行这些记录的插件:它准入移动命令,在每个路段到期时结算,分配运力池, 并把移动报告发给应当收到的角色。事故、危险和敌对行为,以及决定它们的随机抽样,都留在你自己 的系统中。
  • 通信。 canwu-correspondence 负责信件从需求到投递的全过程:地址查询、路线、承运人、 遇灾与截取。它建立在 canwu-information 之上,后者负责文书、副本与解读。
  • 经济。 canwu-resource 负责守恒数量及其履约。canwu-production 消耗资源和技术证据, 驱动设施与工单。canwu-economy-reference 把两者与运输、军事补给组合成季节性粮食循环。 其中的稀缺度和价格压力只是只读投影;只有成交、报价、官价或合同价提供了价格时,它才会报告价格。

跨插件合同(转移清单、动用授权、受托承运人等)各由谁负责,见 模型归属。

crate 职责
canwu-core 类型化 ID、确定性随机数与 schema 元数据
canwu-time 模拟时间与带溢出检查的时长运算
canwu-event 带起因、受众和结构化字段的事件信封
canwu-knowledge 角色知识,包括来源、可信度与信息时效
canwu-decision 决策票据、控制者、确定性求值与决策策略 SDK
canwu-routing 通行时间随时间变化的路线规划
canwu-transport 运输执行、行程修订、交接、预订与运力池的记录类型
canwu-sim 私有运行时:状态、调度、插件、结算、持久化、哈希与重放
canwu-api 对外 API:命令、领域记录、视图、快照、证据与重放

模拟领域扩展(已发布,可选)

Section titled “模拟领域扩展(已发布,可选)”
crate 职责
canwu-resource 资源账户及受保护底线、需求、预留、分配、转移、消费、损耗、动用授权与履约
canwu-production 工艺、生产地点、设施、产能、工单、在制品、项目与产出
canwu-movement 基于 canwu-transport 记录的移动命令、路段结算、运力池分配与移动报告
canwu-military 部队、行动、战斗、占领,以及由其他领域结算并确认的待处理效果;游戏需要不同的战斗规则时可以替换
canwu-society 人群之间的社会传播
canwu-culture 文化编写与编译,以及运行在 canwu-society 之上的文化生命周期
canwu-law 法律编写、制度程序(包括加权、表决单元与征询阶段)、版本化法律与适用;实验性
canwu-technology 从证据出发的技术模拟:能力、实施、采用与传播
canwu-fiscal 财政程序、地区采纳、核算、执行凭证与按持有人区分的知识报告
canwu-information 文书、副本、访问、发布、解读与真伪判定
canwu-correspondence 按地址投递的信件:需求、地址查询、路线、承运人、遇灾与截取
canwu-history-research 技术模拟的可选历史研究评估插件
crate 职责
canwu-ming-fiscal 从明初到南明、带出处和覆盖声明的财政内容
canwu-economy-reference-content 经济模型卡、出处与覆盖声明,并明确标出未知和不适用状态
canwu-military-reference-content 供军事扩展使用的版本化合成军事规则集

参考整合包与工具(仅在仓库中)

Section titled “参考整合包与工具(仅在仓库中)”
crate 职责 另外依赖
canwu-reference-world 小型示例世界(军队、人物、地区、信件)及其移动插件、投影、路由适配器和 starter 示例 仅 canwu-api
canwu-ming-fiscal-reference 可运行的洪武、万历、弘光财政场景 canwu-fiscal、canwu-ming-fiscal、canwu-reference-world
canwu-force-supply-reference 作为可替换资源消费者的军事补给,包含征发 saga canwu-resource、canwu-economy-reference-content
canwu-economy-reference 组合资源、生产、运输、军事补给、稀缺度与价格证据的可运行粮食循环 canwu-resource、canwu-production、canwu-technology、canwu-economy-reference-content、canwu-force-supply-reference、canwu-reference-world
canwu-military-reference 在参考世界中运行的军事扩展及其合成内容 canwu-military、canwu-military-reference-content、canwu-reference-world
canwu-debug 基于对外 API 与参考整合包的桌面调试客户端 canwu-reference-world、canwu-ming-fiscal-reference

知识、决策、资源、军事、财政等方面的具体规则由领域系统提供,每个系统都有单独的设计页面。 领域系统页面列出全部八个系统及提供它们的 crate。