Skip to content

项目结构 ​

crate 布局 ​

MVP 只拆两个 crate(避免过度工程化,理由见技术栈);平台壳按阶段增加,目录提前预留:

text
sandtable/
├── crates/
│   ├── sandtable-core/
│   │   └── src/
│   │       ├── config.rs      # 配置加载 / 校验 / 规范化 / config_hash
│   │       ├── registry.rs    # 参数注册表(path / kind / default / desc)
│   │       ├── scenario.rs    # YAML 场景与实验文件加载(scenario+model/sweep/optimize 节)
│   │       ├── formula.rs     # 有界表达式求值器(加载期编译)
│   │       ├── rng.rs         # 带键随机数派生(SplitMix64)
│   │       ├── kernel.rs      # Clock / EventQueue / System trait(离散事件骨架)
│   │       ├── world.rs       # World 与实体存储
│   │       ├── systems/       # 内置游戏系统(behavior / combat / progression / churn / gacha)
│   │       ├── metrics.rs     # RunMetrics 与在线聚合
│   │       ├── sim.rs         # 仿真主循环(事件驱动)
│   │       ├── experiment.rs  # replicates、CRN 配对比较、统计
│   │       ├── sweep.rs       # 网格 / 随机 / LHS 扫描引擎
│   │       ├── sensitivity.rs # OAT 弹性
│   │       ├── recommend.rs   # 单轴插值推荐
│   │       ├── optimize.rs    # 进化 + Pareto 寻优
│   │       ├── surrogate.rs   # 随机森林代理(只读 sweep 产物)
│   │       ├── disttest.rs    # χ² 分布检验(disttest 子命令数据面)
│   │       ├── export.rs      # 输出渲染(JSON / CSV / 人类可读;Arrow 在 export/arrow.rs)
│   │       └── lib.rs
│   ├── sandtable-cli/
│   │   └── src/main.rs       # clap 子命令,薄封装 core(MVP)
│   ├── sandtable-wasm/       # wasm-bindgen 薄绑定(已落地:validate_config / run_simulation;native 纯函数承逻辑,wasm 层只包装,与 CLI 等价有测试锁死)
│   └── sandtable-python/     # pyo3 薄绑定(已落地:load / run / sweep / recommend / params 只读面 + 阶段 3 日粒度读态回调 run_with_day_hook;同 wasm 双层结构独立实现,maturin 出 wheel,py_parity 与 CLI 锁死)
│
├── apps/
│   ├── web/                  # React + TS + Vite(已落地:配置编辑 → 本地仿真 → KPI/曲线/分群表,零图表库;项目多配置选择器已落地)
│   └── desktop/              # Tauri 2 壳(Phase 7:src-tauri + core path 直连,命令面 6 个全接线,native query 已入 UI;Linux 本机先行)
│
├── examples/                 # 场景与实验 YAML(pokemon / gacha-pity / pokemon-sweep 等)
│   └── python/               # 外挂模式示例(阶段 0:kpi_report / daily_curves / parquet_analysis;零 Rust 依赖回退路径)
├── docs/                     # 本文档站(VitePress)
├── scripts/                  # scripting-design.md + scripting-perf-report.md(阶段 3 实测)+ templates/(阶段 2 官方编排模板)
├── .github/workflows/        # CI(含 wasm32 门禁)与 Pages 部署
└── README.md

依赖方向 ​

text
sandtable-cli     ─┐
sandtable-wasm    ─┼→ sandtable-core
sandtable-python  ─┤
apps/desktop      ─┘
core 内部:experiment / sweep / optimize → sim → systems → world/kernel
config / scenario / registry / formula 被各层依赖
分析层(DuckDB / Arrow)只被壳层调用,不进 core

core 不依赖任何壳;systems 不依赖 experiment;kernel 不依赖任何上层。

平台边界规则 ​

规则落点
cargo check --target wasm32-unknown-unknown 从 Phase 1 起进 CI路线图 Phase 1
core 禁止 duckdb / web-sys / tokio / 文件与网络 I/O / 壁钟仿真内核平台边界
并行(rayon)是 feature,core 算法串行确定,WASM 下退化单线程技术栈

模块职责速查 ​

模块职责关键约束
config / scenarioYAML 装载、校验、规范化、config_hash同语义配置同 hash
registry / formula参数注册表、公式求值未知路径给编辑距离建议
rng(seed, actor_id, day, event_index, purpose) 派生纯函数,无共享状态
kernel / world离散事件队列、实体存储有序容器(BTreeMap / IndexMap)
systems战斗 / 经济 / 成长 / 奖励 / 行为 / 保底确定性;带键随机消费
metrics在线聚合(直方图 / 草图 / Welford)不落个体明细
experiment / sweep / optimize编排、比较、扫描与寻优统计单位 = replicate

命名核查结论(2026-10) ​

平台结论
GitHubcuihairu/sandtable 无冲突(本仓库)
crates.iosandtable 前缀暂无冲突记录;正式发布前需再核一次
PyPIsandtable 已被占用;Python 绑定另行命名已落地(2026-10-11 阶段 1:发行名 sandtable-sim,导入名 sandtable_sim,不占用 sandtable 名;正式发布前按本章纪律再核一次)——载体与分期见 scripts/scripting-design.md

内置系统模块命名 systems;若未来独立成 crate 用 sandtable-systems,不用 sandtable-model(避免与概念 Model 混淆,见技术栈)。

与原计划的差异 ​

原计划列了六个 crate(core / model / config / experiment / report / cli)。合并与调整理由:

  • 配置、实验在 MVP 规模下不足以独立成 crate,拆开只会增加接口维护成本;
  • sandtable-model 与概念 Model 重名,内容(战斗、经济系统)实际是 systems;
  • report 在 HTML 阶段(Phase 5)出现真实需求时再独立;
  • Web / Desktop 是壳(apps/),不是 crate——壳的职责是把 core 装进目标平台,不承载仿真语义。

扩张原则:有真实复用或编译隔离需求时再拆,不预设。

以 Apache-2.0 许可证发布