npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dna-builder-data

v1.5.4

Published

DNA Builder game data models and utilities

Readme

dna-builder-data

游戏数据层独立包(monorepo 内位于 packages/data),包含角色构建系统的核心计算逻辑和游戏数据。 发布到 npm 供外部(MCP Server、服务端、脚本)使用;仓库内前端(apps/web)与服务端(apps/server) 均通过 workspace 依赖(file:../../packages/data)引用,开发期解析到本包源码(免构建、热更新友好)。

npm i dna-builder-data

构建与发布

pnpm run build 单次产出 dist/ 下全部 JS + d.ts(tsconfig.build.json 负责声明,scripts/build.mjs 负责转译与相对引用补 .js 后缀)。MCP 入口 dist/mcp/index.js 仅转译、不打包数据,与数据模块共享 dist/ 产物。prebuild 会先重跑类型快照生成并用仓库 Biome 落盘,保证 regen 无格式分叉。

目录结构

packages/data/
├── d/                    # 静态数据文件
│   ├── abyss.data.ts     # 深渊副本和增益数据
│   ├── achievement.data.ts # 成就数据
│   ├── base.data.ts      # 基础数据
│   ├── buff.data.ts      # 增益数据
│   ├── char.data.ts      # 角色数据
│   ├── draft.data.ts     # 抽卡数据
│   ├── dungeon.data.ts   # 副本数据
│   ├── effect.data.ts    # 效果数据
│   ├── fish.data.ts      # 钓鱼数据
│   ├── onlinemapcache.data.ts # 在线地图缓存(线上真相源,工具刷新,禁手改)
│   ├── mod.data.ts       # MOD 数据
│   ├── monster.data.ts   # 怪物数据
│   ├── pet.data.ts       # 宠物数据
│   ├── reward.data.ts    # 奖励数据
│   └── walnut.data.ts    # 胡桃数据
├── leveled/              # 带等级的游戏对象类
│   ├── LeveledBuff.ts    # 带等级的增益
│   ├── LeveledChar.ts    # 带等级的角色
│   ├── LeveledMod.ts     # 带等级的 MOD
│   ├── LeveledMonster.ts # 带等级的怪物
│   ├── LeveledPet.ts     # 带等级的宠物
│   ├── LeveledSkill.ts   # 带等级的技能
│   ├── LeveledSkillWeapon.ts # 带等级的同律武器
│   ├── LeveledWeapon.ts  # 带等级的武器
│   └── index.ts          # 导出和升级倍率表
├── tests/                # 单元测试
│   ├── CharBuild.test.ts
│   ├── data-types.test.ts
│   ├── evaluateAST.test.ts
│   ├── leveled.test.ts
│   └── index.test.ts
├── ast.ts               # AST(抽象语法树)解析器
├── CharBuild.ts         # 角色构建核心类
├── data-types.ts        # 数据类型定义
├── index.ts            # 导出入口
├── package.json        # 包配置
├── tsconfig.json       # TypeScript 配置
└── vitest.config.ts    # 测试配置

核心模块

CharBuild.ts

角色构建系统的核心类,负责计算角色属性和伤害。

主要功能:

  • 属性计算:计算角色基础属性(攻击、生命、护盾、防御、神智)和其他属性(技能威力、耐久、效益、范围等)
  • 武器属性计算:计算近战武器、远程武器、同律武器的属性
  • 伤害计算:
    • 技能伤害计算(考虑属性穿透、昂扬、背水、增伤、独立增伤、失衡易伤等乘区)
    • 武器伤害计算(考虑暴击、触发、攻速、多重等)
    • 防御乘区计算
  • AST 表达式求值:支持自定义目标函数表达式,如 伤害、DPS、每神智DPS 等
  • 时间线模拟:支持技能释放时间线的 DPS 模拟

关键类和方法:

class CharBuild {
    // 静态宏定义,用于 AST 表达式的快捷替换
    static macros: Record<string, string>

    // 计算角色所有属性
    calculateAttributes(): CharAttr

    // 计算武器属性
    calculateWeaponAttributes(weapon): CharAttr & { weapon?: WeaponAttr }

    // 计算技能伤害
    calculateSkillDamage(attrs): DamageResult

    // 计算武器伤害
    calculateWeaponDamage(attrs, weapon): DamageResult

    // 计算 AST 目标函数
    evaluateAST(astInput, attrs): number

    // 验证 AST 表达式
    validateAST(astInput): string | undefined

    // 计算随机伤害(用于模拟)
    calculateRandomDamage(baseWithTarget, enemy?): number
}

data-types.ts

所有数据类型的接口定义和枚举。

主要接口:

  • Char:角色数据结构
  • Weapon:武器数据结构
  • Skill:技能数据结构
  • Mod:MOD 数据结构
  • Monster:怪物数据结构
  • Buff:增益数据结构
  • SkillField:技能字段
  • SkillEffect:技能效果
  • SkillBuff:技能增益

主要枚举:

  • Elem:元素类型(光、暗、水、火、雷、风)
  • WeaponCategory:武器类别(单手剑、长柄、重剑、双刀、鞭刃、太刀、手枪、双枪、榴炮、霰弹枪、突击枪、弓)
  • WeaponSkillType:武器技能类型(普通攻击、蓄力攻击、下落攻击、滑行攻击、射击)
  • HpType:生命值类型(生命、护盾、战姿)
  • DmgType:伤害类型(切割、贯穿、震荡)
  • SkillType:技能类型(伤害、召唤、增益、治疗、被动、防御)
  • Faction:阵营
  • Quality:MOD 品质(白、紫、绿、蓝、金)
  • ModType:MOD 类型(角色、近战、远程、同律近战、同律远程)
  • ModSeries:MOD 系列(不死鸟、中庭蛇、人面狮、冥犬、囚狼、夜使、夜魔、契约者等)

leveled/

带等级的游戏对象类,根据等级倍率表计算属性。

CommonLevelUp:角色/武器 1-80 级的升级倍率表。

主要类:

  • LeveledChar:带等级的角色,计算基础属性和技能等级
  • LeveledWeapon:带等级的武器,计算基础属性和武器技能
  • LeveledSkillWeapon:带等级的同律武器
  • LeveledMod:带等级的 MOD,计算属性加成
  • LeveledBuff:带等级的增益
  • LeveledSkill:带等级的技能,计算技能字段值
  • LeveledMonster:带等级的怪物,计算属性和当前状态
  • LeveledPet:带等级的宠物

ast.ts

AST(抽象语法树)解析器和求值器。

功能:

  • 词法分析:将表达式字符串转换为 Token 流
  • 语法分析:将 Token 流转换为 AST
  • 宏替换:支持宏定义的快捷替换(如 DPS → or(攻速,1+技能速度)*or(多重,1)*伤害)
  • 支持的表达式特性:
    • 基本运算:+、-、*、/、//(整数除法)、%(取模)
    • 属性访问:攻击、伤害、[幻象]伤害
    • 函数调用:max(a, b)、or(a, b)
    • 命名空间访问:Q::伤害(技能 Q 的伤害)
    • 成员访问:伤害.N(伤害的不考虑血量版本)

AST 节点类型:

  • binary:二元运算(a + b)
  • unary:一元运算(-a、+a)
  • property:属性(攻击)
  • function:函数调用(max(a, b))
  • member_access:成员访问(伤害.N)
  • number:数字字面量

数据包与前端基建(已移出本目录)

数据包加载、存储、差分、图片缓存等属于前端基建,不属于数据层,现位于 apps/web/src/utils/data-pack/:

  • data-pack.ts:包下载、安装、差分升级、卸载
  • pack-storage.ts:OPFS / IndexedDB 存储后端选择
  • hpatchz-wasm.ts:浏览器内应用 HDiffPatch 差分
  • imgs-runtime.ts:图片缓存挂载
  • data-pack-bridge.ts:静态导出绑定的注册与水合
  • data-pack-runtime.ts:启动装配(在此注入 CDN 拼接器、注册水合钩子)
  • data-pack-rewrite-plugin.ts:构建期改写插件
  • translations-pack.ts:文案对照表注入

其中存储后端的挑选规则:数据包(十几 MB 的整包 zip 与逐个模块文件)放在浏览器存储里, 统一由 pack-storage.ts 选择后端:

  • 优先 OPFS,但用一次真实写入做能力探测,而不是只看 navigator.storage.getDirectory 是否存在: Safari 15.2 起就有该 API,却直到 Safari 26 才实现 FileSystemFileHandle.createWritable(), 只判断 API 存在性会让 Safari 上「能建目录、写文件必抛错」。
  • 探测失败回退 IndexedDB(库名 dna-builder-pack,键为 / 分隔的完整路径, 目录记录与文件记录同库存储)。回退实现同样暴露 getDirectoryHandle / getFileHandle / removeEntry / entries 等与 FileSystemDirectoryHandle 同形的接口, 因此 data-pack.ts 的安装、差分升级、卸载、清空逻辑无需感知数据落在哪里。
  • 首次解析出的后端会记在 localStorage 的 dna-builder:pack-storage-backend: 环境升级(如 Safari 26 补上了 createWritable)后不会因为换了存储位置而看起来像「丢包」; 同一把键也可在调试时手工改成 opfs / indexeddb 强制切换后端。

图片缓存(imgs-runtime.ts)目前仍直接使用 OPFS,且只在桌面端启用。

与前端基建的解耦约定

数据层不 import 前端基建,需要外部能力的模块一律用「注入」而非直接依赖:

  • LeveledChar 的资源地址拼接:setCdnUrlBuilder() 注入,默认值为主源绝对地址 (cdn.dna-builder.cn),保证 server / MCP 等不经过前端启动流程的调用方也能拿到可用 URL。
  • 派生索引重建(rebuildStaticIndexes)与潜质缓存失效(invalidatePetTraitCaches): 由 data-pack-runtime.ts 在数据包水合钩子里注册。d/index.ts 在模块首次求值时 自行建一次索引,因此单独引入数据层(不经 runtime)也能正常工作。

当前本包生产代码对外零依赖(不 import 前端应用的 utils / store / composables / api / env; d/onlinemapcache.data.ts 的 dna-api 是外部 API 包声明,tests/ 下的引用不进包)。因此凡是「数据形状 / 纯规则」 都住在数据层,前端基建侧改为转引,避免实现分叉:

| 数据层模块 | 原属地 | 前端侧转引位置 | |---|---|---| | charSettings.ts(CharSettings 及 MOD 变体全部纯函数) | apps/web/src/composables/useCharSettings.ts | 同左(只剩 localStorage + composable 本体)| | timeline-data.ts(RawTimelineData) | apps/web/src/store/timeline.ts | 同左 | | story-text.ts(剧情占位符 / 标签解析) | apps/web/src/utils/story-text.ts | 同左 | | enum-text.ts(枚举值 → 中文展示名) | apps/web/src/utils/i18n-utils.ts | 同左 | | RewardItem(奖励项形状) | apps/web/src/utils/reward-utils.ts | 同左 | | formatPetSkillText(魔灵技能文案) | apps/web/src/utils/pet-skill-text.ts | 同左 | | title-frame/*(称号框渲染) | 本包(已搬出) | apps/web/src/utils/title-frame/*(反向:纯前端渲染)|

判定口径:看谁需要它。计算内核、RAG 索引与 MCP 服务端要用的形状/规则 → 数据层;只有 UI 要的 → utils。 同名的类型只留一份:DotFrequencySettings 直接 export type ... from "./CharBuild", 否则 data/index.ts 里两个 export * 会撞名。

d/

静态游戏数据文件,包含所有角色的技能、武器、MOD、怪物等数据。

主要数据文件:

  • char.data.ts:角色数据(基础属性、技能、同律武器)
  • weapon.data.ts:武器数据(基础属性、武器技能)
  • mod.data.ts:MOD 数据(系列、品质、属性加成)
  • monster.data.ts:怪物数据(属性、阵营)
  • buff.data.ts:增益数据
  • achievement.data.ts:成就数据
  • abyss.data.ts:深渊副本数据
  • dungeon.data.ts:副本数据
  • fish.data.ts:钓鱼数据

tests/

单元测试,使用 Vitest 框架。

测试文件:

  • CharBuild.test.ts:角色构建功能测试
  • data-types.test.ts:数据类型测试
  • evaluateAST.test.ts:AST 求值测试
  • leveled.test.ts:带等级对象测试
  • index.test.ts:导出测试

伤害计算公式

技能伤害计算

伤害 = 基础伤害 × 属性穿透 × 增伤 × 独立增伤 × 失衡易伤 × 血量乘区 × 防御乘区

乘区说明:

  • 属性穿透:max(0, (1 - 敌方抗性) × (1 + 属性穿透))
  • 增伤:1 + 增伤 + 技能伤害
  • 独立增伤:1 + 独立增伤(乘法叠加)
  • 失衡易伤:失衡状态 ? (1 + 失衡易伤 + 1.5) : 1
  • 血量乘区:
    • 昂扬乘区:1 + 昂扬 × 当前血量百分比
    • 背水乘区:1 + 4 × 背水 × (1 - hp%) × (1.5 - hp%)
  • 防御乘区:1 - 防御 / (300 + 防御 - 等级差 × 10)

武器伤害计算

期望伤害 = (物理部分 × 物理倍率 + 元素部分 × 元素倍率 × 抗性) × 暴击期望 × 增伤 × 独立增伤 × 追加伤害 × 失衡易伤 × 血量乘区 × 抗性穿透

暴击期望计算:

暴击期望 = 1 + 暴击率 × (暴击伤害 - 1)

触发伤害期望:

触发期望 = 触发率 × 触发倍率

AST 目标函数

系统支持自定义目标函数,使用 AST 表达式语法。

预定义宏

  • DPS:or(攻速,1+技能速度)*or(多重,1)*伤害
  • 总伤:max(1,召唤物攻击次数)*伤害
  • 暴击伤害:伤害.暴击
  • 每神智DPH:1/神智消耗*伤害
  • 每神智DPS:or(攻速,1+技能速度)/神智消耗*伤害
  • 范围收益:技能范围*伤害
  • 耐久收益:技能耐久*伤害
  • 效益收益:技能效益*伤害

表达式示例

// 基础伤害
"伤害"

// DPS
"DPS"

// 考虑技能效益和神智消耗
"技能效益*伤害/神智消耗"

// 技能 Q 的伤害
"Q::伤害"

// 考虑暴击和触发的期望伤害
"伤害.N * 暴击伤害.暴击 * (1 + 触发伤害)"

// 技能范围和效益的加权平均
"0.5*技能范围*伤害 + 0.5*技能效益*伤害"

使用示例

创建角色构建

import { CharBuild, LeveledChar, LeveledWeapon, LeveledMod, LeveledBuff } from "dna-builder-data"

const charBuild = new CharBuild({
    char: new LeveledChar("黎瑟", 80),
    melee: new LeveledWeapon("铸铁者"),
    ranged: new LeveledWeapon("烈焰孤沙"),
    charMods: [new LeveledMod(41324)],
    buffs: [new LeveledBuff("黎瑟E")],
    hpPercent: 1,
    resonanceGain: 0,
    baseName: "普通攻击",
    targetFunction: "DPS",
    enemyId: 130,
    enemyLevel: 80,
    skillLevel: 10,
})

// 计算伤害
const damage = charBuild.calculate()

自定义目标函数

const charBuild = new CharBuild({...})

// 设置自定义目标函数
charBuild.targetFunction = "技能范围*伤害 + 技能效益*伤害/神智消耗"

// 验证表达式
const error = charBuild.validateAST(charBuild.targetFunction)
if (error) {
    console.error("表达式错误:", error)
} else {
    const result = charBuild.calculate()
    console.log("目标函数值:", result)
}

计算所有伤害

import { WeaponSkillType } from "./data-types"

// 计算所有技能的伤害
const skills = charBuild.charSkills
skills.forEach(skill => {
    const [attrs, damage] = charBuild.calculateByBasename(skill.名称)
    console.log(`${skill.名称}: ${damage.expectedDamage}`)
})

// 计算所有武器技能的伤害
const weaponSkills = charBuild.weaponSkills
weaponSkills.forEach(skill => {
    const [attrs, damage] = charBuild.calculateByBasename(skill.名称)
    console.log(`${skill.名称}: ${damage.expectedDamage}`)
})

运行测试

# 在本包目录下运行全部测试
pnpm test

# 运行特定测试文件
pnpm vitest run tests/CharBuild.test.ts

# 运行测试并生成覆盖率报告
pnpm run test:coverage

仓库根也可用 pnpm --filter dna-builder-data test 跑本包套件。

MCP 服务(npx 直连 stdio)

本包提供了可直接通过 npx 启动的 MCP stdio 服务器,包含两个核心能力:

  1. 本地数据查询:在 d/*.data.ts 中用 fuse.js 执行模糊搜索
  2. 在线数据查询:连接 GraphQL 后端查询实时密函(missionsIngame)

本地数据工具设计参考 Context7 的两步流程:

  1. resolve-data-module:先解析本地模块(返回 /local/<dataset>)
  2. query-data-module:再基于 moduleId 做单模块查询(支持 fields 字段白名单降噪)

密函查询为独立工具:

  1. query-missions:默认查询 missionsIngame(server: "cn")
  2. 返回结果将二维数组转换为结构化字段:角色 / 武器 / 魔之楔

发布后启动示例

npx -y dna-builder-data

配置 GraphQL 端点

默认端点:https://api.dna-builder.cn/graphql

可通过环境变量覆盖:

DNA_MCP_GRAPHQL_ENDPOINT=http://127.0.0.1:8887/graphql npx -y dna-builder-data

也可通过命令行参数覆盖:

npx -y dna-builder-data --graphql-endpoint http://127.0.0.1:8887/graphql

注意事项

  1. 等级系统:所有带等级的对象都使用 CommonLevelUp 数组计算属性倍率
  2. MOD 限制:MOD 有系列限制和极性限制,同一系列的 MOD 最多装备 1 个
  3. 属性上限:某些属性有上限(如技能效益上限 175%,技能范围上限 280%)
  4. AST 缓存:AST 解析结果会被缓存以提高性能
  5. 动态增益:支持带 code 属性的动态增益,可以在运行时修改属性

扩展指南

添加新数据类型

  1. 在 data-types.ts 中定义接口
  2. 在 d/ 目录下创建数据文件
  3. 在 index.ts 中导出

添加新等级对象

  1. 在 leveled/ 目录下创建新文件
  2. 实现 getLevelValue 方法使用 CommonLevelUp 计算属性
  3. 在 leveled/index.ts 中导出

添加新 AST 函数

  1. 在 ast.ts 中的 evaluateIdentity 函数中添加处理逻辑
  2. 在 CharBuild.macros 中添加宏定义(可选)

相关文档