Weiming Kongjian (Jianghu Fengyun: Sunset Reappears)

✅ 可玩

未明空间 (Weiming Kongjian / "wmkj")

wmkj

🔑 fluffos / Mud@2026 更新 66a3bd8 2026-10-28 源码 下载 ZIP

▶ 开始游玩 · Play Now

原始压缩包自称"未明空间",但实际连接后显示的游戏名是"江湖风云之夕阳再现",作者"龙宝宝(xiha)"在 2001 年发布了这份单机存档供他人自行搭建服务器游玩,内容因此定格在当年的版本状态,而非持续运营的活跃游戏;这是"夕阳再现"(Sunset Reappears)引擎系列的一个真正血统分支,与本项目中的 `xyzxfk`、`jhfy`、`xyzx`、`jhfy3`、`xajh4gkb`、`xyzxyl201412` 等同源但各自独立开发,并非简单换皮(本项目里另有一批同样打着"夕阳再现"招牌、实为不同"天涯"家族的档案如 `xysylmhb`/`xyzxiiylzymh`/`yzxiiizylfy`/`xyzx3`,品牌名称不能作为判断血统的依据)。新角色从传统武侠"武庙"踏入江湖,登场时公共频道会广播"听说又来了一位叫做XXX的少年侠士",死亡则有完整的鬼门关体验("白无常"接引,复活落脚武庙,这套死亡系统设计与同血统的 `bixiecanyang` 相同);除共享血统外,本档案还有自己独有的内容——一个以浪客剑心/明治剑客风格为主题的"飞天御剑"门派区域,以及围绕真实存在的"狂风快剑"剑法展开的西夏军队任务线。

English

Archived as "Weiming Kongjian" but branded in-game as "Jianghu Fengyun: Sunset Reappears" — a 2001 single-player snapshot released by its author, 龙宝宝 (xiha), for others to run on their own servers, so its content is frozen at that release rather than a continuously-operated game. New characters step into a traditional wuxia jianghu from the Martial Temple (武庙), announced server-wide with a "a young hero named XXX has just arrived" broadcast; death sends players through a full underworld sequence escorted by 白无常 (the White Guard of Impermanence) before reviving back at the temple, a death-system design shared with this collection's bixiecanyang. Beyond its shared "Sunset Reappears" engine ancestry (also seen in this collection's xyzxfk and jhfy, each independently developed rather than a simple reskin — distinct from another group of same-named archives here that actually descend from an unrelated "Tianya" codebase), this archive has its own distinctive content: a "Feitian Yujian" sect area themed after the Rurouni Kenshin/Meiji-swordsman genre, and a Western-Xia-army questline built around a genuine "Kuangfeng Kuaijian" (Gale Blade) sword technique.

README

内容亮点

深度功能测试新发现的 bug(详见 NOTES.md)

adm/daemons/logind.lpc 有两处 §7.34 调试用 printf("%O\n", ob) 残留和一处 §8.9 食物/饮水初始化误判对象的 bug——已修复。死亡系统的 d/death/npc/wgargoyle.lpc(白无常,实际生效)有 AGENTS.md §7.68 归档的复活软锁死 bug,已按已验证的修法修复;同一个 bug 也出现在两 个确认不可达的死代码文件(bgargoyle.lpc、d/shaolin/npc/ yu-zu2.lpc)里,一并修复以防未来被重新接线。另外发现但未能在 本轮定位根因的一个更深的独立问题:即使 §7.68 修复让五阶段死亡对 话完整走完、reincarnate() 也确认执行成功,紧接着的 ob->move(REVIVE_ROOM) 调用之后角色仍然没有真正传送到武庙,且 debug.log/driver 自身输出全程没有任何报错线索——用调试探针确认 了具体卡住的位置,但受限于本轮时间预算未能找到确切原因,已诚实记 录为待后续排查的新发现,不是被这次修复引入的问题(没有这次修复, 死亡对话根本走不完,问题只会更早出现)。

在线试玩

https://mudlibs.fluffos.info/wmkj/

管理员账号 / Admin account

警告:这是一个公开的默认密码,仅供本地/浏览器试玩。正式对外开服前
请务必修改此密码。

本地运行

cd libs/wmkj
~/src/fluffos/build-debug/src/driver config.fluffos

游戏端口:40049。

NOTES · 移植与修复记录

wmkj — 未明空间

Archive: 未明空间.rar (#55). Port: 40049. Status: done (boots clean, full registration flow verified end-to-end twice, with two different real Chinese names, both reaching the actual game world).

What this is

The archive's own raw/wmkjlib/README.txt (GBK, converted before reading) identifies it explicitly: this is a single-player/offline snapshot of 未明空间 ("Unnamed/Unclear Space", "wmkj"), dumped by its author "龙宝宝 (xiha)" on Dec 13, 2001, described as "a backup from the end of September [2001]" made obsolete by later changes, released for other players to run standalone. The raw root directory is literally wmkjlib/, and the mudlib itself lives at wmkjlib/world/ (identified via wmkjlib/config.jh's master file : /adm/obj/master / mudlib directory : ./world directives) — the slug wmkj is a pinyin transliteration of 未明空间 chosen for this port, it does not appear literally in the archive.

The archive also bundles a second text file, 小熊泥苑.txt — this is not specific to this game; it's the generic download-site boilerplate/branding for 小熊泥苑 (dtxy.126.com, a mudlib-hosting site seen bundled with several other unrelated archives in this project, e.g. shujian2008/sjtx2) and its body text is actually about a completely different game ("狂想"/Kuangxiang), not 未明空间 — a site-wide readme that got bundled with this download by habit, not a clue about wmkj's own lineage. Ignored for lineage purposes.

Live banner identifies the actual displayed game name as "江湖风云" ("Jianghu Fengyun") "之 夕阳再现" (adm/daemons/logind.lpc's logon() banner) — i.e. wmkj is itself a rebrand/fork of the 夕阳再现 ("Sunset Reappears") lineage already seen twice in this project (archives #46 xyzxfk and #47 xyzxfy2). Confirmed via md5sum: adm/simul_efun/chinese.c is byte-identical to xyzxfk's copy (961d77af057bb93db320af05be5883fc), while master.c/logind.c/ securityd.c all differ (not a duplicate archive — a genuine, separately maintained fork sharing a common ancestor, same pattern as previously documented "similar titles/some shared files ≠ full shared lineage"). u/snow/logind.c (a per-wizard sandbox copy) exists in both archives too.

Layout: adm/{daemons,obj,simul_efun,etc,etcc,tmp} (not adm/single/). Uses feature/dbase.lpc's real local set/query/delete (inherit F_DBASE) for per-object property storage — not the nitan-family shared-simul_efun-dbase architecture bug (confirmed by reading feature/dbase.lpc directly: real local functions, no bare efun::set/query/delete calls anywhere in the lib — grep came up empty). ~11,736 raw files, 10,641 .lpc files after the rename — a mid-sized lib for this batch.

Fixes applied

1. AGENTS.md §15h, standard shape, adm/simul_efun/chinese.lpc's is_chinese(): GBK lead-byte range check (strlen(str)>=2 && str[0]>160 && str[0]<255) rewritten to a CJK Unicode codepoint check (strlen(str)>=1 && str[0]>=0x4e00 && str[0]<=0x9fff). 2. AGENTS.md §15h, check_legal_name() in adm/daemons/logind.lpc (this lib has no separate named.lpc-based check_legal_name — it's defined directly in logind.lpc): - Byte-count bound strlen(name) < 2 || > 10 → character-count bound < 1 || > 5 (the message text, "必须是 1 到 5 个中文字", already stated the correct intended character count). - Sliding check i%2==0 && !is_chinese(name[i..<0]) (alternating GBK-lead-byte offsets, checking a variable-length tail slice) → !is_chinese(name[i..i]) on every index (one whole character per index now, no <0]-tail-slice trick needed since is_chinese only ever inspected str[0]). 3. AGENTS.md §15h, adm/daemons/named.lpc's PATH() macro + sliding-window invalid_new_name() (applied proactively per standing policy even though this file turned out to be dead code — see "Confirmed NOT needed" below for how that was verified): - PATH(name) macro: name[0..1] ("first GBK char") → name[0..0] (first character). - strlen(name) < 2 empty-name guards (4 call sites: remove_name, map_name, who_is, invalid_new_name) → < 1. - invalid_new_name()'s combined-length guard strlen(name) < 4 → < 2; sliding-window loop bound i <= l - 4 → i <= l - 2; 2-character-equivalent windows name[i..i+3] (4 bytes) → name[i..i+1]; 3-character-equivalent windows name[i..i+5] (6 bytes) → name[i..i+2]; corresponding i+6<=l guard → i+3<=l. 4. AGENTS.md §15p: adm/etc/preload had /adm/daemons/network/dns_master live — commented it out proactively before the first boot attempt. 5. AGENTS.md §8d/§15o: adm/obj/master.lpc had no get_include_path() apply at all. Added the standard shape (prepend the compiling file's own directory, fall back to :DEFAULT:). This is a correct, harmless, by-the-book fix per the documented pattern — see "Confirmed NOT needed" below for the important caveat that it did not turn out to be the actual cause of this lib's largest lpcc-sweep failure cluster (verified by direct A/B testing, not assumed). 6. AGENTS.md §8b (new mudlib-bug instance, same shape as the xzyx finding): message_combatd(msg, me, victim) is called from adm/daemons/combatd.lpc and two kungfu/skill/*.lpc files, but was never defined anywhere in this lib. Every call site passes the same 3 args as message_vision, so added it as a plain alias varargs void message_combatd(string msg, object me, object you) { message_vision(msg, me, you); } in adm/simul_efun/message.lpc, placed after message_vision's own definition (§8b same-file ordering gotcha). 7. AGENTS.md §11 (copy-paste bug, new instance): clone/weapon/panguanbi.lpc (判官笔, "judge's writing-brush") did inherit PEN; ... init_pen(25); — PEN/init_pen are not defined *anywhere* in this archive (no /inherit/weapon/pen.lpc exists at all). The file's own description text ("这是一柄普通的精钢剑" — "an ordinary refined-steel sword") and its material/unit fields match the SWORD template exactly, confirming this was cloned from a sword weapon file and half-renamed. Fixed to inherit SWORD; ... init_sword(25); (matching /inherit/weapon/sword.lpc's real init_sword(int damage, int flag) signature). 8. Pre-existing typo, new instance: d/wudang/taoyuan/tyroad{4,5,6,7}.lpc all had #include __DIR_"feng.h" (missing the second underscore in __DIR__, a genuinely undefined macro/token) — the intended header d/wudang/feng.h (defining look_feng(), referenced via (:look_feng:) in each room's item_desc) is one directory up from taoyuan/, not in the same directory, so even a correct __DIR__"feng.h" wouldn't have resolved it. Fixed to #include "../feng.h" in all 4 files (confirmed correct against d/wudang/wulao.lpc/sanlao.lpc/etc, which already correctly #include "feng.h" from d/wudang/ itself). 9. Pre-existing missing-opening-quote typos (AGENTS.md §10-shape, several new instances, confirmed against the raw pre-conversion GBK bytes — not an encoding artifact): a set("long", <bare Chinese text> with no opening " before the text (closing " present or, in one case, also missing) in: - d/quanzhen/hudi6.lpc, d/quanzhen_old/hudi4.lpc, d/quanzhen_old/hudi6.lpc (a third, separate copy of the exact same "小湖底" room text under a different directory — found only after re-sweeping post-fix) — added the missing opening ". - d/quanzhen_old/hudi5.lpc — missing both opening and closing quote/\n around the same text block — added both. - d/player/fyue_room.lpc — same shape, one "long" description missing its opening quote (and a trailing \n" before the closing paren) — fixed. - d/city/sj.lpc — a much larger instance: the whole do_out() / look_out() tail of the file had every string literal argument written bare with no quotes at all (add_action(do_out, out), message_vision($N大喊一声...\n, me), me->move(__DIR__guangchang), me->command(chat 啊~~~), me->set_temp(die_for,...), a bare return <text>;, etc — a decorative, non-critical "jump off the world's edge" easter-egg room, not on the boot/registration path). Quoted every literal to match evident intent; also initialized the previously-unset object me; to this_player() (the function is bound via add_action, so this_player() is the correct actor — the original code declared but never assigned me before using it).

Confirmed NOT needed (verified by reading source, not assumed)

The get_include_path() investigation (§8d/§15o) — added the fix, but it wasn't the actual cause

The lpcc sweep's largest single failure cluster (30 files, all under u/snow/wudujiao/ and u/fyue/, personal wizard-zone content) all showed error: Cannot #include globals.h cascading into Undefined variable/syntax error noise for macros like NPC/SWORD/ ITEM that globals.h itself defines. This matched the documented §15o shape closely enough that get_include_path() was added to master.lpc proactively (a correct, harmless improvement, kept in the final code) — but re-running the sweep after adding it changed nothing (still exactly 30 failures in that category). Direct A/B testing (adding/removing the apply, lpcc --batch on the same file list) confirmed the fix had zero effect on this specific cluster.

Further isolation testing revealed the real cause: compiling any single file completely alone via lpcc --batch — including files proven to load perfectly cleanly in a real driver boot, e.g. /d/city/wumiao (one of the 4 actual player start rooms, exercised directly by the interactive registration test below with zero errors) — reliably FAILS the same way, while the exact same file passes when compiled as part of the full ~10,641-file batch. This is a pure artifact of lpcc --batch/a from-scratch VM session needing some amount of "warm-up" compiling before certain inherit chains resolve correctly when tested against a near-empty file list — not a real bug, and not specific to the wizard-zone files (confirmed by reproducing it on an unrelated, known-good start room). Matches AGENTS.md §6b's guidance exactly ("verify against the real full-driver boot log before trusting an lpcc-only failure... if grep for the error string comes up empty in an actual driver boot log, it's a sweep artifact"): grepping log/debug.log from both real interactive sessions for wumiao, kedian, yandang, or any Cannot #include string returns nothing but clean compile-note lines, confirming these 30 (and likely a good fraction of the other 335 no-error-message "Fail to load object" entries — see lpcc pass-rate section below) are sweep-only noise, not live bugs. get_include_path() was kept anyway since it's a correct, free improvement per the documented pattern, just not the fix for this particular cluster.

Registration-flow verification (the critical check)

Read adm/daemons/logind.lpc's full callback chain (logon → get_id → confirm_id → get_name/get_resp → new_password → confirm_password → select_gift/set_gift → get_gift → get_email → get_gender → init_new_player/enter_world) before scripting the test. No hidden pre-id BIG5/student/client-version gate in this lib — the very first prompt ("请输入您的英文名字:") really is get_id, gated only by check_legal_id() (3-14 lowercase English letters) and a banned_id/"guest" substring check.

Test 1 — python3 scripts/mudclient.py 127.0.0.1 40049 --timeout 25 --idle 2 --send "qinfeng" --send "y" --send "秦风" --send "test1234" --send "test1234" --send "0" --send "y" --send "[email protected]" --send "m" --send "look" --send "quit":

Then applied the remaining fixes (get_include_path, message_combatd, panguanbi, feng.h, the 6 missing-quote files) — since LPC objects don't recompile just from editing the file on disk, restarted the driver process and re-ran a second, independent full registration test with a different name to confirm nothing regressed:

Test 2 — same script, --send "linfeng" / --send "林风" (different id and Chinese name, to avoid the first test's now-existing save file): accepted through the identical full chain, landed in a different start room this time (random(4) picked "北疆小镇" / "Northern Frontier Town", /d/xingxiu/beijiang) confirming the start_room random-pick logic itself works, saw the correct channel broadcast (听说又来了一位叫做林风的少年侠士), look/quit both worked. debug.log for both sessions greps clean for error/Undefined function/Read access denied/Bad argument/ segmentation (only benign config-echo lines and the pre-existing, intentional log_error()-to-player mechanism that surfaces harmless Unknown #pragma, ignored compile warnings live to whoever triggers a lazy compile — original mudlib behavior, not a bug introduced here).

Both driver processes were killed after their respective tests; no driver process is left running on port 40049.

lpcc_check.sh sweep

10,641 files total. Ran 4 times as fixes were discovered (each re-run confirmed via free -h/a memory-watching background monitor that this mid-sized lib never came close to the host's 23GB capacity — peak usage stayed well under half of available RAM throughout, no need to abort per §6b):

| Pass | Result | |---|---| | 1 (pre-fix) | 10138 / 10641 = 95.3% | | 2 (+ get_include_path, panguanbi) | 10139 / 10641 (get_include_path fix confirmed NOT the cause of the big cluster — see investigation above) | | 3 (+ message_combatd, feng.h×4, 5 missing-quote fixes) | 10151 / 10641 | | 4 (+ 1 more duplicate missing-quote file found post-sweep) | 10152 / 10641 = 95.4% (final) |

Triage of the remaining 489 failures (categorized by error text, per AGENTS.md §6b):

Encoding

convert_lib.sh's automated pass: 11,325 converted cleanly, 340 already-UTF-8, 62 lossy (invalid bytes dropped — mostly NPC/room files under d/shushan/npc/, d/quanzhen*/obj/bookshelf.c, and a few .bek/map/log data files), 6 skipped as genuinely binary. Re-ran the AGENTS.md straggler check (file -b not reporting text/script/empty for any .lpc/.h) afterward: only one false-positive hit (d/emei/shenshuige.lpc, a short room file that file's heuristic misclassified as "data" despite being valid, clean UTF-8 — verified by hand, no action needed).

Config

config.fluffos adapted from wmkjlib/config.jh (labeled "MudOS 0.9.20"). Original port number : 6666 replaced with 40049 (this project's port assignment for archive #55, per TODO.md's sequential scheme after 40046-40048 reserved for archives #52-54). mudlib directory points at libs/wmkj/work (absolute path). All other directives (master file, simulated efun file, include directories, etc) carried over unchanged; standard modern-FluffOS tuning knobs (time to clean up, maximum evaluation cost, etc) copied from the same template used for the last several libs in this batch (matches xiakexing3's config.fluffos shape).

Re-verification pass (driver rebuild + LPC formatter + WASM build)

WASM-enablement pass (loopback-allow / throttle exemption / admin seeding)

Gates found and patched (AGENTS.md §1.3b/§1.3e/§1.5):

Retrofitted fail-open → fail-closed (2026-07-24): the three band.lpc spots (is_banned(), vaild_allow_address()) and the logind.lpc get_id() per-IP login cap were all originally written so that ANY malformed/non-string ip bypassed the gate, not just genuine loopback — defensive against the old WASM driver bug where query_ip_number() returned garbage for every WASM connection. That driver bug is now fixed (WASM reports a clean "127.0.0.1" same as native), so there is no remaining justification for "can't parse it" ⇒ "must be loopback". Changed: - band.lpc is_banned(): !stringp(site) || site=="127.0.0.1" || strsrch(site,"127.")==0 || sscanf(site,"%*d.%*d.%*d.%*d")!=4 (any unparseable site returns "not banned") → stringp(site) && (site=="127.0.0.1" || strsrch(site,"127.")==0) for the bypass — a non-string site now falls through to the pre-existing if (!site) return 1;/sscanf-based logic below, same as the original pre-WASM code. - band.lpc vaild_allow_address(): same shape fix, plus an added if (!stringp(vip)) return 0; right after the loopback check (deny rather than crash on a non-string ip reaching the allow-list regexp() call below). - logind.lpc get_id(): the per-IP login-cap condition required stringp(query_ip_number(ob)) to be true before the cap would even apply (ip != "127.0.0.1" && stringp(ip) && strsrch(ip,"127.")!=0 && wiz_level<2) — so a non-string ip made the whole condition false and skipped the cap entirely. Introduced a cur_ip/is_local_conn pair computed once (stringp(cur_ip) && (cur_ip=="127.0.0.1" || strsrch(cur_ip,"127.")==0)) and gated the cap on !is_local_conn instead — a non-string ip is no longer local, so the cap still applies to it.

Pre-existing re-login bug found and fixed during this pass:

Admin account: id fluffos, password Mud@2026, name 浮浮, granted (boss) (same rank as the shipped hfzz admin; BOS_PATH command dirs) via adm/etc/wizlist. Verified post-restart: re-login lands in 客店, update /adm/daemons/logind → 成功, clean quit.

Save files for the orchestrator to force-add (untracked, not gitignored):

Retest: fresh registration (qinshiyi / 秦十一) end-to-end with look/score/quit all correct; zero 执行时段错误 in both sessions; test char removed (fluffos kept).

Re-retest after the fail-closed retrofit (2026-07-24): fresh boot, fresh registration (id qretest, real Chinese name 秦风九, talent 0 then y) through look/score/quit — landed in a random starting scene, score output correct, clean quit farewell. fluffos/Mud@2026 admin (boss) login re-verified: look then update /adm/daemons/logind → 重新编译 /adm/daemons/logind.lpc:成功!, then clean quit. Zero 执行时段错误 lines in debug.log for the whole session. Test char qretest removed afterward; fluffos kept.

WASM 修复摘要(迁移自 meta.json 的 group_note)

"夕阳再现"衍生引擎上的一款独立游戏。状态已从过时的 limited 修正——这份档案自己的 README 里从未记录过任何缺陷说明,本轮重新测试也没有发现:管理员登录(fluffos/Mud@2026)干净正常,等级确认("您目前权限:(boss)"),进入起始区域,quit 干净。记录了一处不阻断游戏的历史遗留美观性 bug(本轮未修):某个房间的夜间氛围文字里有一处没有被替换掉的字面 '%s'。

深度功能测试(§10.7,2026-08-04)

原生 driver(端口 40049)跑了一遍超出注册流程的完整游玩。这份档案 和 bixiecanyang 同属"夕阳再现"血统(同源 chinese.lpc/securityd.lpc 等工具文件),注册流程也高度相似:单组密码、天赋可选 1-4 项自定或 0=全随机、六项天赋(含福缘/容貌两项隐藏属性)、email、性别。

主动检查命中 3 处,都在 adm/daemons/logind.lpc:两处紧挨在 ob->set("name", ...) 之前的 printf("%O\n", ob) 调试残留(§7.34, 随机取名/手动取名两条平行路径各一处,和 bixiecanyang 逐字节相同 的形状);enter_world() 里食物/饮水初始化用错对象的经典 §8.9 bug(ob->query("age") 应为 user->query("age"))。三处均已修 复;注册后食物/饮水显示 280/280(满值),确认 §8.9 修复生效。 command_hook(feature/command.lpc)是干净的 nomask,没有 private,不是 bug;没有 MESSAGE_D-> 未防护调用;全树 UTF-8 解码 扫描没有发现 extensionless GBK 文本残留(唯一的 6 个解码失败文件全 部确认是二进制可执行档、tar 归档或巫师私人调试日志,不是应该转码 的内容);feature/alias.lpc 没有 command("quit"),不适用 §7.72 那类 flood-kick bug。

注册与游玩:注册测试角色,落在"铁枪庙"(随机起始点之一,另有 "客店""嘉兴南门"等),携带"法传送帖"道具。探索了客店(有间客栈)、 钱庄方向的南大街、当铺、天安门广场等区域,地图连通性正常。

死亡系统:修复了标准的 §7.68,但同时发现并诚实记录了一个更深、 未能在本轮定位根因的独立异常:d/death/npc/{wgargoyle,bgargoyle}.lpc (只有 wgargoyle.lpc 真正生效,DEATH_ROOM 宏指向它所在的 d/death/gate.lpc;bgargoyle.lpc 未被任何房间引用,是死代码) 和 d/shaolin/npc/yu-zu2.lpc(同样是被 yu-zu.lpc 取代的死代码, 和 jyqxc/syxjl/wmkj 此前发现的同一个监狱机制 bug 一致)都有 标准的 if (!ob || !present(ob)) return; 复活软锁死守卫,已按已 验证的修法全部拆分修复。

现场测试时发现:死亡后被"四只乌鸦"或"小贩"这类极弱的 NPC 杀死 (战力 300 左右,说明测试角色初始战斗力极低,"攻击力:1",几乎任 何 NPC 都能致命——这是内容/数值现象,不是 bug),落到"鬼门关", "白无常"在场。用临时插入的 tell_object 调试探针逐行追踪确认: 五阶段死亡对话在 §7.68 修复后能完整走完(stage 从 0 递增到 4, 每条 death_msg 文本都正确显示),ob->reincarnate() 也确认执行 成功(探针显示 ghost=0),但紧接着的 ob->move(REVIVE_ROOM) 调用之后,连一条最简单、不涉及任何字符串拼接或返回值处理的 tell_object 探针都没有再显示过——反复用不同测试角色、不同起始 房间复现了同样的结果:五段对话全部显示完毕后,角色仍然留在"鬼门 关",只收到白无常的日常闲聊(chat_msg),从未真正传送到"武庙"。 debug.log 和 driver 自身的 stdout(boot.log)全程没有任何报 错,driver 进程本身也没有崩溃。追查了 feature/move.lpc 里 move() 自己的"如果身上有装备就先卸下"逻辑(if (query("equipped") && !this_object()->unequip()) return notify_fail(...),怀疑 notify_fail() 在没有活跃玩家指令的 call_out 语境下可能返回一个 让调用方误判的值)、reincarnate() 内部 UPDATE_D->check_user() 的 is_ghost() 时序等几个假设,但在本轮的时间预算内未能定位到确 切根因就没有继续深挖,也没有做任何"猜测性"修复——诚实记录为一 个新发现、尚未解决的独立异常,不是 §7.68 那个已经验证过的 bug 类,也没有被本次的 §7.68 修复引入(§7.68 修复本身已经证明是正 确的:如果没有这个修复,五阶段对话根本不可能完整走完)。已将调试 探针代码全部还原,不带任何调试残留提交。建议下一次有余力时,从 feature/move.lpc 的 move() 全函数体(不只是 equip 检查那一段) 逐行插桩来精确定位。

quit 正常退出,driver 全程存活未崩溃。debug.log 全程没有真实 的 error:/denied/Bad argument/Too deep recursion 行。 formatter 检查(改动文件均已是干净格式或首次接触触发全文件重排 版,语义改动已逐一核对)、git status --short libs/wmkj/ 复查均 确认改动范围干净——四处源码修改是跟踪变更,测试角色的新存档保持未 跟踪、未提交。

更正(2026-08-05):§7.68 复活软锁"修复"已撤销

上面提到的"鬼魂离开/不在场时被永久放弃复活流程"曾被当作 AGENTS.md §7.68 记录的一类 bug 修复(把单次判定改成每 5 秒重试)。经用户指出并 重新审视:这更可能是有意的游戏设计,不是 bug——大多数这类档案里 鬼魂根本无法自行移动,所以"不在场"要么从未真正发生,要么是"离开去 在阴间游荡,想回来时再走回这个房间、流程会通过 init() 重新从头开始" 这种有意为之的宽松机制,而不是需要强制追上玩家的错误。强行重试还可能 引入新问题:如果鬼魂之后又走回这个房间,旧的重试和 init() 重新触发的 新一轮流程可能同时运行,导致对话重叠错乱。已把这处改动撤销,恢复成 原始的 if (!ob || !present(ob)) return; 单次判定写法(bmxkx2001 除外——那份档案里这确实是一个真实存在、经过实际复现验证的 bug:鬼魂 本身完全无法移动,是另一个不相关的 NPC 强行把鬼魂拖走导致的)。详见 AGENTS.md §7.68 顶部的撤销说明。

§7.86 跨库扫描修复(留言板 post 崩溃)

深度功能测试(2026-08-13,round two,新驱动重测)

Re-tested against the freshly-rebuilt build-debug/src/driver(post 全库 quest_times/win_times %-operator 修复 + Warning/warning 驱动文本回退)。log_error()(adm/obj/master.lpc)已经在更早一 轮正确修复过,管理员账号(fluffos/Mud@2026,adm/etc/wizlist 已有 fluffos (boss))此前的存档也已经真正可用——feature/ dbase.lpc 检查确认这份档案不属于 tybxjh/wlhd 那个"天涯" 血统,没有那条会拦截首次密码设置的防劫持保护,存档文件里 password 字段本身就有正确的哈希值,直接登录 + update 验证全部 一次通过。本轮只发现并修复了 log_file() 一处。

发现并修复的 PROGRAMMING bug

1. log_file()(adm/simul_efun/file.lpc)完全没有 assure_file() 保护(AGENTS.md §7.11-class 的又一确认实例):adm/daemons/ logind.lpc 的 get_gender()(新角色注册流程的最后一步)紧跟 着调用 log_file("login/newid.log", ...)。已补上 assure_file(LOG_DIR + file);(含前向声明)。

Proactive checks(无需改动)

实测过程

用已提交的 fluffos/Mud@2026 直接登录(本代码线无双密码机制, 只有一个普通密码),断线重连("重新连线完毕")+ update /adm/simul_efun/file(就是本轮改过的文件,"重新编译...成功!") 均一次通过验证。

发现但未修复:多条 debug.log 记录,均为既有游戏内容问题(世界

模拟背景活动,和注册/登录/管理员流程无关)

登录测试期间 log/debug.log 新增了不少条目,追查后确认全部是背景 世界模拟活动触发的既有内容问题,和本轮任何改动都无关: adm/daemons/feizeid.lpc(飞贼精灵)的 choose_npc() 传了一个 int(0) 给 call_other();某个帮会房间 inherit 了一个不存在的 文件 /u/xiha/banghui/bhnpc;两处 NPC create() 里 set_skill() 引用了并不存在的技能名(kuang-jian/feitian-yujianliu)。这些都 是纯内容/数据层面的既有问题,按项目惯例不在本轮 §10.7 标准检查范 围内展开修复,如实记录。log/debug.log 里没有任何和 log_error()/log_file()/注册/登录路径相关的条目。驱动最终按精 确 PID kill,ps -p 确认已退出。

已清理

后续处理(2026-08-13):上面三项被记录为"世界内容问题、暂不修复"的发现,逐一深挖并按可行程度修复

用户明确要求把上面标记为"内容层面既有问题、本轮不修"的三项拿回来 实际修:feizeid.lpc 的 call_other(0,...)、缺失的 /u/xiha/banghui/bhnpc、以及 kuang-jian/feitian-yujianliu 两个 不存在的技能名。三项各自的根因、范围比原始记录深很多,逐一说明:

1. adm/daemons/feizeid.lpc(飞贼精灵)—— 已修复。 根因: choose_npc() 第 44 行 newob = new("/u/xiha/npc/" + feizei[...]); ——/u/xiha/npc/ 整个目录在 work/ 和 raw/ 里都完全不存在(不 是某几个文件缺失,是这个 12 个飞贼 NPC 的目录从来没进过这份归 档),所以 new() 每次都回传 0,紧接着的 newob->set(...) 就是对 int(0) 的 call_other——这正是 AGENTS.md §7.63/§7.73 的标准形状。由于飞贼精灵的 call_out 周期是 320 秒且从 create() 就排上,这个 crash 在驱动运行期间 持续、周期性发生,不是偶发。修复:new() 后立即判空,return 之前重排下一次 call_out,不吞掉整个报错循环: ``lpc newob = new("/u/xiha/npc/" + feizei[random(sizeof(feizei))]); if (!newob) { remove_call_out("choose_npc"); call_out("choose_npc", 320); return; } ` 验证:update /adm/daemons/feizeid 编译干净;驱动运行期间不再 出现相关报错(此前 debug.log` 会每 320 秒新增一条)。

2. /u/xiha/banghui/bhnpc(以及同目录下的 banghui.lpc/ vendor.lpc)—— 无法恢复原内容,已改为让崩溃不再发生。 include/globals.h 里 BHNPC/F_BH/F_BVENDOR 三个宏都指向 /u/xiha/banghui/ 下的文件;这整个目录在 work/ 和归档原始的 raw/wmkjlib/world/u/ 里都不存在(u/ 下只有 fyue、snow、 workroom.c,从来没有过 xiha)——这份归档本身的说明文件就写 明作者的 ID 正是 "xiha",所以这是这份 2001 年"离线备份"归档在 打包时就已经缺失的作者个人目录,不是转换流程的问题,也没有任何 同名/近似的候选文件可以恢复(§7.94 式判断:不是"选哪份候选"的 内容判断,是彻底找不到)。按项目惯例不编造替代内容。真正会崩溃 的不是那 28 个直接 inherit BHNPC 的 NPC 文件本身(它们只是编 译失败,不会产生游戏内容之外的连带崩溃)——而是 inherit/room/room.lpc(几乎所有房间的公共基类)的 make_inventory(): ``lpc ob = new(file); ob->move(this_object()); // new() 对编译失败的文件回传 0,这里是 call_other(0,...) ` 以及 reset() 里同一个模式的两处调用点(case 1 单件、 default 多件分支)。凡是房间的 "objects" 表里放了这 28 个 NPC 之一,reset()(包括 natured.lpc 的日夜事件、NPC random_move() 换房间触发的目标房间 reset(),两条路径实测都 命中过)就会在 make_inventory() 里对 0 做 call_other。修 复:给 make_inventory() 的 new() 结果判空,reset() 两处调 用点在使用前也判空——这是修复"房间生成逻辑"本身,不是编造缺失 的帮会内容,28 个 NPC 依然会因为找不到 bhnpc 编译失败(这点 没变、也不可能变),只是不再把这个失败向上传播成整栋房间的 crash。验证:实测触发过两条不同路径(/d/city3/guangchang 经 natured.lpc 的清晨事件、/d/city3/xijie2 经 NPC 游走进房间触 发的 reset()),debug.log` 里两次都只留下预期中的"继承文件不 存在"记录,driver 全程存活,没有级联报错。

3. kuang-jian(有正确技能实现,只是放错目录,已修复)和 feitian-yujianliu(连同同一批彻底缺失的 14 个"飞天"专属技 能,无法恢复,已加保护)—— 两者根因完全不同,分开处理。

- kuang-jian:不是缺失内容,是放错了目录。 quest/weiguo/xixiabing/kuang-jian.lpc(以及配套的 kuang-jian/kuang.lpc、kuang-jian/leitingpili.lpc 招式文 件)本身是一份完整、可用的 SKILL 类实现("狂风快剑"),raw/ 归档里就已经放在这个任务目录下,从来没在 kungfu/skill/(feature/skill.lpc 的 SKILL_D() 宏硬编码 指向的技能查找目录,learn/practice/perform/chkskill 等所有技能相关指令都走这个宏)出现过——所以哪怕 set_skill() 的存在性检查侥幸通过,perform_action() 也永 远解析不到招式文件。这不是"选哪个候选实现"的内容判断(本作者 只写了这一份实现,没有竞争版本),是把已确认正确的文件挪到引 擎唯一认可的位置,对应 AGENTS.md §7.94 的"用归档里已证明正确 的内容补回缺失文件名"这类判断。用 git mv 把三个文件整体搬到 kungfu/skill/kuang-jian.lpc + kungfu/skill/kuang-jian/(保 持 __DIR__ 相对招式文件路径不变,perform_action_file() 不 用改)。验证:update 三份文件、以及 4 个引用它的 quest/weiguo/xixiabing/xixia{1..4}.lpc 全部编译成功;现场 clone 了一个 xixia1 西夏兵实测,set_skill("kuang-jian",..) 不再报错,且在真实战斗里触发了"雷霆霹雳"/风系剑招的战斗文本 (证实 perform_action() → SKILL_D("kuang-jian") → perform_action_file() 整条链路已经生效,不只是编译通过)。

- feitian-yujianliu:深挖后发现原始记录的"两处 NPC"严重低 估了范围——d/feitian/("飞天御剑流"门派区域,绯村剑心/比古 清十郎等 NPC)整个技能体系一共引用了 15 个 kungfu/skill/ 下完全不存在的技能名(feitian-yujianliu、wuxing-dun、 shayi-xinfa、shayi、aikido、bearart、 xuanhualiu-quanfa、edge、huoxinliu-jianfa 等),分布在 11 个 NPC 文件(biguqing/jianxin/qingyun/axun/ miyan/dizi/luo/luoren/shiren/xunjing/zuo)里, raw/ 归档同样完全没有——是这整片"飞天"(其实是新选组/绯村 剑心题材)门派区域自带的一整套自定义技能树,连同 xiha 的个 人目录一起,从归档诞生起就没有实现文件。feature/skill.lpc 的 set_skill()/map_skill() 对不存在的技能名是故意 error()(这是这份代码库统一、正确的校验逻辑,其它调用点用 的都是真实存在的技能,不能因为这三个区域性文件就改 feature/skill.lpc 本身),而这些 NPC 的 create() 里,缺失 技能的 set_skill()/map_skill() 调用夹在正常技能中间——一 旦抛错,create() 当场中断,后面的 create_family()(帮派注 册)、setup()、穿装备统统执行不到,等于这整个门派的掌门/长 老 NPC 从未正常初始化过。既不编造这 15 个技能的具体实现(属于 游戏设计/平衡工作,超出本项目范围),也不能改 feature/skill.lpc 的校验语义,所以修复落在调用点:给这 15 个引用(set_skill() 及唯一一处第一参数就是缺失技能名的 map_skill("edge", "feitian-yujianliu"))逐一套上 catch(...),让 create() 能跳过这一句继续往下执行——这些 NPC 该有的技能数值就是少了几项(本来就从未真正生效过),但至 少角色本身、帮派注册、装备穿戴这些不该被牵连的初始化逻辑都恢 复正常。验证:对全部 11 个文件逐一 update,debug.log 显示每一处缺失技能都变成"错误讯息被拦截"(catch() 生效)后 紧跟"成功!"(create() 完整跑完),不再有任何未捕获的 F_SKILL: No such skill 中断 create()。

顺带在同一次测试中发现一个范围外的同类实例: d/lingxiao/npc/wang.lpc 引用了同样不存在的技能 xueshan-sword (baoshid.lpc 的 choose_baosi()/random_place() 触发),未 修——不属于本轮明确要处理的 kuang-jian/feitian-yujianliu 范围,留给下一轮处理。

验证方式(本次三项修复共用)

原生 driver(端口 40049)重新起过一轮,用 fluffos/Mud@2026 ((boss))登录后对全部改动文件逐一 update 确认编译/create() 干净;另注册了一个全新测试角色(wmkjqatest/中文名"秦风测")走完 整个注册流程直达游戏世界,score 输出正确,quit 后等满 50 秒冷 却、用同一账号密码重新连线,成功恢复到退出前所在房间(断线重连闭 环)。驱动最终按精确 PID kill,ps -p 确认已退出。测试产生的 fluffos 存档时间戳类微小 diff 已 git checkout 撤销;新注册的 wmkjqatest 测试存档文件(未追踪)已删除,未提交。

AGENTS.md §7.100 修复(2026-08-19,批次五)

ROOM 基类冗余 replace_program(ROOM); 自崩溃地雷(详见 AGENTS.md §7.100):2797 个房间文件的 create() 里紧跟 inherit ROOM; 之后 都有这一行多余调用,永久设下"待替换"标记,第一次对该房间对象绑 定闭包就会崩溃。自带建房工具有 4 处拷贝(obj/roommaker.lpc、 clone/misc/roommaker.lpc、u/fyue/misc/roommaker.lpc 简单字符串 拼接写法;obj/rmmaker.lpc 的 room_code += 写法)。累计 2800 处 live 调用删除,和 survey 记录的数字精确吻合,修复后 0 处遗留。

验证:build-debug 驱动真实冷启动,端口 40049 正常监听。启动期间 观察到一条既有的 debug.log 报错(natured.lpc 早晨事件在 /d/city/guangchang 生成一个继承 u/xiha/banghui/bhnpc.lpc 的 NPC, 但该文件在盘面上确实不存在)——确认和本次扫描无关(零处 "cannot replace"/"cannot bind",文件本身就缺失,是一个既有的缺失 继承内容 bug,不是 replace_program 回归),未修,超出本次范围。既 有管理员账号 fluffos/Mud@2026 登录正常(落地北疆小镇, look/quit),全程 debug.log 零新增行。

补完 d/lingxiao/npc/wang.lpc 缺失技能崩溃(2026-08-20)

此前一轮记录本文件的 xueshan-sword 缺失技能"超出范围,留给下一轮", 只是未验证是否真的只有这一处。现场用 update 实测发现:光包住 xueshan-sword 依然在下一行 set_skill("bingxue-xinfa", ...) 崩溃 中断 create()——这个 NPC 的整套"凌霄城"技能(xueshan-sword/ bingxue-xinfa/snow-zhang/snowstep,set_skill+map_skill 共 9 处引用)全部是未实现的内容,不止 NOTES.md 之前记录的那一个。已按 和本库其余 11 个同类档案完全一致的手法,把全部 9 处引用套上 catch(...)。现场验证:update d/lingxiao/npc/wang.lpc 后 debug.log 依次显示 4 次"错误讯息被拦截"(对应 4 个缺失技能),最终 "成功!",create() 完整跑完。

§7.30 uninitialized-mapping accessor sweep (2026-08-20)

Corpus-wide mechanical sweep of the feature/skill.lpc shared-lineage bug (confirmed independently on xiakexing2017/jqxz2015/haiyang2 via round-four testing): 4 accessor(s) in this file returned a raw never-initialized mapping instance variable (defaults to int 0, not ([]), until first assigned), crashing any unguarded keys()/sizeof()/indexing caller for a fresh/untrained character. Fixed at the accessor level (mapp(x) ? x : ([])) per the documented remedy. Verified via lpcc --batch static compile check only (not a live boot) as part of a large mechanical sweep; not individually functionally re-tested live on this lib.

AGENTS.md §7.19 sweep (2026-09-01): enable_player() reentrancy from init()

Same corpus-wide bug class as mhxy/wuhanzhan (AGENTS.md §7.19): this lib's feature/command.lpc enable_player() wrapper (around the raw enable_commands() efun) is reachable from an NPC's init() via a redundant create()-then-init()-calls-reset_me()-calls-setup() chain -- confirmed via a body-aware static scan of every init() in this lib: only 2 files have this exact redundant pattern (d/shushan/npc/zhangmen.lpc, d/shushan/zhenyaota/npc/zhangmen.lpc -- the same zhangmen.lpc lineage already documented as the original live-reproduced crash on mhxy), a much smaller count than most other libs in this sweep but still a real, live reachability path: init() conditionally calls me->reset_me(me), and reset_me() calls setup() which calls enable_player(), after create() already made the object living(). Calling enable_commands() a second time on an already-living() object makes the driver re-invoke that object's own init() as a side effect, re-entering the same chain while the original call is still on the stack -- genuine reentrancy, crashing with "Too deep recursion" (most likely on an NPC's first-ever preload/compile).

feature/damage.lpc's revive() and cmds/std/sleep.lpc's wakeup() both call enable_player() again while the object is still living(). This confirms a bare if (living(this_object())) return; guard would be the WRONG fix -- used the same true reentrancy-flag fix as mhxy instead: a nosave private int in_enable_player_now; set for the duration of the wrapper's body, guarding only genuine same-call-stack reentrancy while leaving every legitimate re-enable (revive/wakeup) unaffected. enable_player() had a single fall-through exit (no early returns), so one guard-at-top + one clear-at-bottom pair was sufficient. Verified via a single-file lpcc --batch compile check (PASS) -- not individually live-boot-tested.

深度功能测试(2026-09-04,round three,shop + 拜师)

新角度:醉仙楼购物 + 丐帮左全拜师。此前各轮覆盖了注册、战斗、死亡/ 复活和若干 sweep,没有买东西、也没有拜师。这是夕阳再现/江湖风云血统 (与 bixiecanyang 同系),不是天涯家族。标准端口 40049 第一输入就是 「请输入您的英文名字:」,不要发 2060。

实测过程

管理员 fluffos / Mud@2026(权限 (boss);wizpwd 不是登录密码)。 落地北疆小镇 /d/xingxiu/beijiang(房间描述里仍有一处未替换的字面 %s,2026-08 已记为美观性遗留,未修)。clone /clone/money/gold 可用。

goto /d/city/zuixianlou,list 烤鸡腿八十文钱 / 牛皮酒袋一两白银 / 包子五十文钱。buy jitui 成功(「你向店小二买下一根烤鸡腿」)。当场 i 是九十九两银子 + 二十文铜板 + 鸡腿(1 两黄金找零 10000−80 = 9920)。 feature/dealer.lpc 已 #include <dbase.h>,query("vendor_goods") 正常。F_DEALER 对丐帮拒绝购买(穷叫化),必须先买再拜。本轮游戏内时间 是「亥时」深夜,但 NATURE_D 没有 room_event_fun(),打烊判断拿不到 event_night,店开着——这是既有缺口,不是本轮要修的内容 bug。

goto /d/gaibang/inhole,左全源码是 kungfu/class/gaibang/zuo-qu.lpc (文件名少一个 n),apprentice zuo 一次成功:左全收徒,score 「丐帮第二十代弟子」、师傅左全、头衔【叫 化 子】。cmds/usr/save.lpc 真正调用 link_ob->save() 和 me->save();60 秒内再 save 是 notify_fail("你迟点才可以储存。")(不是假「档案储存完毕」)。等 62 秒后 save 一次,user.o 立刻带上 family_name":"丐帮" / master_name":"左全" / generation":20。杀驱动冷启动再登录,称谓/ 师傅/银子铜板还在。烤鸡腿未进 autoload。左全只收男性。

发现并修复的 PROGRAMMING bug

1. 华山收徒计数拼写(与 nitan_ceshi/nitan_san 同形,静态对照 修,本轮拜师走的是左全不是华山): kungfu/class/huashan/{yue-buqun,yue-wife,feng-buping}.lpc 的 recruit_apprentice() 写 add("apprentice_availavble", -1),计数 键永远对不上 apprentice_available。改成 apprentice_available。 文件是 LF。

2. wizlist 执行时段崩溃(活体踩到): cmds/imm/wizlist.lpc(以及副本 cmds/imm/ww.lpc、 cmds/wizlist.lpc、adm/etcc/wizlist.lpc)三处: - explode(read_file("/u/xiha/wtm"), "\n"):档案里没有这份巫师 任务文件,read_file 返回 0,explode 要 string。改成 read_file(...) || "#"(# 行会被后面的任务解析跳过)。 - stat(login_path, -1)[1]:FluffOS 里 stat(path, -1) 等于 get_dir(),缺档时返回空数组/0,[1] 越界。巫师 hfzz 在 wizlist 里但没有 login.o。改成不带 -1 的 stat(path)(返回 ({ size, mtime, ... })),并用 arrayp(st) && sizeof(st) > 1 护住缺档。 - get_mission/get_titlemission 对空行做 mission[i][0] 也会 越界;空串先 !sizeof 跳过。/adm/etc/renwu 里确实有空行。 文件是 CRLF,按字节替换。update 后 wizlist 列出 fluffos(连线) 和 hfzz(断线),不再报执行时段错误。

深度功能测试(§10.7,2026-10-04)— negative range ends

scripts/lpc_fix_negative_ranges.py: 5 line(s) in 2 file(s) count a range from the end with < (x[a..-1] -> x[a..<1], x[-2..] -> x[<2..]; KB 06 §7.209). In this driver a negative constant end gave "" / ({ }) and a negative start the whole value, so each of these returned the wrong slice; the compile warning A negative constant as the second element of arr[x..y] is gone from the files that compile. Range lvalues (s[0..-1] = text, the prepend idiom) are left alone. A paired compile of the changed files at HEAD and in the working tree showed no new error.

深度功能测试(§10.7,2026-10-05)— here-document terminators

scripts/lpc_fix_heredoc_terminator.py --all --apply: 7 here-document block(s) repaired (7 with the terminator glued to the last text line, 0 with it indented), so End of file in text block no longer hides the room or object behind them: d/heimuya/shenggu.lpc, d/heimuya/tang.lpc, d/heimuya/npc/tang.lpc, d/quanzhen/manglin1.lpc, d/quanzhen/manglin2.lpc, d/quanzhen_old/manglin1.lpc and 1 more. The terminator must start its line (the lexer's own test, KB 04 §6.10); a glued one lost its newline in the GBK -> UTF-8 conversion together with a half character, which stays out.

深度功能测试(§10.7,2026-10-05)— 任务表里的 .c 路径与任务守护进程的防护

scripts/lpc_dynamic_rows.py:d/obj/quest/dynamic_location、d/obj/quest/dynamic_quest、task/dynamic_location 里 115 行写的是原档案的 .c 路径。转档时文件已改名 .lpc,而显式后缀按原样解析,load_object("/d/x.c")、new("/d/obj/quest/x.c") 返回 0 且不报错(KB 03 §4.2,KB 06 §7.220),所以 adm/daemons/questd.lpc、adm/daemons/taskd.lpc、u/fyue/questd.lpc 读到的每一行都加载不出来:随机任务和任务物品从未生成,在 create() 里直接对结果调用 tar->set() 的版本还会崩溃,连带加载它的 cron 守护进程和 give 的任务钩子。这些行已改为 .lpc;另有 1 行指向的文件两种后缀都不存在(档案缺内容),保持原样。 scripts/lpc_dynamic_quest_guard.py:2 处 spread_quest() 调用(init_dynamic_quest() 的循环里)包进 catch(),缺失的任务物品或编译不过的房间只跳过那一个任务,守护进程照常加载、其余任务照常生成。 验证:adm/daemons/questd.lpc、adm/daemons/taskd.lpc、u/fyue/questd.lpc和 cron 守护进程在新进程里加载(HEAD 一次,工作树三次,选房是随机的):HEAD 通过 3 个,工作树三次分别通过 3、3、3 个(共 4 个),无回退;u/fyue/questd.lpc 在 HEAD 与工作树都加载失败,另有原因,与本次无关。

深度功能测试(§10.7,2026-10-07)— 空的 if (current_water == 0) {}

5 个房间的 valid_leave() 里有一行什么也不做的 if (current_water == 0) {}(编译警告 Expression has no side effects),删去,行为不变:d/gaochang/room11.lpc、d/gaochang/room12.lpc、d/gaochang/room13.lpc、d/gaochang/room14.lpc、d/xingxiu/shanjiao.lpc。

深度功能测试(§10.7,2026-10-07)— 郭靖任务的名单被覆盖

quest/guojob/guo.lpc 先后 #include "zzzjob.lpc" 和 "teamjob.lpc",两个文件都声明全局 mixed names、内容不同(Redeclaration of global variable 'names'),后包含的 teamjob 名单覆盖了 zzzjob 的,"保护"任务的目标其实从 teamjob 的名单里抽。teamjob 的表改名 team_names(KB 04 §6.10)。guo.lpc 在 HEAD 与工作树分别加载(新进程)通过。

深度功能测试(§10.7,2026-10-07)— 编译警告整理

scripts/lpc_warnings.py wmkj --fix 加 scripts/lpc_fix_no_effect.py --apply,共改动 555 个 .lpc 和 6 个 .h(多为删去未用的局部变量)。HEAD 与工作树分别加载(新进程):492 -> 492 通过,无回退;改过的头文件的 43 个包含者 43 -> 43 通过。启动时警告 33 -> 0;新进程登录(新人物确认)正常。

深度功能测试(§10.7,2026-10-11):“无副作用表达式”警告复查

深度功能测试(§10.7,2026-10-11):“无副作用表达式”警告复查

编译警告收尾(2026-10-13)

scripts/toolkit_fix.sh 一轮去掉 2 处多余的 F_CLEAN_UP,其余手工,能编译的文件警告清零;改动的 8 个对象在 HEAD 与工作树各载入一次,regress 0。

内力/精力当作伤害种类(2026-10-15,KB 06 §7.241 第二类)

本库 feature/damage.lpc 的 receive_damage() 不接受 jingli/neili/force 等种类,me->receive_damage("jingli", 30) 之类在练功、绝招、吸取时报 F_DAMAGE: 伤害种类错误。27 处改为 add(type, -N)(scripts/lpc_fix_damage_calls.py 第二步)。

无门派玩家的 family 映射(2026-10-15,KB 05 §7.30 第三种)

mapping fam = ob->query("family"); 之后直接 fam["family_name"]:没有门派(新人或叛师后)的玩家在学习、练功、拜师、进入门派房间时报 Value being indexed is zero,而不是作者写好的提示。8 处在声明行加上 if (!mapp(fam)) fam = ([ ]);(scripts/lpc_fix_family_guard.py)。

东方故事/西游记体系的技能文件(2026-10-15,KB 06 §7.241 第三类)

这些 kungfu/skill 文件来自 gin/kee/sen/force 体系,本库人物只有 jing/qi/neili:receive_damage("kee", 30) 报 伤害种类错误,query("force") 永远为 0,技能学不了也练不了。按 kee→qi、gin/sen→jing、force→neili、max_force→max_neili、force_factor→jiali 改了属性名(scripts/lpc_port_es_props.py),共 1 个文件。

其他体系的属性名(2026-10-15,KB 06 §7.241 第三类,--any-file)

另有 7 个文件(绝招、状态、物品、NPC 等,不限于 kungfu/skill)来自 gin/kee/sen/force 体系,同样按 kee→qi、gin/sen→jing、force→neili 改名(scripts/lpc_port_es_props.py --any-file)。

family 映射(再补)(2026-10-15,KB 05 §7.30)

mapping fam; fam = (mapping)ob->query("family");(先声明后赋值)和泥潭式的 query("family", me) 同样直接取下标:无门派的新人拜师(attempt_apprentice/recognize_apprentice)、NPC 的 greeting、房间的 valid_leave、ask_me 等报 Value being indexed is zero。7 处补上 if (!mapp(fam)) fam = ([ ]);(刚 recruit_apprentice() 之后的除外)。

技能按另一门武功的等级取招(2026-10-15,KB 06 §7.243)

这些技能文件是从别的武功复制改名来的,query_action() 仍用原武功的等级查招式表:只会本技能的人等级为 0,取不到招,每次出招都报错。改为读本技能自己的等级(scripts/lpc_fix_action_level.py):quanzhen-jian、taixuan-gong。

把经验、属性、内力当技能读(2026-10-15,KB 06 §7.247)

经验、属性、内力上限不是技能,xkx/ES 的 query_skill() 对它们只返回 0(风云的还会去载入同名技能文件而报错)。改为 query("...")(scripts/lpc_fix_pool_as_skill.py):/quest/wudang/song 生成的任务怪物照抄玩家福缘(set("kar", who->query_skill("kar")),怪物福缘一直为 0)。

当前内力、精这类名字有时指的是内功技能,逐处读过后手改:落英缤纷 luoying-shenjian/lybf:自己的注释说成功率由“精神高低”决定,两处 query_skill("jing") 改为 query("jing")。

碧海生潮曲空手报错(2026-10-15,KB 06 §7.246)

iceforce/roar(碧海生潮曲)先 ob = me->query_temp("weapon"),再直接拿 base_name(ob) 判断是不是玉箫;空手 exert roar 时 base_name(0) 报错,提示“你必须先找一只玉萧来才可以吹--曲”根本出不来。条件前补 !objectp(ob) ||。

iceforce「chillgaze」从未编译通过(2026-10-15)

iceforce/chillgaze 原档在第一个 return notify_fail(...) 后多了一个 },exert() 就此结束,后面的语句全落在函数外,skill、damage 也没有声明,文件编译失败,这个 exert 从来用不了。照 bixiecanyang、hc、xyzx3 已修好的版本删去多余的 }、补上 int skill, damage;,其余字句不变,只是缩进进函数体。

技能名拼错(2026-10-15,KB 06 §7.249)

query_skill() 里的技能名拼错了,或用的是本库改名前的旧名;本库没有这个技能,调用永远得 0:门槛(< N 就拒绝)永远过不去,相关功夫或绝招学不了、用不了;内功互斥(> N 就拒绝)从不生效;公式里这一项一直是 0。经汉字名(提示文字或中文名词典)或纯拼写差异(_/-、少一个连字符、相邻字母颠倒)核对后,改为本库的技能名(scripts/lpc_fix_skill_typo.py):beimin-shengong→beiming-shengong(/d/quanzhen_old/kungfu/skill/xiantian-qigong、tiangang-zhengqi、xiantian-gong);douzhuan-xignyi→douzhuan-xingyi(/d/mr/npc/obj/shu1、/d/mr/obj/shu1);jinwu-dao→jinwu-daofa(jinwu-daofa);mizongxinfa→mizong-xinfa(longxiang/fanchang);yihua-jimu→yihua-jiemu(yihua-jiemu);zhenfen-xinfa→zhenfeng-xinfa(zfwy-bu)。

文件首行注释少了一个斜杠(2026-10-15)

首行的说明注释只剩一个 /(如 /kuangwu.c金蛇狂舞、/ cloth.txt //),文件第一行就语法错误、编译失败:全真教的布衣 /d/quanzhen_old/obj/cloth 因此从来载入不了。补回斜杠成为 // 注释,现在都能载入。

技能名拼错:技能文件里拼错自己的名字(2026-10-15,KB 06 §7.249)

技能自己的文件(或它的绝招目录)里,query_skill() 读的是差一个字母的自己的名字,永远得 0:“基本功夫要高过本技能”之类的限制从不生效,按等级取招、计算伤害的那一项一直是 0。改为本技能的名字(scripts/lpc_fix_skill_typo.py 的 self 判据):hujian-daofa→hujia-daofa(hujia-daofa);jinggang-quan→jingang-quan(jingang-quan);xuantie-jiafa→xuantie-jianfa(xuantie-jianfa);xuanxie-jianfa→xuantie-jianfa(xuantie-jianfa)。

family 映射内联取下标(2026-10-15,KB 05 §7.30)

ob->query("family")["master_name"]、me->query("family")["family_name"](泥潭式为 query("family", ob)[...])直接对门派映射取下标:没有门派的人(新玩家、叛师者、大多数 NPC)在 NPC 的打招呼和问话、绝招的门派判断、房间的 valid_leave 里报 Value being indexed is zero,而不是得到拒绝。8 处(6 个文件)改为 dbase 路径查询 query("family/master_name"):有门派时值相同,没有时得 0;原有的判断照常生效(scripts/lpc_fix_family_index.py)。给映射赋值的写法未动。

存档读不出来:字符串里的换行、空行(2026-10-15,KB 03 §4.4)

d/city/obj/bingqipu.o:字符串里有原样的换行(save_object() 存成 \r,restore_object() 逐行读,原样的换行让字符串收不了尾),或有空行(Illegal file format),读档的对象(留言板、NPC、玩家)从空白开始。换行改写成 \r、删去空行(scripts/lpc_save_encoding.py --from-raw),驱动核对全部能读回(scripts/lpc_save_restore_check.py)。

移进不存在的巫师房间(2026-10-15,KB 06 §7.251)

用完的物品、要“离开”的 NPC、掷在空中的兵器被移进巫师的工作室(/u/llm/、/u/wind/),本库没有这些房间。本库的 move() 用 load_object() 找目的地,找不到就返回 0,不报错,东西留在原处:被雇来打晕或杀人的李凌(d/city2/npc/liling2)办完事后没有离开,留在原地(d/city2/npc/liling2 本身还载入不了:create() 里 carry_object() 的物品文件缺失或编译失败,见 KB 06 §7.73,另行处理);婚礼结束(d/nanyang/npc/meipo 的 last_marry)时月老没有离开喜堂,每办一次婚礼喜堂里就多一个月老;喜宴结束后喜来福(d/nanyang/npc/xi-laifu)没有退回内堂,每办一次婚礼迎宾楼就多一个喜来福。3 个文件改为移进本库的虚空房间 VOID_OB(/clone/misc/void),与原作把它们“停放”在巫师房间的用意相同(haiyang2 的维护者把月老送进 /d/city/empty,也是同样的做法)。

玉女剑法「合壁」用一次就永久改动经验和剑法(2026-10-15,KB 06 §7.253)

收尾的 hebi() 声明时没有参数(void hebi() { object me, target, env; int i, j, o, p, count; ...),call_out 传进去的人和数值全被同名的局部变量(0)挡住,开头的 if (!me && !target) return; 每次都返回:合壁的攻击、闪避加成和 hebi 标记要到重新登录才消失。更糟的是夫妻判断写成了 target->querry("id")(没有这个函数,得 0),没成亲的人 marry/id 也是 0,于是人人都被当成夫妻:自己的玉女剑法和经验乘以玉女素心功的级数/80(至少变成浮点数,160 级以上翻倍),随后给对方 set_skill("combat_exp", ...) 时报 No such skill,收尾的 call_out 也就没排上,乘过的等级和经验永远不还原。测试里用一次合壁,经验 100000 变成 200000.0、剑法 100 变成 200.0。改正:hebi() 按它自己再次 call_out 时传的八个参数声明,perform 的 call_out 去掉多余的 h, k,querry 改为 query,给对方的 set_skill("combat_exp") 改为与上一行一样的 set("combat_exp")。测试里加成照常生效,hebi() 结束时还原并清除标记,没成亲的人经验和剑法不变。

NPC 带着本库没有的物品,载入失败(2026-10-15,KB 06 §7.73)

17 个文件、22 处在 create() 里 carry_object("<本库没有的文件>")->wear()(或 wield()、set_amount()):carry_object() 得 0,接着的调用报 Bad argument 1 to EFUN call_other(),NPC 根本载入不了,该有它的房间里就少了这个人。多是从别的系统搬来的 NPC 用了原系统的物品路径(最常见:/obj/cloth/cloth、/d/city/obj/tudao、/u/fan/gun)。每处改为 { object carried_ob = carry_object(...); if (carried_ob) carried_ob->wear(); }(scripts/lpc_guard_carry_object.py):NPC 照常出现,只是不带这件东西;文件补回来(或是虚拟对象)照样会带上。载入检查:改动的文件改前能载入 1 个,改后 12 个(11 个原来载入不了),没有退步;其余 5 个另有原因(多为 set_skill() 了本库没有的武功)。

物品清单把名字的第一个字吃掉(2026-10-18,KB 07 §8.1)

inventory、房间的物品列表(feature/move)和部分 look 把同名物品合并计数,键是 query("unit") + short(),只有一件时按 key[2..] 去掉量词。量词是一个汉字,在原来的 GBK 里占 2 字节,[2..] 正好去掉量词;转成 UTF-8 以后一个汉字只占一个下标,这一刀把名字的第一个字也切掉了(「把长剑」只显示「剑」,带颜色的名字切掉的是转义序列开头)。改为 [1..](scripts/lpc_fix_unit_cut.py):cmds/usr/inventory.lpc、feature/move.lpc。

水潭里 ging_cost 是 jing_cost 的笔误(2026-10-18)

shuitan 先算 jing_cost,倒水时却扣 receive_damage("jing", ging_cost),ging_cost 从没声明过:Undefined variable 'ging_cost',整个物件载入不了。改成 jing_cost:d/shaolin/npc/obj/shuitan.lpc。改后用 lpcc 逐个载入这些对象:1 个通过。

全真心法 valid_learn() 里没声明的 lvl(2026-10-18)

kungfu/skill/quanzhen-xinfa.lpc 的 valid_learn() 判断 me->query("gender") == "无性" && lvl > 49,可是函数里只有 nk、nf、nh、ns 四个变量,没有 lvl:Undefined variable 'lvl',这门心法的文件载入不了,学它、用它都失败。nh 正是全真心法的等级(nh = query_skill("quanzhen-xinfa", 1)),改成 nh > 49。改后用 lpcc 逐个载入这些对象:1 个通过。

补回丢掉的基类宏(2026-10-18,KB 04 §6.13)

inherit F_XXX; 里的宏本库任何头文件都没有定义,报 syntax error, unexpected L_IDENTIFIER, expecting L_STRING or '(',整个对象载入不了;宏指向的基类文件本库其实有,别的库都把这个宏定义成同一个路径。在全局头文件 include/globals.h 里补上:SSERVER → /inherit/sserver(3 个文件)、NPC_TRAINEE → /inherit/char/trainee(1 个文件)。(scripts/lpc_restore_macros.py)改后用 lpcc 逐个载入这些对象:4 个里 3 个通过,其余 1 个还有别的错误(d/xingxiu/npc/lingshe.lpc:Undefined function set_color)。

set_skill() 遇到本库没有文件的武功不再抛错(2026-10-18,KB 06 §7.256)

feature/skill.lpc 里的 set_skill()、map_skill()、prepare_skill() 碰到没有武功文件的名字就 error("F_SKILL: No such skill (…)"),调用它们的 NPC create() 整个中断:NPC 载入不了,刷出它的房间也少一个人。本库有 134 个对象设了本库没有文件的武功(64 个名字,最多的是 bingxue-xinfa、snow-zhang、snowstep)。三处都改成 return:这一门武功不给、不映射,对象照常载入,只是少了它(缺的武功本身仍是内容缺口)。抽样载入这些对象:29 个里 29 个通过。(scripts/lpc_guard_set_skill.py)

通向不存在房间的出口,按对面房间的回头出口改正(2026-10-18,KB 06 §7.257)

房间出口 "west": __DIR__"xxx" 指向的文件本库没有,玩家走过去就被卡住(笔误、改过名的房间,或者没带进档案的编号房间)。对面的房间存在、并且它相反方向的出口正好指回这个房间,说明出口原本就是通向它:/d/shushan/zhenyaota/tower 的 west:/d/shushan/d/shushan/jindi → /d/shushan/jindi。改动后每个出口都能解析到本库的文件(scripts/lpc_fix_dead_exits.py;目标在运行时本来就能载入的库——虚拟房间——不动)。

补回本库没有的基类文件(2026-10-18,KB 04 §6.15)

下面这些基类本库没有,继承它们的对象(房间、NPC、物品)整批载入不了(inherit XXX; 的宏没定义,或者 inherit "/std/…"; 的文件不在)。同系的库里有同名文件,两库有大量逐字节相同的文件(亲缘关系),所以从那边原样拷来,缺的宏补进全局头文件 include/globals.h:/inherit/weapon/rake(宏 RAKE)←wxddym,4 个对象继承它,抽样 4/4 载入;/std/weapon/archery(宏 ARCHERY)←hxxtjqb,2 个对象继承它,抽样 2/2 载入;/d/xueshan/obj/anqi-jian←hxxtjqb,2 个对象继承它,抽样 2/2 载入;/inherit/room/city1←fqyy2,1 个对象继承它,抽样 1/1 载入。每个基类补回后单独载入、再抽样载入使用它的对象,基类载不进来或者一个用户也载不进来的就撤掉(本库撤掉了它们,不再补)。(scripts/lpc_restore_bases.py)

武功名拼错的 NPC(2026-10-19,KB 06 §7.258)

set_skill("kunlun-shnfa", …)、map_skill("dodge", "shaolin-shnfa") 这样的调用把武功名拼错了:本库没有这个武功文件,有的是拼对的那个。以前这种 NPC 在 create() 里报 No such skill 载入不了;武功缺失时跳过之后它们能载入,可是少了那门武功(set_skill 被跳过,map_skill 映射不到,门派弟子用普通轻功/拳脚)。按核对过的对照表改正,共 18 处、17 个文件:yan-fly→yanfly(3 处)、xinxiu-duzhang→xingxiu-duzhang(2 处)、tiaji-jian→taiji-jian(2 处)、kongmingquan→kongming-quan(2 处)、taiji-shenfong→taiji-shengong(2 处)、lingbo-weibu→lingboweibu(2 处)、poyu-qua→poyu-quan(1 处)、literare→literate(1 处)等共 11 个名字。(scripts/lpc_fix_skill_names.py)

feature/damage.lpc 丢了 set_ghost()(2026-10-19,KB 06 §7.262)

feature/damage.lpc 里有 int ghost 和 is_ghost(),没有 set_ghost(int i);木人、狼等 NPC 在 create() 里调用它,整个 NPC 报 Undefined function set_ghost 载入不了。从 xkx100 补回这一行函数,受益 NPC 1 个:d/feitian/npc/wolf。(scripts/lpc_transplant_function.py)

删掉 exert_function(整数)(2026-10-19,KB 06 §7.266)

/d/city2/npc/wizer.lpc、/d/player/ltsh/npc/saveme.lpc create() 里的 exert_function(10); 把整数传给了要字符串的直接调用(让 NPC 闲聊时自己运功),驱动报 Bad type for argument 1 of exert_function ( string vs int ),整个 NPC 载入不了。这是存档里的笔误,不知道作者想传哪个字符串,删掉这一句(只影响闲聊时的运功表现)。chidi 的同一个 NPC 早先就是这样处理的。

找不到父类函数的 ::fn() 调用(2026-10-19,KB 06 §7.259)

/d/board/mianju_b.lpc共 1 个物件里写着 ::create();、::init(); 这类调用,而它们继承的基类并没有这个函数。老驱动把这种调用当成什么都不做、返回 0 的空调用,本驱动在编译时报 Unable to find the inherited function 'init'.,整个物件载入不了。这些物件的错误只有这一种(其他错误清掉之后才露出来的),逐个删掉这些调用(return ::fn(...) 改成 return 0;)。(scripts/lpc_fix_dangling_super.py)

区域物件的零碎修正(2026-10-19,KB 06 §7.267–§7.271)

逐个物件与 HEAD 对比载入,没有退步。

RANK_D 对 0 的称呼(2026-10-19,KB 06 §7.273)

adm/daemons/rankd.lpc 的 query_respect()、query_rude()、query_self()、query_self_rude() 里 4 个函数开头补上 if (!objectp(ob)) ob = this_object();。NPC 在 create() 里写 "…" + RANK_D->query_respect(this_player()) + "…"(inquiry 对话、chat_msg),驱动自己跑 reset() 时没有人在场,this_player() 是 0。旧驱动里 0->query("age") 返回 0,称呼走默认分支;新驱动直接报 Bad argument 1 to EFUN call_other(),房间的 make_inventory() 吞掉错误,被打死的 NPC 再也刷新不回来。用 scripts/lpc_reach_census.py --walk 找到(xkx100 的武当弟子、一灯、汴梁书生…);修在守护程序里,不动 1,800 个 NPC 文件。

玩家打造兵器模板被 NPC 带上(2026-10-19,KB 06 §7.275)

/d/npc/m_weapon/weapon/m_club.lpc、/d/npc/m_weapon/weapon/m_sword.lpc(共 2 个)的 create() 用 this_player() 读打造数据(me->query("weapon/lv") 等)。NPC 的 weapon 属性是兵器文件名(字符串),NPC 在别的 NPC 的命令环境里 carry_object() 这个模板时,set_desc() 里 switch (w_lv) 拿到的是那个字符串,驱动报 Bad argument 1 to switch,房间和 NPC 都载入不了(旧驱动里 switch 落到 default)。把 if (me) { 改成 if (me && mapp(me->query("weapon"))) {,玩家打造的流程不变。

玩家打造兵器模板没有打造者时(2026-10-19,KB 06 §7.275)

/d/npc/m_weapon/weapon/m_bian.lpc、/d/npc/m_weapon/weapon/m_staff.lpc、/d/npc/m_weapon/weapon/m_whip.lpc、/d/quanzhen/npc/obj/m_sword.lpc、/d/quanzhen_old/npc/obj/m_sword.lpc(共 5 个)的 create() 开头 me = this_player(); 之后无条件读 me->query("weapon/name") 等打造数据。房间刷新时没有人在场(me 为 0),或者 NPC 在别的 NPC 的命令环境里 carry_object() 这个模板(NPC 的 weapon 属性是文件名字符串),旧驱动里读出来是 0 或字符串,switch 照样落到 default;新驱动报 Bad argument 1 to EFUN call_other() / Bad argument 1 to switch,NPC 和它所在的房间载入不了(--walk 普查里一个玩家走进房间就触发)。在 //读入数据 之后加 if (!me || !mapp(me->query("weapon"))) { setup(); return; }:没有打造者就留一个没有名字的空模板,玩家打造的流程不变。

补回丢失的标点(2026-10-19,KB 03 §4.6)

转换时丢掉的分号、逗号、引号或文件末尾的 },共 4 个文件,修前 HEAD 载入失败。别的库里同路径的完好副本只比这里少几个标点,按它补回(括号里是那个库):/d/baituo/npc/obj/bowl.lpc(cctx)、/d/baituo/obj/bowl.lpc(cctx)、/kungfu/skill/huang.lpc(bixiecanyang)、/quest/murong/qlist3.lpc(bixiecanyang)。修后与 HEAD 逐个对比载入:这 4 个物件全部载入,没有退步(scripts/lpc_restore_from_twin.py、lpc_fix_eaten_quote.py --comma、lpc_fix_eof_braces.py)。

== !"字符串" 多出来的 !(2026-10-19,KB 06 §7.280)

!"taoist" 是整数 0,x == !"taoist" 就是“x 等于 0”,作者为其余所有人写的那一支永远走不到。具体是:龙女对古墓弟子的机关暗门提示永远给不出来(5 处);孙婆婆的“你去吧”只对 class 没设置的人生效;性别检查(“你不是女的,无法领会其中至阴之理”)永远不拦人,男的照样能学玉女心法。全部改成 != "字符串"(scripts/lpc_fix_not_literal_cmp.py):/kungfu/class/gumu/long.lpc(5 处)、/kungfu/class/gumu/sunpopo.lpc(1 处)、/kungfu/skill/yunu-xinfa.lpc(1 处)。同样的行在 xkx 一系的 35 个库里都有。

x != "a" || x != "b" 和 x == "a" && x == "b":同一个值的比较链永远成立/永远不成立(2026-10-20,KB 06 §7.282)

if (arg != "wan" || arg != "丸") return notify_fail(...) 对任何 arg 都为真,dir == "south" && dir == "north" 永远为假:条件下面的守卫要么永远拦、要么永远不拦。作者要的是“既不是 A 也不是 B”(&&)或“是 A 或 B”(||)。!= 链的 || 改成 &&(仅当条件下面是 return 的拒绝/守卫),== 链的 && 改成 ||(scripts/lpc_fix_cmp_chain.py)。具体是:客栈小二从不拦住付了房钱又往南/往北走的客人;百日十龙丸怎么 eat 都只得到“你要吃什么?”。改动:/d/changan/ca2.lpc(1 处)、/d/longmen/xuehepai/obj/bairiwan.lpc(1 处)。

if (x = 常量):条件里写成赋值的比较(2026-10-20,KB 06 §7.290)

if (arg = "button" || arg = "按钮")、if (!arg || arg = "") return 0;、else if (check = 0 && tempB != ""):把 == 写成了 =,条件的值就是那个常量,分支对所有非零数和任何字符串(连 "" 都算)永远成立、对 0 永远不成立,变量还被覆盖;驱动对此没有任何警告。每一处 = 改成 ==(scripts/lpc_fix_cond_assign.py,共 6 处);其后 x == "a" && x == "b" / x == "a" || "b" 这类被 == 暴露出来的链也随之改成 || 或补全变量(/d/hainan/npc/xianhe.lpc、/d/hainan/npc/xiaohe.lpc)。改动:/d/hainan/npc/xianhe.lpc(3 处)、/d/hainan/npc/xiaohe.lpc(3 处)。

登录密码超过 255 字节:crypt() 抛错(2026-10-20,KB 06 §7.294)

驱动的 crypt() 对超过 255 字节的密钥直接报错(Error in crypt(), check your salt),老驱动则按任意长度散列。在登录提示符下输入 256 字节以上的密码,密码检查那一行就抛错,连线停在一个裸的 > 提示符上,登录走不完(password 指令的旧密码检查同样);用 300 个 x 当参数的扫描发现的。/adm/obj/simul_efun.lpc 里补了一个同名的 simul_efun crypt(key, salt):只有超长的密钥才被截短(先截到 255 个字符,再逐字符截到 sizeof(to_buffer(key)) <= 255,限制按字节算,一个汉字占三个字节),再交给 efun::crypt();普通密码原样散列,已存的密码散列不受影响(scripts/lpc_add_sefun.py crypt)。

翻页器 start_more(read_file(...)):文件缺失时 explode(0)(2026-10-20,KB 06 §7.300)

东方故事系的翻页器 void start_more(string msg) { ... explode(msg, "\n") ... } 被这样调用:start_more(read_file(HELP_DIR + "help/topics"))、start_more(read_file(NEWS))。压缩包没带的文件使 read_file() 回 0,explode(0, ...) 在本驱动里报 Bad argument 1 to explode()(不带参数的 help 指令就是这样出错的),老驱动把 0 当空文本。在 start_more 开头加了 if (!stringp(msg)) return;(scripts/lpc_fix_start_more.py)。改动:/feature/more.lpc。

NPC 的 chat() 在 chat_msg 为空数组时下标越界(2026-10-21,KB 06 §7.334)

NPC 基类的 chat() 是 if (arrayp(msg = query(...))) { if (random(100) < chance) { rnd = random(sizeof(msg)); if (stringp(msg[rnd])) ...,不检查列表是否为空。本库现有的 NPC 文件里没有字面写成空 chat_msg 的(扫描只认 set("chat_msg", ({ })));守卫挡的是运行时才为空的列表和以后新增的 NPC。在 random(100) < chance 前面加 sizeof(msg) &&(scripts/lpc_fix_chat_empty.py;if (random(100) > chance) return 0; 的写法是 !sizeof(msg) ||)。改动:/inherit/char/npc.lpc(共 1 个文件)。

yaoqing:#include "/data/npc/npcneed.h" 的头文件不在存档里(2026-10-21,KB 06 §7.270 的同类)

cmds/usr/yaoqing.lpc(帮会邀请 NPC 入伙的命令;tiexuejianghu 的与 fys 逐字节相同,wmkj 的是它的 qi/xiha 改写版)第四行 #include "/data/npc/npcneed.h",那是一个数据头文件(mapping npcneed = ([ "shedan gao": "蛇胆膏", ... ]),NPC 向玩家索要的东西),fys、tianxiawuxue、tybxjh、wlhd、xiyouji2003、yxcs、yxjh、zxty、zxty08nxgbb 都带着,这两个存档没有:Cannot #include /data/npc/npcneed.h、Undefined variable 'npcneed',整条命令不加载。从 fys 复制(6,473 字节)。实测 yaoqing 回答 “你没有参加任何帮会,无法邀请他人加入。”。表里的东西是 fys 世界里的物品,在这个库里能不能找到没有核对(只影响这个任务的内容,不影响命令)。没有改:xhcii 的 whotest(who 的半成品实验版,行被拼在一起)、xianlvqiyuan 的 pperform(obj 没有声明的手改副本)。

socket:dump_socket_status() 在本库没有(2026-10-21,KB 06 §7.291)

管理员扫描里 socket 指令(/cmds/bos/socket.lpc)编译不了:write(dump_socket_status()); 用的是 MudOS 有、本驱动没有的 efun。2026-10-20 的补丁只按名字找了巫师目录里的同名指令,这一条在 cmds/bos、cmds/hufa、cmds/island、cmds/ser 这类目录里;用 scripts/lpc_add_sefun.py dump_socket_status 在 /adm/obj/simul_efun.lpc 末尾补了一个由 socket_status() 构造表格的 simul_efun(没有 sockets 包的构建,比如 WASM,只打印表头)。指令 HEAD 编译失败,现在通过。

睡袋:/cmds/adm/bag 本库没有,使用者被留在聋哑状态(2026-10-21,KB 06 §7.344)

clone/misc/sleepbag.lpc、sleepbag2.lpc 的 do_sleep() 在设好 block_msg/all、no_get 和房间的 sleeping_person 之后调用 "/cmds/adm/bag"->main(me, "<休息中>")。这条巫师指令只有 hc、tianxiawuxue 带着,本库没有:call_other() couldn't find object '/cmds/adm/bag',玩家之后什么消息也收不到(look 一片空白),十秒后的 wakeup call_out 没有排上,房间一直 no_fight。城里的小贩 xiaofan 卖这个睡袋,没有人在扫描里买过它。bag 的全部内容就是 me->disable_player(msg)(feature/command.lpc 里的 nomask void disable_player(string type),没有权限检查),两个文件都改成直接 me->disable_player("<休息中>");。chidi 上实测:sleep 之后十秒 "你一觉醒来,只觉精力充沛",look 正常(HEAD 上玩家被留在空白屏里,log/debug.log 有 trace)。改动:/clone/misc/sleepbag.lpc、/clone/misc/sleepbag2.lpc。

mapp:全局变量不能写 varargs(2026-10-21,KB 04 §6.28)

varargs mixed m; 和 varargs string *rfile; 是 mapp 指令的两个全局变量,本驱动只允许函数用 varargs(Illegal to declare varargs variable.),指令编译不了。去掉两处 varargs。

香烟 smoke.lpc:do_smoking() 读没赋值的 me(2026-10-21,KB 06 §7.348)

smoke 指令的第一句是 jing = me->query("jing"),me 声明了没赋值,每次抽烟都抛 Bad argument 1 to call_other()。补 me = this_player();(后面的 this_player() 调用不变)。改动:/d/emei/user-room/melodies/smoke.lpc。

注册到不存在函数的 add_action(2026-10-21,KB 06 §7.349)

add_action("函数", "动词") 绑定的函数,在对象本身、它包含的头文件、它继承的父类和继承它的子类里都没有定义(scripts/lpc_scan_callout_targets.py 静态解析,子类用传递闭包复核,scripts/lpc_verify_handlers.py 运行时 function_exists() 复核)。驱动从玩家最新的一条动作往回找,遇到这样的句子就报 *Function for verb 'drop' not found.,同一个动词的其他处理函数不再尝试(不是最新的一条就悄悄跳过)。删除了 45 条注册(39 个文件,scripts/lpc_fix_dead_add_action.py),动词留给别的处理函数:/d/city/chatroom2.lpc(do_jump)、/d/city2/qishi.lpc(do_pass)、/d/city3/npc/sister.lpc(do_vendor_list)、/d/feitian/npc/biguqing.lpc(do_accept)、/d/gumu/duanchang.lpc(do_no、do_tiao、do_yes)、/d/japan/npc/daxiong.lpc(do_vendor_list)、/d/japan/npc/paotang.lpc(do_vendor_list)、/d/japan/npc/shantian.lpc(do_vendor_list)、/d/player/yysz/hupan.lpc(do_han)、/d/quanzhen/npc/haodatong.lpc(do_decide) 等共 39 个文件。最多的函数名:do_send 15 处、do_vendor_list 8 处、do_decide 7 处、do_jump 2 处、do_pass 1 处。没有动(读过):/d/shushan/npc/daboss.lpc 的 do_vendor_list(对象本身编译不过,登记留着,等对象能加载再处理)、/d/shushan/npc/daboss.lpc 的 do_vendor_buy(对象本身编译不过,登记留着,等对象能加载再处理)。

对象路径里的 ..:new(__DIR__ "../obj/x") 报 Read access denied(2026-10-22,KB 06 §7.351)

__DIR__ 是当前文件所在目录(带结尾斜杠),__DIR__ "../obj/x" 就是 /d/zhiye/npc/../obj/x;驱动的 legal_path() 不接受带 .. 的路径,new() / load_object() 直接抛 *Read access denied.(实测,find_object() 对它答 0)。走库自己的 carry_object() / 房间 objects 表的路径,库的基类会先规范化,能用;直接把路径交给 new() / clone_object() / load_object() / move() 的不行,调用到那一步才报错。改成规范化后的绝对路径(scripts/lpc_fix_dotdot_dir.py --direct):/d/wudang/npc/xiaocui.lpc(__DIR__ "../obj/nuerxiang" → "/d/wudang/obj/nuerxiang")。

商人的 list 命令:登记的是另一个血统的函数名(2026-10-22,KB 06 §7.349)

第 42 批把 add_action("do_vendor_list", "list"); 当成死登记删掉了(这些文件里没有 do_vendor_list,输入 list 只会得到 *Function for verb 'list' not found.),但它们的商人基类里同一个工作的函数叫 do_list,list 动词就此没了:/d/shushan/npc/jiuboss.lpc。按真正存在的函数名放回 add_action("do_list", "list");;用库的管理员账号克隆 NPC 再输入 list 实测(/d/shushan/npc/jiuboss.lpc:你可以向马老板购买下列物品: 五香花生(Huasheng): 三十文钱 翡翠豆腐(Doufu): 四十文钱 茶壶(Ket),每个文件都列出商品或问要看哪一类。同一批里放回去后仍答 什麼?、没有商品或者列表时报错(货品文件缺失)的商人没有动。

缺失物品的 new() / carry_object() 调用链加了保护(2026-10-22,KB 06 §7.73 补充)

new(路径)->move(...); / carry_object(宏("x"))->wear(); 这类语句,路径指向的文件在这个压缩包里没有:new() 返回 0,->move() 在 0 上报 Bad argument 1 to EFUN call_other()。在 create() 里这个对象永远加载不了,在 reset() 里第一个缺失物品之后的刷新每次 reset 都被跳过。5 个文件里 7 处(new)改成 { object new_ob = new(路径); if (new_ob) new_ob->move(...); }(scripts/lpc_guard_carry_object.py --new:路径按这个文件自己看到的宏解析,宏名冲突、虚拟对象路径一律跳过)。 对这 5 个改动文件做加载检查(HEAD 与工作区对比):HEAD 能加载 5 个,现在 5 个(新增可加载 0 个,回归 0 个)。

调用了、但这个库自己的守护进程里没有的函数(2026-10-22,KB 06 §7.354)

MACRO->函数() 调用的函数在这个库的守护进程里不存在:call_other() 对不存在的函数不报错、只返回 0,所以这些功能(时间显示、昼夜事件、名字检查、价格文字……)一直没起作用。同一血统另一个库的同名守护进程里有这些函数,原文照抄到本库守护进程末尾(scripts/lpc_port_function.py;调用处传的参数个数、函数体用到的函数 / 全局变量 / 宏 / 字符串键都在本库里有,已核对;守护进程在 HEAD 和工作区都能加载,每个函数用固定参数各调用一次:HEAD 返回 0,现在返回正常的值):/adm/daemons/natured.lpc ← aoxiangtianji:room_event_fun()(9 处调用);/adm/daemons/chinesed.lpc ← fengyun434:check_control()(1 处调用)、check_length()(5 处调用)、check_return()(1 处调用)、check_space()(1 处调用)、check_chinese()(1 处调用)。

(: 函数 :) 指针指向对象自己没有定义的函数(2026-10-22,KB 06 §7.355)

item_desc / inquiry / chat_msg_combat 里的 (: 函数名 :) 指向本对象(含包含文件、继承的父类)没有函数体的函数:编译不报错,用到时驱动报 *Undefined lfun pointer called: 函数名(look 某物、ask NPC about 话题 直接出错,战斗 / 闲聊里的指针在 NPC 的 chat() 里出错,这一拍心跳的后半段被跳过)。scripts/lpc_scan_callout_targets.py --kinds=lfun。 还剩 15 个函数没有补(inquiry 9, item_desc 5, chat_msg 1):原型还在函数体丢了、或者根本没写过,没有可以直接补回的捐赠(别的库同一路径的文件里没有这个函数,或者它还要用本库没有的辅助函数、签名不同),不编造:/d/city/npc/hua_girl.lpc:ask_me、/d/city/npc/zhuziliu.lpc:give_job、/d/city/npc/zhuziliu.lpc:task_ok、/d/feitian/npc/luo.lpc:kungfu_asked1、/d/feitian/npc/shiren.lpc:away、/d/npc/guojing.lpc:ask_job、/d/npc/guojing.lpc:ask_gonglao、/d/npc/guojing.lpc:ask_fangqi、/d/npc/guojing.lpc:ask_jianxi、/d/player/xth/clc1.lpc:look_CAI 等另外 5 个。

读不到的留言板:"/clone/board/x"->foo(); 在 create() 里报错(2026-10-22,KB 06 §7.357)

xkx 系的房间在 setup() 之后写 "/clone/board/gaibang_r"->foo(); 来加载留言板(foo() 本来就没有定义,只为了触发加载)。这个库没有这个文件,call_other() 报 *call_other() couldn't find object '/clone/board/gaibang_r',对象留在内存里、load_object() 却抛错:玩家第一次走进房间就看到错误,写在 create() 中间的还会切掉后半段。scripts/lpc_fix_missing_foo.py 把 2 条单独成行的语句(/clone/board/tangmen_b、/clone/board/tiezhang_b;/d/tangmen/chashi.lpc、/d/tiezhang/guangchang.lpc)注释掉并写明原因(别的房间里同样的语句本来就是作者自己注释掉的)。证明和 45 个库的整体加载检查见 KB 06 §7.357。

log/ 下的日志子目录没有人建:写日志的 write_file() / log_file() 报错(2026-10-22,KB 06 §7.358)

这个库的代码往 log/ 的 1 个子目录写日志:log/doc/register(cmds/usr/helpbbs.lpc)。压缩包、git clone 和站点包里都没有这些目录(本地启动没有写过它们,gen_keep_dirs.py 没记),write_file() 对不存在的目录抛 *Wrong permissions for opening file /log/dlog/money for append. "No such file or directory",调用它的函数在写日志那一行中断,后面的奖励、标志、步骤都没有执行。本库的 log_file() 会自己建目录(实测,或读源码:nitan 系的 assure_file()),所以这里只记了直接用 write_file() / save_object() 写的目录。把 log/doc/register 记进 scripts/wasm_keep_dirs.txt(scripts/lpc_keep_log_dirs.py;站点和 pristine 树按它建空目录)。证明(scripts/lpcc_eval.py,在 /adm/daemons 这类目录下的求值对象里写 /log/zzdirprobe/...,新进程)见 KB 06 §7.358 的实测表。

(: 函数名 :) 指针指向本库没有的函数:只含这个指针的行加了注释(2026-10-22,KB 06 §7.355 补充)

inquiry / item_desc / chat_msg* 里的 (: 函数名 :) 指向本对象(含包含文件、继承的父类)没有函数体的函数:用到时(ask、look、NPC 闲聊)驱动抛 *Undefined lfun pointer called: 函数名,这一拍心跳的后半段被跳过。这些函数没有可以补回的来源(别的库同一路径的文件里没有,或者它还要用本库没有的东西),所以 9 个文件里 10 行只含这个指针的行("song": (: ask_me :), "杀": (: kungfu_asked1 :), (: away :),)加了注释,原文保留并写明原因,这一项当作没有这个话题 / 物品 / 闲聊条目(scripts/lpc_fix_dangling_lfun.py;#include 的文件在库里缺失的对象、指针不在整行上的写法没动)。 前提(function_exists())和加载检查(HEAD 与工作区对比,本库改动的 .lpc 文件)的结果见 KB 06 §7.355:没有一个回归。

写死的 "/路径"->函数() 指向库里没有的文件:改成现存的同名文件(2026-10-22,KB 06 §7.359)

1 处语句级的 call_other 字面量路径,库里没有这个文件(区域改了名 / 大小写不对 / 差一个字母 / 文件挪了地方):"/d/mj/obj/baihong-jian"->move()(/d/mingjiao/npc/yingwang.lpc)→ "/d/mingjiao/obj/baihong-jian"。call_other() 对不存在的对象抛 couldn't find object,所在函数当场中断。改成库里现存、并且定义了被调用函数的文件(scripts/lpc_fix_call_path.py;巫师目录、备份目录、名字不同的兄弟文件都不算候选)。 其中殷天正(白眉鹰王)的 do_answer():玩家念对暗语(answer 怜我世人,忧患实多;保护教主,同抗外敌)时把白虹剑 move 给玩家,区域目录改名 mingjiao 之后这个路径没跟着改,回答暗语只得到 couldn't find object,剑永远发不出来。

汉字按字节切片的老写法没有换成按字符:改法名 "澄" + name[2..3]、辈分判断 name[0..1] == "澄" 等 19 处(2026-10-22,KB 06 §7.360)

原档按字节算字符串区间(一个汉字 2 字节):name[2..3] 是名字的第二个字,name[0..1] == "澄" 问名字是不是以「澄」开头。转成 UTF-8 之后,这个驱动的区间和 strlen() 都按字符算(strlen("澄观") 是 2,"澄观"[0..1] 是两个字),老算术原样留着、意思全变:拜入少林 / 武当 / 峨嵋等派的玩家被改成错误的法名(二字名 张三 变成一个字的 澄,更长的名字取到第三个字);各派掌门的辈分判断(name[0..1] == "澄")永远不成立。

本库 19 处(14 个文件):拼名字的赋值 11 处、与汉字常量比较 8 处。例:name[2..3] → name[1..1](/kungfu/class/emei/jingxin.lpc:101);name[0..1] → name[0..0](/kungfu/class/shaolin/qing-fa.lpc:100);name[0..1] == "慧" → name[0..0] == "慧"(/kungfu/class/shaolin/cheng.h:108)。scripts/lpc_fix_gbk_slice.py 把下标按字符重算(社区的 UTF-8 版 xkx100utf8 里就是同样的写法,作对照);没有改的:截断(name = name[0..7],现在最多 8 个字,只是放宽)、ASCII 的区间(fname[0..3] == "room"、ctime(time())[4..19])和上下文看不出是汉字的区间。证明(scripts/lpcc_eval.py,bixiecanyang;其余各库是同一份文本):让澄字辈掌门 attempt_apprentice() 一个名叫「张三」的访客,HEAD 的法名是 慧,改后是 慧三;抽样 28 个库的 HEAD / 工作树加载对比 0 退步。工具不幂等([0..3] 折半得 [0..1],又是对齐区间),改过的文件记在 scripts/gbk_slice_converted.txt,不要重跑。

长度检查按字节写,旁边的提示按汉字写:22 处(2026-10-22,KB 06 §7.362)

老档的 strlen() 数字节(一个汉字 2 字节),转成 UTF-8 后它数字符:提示写「必须是 2 到 6 个中文字」的检查还是 strlen(name) < 4 || strlen(name) > 12,于是两三个字的房名、帮会名、群名、聊天室名、称号被提示自己说允许的那句话拒绝,上限却是提示的两倍;留言板的标题检查 i < 4 || i > 24 || i % 2 还会拒绝所有奇数个字的标题(post 你好吗)。本库 22 处(11 个文件):if ((strlen(name) < 2) || (strlen(name) > 10)) {(/adm/daemons/复件 logind.lpc:908);if ((strlen(name) < 2) || (strlen(name) > 12)) {(/cmds/bakcmds/csc.lpc:611)。scripts/lpc_fix_strlen_gate.py 以提示为准:条件里每个 strlen 门槛都恰是提示所说数字的两倍才折半,存长度的变量(i = strlen(arg);)的门槛和 || i % 2 奇偶项、其后循环的 i % 2 == 0 && 一并处理;提示里有英文 / 字母 / 字节的不动。证明(scripts/lpcc_eval.py,bxsj 的留言板,求值对象继承 NPC 并重写 edit() 记录调用,command("post 标题")):HEAD 拒绝「你好」和「你好吗」、放行 23 个字的标题;改后接受前两个、拒绝第三个;shenmo 的 named.lpc invalid_new_name("张三"):HEAD 回 名字只能是2-4个中文字。,改后回 0。抽样 24 + 15 个库的 HEAD / 工作树加载对比 0 退步。

按字节写的汉字循环、茶馆猜诗和同盟频道标题(2026-10-23,KB 06 §7.363)

老档按字节做「一个汉字」:while (i--) if (i % 2 == 0 && !is_chinese(name[i..<0])) 只检查偶数下标,奇数位上的拉丁字母(张a)会过;茶馆猜诗 mixup() 用 strlen(str)/2 再 j=j+j、str[k..k+1] 交换两字节;泥潭系 channeld 的 switch (strlen(fname)) case 4/6/8/10 和 strlen(family)==4/6 按字节长度给同盟 / 门派名加空格。本驱动的 strlen() 和区间都按字符算。scripts/lpc_fix_byte_char.py:去掉奇偶项、把区间改成 name[i..i],按字符重写 mixup() 并把 strlen(first)>=14 折成 7,频道标题的 case / 门派长度改成字符数(对照 aoxiangtianji)。本库 汉字循环 / is_chinese 区间 14 个文件。证明(scripts/lpcc_eval.py):sjplii 的 check_legal_name 在 HEAD 接受「张a」、改后拒绝,两边都接受「张三」;xkx100 的 clubpoem->mixup("离离原上草") 得到「离离原草上」(真交换汉字);nitan_san 两字同盟名得到 【 兄 弟 】。关键对象加载通过。

血条 / 表情标题按字节算显示宽度(2026-10-23,KB 06 §7.365)

老档把汉字当两字节:bar_string[0..(val * N / max) * 2 - 1] 把「格数」换成字节下标,半格血条在本驱动(按字符算区间)上会整条画满;巫师表情 edemote 的 repeat_string("─", 13 - (strlen(emotion) / 2)) 也会少减汉字宽度。scripts/lpc_fix_display_pad.py:去掉 CJK 血条 / 空白条上的 * 2(jings/qis 赋值和 blank_string3[0..(23-a)] 的 23→11 一并改),表情标题去掉 / 2;ASCII 空格的 none_string / empty_string 仍保留 * 2(一格两个空格)。本库 2 处(1 个文件)。证明(lpcc_eval.py hhsj):tribar_graph(6,9,12) 在 HEAD 画出整条 12 个■,改后为 6 个■+3 个□;麻将 strlen(tempB)/2 是两字符牌码,未改。

Beyond 出口仍指向 /u/beyond(2026-10-23,KB 06 §7.368)

宁波 / 苏州 / 慕容等区域已进 /d/ningbo、/d/suzhou、/d/mr、/d/hz,出口与任务物路径仍写 /u/beyond/…。scripts/lpc_fix_beyond_exits.py 在目标 .lpc 存在时改写(murong→mr)。本库 1 处。证明:sjplii xikou HEAD 西向 /u/beyond/ningbo/aywsi,改后 /d/ningbo/aywsi 可加载;bxsj hubian1 三向均可加载。

死巫师出口 gold/dock、sunrise、mei(2026-10-23,KB 06 §7.370)

/d/wanjiegu/road4 东向 /u/g/gold/dock、峨眉寿星居南向 /u/xinyue/sunrise_room、玩家卧室通往 /u/mei/… 均无对应房间。scripts/lpc_fix_drop_dead_u_exits.py 删除这些出口行,并去掉同方向的 create_door(否则 create_door 无出口会炸)。本库 5 处。证明:zxty08nxgbb 的 road4 HEAD 有东向,改后没有;mei_room1 可加载。

中文名 / 验证码仍按 GBK 取「两字节一字」(2026-10-23,KB 06 §7.373)

pname = pname[(random(sizeof(pname)) & 0xFFFE)..<1]; pname = pname[0..1]; 在按字符计下标时会取出两个汉字。scripts/lpc_fix_pname_slice.py 去掉掩码并把收尾改成 [0..0](pname/pname2/sec_name/str/str1)。本库 4 处。证明:nt1 生成名长度 2–4;HEAD 常见 3–5。

example/book 注释折行无法加载(2026-10-27,KB 04 §6.25 Also)

obj/example/book.lpc 的 // name of the skill 等注释被折行,下一行 the skill 成了裸标识符,驱动报 unexpected L_IDENTIFIER。用手足 sjsh 完好副本覆盖。证明:HEAD 加载失败;改后加载成功。

hanbing `random 反引号(2026-10-27,KB 04 §6.25 Also)

hanbing-mianzhang / hanbing-mianzhang2 在 random( 前多了一个反引号,驱动按模板字面量读到 EOF。删掉。证明:HEAD 失败;改后加载。

深度功能测试(2026-10-27,§6.25 zhongling tell_object 引号错位)

d/wanjiegu/npc/zhongling(及同路径副本)的 tell_object("who, 钟灵脱下一双绣花鞋。\n") 把对象参数写进了字符串;改为 tell_object(who, "…")。证明:原文错位;改后加载,语料残渣 0。

深度功能测试(2026-10-27,§6.25 tell_object 缺 me(自动放弃/愿否))

一参 tell_object("…") 在已有 me 时改为 tell_object(me, "…")(city.lpc, city1.lpc)。证明:抽样 city / xiaolongnv 加载。

深度功能测试(2026-10-27,§6.25 one-arg message_vision)

message_vision("…") 补第二参(me / TP / this_player())。

深度功能测试(2026-10-27,§6.10 未知 pragma save_binary/optimize)

删除本库中 FluffOS 不认的 #pragma save_binary / #pragma optimize… 行。