Skip to main content

通用游戏数值计算框架 — DAG 公式引擎 + 声明式 UI 渲染 + 搜索枚举引擎

Project description

calc-framework — 通用伤害计算框架

适配任意 RPG 游戏的公式可配置伤害计算框架。 公式写在 DAG JSON 中,无需改代码即可调整乘区顺序、增删乘区、修改计算逻辑。


架构总览

┌─────────────────────────────────────────────┐
│               适配包 (AdapterPackage)         │
│  ┌──────────┐  ┌──────────┐  ┌───────────┐  │
│  │ meta.json│  │ dag/*    │  │ ui/*      │  │
│  │          │  │ .dag.json│  │ layout.json│  │
│  └──────────┘  └──────────┘  └───────────┘  │
└──────────────────────┬──────────────────────┘
                       │ 加载
┌──────────────────────▼──────────────────────┐
│              框架核心 (calc_framework)        │
│                                              │
│  ┌─────────────┐  ┌──────────────────┐       │
│  │ DAG 引擎     │  │ DataContext      │       │
│  │ 9 种节点类型  │  │ 标准上下文       │       │
│  │ 拓扑排序     │  │ make_context()   │       │
│  │ 子图展开     │  │ DataContextLoader│       │
│  │ AST 沙箱     │  │ (抽象基类)       │       │
│  └─────────────┘  └──────────────────┘       │
│                                              │
│  ┌─────────────┐  ┌──────────────────┐       │
│  │ ComputeSheet│  │ 日志系统          │       │
│  │ 自动渲染输入  │  │ setup_logging() │       │
│  │ 实时求值     │  │ get_logger()    │       │
│  └─────────────┘  └──────────────────┘       │
└──────────────────────────────────────────────┘

快速开始

详见 docs/quickstart.md

from calc_framework.config.adapter import AdapterPackage
from calc_framework.data.loader import DataContextLoader
from calc_framework.data.context import make_context

# 1. 加载适配包
pkg = AdapterPackage("path/to/game-adapter")

# 2. 构建数据上下文
ctx = make_context(
    character={"基础攻击": 100, "力量": 50},
    weapon={"基础攻击": 40},
    computed={"最终攻击力": 140},
)

# 3. 求值
result = pkg.dag_service.evaluate(ctx)
print(result.outputs)

核心模块

DAG 引擎 — calc_framework.dag

模块 职责
schema.py 9 种节点类型(const/var/unary/binary/condition/expr/user_input/call)
engine.py 拓扑排序 + 节点求值 + 默认值回退
subgraph.py call 节点内联展开
sandbox.py AST 解析 + 白名单校验 + 安全求值
serializer.py DAG JSON ↔ DAGGraph(加载时自动展开模板引用)
service.py DAGService 统一入口
templates.py 可复用公式模板库(5 内置模板,支持 "template" 字段引用)

配置/加载层 — calc_framework.config

模块 职责
adapter.py 适配包加载器(meta.json → DAGService)
manager.py 适配器管理器(发现/缓存/加载多个适配包)

搜索/枚举引擎 — calc_framework.search

模块 职责
tracker.py Top-N 结果追踪(通用泛型)
cancel.py 搜索取消令牌(超量/主动取消)
parallel.py 并行执行器(进度回调、Top-N、取消)
result.py 通用搜索结果类型

适用于任何需要遍历大量候选并保留最优结果的场景(配装搜索、参数枚举、伤害最大化等)。

插件系统 — calc_framework.plugin

模块 职责
base.py BasePlugin / PluginMeta 基类
registry.py PluginRegistry 全局注册表
builtin.py 3 内置插件(crit_handler / dodge_handler / distance_decay)

发布/分享 — calc_framework.publish

模块 职责
schema.py JSON Schema 校验(validate_package)
catalog.py 静态 HTML 目录生成(build_catalog)

数据层 — calc_framework.data

模块 职责
context.py DataContext TypedDict + make_context 工厂
loader.py DataContextLoader 抽象基类
schema.py 四层数据契约(EntitySchema / SkillSchema / SegmentSchema)
attr_schema.py 属性声明 Schema — 适配器声明字段结构,框架自动构建 DataContext(resolve/validate)

UI 层 — calc_framework.ui

模块 职责
compute_sheet.py 声明式计算表 QWidget,从 DAG + layout.json 自动渲染
controls.py infer_control 根据变量声明推断控件类型
layout.py Layout/Section 排版定义
format.py 数值格式化

配置层 — calc_framework.config

模块 职责
adapter.py AdapterPackage 加载 meta.json + DAG

适配包结构

一个完整的游戏适配包:

my-game-adapter/
├── meta.json              # 元信息
├── attr_schema.json       # 属性声明 Schema(可选)
├── dag/                   # DAG 公式定义
│   └── main.dag.json
└── ui/                    # UI 排版定义
    └── layout.json

meta.json 示例:

{
  "name": "我的游戏伤害计算",
  "game": "我的游戏",
  "version": "1.0.0",
  "schema_version": "dag-v1",
  "entry_dag": "dag/main.dag.json"
}

也可引用 attr_schema.json 和自定义函数:

{
  "name": "卡牌RPG伤害计算",
  "game": "经典卡牌RPG(示例)",
  "version": "1.0.0",
  "schema_version": "dag-v1",
  "entry_dag": "card_rpg.dag.json",
  "attr_schema": "attr_schema.json",
  "functions": {
    "clamp": "functions.py"
  }
}

适配器示例

终末地(15 乘区)

framework/games/endfield/ — 真实游戏完整适配器。

卡牌RPG(攻击-防御公式)

framework/adapters/card_rpg/ — 示例适配器,证明框架跨品类通用。

framework/adapters/card_rpg/
├── meta.json               # 适配器元信息
├── attr_schema.json        # 属性声明(ATK/DEF/crit_rate/crit_dmg)
├── card_rpg.dag.json       # DAG 公式(attack - def × 0.5 + crit)
├── functions.py            # 自定义函数(clamp)
├── loader.py               # CardRPGLoader(DataContextLoader 实现)
└── ui/layout.json          # ComputeSheet 排版
from calc_framework.config.adapter import AdapterPackage

# 加载卡牌RPG适配器
pkg = AdapterPackage("framework/adapters/card_rpg")

# 构建上下文并求值
ctx = {
    "character": {"ATK": 100, "crit_rate": 0.05, "crit_dmg": 0.5},
    "weapon": {"ATK_bonus": 15},
    "enemy": {"DEF": 60},
    "user_input": {"skill_mult": 1.0, "is_crit": True},
}
result = pkg.dag_service.evaluate(ctx)
print(result.outputs)
# {"总攻击力": 115.0, "基础伤害": 85.0, "暴击倍率": 1.5, "最终伤害": 127.5}

构建 DAG 公式

DAG JSON 是框架的核心配置。一个完整 DAG 包含:

{
  "schema_version": "dag-v1",
  "name": "伤害计算",
  "variables": {
    "character.基础攻击": {
      "type": "float",
      "source": "character",
      "description": "角色基础攻击力"
    }
  },
  "subgraphs": {
    "final_attack": { "nodes": { ... }, "outputs": { ... } }
  },
  "nodes": {
    "base_atk": {
      "type": "var",
      "path": "character.基础攻击"
    },
    "total_atk": {
      "type": "binary",
      "op": "+",
      "lhs": "base_atk",
      "rhs": "weapon_atk"
    }
  },
  "outputs": {
    "最终攻击力": { "node": "total_atk", "label": "最终攻击力" }
  }
}

DAG 模板

框架内置 5 个通用公式模板(defense_reductioncrit_multiplierclamp_to_rangepercent_ofattribute_scaling),可在 DAG JSON 中直接引用:

{
  "def_reduc": {
    "template": "defense_reduction",
    "bindings": {
      "defense": "enemy_def",
      "scale": "const_0_5"
    }
  }
}

加载时自动展开为完整节点。也可通过 register_template() 注册自定义模板。


日志

from calc_framework.logging import setup_logging, get_logger
from calc_framework.data.attr_schema import AttributeSchema

# 在应用入口调用一次
setup_logging(level="INFO", log_file="calc.log")

# 在各模块获取 logger
logger = get_logger(__name__)
logger.info("DAG 求值完成")

# 加载属性 Schema
schema = AttributeSchema.from_file("attr_schema.json")
ctx = schema.resolve(raw_data)
errors = schema.validate(ctx)

环境变量控制:CALC_FRAMEWORK_LOG_LEVEL(默认 WARNING)、CALC_FRAMEWORK_LOG_FILE

游戏启动器

通过 calc_framework.launcher 可交互选择适配包并启动 ComputeSheet GUI:

# 交互选择
python -m calc_framework.launcher

# 直接指定
python -m calc_framework.launcher "终末地计算器(Calc Framework)"

适配器搜索路径由 CALC_ADAPTERS_DIR 环境变量控制(默认 framework/adapters/)。

发布 Catalog

python -c "from calc_framework.publish import build_catalog; build_catalog('dist')"

生成 dist/index.html,可部署到 GitHub Pages 作为社区适配器市场。


开发与测试


测试

cd framework
python -m pytest tests/ -q    # 293 passed

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

calc_framework-0.3.0.tar.gz (141.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

calc_framework-0.3.0-py3-none-any.whl (189.7 kB view details)

Uploaded Python 3

File details

Details for the file calc_framework-0.3.0.tar.gz.

File metadata

  • Download URL: calc_framework-0.3.0.tar.gz
  • Upload date:
  • Size: 141.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for calc_framework-0.3.0.tar.gz
Algorithm Hash digest
SHA256 389339b970dbcab518a71231047c5b799acd932f17f375145061ad4effc0f3c7
MD5 55c7952bf19958846da81c3eebe1e422
BLAKE2b-256 41a85bc8d7093e0a74edb6669bb4cc3bd9de959ab92a32bd7e774d4cb6e55b95

See more details on using hashes here.

File details

Details for the file calc_framework-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: calc_framework-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 189.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for calc_framework-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 840e5d0add6596a7289252a70e98d3a473521d775ea85a7423db3cb4fded376e
MD5 27d4283633f22fbb1ab3a454512784b6
BLAKE2b-256 5751e954610db8c2c11a99afb62dd52a87175aa1996eb851897232c4bdb46f86

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page