NPC 修改脚本教程

用 Windows 自带的记事本就能改:以 聚合功能.js 为真实案例,手把手教你「删除某个功能」,改完保存就生效

冒险岛私服 NPC 脚本 start() 菜单 + action() 分发 带前后对比图 新手友好

⚠ 前提提醒:先找到 NPC 对应的脚本文件

改之前要先知道「这个 NPC 的脚本在哪个文件」,方法如下:

  1. 设置 GM 权限:先把你的游戏角色设为 GM100 管理员权限。
  2. 在游戏里点 NPC:角色有 GM 权限后,点任意 NPC 功能,游戏聊天窗口就会显示该 NPC 的 ID 或名字(例如显示「聚合功能」)。
  3. 按名字找文件:打开服务端文件夹里的 scripts 文件夹,搜这个 ID 或显示的名字(例如搜「聚合功能」),就能直接定位到对应的 .js 脚本文件,打开它就能改了。

补充:游戏里点「拍卖」功能,本质上就是打开的「聚合功能」这个 NPC,所以聊天窗口显示的正是「聚合功能」。

一、实战演示:删除【自由市场】功能(#L0#)

我们就拿编号 0 的"自由市场"开刀,因为它最简单:菜单里一行 + action 里一个 case,非常适合当第一个练习。

第 1 步:在 start() 里删掉菜单按钮

用记事本打开 聚合功能.js(右键文件 → 打开方式 → 记事本,不用装任何软件),按 Ctrl+F 搜 #L0# 或"自由市场",找到第 150 行。下面是删除前的样子,红框那行就是要删的:

// start() 内,第 148–152 行附近
add += "#L3344##e#r测试专用#l\r\n\r\n";
add += "#L0##k#n#b" + 蓝箭头 + "自由市场#l";   // ← 这一行删除 / 注释掉
add += "   #L1#" + 蓝箭头 + "综合地图#l";
add += " #L2#" + 蓝箭头 + "副本大厅#l\r\n\r\n";

删掉(或注释)之后的样子:

// 方法A:直接删除整行
add += "#L3344##e#r测试专用#l\r\n\r\n";
add += "   #L1#" + 蓝箭头 + "综合地图#l";
add += " #L2#" + 蓝箭头 + "副本大厅#l\r\n\r\n";

// 方法B(推荐新手):用 // 注释,万一要恢复很方便
// add += "#L0##k#n#b" + 蓝箭头 + "自由市场#l";

第 2 步:在 action() 里删掉对应的 case

找到第 212–217 行的 case 0。这段是点了"自由市场"后实际执行的代码(传送到自由市场地图 910000000):

        case 0:
        {
            cm.dispose();
            cm.warp(910000000, 0);
            break;
        }

整段删除,或者被注释掉。删掉后,switch 会从 case 1 接着往下排,不影响别的功能。

删除前(有自由市场) #L0# 自由市场 #L1# 综合地图 #L2# 副本大厅 删除后(自由市场消失) #L1# 综合地图 #L2# 副本大厅 ✕ #L0 已移除 删除 case 0: { cm.warp(910000000,0) break; } ▲ 删除前:case 0 存在 // case 0 已删除 case 1: { cm.warp(910000023,0) break; ▲ 删除后:case 0 没了
图 2 · 前后对比:菜单按钮(上)和 case 代码(下)同步消失,编号 0 彻底退出舞台
完成判定:两处都处理完,再搜一遍 #L0# 和 case 0,确认文件里不再出现,就成功了。

二、进阶:删除"一整块"功能(以 GM 管理区为例)

有时候要删的不是单个,而是一组。原文件第 188–197 行有一整块"游戏 GM 功能管理":

add += "\r\n\r\n         以下是游戏GM功能管理 - 下拉还有\r\n";
add += "#L997#" + 熊3 + "活动事件管理#l";
add += "#L991#" + 熊3 + "泡点福利#l";
add += "#L992#" + 熊3 + "记录日记#l\r\n\r\n";
add += "#L990#" + 熊3 + "BOSS刷新时间#l";
add += "#L998#" + 熊3 + "清理次数#l";
add += "#L993#" + 熊3 + "积分查询#l\r\n\r\n";
add += "#L899#" + 熊3 + "修改副本次数#l";
add += "#L898#" + 熊3 + "怪物图鉴#l";
add += "   #L16#" + 熊3 + "查询掉落#l";

对应的 action() 里也有一窝 case(case 997/991/992/990/998/993/899/898/16 等)。整块删除的做法:

  1. 在 start() 里把这 10 行(含标题行)一次性选中删除 / 注释。
  2. 在 action() 里把对应的每个 case 整段(从 case XX: 到它下面那个 break; 以及闭合 })逐个删掉。
  3. 注意 case 992 和 case 991 在第 568–575 行是"合并写法"(一个 case 接另一个 case),删的时候要连同一起删干净,别留下半截 break; 悬空。
合并 case 的坑:原文件 568–575 行是 case 992: case 991: { ... } 这种"落空穿透"写法——两个编号共用一段代码。删的时候两条编号(991、992)都要从菜单里移除,否则玩家点了 991/992 会跑到别的 case 或 default。

三、标准操作流程(照着做不踩坑)

1
备份。先复制一份 聚合功能.js 改名为 聚合功能.js.bak。改崩了能秒还原。
2
定位菜单行。在 start() 里搜目标文字(如"自由市场")或 #L编号#,找到那一行 add += ...。
3
记下编号。记下按钮前面的数字(如 #L0# 的 0),这是去 action 找代码的钥匙。
4
删菜单。删除或 // 注释该行。
5
删 case。在 action() 里搜 case 编号:,把整段(到对应 break; 和 })删掉。
6
校验。全文件搜一次编号,确认菜单和 case 都没了,且大括号 {} 配对正常(没有多出来的 break; 或缺少 })。
7
保存就生效。改完直接按 Ctrl+S 保存(记事本里点 文件 → 保存 也一样),然后进游戏重新点一下 NPC,新菜单立刻就能看到——就这么简单。如果没变化,再重启一次服务端。
① 备份文件 ② 搜菜单行 ③ 记编号 ④ 删菜单 ⑤ 删 case ⑥ 校验 → ⑦ 保存重载 → 进游戏看效果(不对就还原备份)
图 4 · 标准删除流程:备份 → 定位 → 记编号 → 删两处 → 校验 → 重载

四、怎么让修改"生效" + 验证

最简单的方式(记住这条就够了):用记事本打开 聚合功能.js → 改完 → Ctrl+S 保存 → 进游戏重新点一下 NPC,就生效了。不需要任何编程软件,也不需要编译,Windows 自带的记事本就够了。
方式操作适用
脚本重载指令游戏里用 GM 指令 @reloadjs / 控制台 reload npc(不同端命令略有差异),或文件里第 199 行被注释掉的 cm.重载数据() 可启用。改完想立刻看效果
重启服务端关掉服务端再开。最稳妥,100% 重新加载所有脚本。不确定重载指令、或改了很多处
清缓存部分端会缓存脚本,必要时删 scripts 对应的 .class/.cache 缓存文件。改了但没变化
验证清单:① NPC 菜单里不再出现该功能;② 点原来的位置不会报错(因为按钮都没了,自然点不到);③ 其它功能正常。三关都过 = 删除成功。

五、新手最容易踩的 5 个坑

  1. 只删菜单不删 case:功能在菜单上看不见了,但 case 代码还在。一般无害(点不到),但属于"僵尸代码",积多了难维护。
  2. 只删 case 不删菜单:玩家还能看到按钮、还能点,结果触发到 default(第 597 行 "此功能未完成")或报错。这是最该避免的。
  3. 删 case 时没带闭合 }:原文件每个 case 都是 { ... break; } 结构。删到一半留下 break; 或少了 },整个脚本语法报错、NPC 直接打不开。
  4. 编号冲突:新增/保留时如果用了已存在的编号(如把别的功能也标成 #L0#),点菜单会乱跳。删功能不会冲突,但还原时要小心。
  5. 忘记备份:手滑多删一行,没有 .bak 就只能手动补回。养成"先复制再动手"的习惯。

六、举一反三:不止能"删"

掌握了"菜单行 + case"的双生结构后,这些改法都是同一个套路:

你想做的改哪里怎么改
改功能名字start() 的菜单行把"自由市场"文字换成别的,#L0# 编号不动。
换图标菜单行的图标变量把 蓝箭头 换成文件顶部定义的其它变量(如 红枫叶)。
改跳转目标action() 的 casecm.warp(新地图ID,0) 或 openNpc(npc新ID,"新脚本名")。
新增一个功能两处都加start() 加一行 #L新编号#文字#l,action() 加一个 case 新编号:{...break;}。编号别重复。
想新增功能时,最安全的做法是复制一个现有 case 改编号和内部逻辑,而不是从零写——能直接套用成熟的 cm.dispose() + 业务逻辑 + break 模板。