0x00 前言
符文石碑系统是 2023 年引入的新特性,由于其配置比较繁杂,本文梳理了各个配置模块及其影响的作用,方便大家以后食用。
首先是符文石碑的 UI 的启动,方法比较简单,只需要在 npc 脚本调用 runeui(); 函数即可:
prontera,161,192,4 script Runic Stone#eAcustom 10547,{
mes "[符文石碑系统]";
mes "UI 测试";
close2;
runeui();
end;
}

0x10 符文石碑机制说明
0x11 符文套装激活
在说明如何配置符文石碑之前,有必要先讲解一下符文石碑的机制。
在符文石碑 UI 第 1 个 Tab 页面中,左上角有 9 个按钮,每个按钮对应一个系列的符文石碑:

譬如点击 E17 按钮即列出了 EP17 系列下的所有符文石碑套装。
再选中任意一个套装,则看到需要收集一些材料才能激活套装。

激活套装后,在中间栏可以看到每个套装最多会有 6 个符文碎片槽(卡牌形状),最右边栏则写着激活多少个碎片会获得什么效果。
套装本身是没有任何效果的,根据套装的要求,激活对应的碎片越多,效果越好。
需要将套装【安装】到符文石碑上才能触发效果,同一时间只能安装一个套装。
0x12 符文碎片激活
在符文石碑 UI 第 2 个 Tab 页面中,左上角有 9 个按钮,每个按钮对应一个系列的符文碎片:

套装所需要的碎片必定可以在同系列中找到。
选中套装所需要的符文碎片,可以看到同样需要收集一些材料才能激活。
0x13 符文套装强化
回到 UI 第 1 个 Tab 页,选中任意一个已激活的套装,此时右上角可以切换到【强化】Tab:

同样凑齐材料即可强化套装的 BUFF。
0x14 机制小结
其实:
- 把
符文套装类比为卡册 - 把
符文碎片类比为卡牌
整个符文石碑机制就很好理解了:无非就是一个集卡小游戏。
0x20 配置文件一览
0x21 客户端配置文件
主要集中在 System\Rune 目录下:
itemDecom.lub: 定义卡片分解池,与服务端分解池关联runesystemid.lub: (1) 定义符文系列的标签按钮;(2) 与服务端 激活/强化 符文套装/碎片 的配置表关联runeSystem_table.lub: 定义符文套装/碎片 激活/强化 的素材池runeset_info.lub: 定义符文套装的设定runeset_desc.lub: 描述符文套装的设定rune_info.lub: 定义符文碎片的设定rune_desc.lub: 描述符文碎片的设定runesystemInfo.lub: 定义符文界面的默认标签按钮runesystem_f.lub: 符文系统的初始化函数,非必要不要动

0x22 服务端配置文件
主要集中在 db 目录下:
re/item_db_etc.yml: 设定每张卡片的分解类型,对应配置在客户端的itemDecom.lubrunedecomposition_db.yml: 设定卡片分解池,对应配置在客户端的itemDecom.lubrune_db.yml: 设定激活符文套装的配置表,对应配置在客户端的runeset_info.lub和runeSystem_table.lubrunebook_db.yml: 设定激活符文碎片的配置表,对应配置在客户端的rune_info.lub和runeSystem_table.lub

0x23 客户端图档
主要集中在 data/texture/蜡历牢磐其捞胶/runesystem 目录下:
tag: 符文套装/碎片系列的标签按钮的图档rune_icon: 符文碎片的 35x35 缩略图标rune: 符文碎片的 180x240 卡牌图片runeset: 符文套装中心的魔法阵图片

0x30 分解卡片
0x31 分解类型和数量
符文石碑有两个基础的关键道具:


这两个道具需要分解卡片获得,分解卡片在符文石碑 UI 第 3 个 Tab 页面中:

界面中有两个单选按钮,其实就是让玩家选择分解的类型:
| 按钮 | 类型 |
|---|---|
| 分解 1 个 | 分解单个 |
| 分解 10 个 | 分解批量 |
这两个按钮在客户端 System/Rune/itemDecom.lub 中配置:
itemDecomItemNum_tbl = { 1, 10 }
这里固定格式只能配置 2 个值,控制 UI 上 2 个按钮显示分解卡片的数量。
但实际上一次分解多少,不是由客户端控制的,即使在客户端修改了数量,最终还是取决于服务端。
在服务端 src/map/clif.cpp 的函数 clif_parse_decompo_rune 中,定义了:
// 对应客户端 itemDecom.lub 的
// itemDecomItemNum_tbl = { 1, x }
uint32 amount;
if(p->type == 1) { // 客户端选择了分解单个的按钮,p->type 总是 1
amount = 1; // 分解单个的数量
} else { // 客户端选择了分解批量的按钮,p->type 总是 2
amount = 10; // 分解批量的数量(客户端指定的批量值没有意义)
}
因此如果需要修改批量分解卡片的数量,必须要修改源码并重新编译。
其实两个按钮都可以设计为分解批量,只需要服务端配合修改即可,但是上限只有两个按钮。
0x32 分解池
那么分解卡片后可以得到什么呢?
在客户端 System/Rune/itemDecom.lub 中有一个分解池:
itemDecomType_tbl = {
[1] = {
{ 1001282, 1, 3, 100000 }
},
[2] = {
{ 1001282, 110, 330, 100000 },
{ 1001283, 1, 2, 25000 }
},
...
说明如下:
- 第一组分解设定的索引为
[1] - 第二组分解设定的索引为
[2] - … 以此类推
每一组都设定了:分解后多大概率可以获得多少个什么道具。
格式为: [索引index] = { { 道具ID, 最少数量, 最大数量, 获得概率/1000 }, ... }
例如 { 1001283, 1, 2, 25000 },表示有 25% 概率获得道具 1001283 完美的符文,最少得到 1 个、最多得到 2 个。
但是实际上,客户端的分解池 itemDecomType_tbl 仅供 UI 显示用,它无法控制分解后能得到什么,必须依赖服务端配置。
其实 itemDecomType_tbl 对应服务端的分解池 db/runedecomposition_db.yml:
Body:
- Id: 1
Materials:
# 不完美的符文
- Material: Imperfect_Rune
Amountmin: 1
Amountmax: 3
Chance: 100000
- Id: 2
Materials:
# 不完美的符文
- Material: Imperfect_Rune
Amountmin: 110
Amountmax: 330
Chance: 100000
# 完美的符文
- Material: Perfect_Rune
Amountmin: 1
Amountmax: 2
Chance: 25000
其中:
- 第一组分解设定的索引为
Id: 1,设定为100% 获得 1~3 个 不完美的符文 - 第二组分解设定的索引为
Id: 2,设定为100% 获得 110~330 个 不完美的符文和25% 获得 1~2 个 完美的符文 - … 以此类推
0x33 分解获得设定
以 31016 恶灵树装饰卡片 为例,先在客户端 System/Rune/itemDecom.lub 配置这张卡片的分解时、两种分解类型对应的分解池索引:
itemDecom_tbl = {
[31016] = { 1, 2 },
...
}
然后就可以在客户端 UI 的分解面板看到分解可获得的详情:

同样地,客户端无法控制如何分解,还需要在服务端的 db/re/item_db_*.yml 中新增 Decomposition 属性,例如:
- Id: 31016
AegisName: XM_Tree_Card
Name: 恶灵树装饰卡片
Type: Card
Decomposition:
Type1: 1
Type2: 2
其中:
Type1的数值表示:在单张分解31016卡片时,关联分解池中索引值为1的分解设定Type2的数值表示:在批量分解31016卡片时,关联分解池中索引值为2的分解设定
0x34 分解错误
如果服务端的 db/re/item_db_*.yml 道具没有配置 Decomposition 属性,此时分解会报错:

对应错误信息在
data/msgstringtable.csv设定:MSI_DECOM_TABLE_NOT_EXIT
0x40 系列的标签按钮
0x41 标签按钮配置
前面已经提到过,在 UI 左上角有 9 个标签按钮位置:

这 9 个标签按钮都在同一个地方配置,提供给 符文套装 和 符文碎片 两个 Tab 共用。
首先需要在 runesystemid.lub 的 RUNETAGIDTBL 定义每个标签按钮的 TagID 变量。
这里所定义的按钮变量、之后会在符文碎片配置
rune_*.lub和符文套装配置runeset_*.lub中被引用。
例如:
RUNETAGIDTBL = {
EVT = 500, -- 21周年
EPISODE17 = 17, -- EP17
EPISODE18 = 18, -- EP18
EPISODE19 = 19, -- EP19
COSTUME_Tower = 4000, -- 极限之塔
COSTUME_Game = 1001, -- 乐园
COSTUME_Bless = 1002, -- 祝福
COSTUME_UR = 1000, -- UR
}
注意 TagID 必须为数字,非数字会报错,它会关联图档位置 data/texture/蜡历牢磐其捞胶/runesystem/tag,图档名称格式为:
- 未点击:
bt_tag_${TagID}_0.bmp - 已点击:
bt_tag_${TagID}_1.bmp - 系列下任意石碑被安装后的左上角角标:
bt_tag_${TagID}_equip.bmp
同时 TagID 还会关联服务端 db/rune_db.yml 的系列 Id:

然后需要在 runeset_desc.lub 的 Runesystemtbl_tag 配置鼠标悬浮在标签按钮上时的提示文本:
Runesystemtbl_tag = {
[RUNETAGIDTBL.EVT] = "EVT",
[RUNETAGIDTBL.EPISODE17] = "EP17",
[RUNETAGIDTBL.EPISODE18] = "EP18",
[RUNETAGIDTBL.EPISODE19] = "EP19",
[RUNETAGIDTBL.COSTUME_Tower] = "极限之塔",
[RUNETAGIDTBL.COSTUME_Game] = "乐园",
[RUNETAGIDTBL.COSTUME_Bless] = "祝福",
[RUNETAGIDTBL.COSTUME_UR] = "UR",
}

0x42 默认按钮设定
在 runesystemInfo.lub 仅有的作用是设定初始打开 UI 时、默认选中哪个标签按钮,例如这里选中了 EVT:
dofile("System\\Rune\\runesystemid.lub")
GetDefultTag = function()
return RUNETAGIDTBL.EVT
end
0x43 标签按钮顺序
按钮顺序既不是定义在 RUNETAGIDTBL 或 Runesystemtbl_tag 的顺序、也不是 TagID 的数值顺序。
官方提供的 lua 代码中,在 runesystem_f.lub 中有这段加载标签按钮的代码:
for TagID,TagData in pairs(Runesystemtbl_tag) do
result = AddTag(TagID, TagData)
if not result then
return false, msg
end
end
它使用 pairs(Runesystemtbl_tag) 迭代,而 Runesystemtbl_tag 是字典,顺序是 Hash 顺序(固定的随机顺序),所以 UI 的顺序与人类的直觉不一样,
为了解决顺序问题,可以再定义一个数组 ORDER_RUNETAGIDTBL 设定 TagID 的顺序 :
ORDER_RUNETAGIDTBL = {
RUNETAGIDTBL.EVT, -- 21周年
RUNETAGIDTBL.EPISODE17, -- EP17
RUNETAGIDTBL.EPISODE18, -- EP18
RUNETAGIDTBL.EPISODE19, -- EP19
RUNETAGIDTBL.COSTUME_Tower, -- 极限之塔
RUNETAGIDTBL.COSTUME_Game, -- 乐园
RUNETAGIDTBL.COSTUME_Bless, -- 祝福
RUNETAGIDTBL.COSTUME_UR, -- UR
}
然后修改加载标签按钮的代码,使其按照 ORDER_RUNETAGIDTBL 的顺序依次加载:
for _, TagID in ipairs(ORDER_RUNETAGIDTBL) do
local TagData = Runesystemtbl_tag[TagID]
if TagData then
result = AddTag(TagID, TagData)
if not result then
return false, msg
end
end
end

0x44 标签按钮 BUG
特别需要注意的是:
虽然 UI 的标签按钮栏的两边有 < 和 > 两个平移滚动按钮,似乎支持配置更多的按钮,但事实上,超过 9 个按钮会有错位 BUG。
例如这里设置 17 个按钮:
RUNETAGIDTBL = {
EVT = 500, -- 21周年
EPISODE17 = 17, -- EP17
EPISODE18 = 18, -- EP18
EPISODE19 = 19, -- EP19
COSTUME_Tower = 4000, -- 极限之塔
COSTUME_Game = 1001, -- 乐园
COSTUME_Bless = 1002, -- 祝福
COSTUME_UR = 1000, -- UR
JSXL = 7, -- 剑士
MFSXL = 9, -- 魔法师
GJSXL = 1, -- 弓箭手
FSXL = 2, -- 服侍
SRXL = 4, -- 商人
DZXL = 8, -- 盗贼
QSXL = 3, -- 神枪手
RZXL = 5, -- 忍者
LMXL = 6, -- 灵媒
}
此时点击 > 后只有按钮本身右移了,但按钮对应的 套装/碎片 数据区域并未同步移动。
导致无论配置了多少按钮,始终只能选中前 9 个按钮的套装/碎片:

这种问题的根本原因在于 exe 内部所设计的 UI 控件本身只支持最多处理 9 个按钮,
即使 Lua 脚本可以配置更多按钮,UI 控件却无法正确处理,只能等官方下个版本修复。
0x50 激活/强化素材池
在客户端的 runeSystem_table.lub 中,定义了符文套装/碎片 激活/强化 的素材池。
素材池和分解池的作用都是类似的,它使得一些复杂的素材组可以通过索引的形式被复用起来,简化配置。
素材池 RuneTable_itemList 参考的配置项如下:
RuneTable_itemList = {
[1] = {
{ 25669, 75 },
{ 25723, 35 },
{ 25668, 5 },
{ 1001282, 150 },
{ 1001283, 1 }
},
[2] = {
{ 1000103, 1350 },
{ 1001282, 100 },
{ 1001283, 1 }
},
...
其格式很简单:
[索引index] = {
{ 道具id 1, 道具数量 1 },
{ 道具id 2, 道具数量 2 },
{ 道具id 3, 道具数量 3 },
}
每个索引都定义了一组素材,这组素材可被指定于任意 符文套装/碎片 的 激活/强化。
目前只有 3 种使用情况:
- 在
rune_info.lub符文碎片的 激活 索引:Rune_ActiveList - 在
runeset_info.lub符文套装的 激活 索引:RuneSetActiveList - 在
runeset_info.lub符文套装的 强化 索引:RuneSet_UpGradeList
0x60 符文碎片激活
0x61 客户端配置
主要是 rune_info.lub 的 Runetbl_info 表:
Runetbl_info = {
[RUNETAGIDTBL.EVT] = {
[RUNEIDTBL.Rp_21th_Poring] = { Rune_Res = "Rp_21th_Poring", Rune_ActiveList = 76 },
[RUNEIDTBL.Rp_21th_Lunatic] = { Rune_Res = "Rp_21th_Lunatic", Rune_ActiveList = 77 },
[RUNEIDTBL.Rp_21th_Fabre] = { Rune_Res = "Rp_21th_Fabre", Rune_ActiveList = 78 },
[RUNEIDTBL.Rp_21th_Food] = { Rune_Res = "Rp_21th_Food", Rune_ActiveList = 79 }
},
[RUNETAGIDTBL.EPISODE17] = {
[RUNEIDTBL.Rp_Ep17_Melee] = { Rune_Res = "Rp_Ep17_Melee", Rune_ActiveList = 14 },
[RUNEIDTBL.Rp_Ep17_Range] = { Rune_Res = "Rp_Ep17_Range", Rune_ActiveList = 15 },
...
},
...
不难发现,[RUNETAGIDTBL.*] 被用于分组,它同时也是在 runesystemid.lub 中定义的标签按钮 TagID,换言之 符文碎片 是按 TagID 为系列定义的。
以系列 [RUNETAGIDTBL.EVT] 为例,其下面每一行都是定义了一个符文碎片,如:
[RUNEIDTBL.Rp_21th_Poring] = { Rune_Res = "Rp_21th_Poring", Rune_ActiveList = 76 },
[RUNEIDTBL.Rp_21th_Lunatic] = { Rune_Res = "Rp_21th_Lunatic", Rune_ActiveList = 77 },
...
其中:
RUNEIDTBL.*是符文碎片的名称,也是关联在runesystemid.lub的RUNEIDTBL表所定义的变量,该变量用于关联服务端对应符文碎片的激活配置表Rune_ActiveList关联在runeSystem_table.lub中设定的素材池索引,用于 UI 显示激活这个碎片需要收集哪些的素材Rune_Res是该符文碎片的图档名称,缺失会闪退:- 左侧为 35x35 的小图档,位置在:
data/texture/蜡历牢磐其捞胶/runesystem/rune_icon - 中间为 180x240 的大图档,位置在:
data/texture/蜡历牢磐其捞胶/runesystem/rune
- 左侧为 35x35 的小图档,位置在:

rune_desc.lub 是与 rune_info.lub 配套的描述表,格式基本一致:
Runetbl_desc = {
[RUNETAGIDTBL.EVT] = {
[RUNEIDTBL.Rp_21th_Poring] = { Rune_DisplayName = "夜市波利" },
[RUNEIDTBL.Rp_21th_Lunatic] = { Rune_DisplayName = "夜市疯兔" },
[RUNEIDTBL.Rp_21th_Fabre] = { Rune_DisplayName = "夜市绿棉虫" },
[RUNEIDTBL.Rp_21th_Food] = { Rune_DisplayName = "夜市食物" }
},
[RUNETAGIDTBL.EPISODE17] = {
[RUNEIDTBL.Rp_Ep17_Melee] = { Rune_DisplayName = "可疑配件" },
[RUNEIDTBL.Rp_Ep17_Range] = { Rune_DisplayName = "可疑配件(远距离)" },
...
},
...
其中追加的额外属性 Rune_DisplayName 就是在 UI 上显示符文碎片的名称:

0x62 服务端配置
其实客户端的所有配置,都是为了在 UI 上展示而服务。
真正决定某个符文碎片应该用什么素材激活,只有关联到服务端的配置表才能控制它。
前面说过,每一个符文碎片的名称 RUNEIDTBL.* 在 runesystemid.lub 的 RUNEIDTBL 表中都定义了 id:
RUNEIDTBL = {
Rp_21th_Poring = 1263031,
Rp_21th_Lunatic = 1263032,
Rp_21th_Fabre = 1263033,
Rp_21th_Food = 1263034,
Rp_Ep17_Melee = 1263000,
Rp_Ep17_Range = 1263001,
...
}
而每一个 id 都可以在服务端的 db/runebook_db.yml 表中找到对应的激活配置表,
如符文碎片 Rp_21th_Poring 的 id 是 1263031:
- Id: 1263031
Name: Rp_21th_Poring
Materials:
- Material: Jellopy
Amount: 100
- Material: Sticky_Mucus
Amount: 35
- Material: Apple
Amount: 5
- Material: Unripe_Apple
Amount: 3
- Material: Poring_Card
Amount: 3

需要提醒的是,服务端的激活配置表,应该要与这个符文碎片的 Rune_ActiveList 所指定的素材池一致,
如这个符文碎片 Rp_21th_Poring 的素材池索引是 [76]:
RuneTable_itemList = {
...
[76] = {
{ 909, 100 },
{ 938, 35 },
{ 512, 5 },
{ 619, 3 },
{ 4001, 3 }
},
...
如果客户端的素材池与服务端的激活配置表不一致,以服务端为准。
但若如果服务端的 db/runebook_db.yml 缺失对应 id 的激活配置表,就会报错:

对应错误信息在
data/msgstringtable.csv设定:MSI_RUNESYSTEM_INVALID_OWNER
0x70 符文套装激活
0x71 客户端配置
类似符文碎片,符文套装主要是 runeset_info.lub 的 RuneSettbl_info 表:
Runetbl_info = {
[RUNETAGIDTBL.EVT] = {
[RUNESETIDTBL.Rt_21th_Event] = {
RuneSetRes = "Rt_21th_Event",
RuneSetActiveList = 75,
RuneSet_SlotList = {
RUNEIDTBL.Rp_21th_Poring,
RUNEIDTBL.Rp_21th_Lunatic,
RUNEIDTBL.Rp_21th_Fabre,
0,
0,
RUNEIDTBL.Rp_21th_Food
},
RuneSet_UpGradeList = { 80, 81, 82, 83, 84, 84, 86, 87, 88, 89, 90, 91, 92, 92, 94 },
RuneSet_UpGrade_Percentage_table = 1,
RuneSet_UpGrade_Percentage_table_Fail = 1
}
},
[RUNETAGIDTBL.EPISODE17] = {
...
},
...
不难发现,套装的配置还是以 [RUNETAGIDTBL.*] 分组,它是在 runesystemid.lub 中定义的标签按钮 TagID,换言之 符文套装 也是按 TagID 为系列定义的。
以 [RUNETAGIDTBL.EVT] 为例,这个系列只有一个符文套装:
[RUNESETIDTBL.Rt_21th_Event] = {
RuneSetRes = "Rt_21th_Event",
RuneSetActiveList = 75,
RuneSet_SlotList = {
RUNEIDTBL.Rp_21th_Poring,
RUNEIDTBL.Rp_21th_Lunatic,
RUNEIDTBL.Rp_21th_Fabre,
0,
0,
RUNEIDTBL.Rp_21th_Food
},
RuneSet_UpGradeList = { 80, 81, 82, 83, 84, 84, 86, 87, 88, 89, 90, 91, 92, 92, 94 },
RuneSet_UpGrade_Percentage_table = 1,
RuneSet_UpGrade_Percentage_table_Fail = 1
}
符文套装的配置项其实和符文碎片比较相似:
RUNETAGIDTBL.*关联在runesystemid.lub的RUNETAGIDTBL表所定义的变量,该变量用于关联服务端对应符文套装的激活配置表RuneSetRes是该符文套装的图档名称,位置在:data/texture/蜡历牢磐其捞胶/runesystem/runeset(缺失不会闪退)RuneSetActiveList关联在runeSystem_table.lub中设定的素材池索引,用于 UI 显示激活这个套装需要收集哪些的素材RuneSet_SlotList这个套装拥有的碎片的名称列表,在 UI 槽位中,按从上到下、从左到右的顺序依次排列(0 表示该槽位没有符文碎片)
RuneSet_UpGrade *是强化相关的配置项,留到下一节说明

runeset_desc.lub 是与 runeset_info.lub 配套的描述表,格式基本一致:
Runetbl_desc = {
[RUNESETIDTBL.Rt_21th_Event] = {
RuneSetDisplayName = "祝贺21周年",
RuneSetDescription = {
[2] = {
"强化每 +3,",
"ATK + 1, MATK + 1。"
},
[3] = {
"使用魔物面包的 HP 恢复量 +100%,",
"使用波利康普茶的 HP 恢复量 +100%。",
"(此道具效果于活动结束后移除),"
},
[4] = {
"追加 ATK + 10, MATK + 10。",
"─────────────",
"全碎片启动时(无须套用),",
"强化+15时,道具掉落率+3%"
}
}
}
[RUNETAGIDTBL.EPISODE17] = {
...
},
...
其中追加的额外属性:
RuneSetDisplayName就是在 UI 上显示符文套装的名称RuneSetDescription描述激活[x]个符文碎片时套装可以获得的效果

0x72 服务端配置
类似符文碎片,真正决定了某个符文套装应该用什么素材激活的,只有是服务端所关联的配置表。
这里也是一样的关联点:每一个 RUNETAGIDTBL.* 符文套装名称在 runesystemid.lub 的 RUNETAGIDTBL 表中都定义了 id:
RUNETAGIDTBL = {
Rt_21th_Event = 1260013,
Rt_Ep17_Doubt = 1260000,
Rt_Ep17_Auto = 1260001,
...
}
而每一个 id 都可以在服务端的 db/rune_db.yml 表中找到对应的激活/强化配置表,
如符文套装 Rt_21th_Event 的 id 是 1260013:
- Id: 500
Name: EVT
Set:
- Id: 1260013
Name: Rt_21th_Event
Books:
- Slot: 0
Name: Rp_21th_Poring
- Slot: 1
Name: Rp_21th_Lunatic
- Slot: 2
Name: Rp_21th_Fabre
- Slot: 5
Name: Rp_21th_Food
Activation:
- Material: Imperfect_Rune
Amount: 21
Scripts:
- Amount: 2
Script: |
.@val = getupgrade_rune() / 3;
if(.@val > 0){
bonus bBaseAtk,.@val;
bonus bMatk,.@val;
}
- Amount: 3
Script: |
bonus2 bAddItemHealRate,1100011,100;
bonus2 bAddItemHealRate,1100010,100;
- Amount: 4
Script: |
bonus bBaseAtk,10;
bonus bMatk,10;
...
...
关键属性说明如下:
Books: 所包含的符文碎片的槽位,对应客户端RuneSet_SlotListActivation: 激活符文套装的素材,对应客户端RuneSetActiveListScripts: 激活多个符文碎片时所获得的套装效果,对应客户端RuneSetDescription

需要提醒的是,若如果服务端的 db/rune_db.yml 缺失对应 id 的配置表,就会报错:

对应错误信息在
data/msgstringtable.csv设定:MSI_RUNESYSTEM_INVALID_ID
0x80 符文套装强化
前面在讲解符文套装的配置项时,留了个尾巴,强化相关的配置项 RuneSet_UpGrade * 被跳过了.
这是因为在讲解强化之前,首先得引入两个新的池子:
- 每级强化的【基础成功率池】
- 每级每次强化失败后的【失败增益率池】
0x81 基础成功率池
首先我们要知道,类似于装备的精炼系统,每个符文套装也是可以强化的,最大可以强化到 +15。
但是每级强化都是有成功率的,控制最低成功率的就是【基础成功率池】。
它配置在 runeset_info.lub 的 GradeTable 表:
GradeTable = {
[1] = { 10000, 10000, 10000, 9000, 9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000, 500, 100 },
[2] = { 8000, 8000, 8000, 7000, 7000, 6000, 5000, 4000, 3000, 2000, 1000, 500, 500, 250, 50 },
[3] = { 100000, 100000, 100000, 90000, 90000, 90000, 80000, 80000, 80000, 70000, 70000, 70000, 60000, 60000, 50000 },
[4] = { 15000, 15000, 15000, 13500, 13500, 12000, 10500, 9000, 7500, 6000, 4500, 3000, 1500, 750, 150 },
[5] = { 15000, 15000, 15000, 13500, 13500, 12000, 10500, 9000, 7500, 6000, 4500, 3000, 1500, 750, 150 },
[6] = { 12000, 12000, 12000, 10500, 10500, 9000, 7500, 6000, 4500, 3000, 1500, 750, 750, 370, 70 },
...
}
其格式也很简单:
[索引index] = { +1成功率/1000, +2成功率/1000, ..., +15成功率/1000 }
0x82 失败增益率池
但是游戏需要照顾到玩家强化失败的心情,因此每次强化失败时,都会提高一点成功率,这就是【失败增益率池】。
它配置在 runeset_info.lub 的 GradeTable_Fail 表:
GradeTable_Fail = {
[1] = { 4000, 4000, 4000, 3600, 3600, 3200, 2800, 2400, 2000, 1600, 1200, 800, 400, 200, 40 },
[2] = { 3000, 3000, 3000, 2500, 2500, 2000, 1500, 1000, 900, 800, 600, 500, 300, 100, 20 },
[3] = { 0, 0, 0, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100 },
[4] = { 9000, 9000, 9000, 8100, 8100, 7200, 6300, 5400, 4500, 3600, 2700, 1800, 900, 450, 90 },
[5] = { 9000, 9000, 9000, 8100, 8100, 7200, 6300, 5400, 4500, 3600, 2700, 1800, 900, 450, 90 },
[6] = { 7200, 7200, 7200, 6300, 6300, 5400, 4500, 3600, 2700, 1800, 900, 450, 450, 220, 40 },
...
}
它的格式也是显而易见的:
[索引index] = { +1增益率/1000, +2增益率/1000, ..., +15增益率/1000 }
0x83 客户端配置
有了池子的概念,这时我们再回到符文套装的三个强化项就不难理解了:
[RUNESETIDTBL.Rt_21th_Event] = {
...
RuneSet_UpGradeList = { 80, 81, 82, 83, 84, 84, 86, 87, 88, 89, 90, 91, 92, 92, 94 },
RuneSet_UpGrade_Percentage_table = 1,
RuneSet_UpGrade_Percentage_table_Fail = 1
}
RuneSet_UpGradeList关联runeSystem_table.lub表的素材池,用于显示这个石碑每一级强化需要收集哪些的素材RuneSet_UpGrade_Percentage_table关联基础成功率池GradeTable的索引,显示每一级强化的基础成功率RuneSet_UpGrade_Percentage_table_Fail关联强化失败增益率池GradeTable_Fail的索引,显示每一次强化失败后可以获得的失败增益率
举个例子,某个符文套装当前是 +5,正在尝试升 +6,引用的 基础成功率池 和 失败增益率池 索引都是 [1]。
通过查表可得:
- 基础成功率池索引为
[1]的+6成功率为8000 / 1000 = 8% - 失败增益率池索引为
[1]的+6增益率为3200 / 1000 = 3.2%
因此界面上展示的就是这两个数值:

- 当玩家强化 1 次失败后,当前成功率叠加为
8% + 3.2% x 1 = 11.2% - 当玩家强化 2 次失败后,当前成功率叠加为
8% + 3.2% x 2 = 14.4%

强化成功后,叠加的成功率会清零,回到下一级的基础成功率
0x84 服务端配置
在服务端中,强化配置表 与 激活配置表 都是通过 RUNETAGIDTBL 的 id 关联到 db/rune_db.yml,
这里还是以符文套装 Rt_21th_Event(id = 1260013)为例:
- Id: 500
Name: EVT
Set:
- Id: 1260013
Name: Rt_21th_Event
Books:
...
Activation:
...
Scripts:
...
Upgrades:
- Grade: 0
...
- Grade: 5
Chance: 9000
ChancePerFail: 3600
Materials:
- Material: Imperfect_Rune
Amount: 3
- Material: Clover
Amount: 6
- Material: Jellopy
Amount: 6
- Material: Feather
Amount: 6
- Material: Tree_Of_Archer_2
Amount: 2
- Grade: 6
Chance: 8000
ChancePerFail: 3200
Materials:
- Material: Imperfect_Rune
Amount: 4
- Material: Clover
Amount: 7
- Material: Jellopy
Amount: 7
- Material: Feather
Amount: 7
- Material: Tree_Of_Archer_2
Amount: 3
...
- Grade: 14
Upgrades 下面就是符文套装的强化配置,其中:
Grade: 强化等级,从 0 开始到 14,对应就是+1 ~ +15Chance: 强化到这个等级的 基础成功率,对应客户端GradeTableChancePerFail: 强化到这个等级的 失败增益率,对应客户端GradeTable_FailMaterials: 强化到这个等级的 素材列表,对应客户端RuneSet_UpGradeList
以上就是符文石碑系统的所有配置说明。