AI地下城主引擎——基于2024版D&D 5e规则,三层架构(dnd-engine + dnd-api + dnd-dm Skill),支持模块化运行、战斗裁决、角色创建与存档管理
基于 2024版 D&D 5e 规则 的 AI 地下城主系统。纯对话交互,无需专用客户端,任何 IM 软件即可运行。本 Skill 将 DM(地下城主)角色交给 AI,严格按照模组剧本和规则书推进游戏。
城主人格:明萨拉·班瑞(Minthara Baenre)——守序邪恶卓尔圣武士,前魔索布莱城贵族。语气霸道、果断、直接,但绝不放水作弊。详见 SOUL.md 和 IDENTITY.md。
text
┌─────────────────────────────────────────────┐
│ LLM 层:dnd-dm Skill (OpenClaw) │
│ 叙事生成、NPC 对话、场景描述、行为红线 │
│ ← prompt 驱动,保持 LLM 核心优势 │
├─────────────────────────────────────────────┤
│ API 层:dnd-api (FastAPI,端口自动检测) │
│ 30 个 HTTP 端点 + CLI 命令行工具 │
│ ← 任何平台(Discord/Foundry/Web)均可调用 │
├─────────────────────────────────────────────┤
│ 引擎层:dnd-engine(已内置) │
│ 骰子、战斗、存档、世界状态、模组缓存、SRD 搜索 │
│ ← 纯 Python,零 LLM 依赖,220 项测试覆盖 │
└─────────────────────────────────────────────┘
核心原则:上层依赖下层,下层不依赖上层。LLM 层只管叙事 + 调用引擎函数,不自行计算或拼数据。
模式(mode):系统支持两种运行模式: adventurer(默认)和 gm_assist。
adventurer:引擎按规则自动执行掷骰与结算,玩家不干预骰面结果。gm_assist:城主辅助模式,允许通过 MCP 工具预设「手动骰」,用于演示、复现或争议裁定。选择时机:在新游戏启动时选择(例: start_new_game(mode="gm_assist"))。
MCP 工具: start_new_game(mode)、 get_mode()、 set_manual_roll(name, value)、 list_manual_rolls()、 clear_manual_rolls()。
行为: gm_assist 且存在手动骰时,掷骰函数优先使用手动骰并记录使用历史;否则正常随机掷骰。
透明性要求:所有手动骰操作必须在会话内记录并可查询,避免秘密修改。
将 dnd-dm-skill-x.x.x.zip 解压到空目录即可使用。
text
your-workspace/
├── SKILL.md / _meta.json
├── references/ ← 核心规则文件(供 LLM 读取)
│ └── party-sheet.html ← 角色卡网页(双击打开)
├── dnd-engine/ ← 引擎源码(已内置,无需安装)
├── items/ ← 物品模板
└── DND Lens(可选子技能)
├── data/ ← 知识资产(世界卡 / 模组范式 / 映射字典)
├── scripts/ ← lens_rag.py(BM25 中文检索)+ lens_pipeline.py
├── world-lore/ ← 功能一:世界观 / 编年史检索
├── module-forge/ ← 功能二:按需求生成模组
└── echo-map/ ← 功能三:真实经历 → DND 映射
⚠️ 需用户自行准备:规则书和模组因版权原因无法随 Skill 分发。
将 2024版三宝书放入 rules/ 目录,模组文件放入 modules/ 目录。
在对话中回复 /verify,Agent 自动校验环境。通过后即可开始游戏。
首次使用时 LLM 会自动加载引擎: import sys; sys.path.insert(0, "dnd-engine")
bash
dnd-check --actor 老白 --skill 潜行 --dc 15 # Windows 用 dnd-check.cmd
dnd-check --actor 老白 --ac 16 # 攻击检定(走 AC)
自动读 live_party.json、组装加值、投骰,输出即为可直接贴给玩家的明细。
实测 ≈0.13 秒/次(含 Python 启动)。 不要为了调引擎去写临时 Python 脚本。
参数与“角色卡缺技能信息怎么办”见 references/DM_RULES.md 规则 1.2.1。
技能作用配合方式**dnd-dm(本技能)城主行为规则 + 三层架构调度主技能,定义 DM 如何行动dnd5e-srdSRD 5.2.1 RAG 检索战时快速查规则,通过 Python 脚本搜索+展开引用dnd-dm-skill:world-lore功能一·世界观对话 + 费伦编年史RAG 检索 world_cards.jsonl,托尔金式叙述dnd-dm-skill:module-forge功能二·按需求生成模组选范式 + DMG 标准 CR 平衡,输出模组骨架 JSONdnd-dm-skill:echo-map**功能三·真实经历→DND 映射脱敏 + 按 mapping_dict 映射,输出 anonymized 模组
宿主于本技能下的三件套,共享
scripts/lens_rag.py(BM25 中文检索)与data/知识资产。三者可独立调用,也可串联:真实经历 → echo-map 映射 → module-forge 做 CR 平衡 → world-lore 检索设定锚点。
子技能触发场景数据资产入口脚本world-lore「深水城历史是怎样的?」「给我讲一段阴影帝国编年史」data/world_cards.jsonl(360 张知识卡)world-lore/scripts/lore_query.pymodule-forge「4 人 5 级、玩一晚的都市寻宝模组」data/module_paradigms.json(59 篇范式)+ DMG 表module-forge/scripts/module_forge.pyecho-map「把我和甲方的扯皮改成冒险」data/mapping_dict.json(8 槽位 + 脱敏池)echo-map/scripts/echo_map.py
一键串联:经历 → 映射 → 平衡 → 背景,运行
python scripts/lens_pipeline.py --story 经历.txt --names "张三" --places "上海" --players 4 --level 5 --duration medium(详见脚本头部说明)。
调用方式( 相对本技能目录,用当前环境的 Python 运行):
bash
# 功能一:世界观 / 编年史检索
python scripts/lens_rag.py "深水城 历史" --top-k 6
# 功能二:按需求生成模组(带 CR 平衡)
python module-forge/scripts/module_forge.py --players 4 --level 5 --duration medium --type 都市寻宝
# 功能三:真实经历脱敏 + 映射
python echo-map/scripts/echo_map.py anonymize --names "张三" --places "上海"
数据流:各子技能脚本通过
sys.path复用scripts/lens_rag.py;数据目录默认data/,可用环境变量DND_LENS_DATA覆盖。
层级名称技术栈核心职责LLM 层dnd-dm SkillMarkdown + prompt叙事、NPC、检定发起、行为红线——不可代码化API 层dnd-apiFastAPI(端口自动检测)30 个 HTTP 端点 + CLI 命令行工具引擎层dnd-enginepip 包, Python 3.10+骰子/战斗/存档/世界状态/模组缓存/判定/叙事后端——纯函数
新增/修改功能时按 DM_DEV_GUIDE.md 开发规则9 做三层分析。
问题:LLM 直接决定「要不要检定 / 投什么技能 / DC 多少」时,同一条输入会给出不同答案,且无法审计。
做法:把判定拆成「批量原子提问 → 类型化回答 → 代码组合成 DecisionPacket → 引擎结算」。
Choice(选一个)、 Score(打 0–1 分)、 Noul(是/否)。0.60;低于门限的字段回退本地依据并记入 low_confidence_fields。contract_error:...),不会让游戏卡住。check_rules.json 映射始终可用, 不依赖任何外部模型。问题:长模组(40 万 token 级)每轮整份注入,导致成本高、首字慢、且剧情状态无处落地。
做法:四级注入 + 确定性节点图 + 一轮一次调用。
L0 骨架 ≈ 300 tok / L1 当前场景 2–4k / L2 邻域摘要 ≈ 600 / L3 按需全文。实测每轮注入 52.9k → 6.1k tok。module_plot.json(节点+边)+ plot_state.json(当前节点/已访问/事件)。推进由代码裁决,不由模型自由发挥。delta 一次返回,实测 3 次 → 1 次。system(契约)/ user-stable(队伍+本章索引)/ user-volatile(本轮变化)。实测 88% 输入命中缓存。narration 字段,实测首字 ≈2.6 s 出现。dnd_engine.combat.checks 结构化返回,LLM 仅展示结果dnd_engine.save.templates 工厂生成,LLM 不自拼 JSON<!-- layer: N --> 标记)multiattack 真打 N 次(上限 4 次)combat_state.jsonPOST /api/combat/resolve-round 合并命中+伤害+状态更新_scene_cache_*.json 追踪房间checks.py 的 detail_lines 数组,格式由代码保证party-sheet.html 双击即可查看队伍状态roll_stat() 由引擎层执行live_party.json 和角色卡dnd_engine.save.io: write_save() / load_save() / list_saves()scene_cache.py)make_character_template() / make_save_template() / make_quest_template()命令功能dnd-engine初始化工作目录(创建 saves/ rules/ modules/ live_party.json)dnd-engine verify校验环境(直接调用 dnd_engine.verify.verify_environment())dnd-engine server --port auto启动 API 服务(自动检测端口)
骰子:
接口功能POST /api/roll骰子表达式求值
战斗:
接口功能POST /api/combat/check-hit命中判定POST /api/combat/calc-damage伤害结算POST /api/combat/skill-check技能检定(完整公式)POST /api/combat/state/*战斗状态 CRUD(6 端点)POST /api/combat/resolve-round一键命中+伤害+状态更新POST /api/combat/roll-initiative一键掷先攻+排序
队伍:
接口功能POST /api/party/calc-combat-xpXP 计算POST /api/party/rest短休/长休结算GET /api/party/character/{name}角色属性查询POST /api/party/level-up升级自动结算GET /api/party/live实时角色状态POST /api/party/live/rebuild从存档重建实时状态
存档:
接口功能GET /api/saves/list存档列表POST /api/saves/load读档POST /api/saves/write存档
SRD:
接口功能GET /api/srd/search?q=SRD 全文搜索POST /api/srd/expand展开上下文GET /api/srd/files查询 SRD 文件列表GET /api/srd/search-in-file在指定文件中搜索
系统:
接口功能GET /api/system/verify预飞校验:引用文件、引擎、权限POST /api/system/init自动创建工作目录GET /api/system/port查询当前 API 端口
世界状态:
接口功能GET /api/state/world世界状态
DM_RULES.md 中 26 条运行规则按 6 层组织,每条规则开头有 <!-- layer: N --> 标记。加载时按层优先级常驻:
层名称包含规则常驻时段0全局基石0(会话启动), 0a(模组选择), 0.5(微互动), 10(红线), 18(代码), 19(Token), 21(安装)整个会话1运行时交互1(检定), 1.5(叙事匹配), 2(场景空间), 3(推进), 4(支线), 17(不泄题), 20(回声)每次场景2展示模板2b(地图), 9(信息展示)展示信息时3战斗系统15(回合), 15b(装备)战斗回合4进度与状态5(经验), 7(锚点), 8(章节), 13(存档), 14(存档), 16(实时状态)存档/升级5模组控制12(构建), X(特殊)开新局/跨章
文件/目录说明references/14 个核心引用文件(规则、模板、开发指南、人格定义、角色卡模板)items/物品模板目录(3 个 .md)srd/SRD 5.2.1 检索资源(references + scripts)dnd-engine/src/dnd_engine/引擎层 Python 包(dice/combat/party/save/state/module/npc/runtime/context/judge/narrative/cli)dnd-check.py + .cmd / .sh一条命令完成一次检定(自己把包内引擎加进 sys.path,不依赖 PYTHONPATH;读 live_party.json、组装加值、投骰)data/[DND Lens] 共享知识资产: world_cards.jsonl(360 张知识卡)/ module_paradigms.json(59 篇范式)/ mapping_dict.json(8 映射槽位)scripts/lens_rag.py[DND Lens] BM25 中文检索引擎,RAG 底座,三子技能共用scripts/lens_pipeline.py[DND Lens] 联动流水线:经历 → echo-map → module-forge → world-lore 一站式(见脚本内 --help)world-lore/[DND Lens·功能一] 世界观对话 + 费伦编年史子技能module-forge/[DND Lens·功能二] 按需求生成模组(DMG 标准 CR 平衡)子技能echo-map/[DND Lens·功能三] 真实经历 → DND 映射(脱敏 + 字典规范化)子技能saves/[自动生成] 存档文件rules/[自行准备] 2024版三宝书modules/[自行准备] D&D 模组文件party-sheet.html角色卡网页(双击即看,从 live_party.json 读取)live_party.json[自动生成] 实时角色状态_api_port.txt[自动生成] API 运行端口_scene_cache_*.json[自动生成] 场景缓存reports/prefetch_cache.json[自动生成] 叙事预取缓存
版本 1.2.1 · 2026-09-25 · 合并发布:线上 1.2.0 的 DND Lens 三子技能(world-lore / module-forge / echo-map)+ 本地新一代引擎(类型化判定层 judge、叙事层 narrative:四级注入 52.9k→6.1k tok、一轮一次调用、prefix cache 命中 88%、流式首字 2.6s、防出戏守卫)· 严格按 2024版 D&D 5e 规则 · 220 项测试通过 · 支持 Windows / macOS / Linux