D&D(龙与地下城)跑团辅助应用的核心目标不是替代DM与实体聚会,而是把角色卡维护、规则查询、掷骰结算、先攻追踪、法术检索这些打断沉浸感的后台操作收敛进单机可离线运行的移动端。React Native + Expo 启动,单向数据流,规则引擎与UI彻底分离,静态规则数据(SRD/5e API缓存)与动态角色数据(AsyncStorage/SQLite)分层存储,是这类项目落地最稳的结构。
一、总体分层架构
1. 表现层(screens / components):角色卡页、骰子页、先攻追踪页、法术书页、战役笔记页,React Navigation v5 的 Stack + Drawer 串联,FlatList 渲染长列表(法术/装备/历史),StyleSheet 中心化颜色与间距常量。
2. 状态层(Redux Toolkit / Context + useReducer):全局存掷骰模板、当前战役、主题、历史记录;角色实例用规范化结构,避免深层嵌套不可更新。
3. 规则引擎层(pure functions / lib/character.ts 类):只算不渲染,输入基础值返回调整值、豁免、技能加值、先攻、被动感知,便于单测与换规则书(5e / Pathfinder)。
4. 静态数据层(data/*.json 或 dnd5eapi.co 缓存):种族、职业、背景、法术、怪物、专长、装备,只读,首次拉取后落本地。
5. 持久层(AsyncStorage / Expo SQLite / Realm):角色卡JSON、掷骰模板、战役笔记、离线缓存;AsyncStorage 存小KV,SQLite 存掷骰历史与多角色关系更合适。
二、角色卡数据模型(ICharacter 结构要点)
基础存盘字段:playerName、name、race(9核心种族)、class(12核心职业)、background、level(1-20)、experience、alignment、proficiency、inspiration、abilities(STR/DEX/CON/INT/WIS/CHA 六维原始值)、skills(18项技能熟练标记)、savingThrows、equipment[]、spellsKnown[]、spellSlots、hitPoints/curHP/maxHP、armorClass、initiative、gold、notes。
衍生值不落盘,由 Character 类 getter 实时算:
• 属性调整值:Math.floor((score - 10) / 2)
• 熟练加值:Math.floor((level - 1) / 4) + 2(1级+2,5级+3,17级+6)
- 技能加值 = 对应属性调整值 + (熟练? 熟练加值 : 0)
• 豁免同上逻辑
• 先攻 = DEX调整值 + d20
• 被动感知 = 10 + 察觉技能加值
修改STR从15→16,触发重算链:调整值+2→+3,运动技能、力量豁免、近战命中全部联动刷新,UI订阅状态自动更新。
三、骰子模块实现(通用表达式解析)
核心函数接收 "2d6+3"、"1d20+DEX+PB" 这类 notation:
function rollDie(sides){ return Math.floor(Math.random()*sides)+1; }
function parseNotation(expr, ctx){
// ctx = { STR_MOD, DEX_MOD, PB, ... }
// 拆分数量d面数/加值/属性令牌,累加随机与修正
}
function rollNotation(expr, ctx){
const {count,sides,flat} = tokenize(expr);
let total = flat;
for(let i=0;i<count;i++) total += rollDie(sides);
return total;
}
支持 d4~d100、优势/劣势(骰两次取高/低)、暴击翻倍、熟练与属性令牌替换。结果写历史栈,DM 可存“哥布林攻击模板”“火球伤害模板”一键连掷,Modalize 弹窗管理模板,落 AsyncStorage 键 dice_templates。
四、先攻追踪与战斗模块
Encounter 结构:participants[{id,name,initiative,type:'pc'|'npc',hp,ac,conditions[]}],按 initiative 降序排回合队列。Round 推进时标记当前行动者,支持插入新参与者、延时、倒地/死亡状态、条件计时(昏迷2回合等)。战斗日志 append 进战役笔记,撤销靠不可变更新快照。
攻击结算流程:选攻击者→选武器→选目标→attackBonus = abilityMod + PB(if proficient) + magicMod→d20+bonus vs 目标 AC→命中后 damage = parseNotation(weapon.damage, ctx)→暴击翻倍→扣HP→反馈面板显示命中/闪避/重击。
五、法术书与规则查询
首次启动拉 https://www.dnd5eapi.co/api/2014/spells 索引,按需拉详情缓存进 SQLite;法术书页存角色已知/准备法术 index 列表,autocomplete-input 检索,collapsible 展示施法时间/范围/成分/描述/升环效果。离线优先读缓存,无网进详情提示未下载。
六、持久化与导出
角色卡 JSON 序列化 characters/{guid}.json 概念映射到 AsyncStorage 键或 SQLite 行;提供导出字符串/导入还原,换机不断档。多角色切换走 Redux 当前 activeCharacterId,落 app_state 键。
七、目录范式参考
App.js
/navigation (Stack+Drawer)
/screens (CharacterSheet / DiceRoller / InitiativeTracker / SpellBook / CampaignNotes)
/components (StatRow / SkillList / HpBar / DiceHistoryModal)
/lib (character.ts / dice.ts / rules5e.ts)
/store (redux slices: character / dice / campaign)
/data (races.json / classes.json / spells_cache)
/storage (asyncStorage wrappers / sqlite helper)
/constants (colors.ts / layout.ts)
Hooks(useState/useEffect/useCallback)写组件,纯函数写规则,Redux 管跨页状态,AsyncStorage/SQLite 管落盘,React Navigation 管路由——改规则只动 /lib,改界面只动 /screens,改存档只动 /storage,三层互不污染。
D&D 移动端辅助器的本质是把 SRD 规则写成纯函数、把角色状态写成可序列化文档、把掷骰写成可解析表达式,RN 只负责把这三件事在离线环境下跑顺。
React Native构建D&D龙与地下城角色扮演应用:分层架构与角色卡骰子战斗模块实现
来源:
作者:
点击:

