0x00 前言
最近在 hercules 入手了一个二次元的魔物图档包,里面有口袋妖怪、火影忍者、进击巨人、合金弹头、洛克人、拳皇等一堆乱七八糟的次元魔物:

现在就这个图档包讲解下怎么往 RO 中添加自定义魔物。
0x10 在服务端添加魔物设定
0x11 添加魔物设定
例如我希望添加口袋妖怪中的「皮卡丘」,首先要在魔物库 db/re/mob_db.yml 添加其设定:
- Id: 20172
AegisName: PIKACHU
Name: 皮卡丘
JapaneseName: 皮卡丘
Level: 5
Hp: 1000
Sp: 1000
BaseExp: 100
JobExp: 100
Attack: 10
Attack2: 30
Defense: 20
MagicDefense: 20
Str: 10
Agi: 20
Vit: 10
Int: 10
Dex: 10
Luk: 10
AttackRange: 2
SkillRange: 10
ChaseRange: 10
Size: Small
Race: Brute
Element: Neutral
ElementLevel: 1
WalkSpeed: 200
AttackDelay: 1564
AttackMotion: 864
DamageMotion: 576
Ai: 19
Modes:
Detector: true
Drops:
- Item: Glass_Bead
Rate: 5000
魔物的设定比较复杂,建议通过 SDE 去配置魔物参数会更有效率:

关于魔物的属性、掉落物等,根据自己喜好设定即可;唯独需要注意的只有两个地方:
AegisName: 必须和魔物的图档名一致Id: 必须在某个范围内,否则加载魔物数据时会报错:- 复兴前范围:
(1000, 3999)(不包括两端) - 复兴后范围:
(20020, 31999)(不包括两端)
- 复兴前范围:
这两个范围在 src/map/mob.cpp 中定义了:
#define MIN_MOB_DB 1000
#define MAX_MOB_DB 3999
#define MIN_MOB_DB2 20020
#define MAX_MOB_DB2 31999
官方都没有用完这两个范围,挑一些保留 ID 出来分配给自定义魔物就可以了。
当然如果你要加的魔物数量特别多,也可以扩展出一个范围,但是需要重新编译服务端:

0x12 添加魔物技能(可选)
在添加魔物基本设定后,可以在 db/re/mob_skill_db.txt 技能库为其添加技能:
20172,皮卡丘@十万伏特,chase,20,10,2000,0,0,yes,target,always,0,,,,,,,
20172,皮卡丘@电球,chase,84,10,2000,0,0,no,target,always,0,,,,,,,
20172,皮卡丘@百万伏特,angry,85,10,3000,0,0,no,target,always,0,,,,,,,
魔物技能库 mob_skill_db.txt 是目前少有的几个尚未 yml 格式化的数据库,因此配置起来比较晦涩,上述配置具体的含义在 mob_skill_db.txt 里面能查到,这里就不解读了。
为了高效配置魔物技能,建议使用 SDE :

0x13 在地图召唤自定义魔物
召唤魔物需要写 NPC 脚本,具体语法查 doc/script_commands.txt 即可。
这里提供一个最简单的 NPC 脚本,它表示在首都南门外任意坐标召唤我们添加的「皮卡丘」,这张地图最多召唤 50 只:
prt_fild08,0,0 monster 皮卡丘 20172,50
这样当我们进入游戏时,就能去首都南门外去找「皮卡丘」了。
0x20 在客户端添加魔物设定
参考《客户端目录结构及功能说明(2024 修订)》,魔物图档目录为 data/sprite/阁胶磐,在其中找到服务端 AegisName 设置的图档名 PIKACHU,确认是「皮卡丘」:

0x21 添加到魔物外观池
和《防具外观 ID 解读 - 头饰篇》类似,魔物也有外观池:
- 定义「魔物唯一代码」和「魔物 ID」的关系:
data/luafiles514/lua files/datainfo/npcidentity.lub - 定义「魔物唯一代码」和「魔物图档名称」的关系:
data/luafiles514/lua files/datainfo/jobname.lub
现在在 npcidentity.lub 添加一行 JT_POKEMON_PIKACHU = 20172,其中:
JT_POKEMON_PIKACHU: 就是「魔物唯一代码」,唯一的任意字符串20172: 就是前面服务端为魔物分配的 ID

然后在 jobname.lub 添加一行 [jobtbl.JT_POKEMON_PIKACHU] = "PIKACHU",其中:
JT_POKEMON_PIKACHU: 和npcidentity.lub定义的字符串保持一致PIKACHU: 就是在 GRF 中魔物的图档名称
注意,NPC 人物和 魔物 是共用一套外观池的。早期的时候,
npcidentity.lub把小于 1000 的图档 ID 预留给 NPC,大于 1000 的都是魔物。现在已经没有这个限制了。
0x22 为魔物某些动作添加效果音(可选)
例如我们希望「皮卡丘」被攻击时,会发出像老鼠一样的「吱」一声,应该怎么做呢?
首先,音效文件你需要自己准备,或者到 GRF 里面的 data/wav 下挑选也可以。
其次需要把「皮卡丘」的图档文件 PIKACHU.act 和 PIKACHU.spr 提取出来:

然后使用 Act Editor 等工具编辑 PIKACHU.act,选择状态 3 - Receiving Damage(受到伤害时):

接着选择这个状态中间的某一帧,譬如 2/4 frames,为这一帧添加声音: Frame sound -> Add new ... :

输入的音效名称 pikachuscream.wav ,确保这个文件在 data/wav 下存在即可:

0x30 验证效果
此时进入游戏,去首都南门外,就能遇见我们添加的「皮卡丘」了:

备用视频源:youtube
0x40 魔物图档映射
有时候我们没有魔物图档,但是又想添加自定义魔物,应该怎么做呢?
譬如我想添加「雷丘」,但是没有「雷丘」的图档。
首先还是要在魔物库 db/re/mob_db.yml 添加其设定:
- Id: 20173
AegisName: RAICHU
Name: 雷丘
JapaneseName: 雷丘
... ...
对魔物 ID 的范围要求还是一样的,但是因为不存在图档,AegisName 可以随意使用一个任意的唯一字符串。
随后直接编辑魔物外观的映射表 db/import/mob_avail.yml (如果文件不存在,新建即可),内容如下:
Header:
Type: MOB_AVAIL_DB
Version: 1
Body:
- Mob: RAICHU
Sprite: BONE_DETALE
- Mob: ...
Sprite: ...
其中 RAICHU 是「雷丘」的 AegisName, BONE_DETALE 是官方存在的图档的一只魔物,意为把 RAICHU 映射到 BONE_DETALE 图档:

此时配置就完成了,进入游戏使用命令 @monster 20173 召唤「雷丘」看一下效果:

魔物掉落、魔物技能等和正常魔物一样配置即可,客户端不用做任何配置。
0xF0 参考文档
最后提醒一下,如果检查任何地方的设定都没问题,但就是无法用 @monster 等命令把魔物召唤出来,有可能就是 ID 范围不对,换个 ID 可能就没问题了。