info.html · 介绍 · play.html · 游玩 · llms.txt · 下载与本地运行 · ZIP · GitHub
自称 【随缘洗剑录】,是"ES II"引擎家族的一员(与本项目中的神州、火影、武汉站等同宗),由 Annihilator 等人在原始 ES II 基础上多次改写而成,是一款有较长运营历史的老牌武侠 MUD。玩家从扬州"随缘客栈"起步,古龙笔下的浪子李寻欢会热情引导新手熟悉基本指令;玩法延续经典武侠养成路线——属性天赋抽取、门派拜师、武功修炼、江湖闯荡,风格朴实,没有花哨的额外系统。扬州广场常驻一个不算常见的彩蛋 NPC"圣诞老人"(随缘节日大使),全年送上节日祝福;死亡则有完整的鬼门关体验,由"白无常"接引,落脚在扬州武庙复活,鬼魂状态下无法移动,只能原地等待复活完成。
English
Self-titled "Sui Yuan Xi Jian Lu" (roughly, "the chronicle of washing one's sword as fate wills"), a member of the ES II engine family — kin to this archive's Shenzhou, Huoying, and Wuhan-station titles — repeatedly rewritten from the original ES II base by Annihilator and others, and a long-running, well-established wuxia MUD in its own right. New players start at the Chance Inn (随缘客栈) in Yangzhou, where Li Xunhuan — a wandering-swordsman character borrowed from Gu Long's novels — greets arrivals and walks them through the basics; play otherwise follows a classic, unadorned wuxia arc of stat rolling, sect apprenticeship, martial-arts training, and roaming the jianghu. Yangzhou's main square carries an unusual, permanent easter egg: a "Santa Claus" NPC (随缘节日大使) who hands out holiday greetings year-round. Death sends a character through a full ghost/afterlife sequence, escorted by the White Guard of Impermanence to the War God Temple (武庙) for revival, with the character unable to move until the process completes.
README
内容亮点
- 更正(2026-08-05):上面提到的"7.68 复活软锁"修复已经撤销——经重新评估,鬼魂"不在场"时放弃复活流程更可能是有意的游戏设计(多数这类档案里鬼魂本身就无法自行移动,离开是一种游荡机制,回来时 init() 会重新触发流程),不是需要强制重试的 bug;详见 NOTES.md。
深度功能测试新发现的 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,已修复并现场完整验证。同一系统里的
bgargoyle.lpc(黑无常)发现了一个更严重的变体:death_stage()
函数整个被注释掉,导致 init() 排程的 call_out 永远静默调用一个不
存在的函数,任何走到黑无常面前的人(正常玩法里鬼魂无法移动,实际
不可达)会被永久晾在原地——已恢复函数体并按标准修法修复。另外发
现并修复了两个和死亡系统无关的独立 bug:防刷屏踢人逻辑在
command("quit") 销毁玩家物件后仍继续执行,每次踢人都在
debug.log 留下一条运行时错误;广场彩蛋 NPC"圣诞老人"引用的一件
存档里从未存在过的物品文件,导致每次这个 NPC 被克隆都报错。以及一
个和姊妹会话(yhyxs/yanhuangwuhun)同类的 extensionless GBK 文
本残留:真正的 137 项姓名黑名单(adm/etc/banned_name)从未被转
码,运行时的自我播种逻辑悄悄用一份只有 6 项的弱化兜底列表顶替了原
本的内容审核名单——已转码恢复原始的完整名单。
在线试玩
https://mudlibs.fluffos.info/syxjl/
管理员账号 / Admin account
- ID:
fluffos - 密码:
Mud@2026 - 中文名: 浮浮
- 权限:
(admin)(本 mudlib 巫师等级表的最高级别,上线时以【巫师】 头衔公告) - 权限授予方式:
/adm/etc/wizlist数据文件追加fluffos (admin)。 - 登录小提示:连接后先回答 GB/BIG5 编码选择(输入
gb),然后有一个 容易被淹没在站点列表里的 "Press Enter to Continue..." 提示,需要多 敲一次回车才会出现英文名字提示。
警告:对外公开架设前请务必修改此密码。
本地运行
cd libs/syxjl
~/src/fluffos/build-debug/src/driver config.fluffos游戏端口:40088。
NOTES · 移植与修复记录
随缘洗剑录 (syxjl) — NOTES
Archive #96: archives/随缘洗剑录.rar ("Record of Sword-Washing by Fate").
What this lib is
An ES II-lineage MudOS v22 wuxia mudlib. Confirmed via adm/obj/master.c's
own header comment: // for ES II mudlib, // original from Lil,
// rewritten by Annihilator (11/07/94), plus a later 98-10-23 upgrade
credit to ken@XAJH and a securityd.c credit to aeolus 12/25/2000. This
is the same lineage family as many previously-done libs in this project
(yueyingqiyuan, wuhanzhan, huoying, shenzhou, yanhuangwuhun, etc.) — same
adm/daemons/securityd.c ACL-table shape, same feature/dbase.c real
local set/query/delete implementation (i.e. NOT the nitan-family
bare-simul_efun dbase architecture bug, §15 — this lib inherits F_TREEMAP
and has genuine per-object storage, confirmed safe).
The raw archive's mudlib root is syxjl/world/ (syxjl/config.cfg points
mudlib directory : ../mud/world, master file : /adm/obj/master). The
directory shape (adm/, clone/, cmds/, d/, feature/, inherit/,
kungfu/, maxim/, obj/, quest/, task/, u/) and content (kungfu/
skill-class directories, 客栈/李寻欢 starting NPC, 明教/武当/嵩山/衡山 etc.
zone names) are standard wuxia-genre ES II content — nothing suggesting a
closer match to any more specific already-done sibling lib than "generic ES
II family", so no forced lineage claim beyond that.
Archive also bundled a prebuilt Windows driver (mudos.exe/mudos.dll,
May 1998) and an addr_server binary — both left untouched/ignored per the
pipeline (we use our own FluffOS build).
Port
40088 (per TODO.md's reservation for archive #96 in the #92-96 batch).
Fixes applied (with why)
1. §15ao — switch(port){ default: ... } with no real case in
master.lpc's connect(). Hard parse error on this driver (a switch
needs at least one real case label). There was no actual branching on
port in the original code anyway (default: was the only clause) —
rewrote as a plain unconditional block, preserving the catch(new(LOGIN_OB))
body verbatim. This is adm/obj/master.lpc, the file the config actually
points at (a sibling copy at adm/single/master.lpc has the same pattern
but isn't used by our config — left alone, noted here in case a future
agent points a config at it).
2. §15h — is_chinese() GBK-byte-range check. adm/simul_efun/chinese.lpc
had the classic strlen(str)>=2 && str[0] > 160 && str[0] < 255
byte-range check — always false against real UTF-8 codepoints on this
driver. Fixed to a CJK Unicode range check (str[0] >= 0x4e00 && str[0]
<= 0x9fff) with strlen(str)>=1 (a single Chinese character is a
complete valid name-char now, not "half a GBK character").
3. §15h — check_legal_name()'s byte-length bounds and byte-stride loop,
in adm/daemons/logind.lpc. strlen(name) < 2 || > 8 (meant "1 to 4
Chinese characters" per the message text, calibrated for 2 bytes/char)
halved to < 1 || > 4. The sliding-window loop's i%2==0 &&
!is_chinese(name[i..<0]) (only checking even BYTE offsets, i.e. each
GBK character's lead byte) had the i%2==0 && guard dropped entirely,
since every UTF-8 index is already one full character now. Verified via
full registration test with a 3-character Chinese name (秦风寒).
4. §15p / §15ai — network/dns_master preload exclusion, PLUS a live
call-site guard. Removed /adm/daemons/network/dns_master from
adm/etc/preload (standing policy — avoids a boot-time hang against an
unreachable intermud "boot server"). Also, unlike some prior libs,
adm/daemons/logind.lpc's encoding_to_mudlist() (the very first step
of EVERY connection, right after the GB/Big5 prompt) called
DNS_MASTER->query_muds()/->query_svc() unconditionally, with no
find_object() guard — this would have silently lazy-loaded the
excluded daemon back in on every single connection (defeating the
preload exclusion entirely), and the subsequent keys(mud_list) would
have thrown on a 0 mud_list if the daemon failed to load. Guarded
the whole mud-list-fetch block behind find_object(DNS_MASTER),
falling back to an empty ([]) mud list (the code already printed a
"not connected to other muds" message in this case — just made sure it
doesn't also crash). Confirmed via the debug.log's Undefined function/
Bad argument absence and a clean multi-run registration test that this
never surfaces.
5. §15ar-adjacent — commandd.lpc's sscanf(cmds[i], "%s.c", cmds[i]).
Checked proactively per policy. This one was already fixed by
convert_lib.sh's own .c"-reference sed (the format string's .c
sits immediately before the closing quote, exactly the pattern that sed
already handles) — confirmed it now reads "%s.lpc" with no manual
intervention needed. Documenting as confirmed NOT needed as a manual
fix, since this exact bug class has bitten two previously-shipped
libs (bxsj/bxsj1) that needed it fixed by hand.
6. §15ae — private nomask command-hook. Checked feature/command.lpc's
command_hook() proactively. It's declared plain nomask (no
private) and dispatch (add_action("command_hook", "", 1)) works
correctly — confirmed NOT present, no fix needed. Verified
end-to-end with real post-login look/score/i commands (see below).
7. §15n / §8c / §4 — custom securityd.lpc's valid_read/valid_write,
and master.lpc's lazy SECURITY_D load. Checked proactively. This
lib's valid_read/valid_write only apply their ACL restriction for a
short allow-list of sensitive func values (read_file, file_size,
stat, read_bytes, tail, ed_start for read; write_file,
save_object special-cased, else the ACL for write) — anything else
(including load_object/recompile_object/include) falls through to
return 1; unconditionally. Confirmed NOT the §15n bug — compiling/
including code was never blocked here. master.lpc's own
valid_read/valid_write already wrap load_object(SECURITY_D) in
catch() (no reentrancy flag, but the catch() alone was sufficient —
confirmed no stack-overflow/recursion crash on a clean boot) —
confirmed the §4 pattern's dangerous shape (unguarded lazy load with
no catch) is NOT present, no fix needed.
8. §7 — get_root_uid()/get_bb_uid(). Both already implemented in
master.lpc, returning ROOT_UID/BACKBONE_UID. Confirmed present,
no fix needed.
9. §15ag — ed_start/ed_cmd/query_ed_mode. Grepped the whole lib —
zero hits. Confirmed not present, no fix needed.
10. §15l — master.lpc create() destructing SIMUL_EFUN_OB. create()
is just write("master: loaded successfully.\n"); — confirmed not
present, no fix needed.
11. §15r — check_config.lpc-style driver self-check. No such file
anywhere in the archive. Confirmed not present.
12. §3 — static → nosave blanket sed, and its known string-literal
counterexample. Ran the standard \bstatic\b → nosave sed (89
files touched net of the revert below). Then found and fixed a real
instance of the exact moniHuafu counterexample from AGENTS.md §3:
this lib uses a log_file("static/CRASHES", ...)-style convention
(a literal "static" path SEGMENT, not the keyword) in 22 files,
PLUS a subtler variant the counterexample note doesn't explicitly
cover — "/log/static/LASTCRASH"-shaped strings where static
appears mid-path, not at the very start of the string (17 more
occurrences across combatd(1).lpc, adm/single/master.lpc,
cmds/.../{kill,fuhuo,shutdown,reboot,recover,bai,apprentice,uptime}.lpc).
The word-boundary sed corrupted ALL of these to "nosave/..." /
"/log/nosave/...". Found this because cmds/usr/uptime.lpc's
write(read_file("/log/nosave/LASTCRASH")) (called from
logind.lpc's login() on EVERY connection) then read a
nonexistent file, got 0 back, and write(0) crashed with *Bad
argument 1 to receive(): Expected string or buffer Got: 0 inside
clone/user/login.lpc's receive_message() — this derailed the
entire registration flow on the FIRST test run: after that crash,
the connection's input_to() chain never got (re-)armed, so every
subsequent typed line just hit the default fail message ("What ?"),
looking exactly like a totally broken/silent server. Fixed by
reverting every "[/]nosave/... string back to "[/]static/...
(verified against the raw pre-conversion archive that static — never
nosave — was the ORIGINAL word in every one of these 39 total
occurrences, so this is a pure revert, not a guess).
13. A same-named directory colliding with the .c→.lpc rename (the
xjcq2000/zitengzhan-shaped bug, but a fresh instance):
kungfu/skill/chuixue-jian.c/ (a directory containing taiji-jian.c/
liehuo-jian.c) and u/duanfei/chuixue-jian.c/ (containing lian.c)
both got renamed to ...chuixue-jian.lpc (a directory, not a file) by
the blind rename pass, with their *inner* files left un-renamed (the
parent directory rename raced ahead of find's listing). Confirmed
via grep that NOTHING in the whole lib references either directory by
that literal path (the live, working skill is a differently-named
sibling, hantian-chuixue-jian) — these are orphaned/superseded
duplicate-content folders, not live code. Renamed both directories to
*.orphaned-dir (and their never-renamed inner .c files to .lpc
for consistency) so nothing mistakes a directory for a compilable
object. A third, genuinely-empty directory, kungfu/skill/cuixue-jian.c/
(note: different spelling, no h) hit the same rename bug but had
zero children even in the raw archive — renamed to
cuixue-jian.orphaned-empty-dir.
14. Uppercase .C files (the shenmo-shaped bug). 6 files:
d/shashou/obj/{YINGXION,XUEYI}.C, d/quanzhen/obj/jia.C,
d/shashou/npc/obj/{YINGXION,XUEYI}.C, d/quanzhen/npc/obj/bookshelf.C.
convert_lib.sh's glob is case-sensitive and skipped these; one file
(cangjingge2.lpc) references bookshelf via an extensionless
__DIR__"obj/bookshelf" path that would have resolved fine on a
case-insensitive filesystem but not here. Renamed all 6 directly to
.lpc (their file-based encoding guess already correctly ran them
through iconv during the original convert pass, confirmed valid UTF-8).
15. A genuinely corrupted/truncated raw source file:
d/wudujiao/npc/cunfu.c failed BOTH strict and -c/lossy iconv
(exit 1 either way — iconv: incomplete character or shift sequence at
end of buffer), and convert_lib.sh's current fallback logic treats
ANY nonzero exit from the -c attempt as total failure (discards the
temp file, logs "FAILED to convert", leaves the original raw GBK bytes
in work/ untouched) — this is a real gap in convert_lib.sh
itself worth flagging for the main session to consider: iconv -c
can still exit nonzero even after writing a perfectly good *partial*
conversion to stdout (confirmed: piping the same command's stdout
directly showed clean, correct UTF-8 text right up to where the raw
bytes are genuinely garbage), so the current "discard on any nonzero
exit" logic throws away recoverable partial output, not just failed
output. Inspected the raw bytes directly (xxd): the file is a small,
trivial random-NPC-name generator (cunfu.c — "村妇", a random
village-woman NPC) whose content is cleanly valid right up through
set("max_qi", 200);, then abruptly turns into non-text binary
garbage for the rest of its ~340 remaining raw bytes (looks like
unrelated corrupted/overwritten disk content, not anything
resembling LPC or even valid GBK). Fixed by extracting only the
valid leading ~500 bytes, converting those cleanly, and closing the
create() function's brace immediately after the last valid
statement — no fabricated content, matching the project's established
"close gracefully, don't invent" convention for genuinely truncated
files (same approach used for archive #91's one similarly-truncated
file). This file is not preloaded/reachable from the standard
registration/look/score path either way.
16. A one-shot, whole-mudlib-affecting header bug:
kungfu/skill/eff_msg.h duplicated its ENTIRE body within itself
(confirmed present byte-for-byte in the RAW pre-conversion archive too
— not something our pipeline introduced): eff_status_msg() and
damage_msg() were each fully defined TWICE in the same file (once
around line 9, once again around line 150), each copy also trailed by
a stray, non-matching #include "/kungfu/skill/eff_msg.h"; /
int p; ... snippet (an unclosed second "usage example" left active
instead of commented, unlike the identical-looking, correctly
commented-out block at the very top of the file) — this crashed EVERY
file that includes it (linboweibu, linboweibu1, taiji-quansd,
taiji-quan/zhensd, huifeng-jian, yijin-jing, 6 kungfu-skill
action files) with Redeclaration of function 'eff_status_msg'/
'damage_msg'. The two copies' damage_msg() actually cover
*different, non-overlapping* damage-type case labels (one has
擦伤/割伤/砸伤/default, the other has 瘀伤/内伤/震伤/抓伤/刺伤/default) —
NOT simple duplicates, so a naive "just delete the dupe" fix would
also silently drop real damage-flavor-text coverage either way. Kept
the FIRST copy (immediately after the doc comment, the position every
sibling working file's own eff_msg.h-alike would put the real
definitions) and removed the second, to keep the fix conservative
(no fabricated merge risking a duplicate-case compile error of its
own). One of the 6 dependent files (huifeng-jian.lpc) had a SECOND,
independent bug once this was fixed: #include
"/kungfu/skill/eff_msg.h"; (which defines global variables) appeared
textually BEFORE inherit SKILL; — illegal on this driver (§15t
variant 3) — reordered so inherit comes first. All 6 files verified
passing via direct lpcc afterward.
17. A recurring "pager status line pasted into the source" corruption
(confirmed present in the raw archive, NOT a conversion artifact) —
found in 3 unrelated places: d/xingxiu/obj/sheep.c and
kungfu/skill/yijin-jing/heal.c each had a stray, standalone line
reading == 未完继续 NN% == (ENTER 继续下一页,q 离开,b 前一页) (a
Chinese more-style pager's "-- More --" status line) embedded
mid-function — clearly captured by accident during some long-ago
editing/screen-scraping session, not code. Deleted both lines
outright (they're 100% non-code noise, confirmed by comparing
against the surrounding statements' obvious intent). A related,
nastier variant in u/linghu/ground2.lpc (a PK-arena feature in a
personal wizard directory) had the SAME pager garbage spliced into
two live statements rather than sitting on its own line:
{(q 离开,b 前一页,其他继续下一页) (should just be {) and
if (brief)== (q 离开,b 前一页,其他继续下一页) (should just be
if (brief)), plus a case MO with no colon and no real constant
name a few lines earlier (inferred, from this same switch's sibling
cases elsewhere in the file using MODE_SINGLE_SD/MODE_SINGLE_LT/
MODE_TEAM_LT/MODE_TEAM_DZ/MODE_TEAM_XH in that exact order and
this being the FIRST case in its switch, to be the truncated start of
MODE_SINGLE_SD:). Fixed all three spots in ground2.lpc.
Left un-fixed, documented as a known gap (see below): the SAME
file's do_debug() function (much further down, ~250 lines) has
extensive, unrelated pre-existing corruption (missing semicolons and
closing parens across ~40+ lines) that also predates this project —
a genuinely unfinished/never-tested wizard debug utility, not reached
by any normal play, not worth the repair time this session.
18. Missing/dropped closing quotes in string literals (§10-shaped,
confirmed pre-existing in the raw archive via byte-level diff against
both strict and lossy iconv output) — found in 7 unrelated files:
d/quanzhen/{hudi3,hudi4,hudi5,hudi6}.lpc (missing OPENING quote
before a set("long", ...) multi-line text block — hudi5 was
additionally missing its CLOSING quote too, a second independent
instance in the same file), kungfu/skill/qingyi-jian.lpc
("skill_name" : "大悲式, missing the closing quote before the
comma), kungfu/skill/yanxing-dao.lpc (same shape, ...刺去,),
kungfu/skill/jueqing-chenfa.lpc (two independent instances in the
same file: ...阴毒无\n塘, — note this one lost more than just the
quote, an unrecoverable original-content truncation the raw bytes
confirm predates us too, closed cleanly after the last legible word
rather than fabricating the rest — and a second ...阴毒无 case
further down, same fix). Each fixed by inserting the missing "
at the exact point the content/context indicates.
19. A 4-file set("long", @LONG ... LONG) closing-tag-merged-onto-text
bug (the exact tianxia/AGENTS.md-documented "iconv -c eats an
adjacent real newline" shape) in d/quanzhen/{manglin1,manglin2}.lpc,
d/chang'an/gulouerceng.lpc, d/wudang/xiaolu2.lpc — the closing
LONG heredoc tag must start its own line, but was merged onto the
end of the preceding Chinese text line in all 4. Diagnostic
footnote for future agents: my first repair attempt used a careless
manual iconv -f GB18030 -t UTF-8 ... 2>/dev/null (no -c, stderr
discarded) to re-extract 2 of these 4 files from raw for inspection,
which SILENTLY TRUNCATED both of them mid-file (strict iconv was
failing partway through on an unrelated bad byte elsewhere in each
file, and redirecting stderr to /dev/null hid the nonzero exit and
the truncation both) — caught immediately by a sanity line-count/
content check before it was ever written back into work/, redone
correctly with -c. This was purely a self-inflicted diagnostic
mistake, not a flaw in convert_lib.sh itself (which already does
the correct strict-then--c-fallback dance with proper exit-code
checking) — noting it here only as a reminder to always re-derive a
file from raw/ through the SAME strict→-c-fallback discipline the
real pipeline uses, never a bare one-off iconv call.
20. A shared-header path mismatch, 21 files at once (§8g: one root
cause, not 21 bugs): every file under u/think/gfjob/npc/*.lpc
(~21 files) did #include "/quest/gfjob/npc/npc.h" — but
/quest/gfjob/ doesn't exist anywhere in the archive; the real
npc.h lives at /u/think/gfjob/npc/npc.h (same directory as the
files including it — a personal-wizard quest-content area, clearly
moved at some point without updating its own header's #include
path in whichever template it was cloned from). Fixed the #include
path in all 21 files in one sed pass to point at the real location.
A related, unrelated-cause pair: u/bombju/wudang/{hutou,langmei}.lpc
did #include "feng.h" (quoted, local-dir-first resolution) but
neither file's own directory has a feng.h — the real one lives at
/d/wudang/feng.h (these two files are near-verbatim clones of the
d/wudang/taoyuan/tyroad*.lpc room family, sharing that header).
Fixed both to the absolute path. d/wudang/taoyuan/{tyroad4,5,6,7}.lpc
had a THIRD, distinct variant of the same underlying "which feng.h"
confusion: #include __DIR_"feng.h" (note: single trailing
underscore, not the real __DIR__ macro) — a typo that resolves to
nothing at all (__DIR_ isn't a macro), and even a corrected
__DIR__"feng.h" would have been wrong anyway since feng.h lives
one directory up, not alongside these 4 files. Fixed all 4 to the
same /d/wudang/feng.h absolute path.
21. new used as a bare variable name (7 files) — the exact bug class
already retroactively found in jqxz2008/xiakexing3
(archive #91's report): d/quanzhou/npc/{tang,tang1,tang2,tang3}.lpc,
d/taishan/{tang2,tang3,xingtang}.lpc all declared
object *inv, new; then did new = new("/clone/npc/...") — new is
a reserved token (L_NEW) on this driver's lexer, not just a
shadowable identifier, so the DECLARATION itself is a hard parse
error. Renamed the variable to new_ob throughout all 7 files
(declaration + both use sites each) via a scoped sed, verified each
compiles clean afterward.
22. A duplicate inherit F_UNIQUE; line (3 files) — same shape as
already found in the jqxz2008 pass:
d/mingjiao/npc/{yinwufu,yinwulu,yinwushou}.lpc all had inherit
F_UNIQUE; written TWICE (byte-identical files, likely all cloned from
one template with the same authoring slip), producing Illegal to
redefine 'nomask' function 'violate_unique' (the second inherit tries
to re-bring-in a nomask function F_UNIQUE already installed by
the first). Removed the duplicate line from all 3.
23. message_combatd — the exact simul_efun gap AGENTS.md's own §8b
write-up is named after, recurring here: called from 4 kungfu
combat-skill files (chousui-zhang/{sandu,throw}.lpc,
force/transfer.lpc, one more commented-out call site) with the same
(msg, me, target) 3-arg shape as message_vision(), but never
defined anywhere in this lib's simul_efun. Restored as a thin alias
to message_vision() in adm/simul_efun/message.lpc (added AFTER
message_vision's own definition in the same file, per the §8b
same-file-ordering rule), which already handles exactly this $N/$n
attacker/target substitution shape. All 3 real call sites verified
compiling clean afterward.
24. A same-file forward-declared function whose real body lives entirely
inside a comment (3 files): d/jingzhou/npc/{dingdian,shiye,
lingtuisi}.lpc each reference (: do_zhuibu :) in an inquiry
mapping (an NPC "ask about work" hook), but do_zhuibu()'s actual
body — along with a ~200-line quest implementation — is entirely
inside a /* ... */ block (confirmed: even the function's OWN
forward declaration a few lines above create() is itself commented
out, //string do_zhuibu();, in all 3 files) — a deliberately
disabled/unfinished feature, not something this project should
resurrect (that would mean writing ~200 lines of new quest logic from
scratch, well out of scope). Removed just the "工作" : (: do_zhuibu
:), entry from each NPC's inquiry mapping (leaving an empty ([
])), which is the minimal fix that stops referencing a genuinely
absent function without fabricating the missing feature.
Directories created (raw archive didn't ship them, but code references
them)
static/, binaries/, adm/swap/, data/nosave/, log/nosave/,
nosave/ (bare — cmds/adm/recover.lpc writes to /nosave/RECOVER),
hate/ (PK-hatred-list feature, feature/attack.lpc/combatd(1).lpc/
cmds/usr/hatred.lpc), topten/ (referenced by TOPTEN_DIR in
toptend.lpc). None of these being absent caused a HARD failure during
registration/look/score (mostly write_file()/log_file() calls that
either aren't on the critical path or degrade gracefully), but per §15ah
precedent they're cheap, proactive insurance against a silent write
failure derailing some other flow later.
Config (config.fluffos) adjustments
port number : 40088,noninteractive stderr write : 1added.mudlib directorypointed at the absolutework/path.- Dropped obsolete keys the driver warned about:
address server ip,address server port,reserved size,swap file(none used/recognized by this driver build). maximum local variables : 30→64(this driver's config schema enforces a minimum of 64; the original value was silently reset to default with a warning otherwise — bumped to the real minimum instead of leaving the warning in place).external_port_1 : telnet 8888commented out (fully superseded byport number; was only producing an "ignoring" info line, not an error).
Registration flow + post-login command test (verified twice, full
transcripts)
Flow shape: GB/Big5 encoding choice → "Press Enter to Continue" (past an
inline DNS-mud-list display, now empty since dns_master is excluded) →
banner/stats/uptime → English id (check_legal_id: lowercase a-z only,
3-12 chars) → (existing-save-file check; new id → confirm y/n) → Chinese
name (check_legal_name: 1-4 real Chinese characters after the §15h fix)
→ password (twice) → gift-stat selection (0 = random, or 1-5 to pick one
stat to name a value for, then accept/reject the rolled set) → email →
gender (m/f) → drops into the game world at 随缘客栈 (the starting inn),
greeted by NPC 李寻欢.
Final verification run (mudclient.py 127.0.0.1 40088, one continuous
session, --idle 1.0):
gb → "" → qinfengfinal → y → 秦风寒 → password123 → password123
→ 0 → y → [email protected] → m → look → score → i → quitResult: registration completed cleanly, landed in 随缘客栈 with the
correct room description, NPC greeting text, and exit list; look
re-displayed the room correctly; score printed the full character
sheet (中文姓名 秦风寒, 英文姓名 qinfengfinal, stats, all fields populated,
no crash); i (inventory) listed the starting items correctly; quit
cleanly dropped an item and printed the goodbye message. log/debug.log
for this run has exactly one non-fatal runtime line
(*/topten/source: lstat failed, harmless — topten/ directory was
missing pre-existing content for whatever sub-path constructs "source"
as a topten category key; didn't block anything, not chased further given
time budget) and otherwise zero errors.
An earlier full run (before the final config/driver restart, id
hantianli/name 秦风寒/gender f) is what originally caught bug #12 above
(the uptime.lpc/LASTCRASH static→nosave corruption) — that run's
look command hard-crashed the object (*No program in object
'/cmds/std/look'!) before the fix (bug #18's look_msg.h dropped-quote
issue, found in that same first pass) was applied; both are now confirmed
fixed with a subsequent clean run.
lpcc_check.sh sweep results
97.3% pass: 7306/7508 (lpcc_fail.log in this directory has full
detail). Started at 96.5% (263 failures) before this pass's fixes; every
genuine driver-compat/typo bug found in the sweep that's described above
was fixed and individually re-verified via direct lpcc before the final
sweep. Memory stayed well within safe bounds throughout (peaked ~1.3GB RSS
on the lpcc process, ~9-10GB free system-wide) — no need to back off per
§6b, this lib (7508 files) isn't in the "mega-lib" risk tier.
Remaining ~200 failures, triaged into known-noise categories (not bugs to fix):
- **
kungfu/skill/xiake-shengong/*(侠客神功 skill class, ~9 files):** calls an entirely undefinedtest_zouhuorumo()function (21 hits) and#includes two headers (cond.h,spec.h) that don't exist anywhere in the archive. Confirmed via grep this whole skill class was incomplete/broken from the start (nothing else in the lib defines either), not something to fabricate — this is a real, pre-existing content gap (§13-shaped), not reachable unless a player actually learns and tries to use this one specific (apparently never-finished) skill. - **
adm/daemons/network/*(mail/ping/telnet/inetd/userid/dns_master sibling daemons, ~15-20 files):** missingconfig.h/uid.h/daemons.h/mailer.hheaders and undefinedmember_group(). None of these are preloaded (dns_master and its whole family are excluded per §15p) or reachable from the registration/login flow — pure intermud/mail-relay plumbing, expected noise per this project's standing DNS-daemon policy. maxim/skill_model_{default,unarmed,weapon}.lpc(3 files): these are literal COPY-PASTE TEMPLATES for wizards writing new kungfu skills (comment://line number must be same!!! so it is done) — referenceSKILL_CH_NAME/SKILL_EN_NAME/SKILL_BASE_NAME/actionas intentional placeholders meant to be filled in by whoever clones the template. Never#included/inherited/loaded as real objects anywhere.- A long tail of individually-small, genuinely pre-existing content issues in personal-wizard directories (
u/linghu/ground2.lpc'sdo_debug(), see fix #17 above),cmds/arch/examine.lpc(a wholeelsebranch missing semicolons throughout — confirmed present byte-for-byte in the raw archive, a wizard-only admin command, never finished/tested even originally), and scattered individual NPC/room/ skill files with one-off typos in code paths not reachable from ordinary play. None of these block boot, registration, or the standard post-login command set; documented rather than chased further, per this project's stated breadth-over-depth policy for a ~100-archive batch.
What was confirmed NOT needed (checked proactively, all negative)
- §4 (master.lpc lazy security-daemon load recursion) — already catch()-guarded in the original code.
- §7 (
get_root_uid/get_bb_uid) — already present. - §8c (
valid_read/valid_writeblindly overridinguserwiththis_player()) — not this lib's shape; the ACL only fires for a narrowfuncallow-list,load_object/include/recompile_objectalways pass. - §15ae (
private nomaskcommand_hook) —command_hook()is plainnomask, dispatch confirmed working via the reallook/score/itest. - §15ag (
ed_start/ed_cmd/query_ed_mode) — zero hits anywhere. - §15l (master.lpc
create()destructingSIMUL_EFUN_OB) —create()is a one-linewrite(), nothing else. - §15n (custom securityd blocking compile-time
load_object/include) — this lib's ACL already special-cases thosefuncvalues as always-allow. - §15r (
check_config.lpc-style driver self-check) — file doesn't exist in this archive. - §15v/§15b's whole-mudlib bare-simul_efun
set/query/deletedbase architecture bug (the "nitan" family's core bug) — this lib'sfeature/dbase.chas real localset/query/deletemethods (inherit F_TREEMAP), not the bare-simul_efun pattern; confirmed not applicable to this lineage. - §8f (
TYPE * a, b;C-style array-modifier scoping treated as a bug) — spot-checked several instances (feature/equip.c'sstring *apply, type;,kungfu/skill/qixing-array.c'sobject *member, ob;) and confirmed these are INTENTIONAL single-star-scoping (the second identifier is genuinely meant to be a scalar, used as such throughout) — this is the Dead Souls/English-lineage bug shape, not something this Chinese ES-II-lineage codebase's authors got wrong. - §15u (dormant "phone-home" destructive license check in securityd) — grepped for mass-deletion/
shutdown()patterns gated on suspicious checks; none found.
Process hygiene
Driver launched via run_in_background/setsid nohup ... & disown
(several times across the fix/re-verify cycle), always killed by exact
recorded PID (never a broad pkill pattern) once done with each round of
testing. Confirmed via ss -tlnp/ps after each kill that the port was
actually freed and no stray process remained. Multiple other sibling
agents' driver processes were observed running concurrently on this host
throughout (archives #92-95) — none were touched.
Rebuilt-driver / formatter / WASM re-verification pass (2026-07-23)
1. LPC formatter applied across all 7,509 .lpc files in work/:
{"total":7509,"written":7454,"wouldChange":0,"unchanged":6,
"errors":49}. Verified post-format feature/command.lpc's
command_hook is still plain nomask. Found and fixed the same
formatter bug discovered across this pass's other libs (full
writeup in tianxia/NOTES.md): a bare ::fn(...) call immediately
after ( with no space is mis-lexed as a (: ... :) closure
literal. Hit once, in adm/object/bm.lpc's short():
capitalize(::query("id")) got rewritten to the syntactically broken
capitalize (: : query("id")\n)\n+ ")". Hand-fixed back to
return ::name(1) + "(" + capitalize(::query("id")) + ")";.
Re-verified via a full lpcc_check.sh sweep: 7,306/7,508 pass (202
fail, matching the pre-format baseline below), bm.lpc not in the
failure log.
2. Native re-test against the rebuilt build-debug/src/driver:
booted clean (zero fatal errors). Full registration verified
end-to-end via mudclient.py (this lib prompts for a GB/Big5
encoding choice before the ID prompt, first send "g"): id
syxfmte → confirm → real Chinese name 秦风廿八 → password ×2
→ attribute roll (0/random) → accept → email [email protected] →
gender m → entered the game world at 随缘客栈, look displayed the
room (correctly re-shown), score showed a correctly-populated
character card matching registration, quit dropped items and
printed "欢迎下次再来!". debug.log: zero error in error
handler/denied/undefined function/bad argument lines. No new
fixes needed; the reformatted source is still fully sound.
3. WASM test: boots cleanly through Initializations complete
(only the expected missing-sockets-package compile errors for
ftpd/httpd/emaild). A real registration playthrough could not
be driven through this specific harness, for a reason distinct from
the documented query_ip_number() limitation: cmds/usr/uptime.lpc's
main() does write(read_file("/log/static/LASTCRASH")) with no
type-check on read_file()'s return, called from logind.lpc's
login() on every new connection to print the "上次当机原因" banner
line. scripts/wasm_client.js deliberately does not copy the
*contents* of work/log/ into the wasm instance's in-memory FS (see
the script's own comment — avoids wasting time/memory on runtime-churn
log files), so /log/static/LASTCRASH — a legitimate small reference
file, not actually churn — doesn't exist there, read_file() returns
0, and write(0) throws Bad argument 1 to receive() uncaught
mid-login(). Because this happens before login() reaches the code
that prints the ID prompt and registers input_to(), the connection
is left with no input handler at all — every subsequent line sent
just falls through to the ordinary (empty-environment) command parser
("What?") instead of being treated as an ID/name/password answer.
Assessment: this is a wasm-harness/no-persistent-log-data
interaction, not a mudlib bug in the sense of "broken on a real
server" (the archive ships LASTCRASH, and the native session above
is proof registration works perfectly there) — but it is a genuine
latent fragility (write(read_file(x)) with no string-type guard)
that would reproduce identically on ANY from-scratch deployment
lacking pre-existing /log/static/LASTCRASH data (e.g. a real
from-scratch browser/wasm deployment with no prior log history), so
it's worth flagging even though it isn't the already-catalogued
query_ip_number() limitation. Not patched, per the task's "note,
don't force a fix for wasm-specific gaps" guidance.
WASM-enablement pass (2026-07-24)
Standard four-change pass (AGENTS.md §1.3b/§1.3e/§1.5):
1. Loopback-allow (empty/non-string/127.* IP treated as loopback):
- adm/daemons/logind.lpc login() — BAN_D->is_banned() gate and
the ip_cnt >= 20 same-host cap both skipped for loopback.
- adm/daemons/band.lpc is_banned() — loopback/localhost/malformed
sites never banned. (The sited is_valid/is_multi calls in this
lib were already commented out upstream.)
2. Uptime gate: none present.
3. cmds/usr/uptime.lpc LASTCRASH crash FIXED (was documented-only):
write(read_file("/log/static/LASTCRASH")) now guarded with
stringp() (§7.9 fresh-checkout bomb — log/ is gitignored, so every
fresh checkout/WASM bundle lacked the file and write(0) killed the
whole login chain before the ID prompt; this was the lib's documented
WASM blocker).
4. Admin seeded: fluffos / Mud@2026 / 浮浮 → (admin) appended
to /adm/etc/wizlist. Save files: work/data/login/f/fluffos.o,
work/data/user/f/fluffos.o (data/ not gitignored). Verified:
update /cmds/usr/uptime → 重新编译成功 (conveniently recompiling
the patched file itself cleanly).
5. Retest: fresh registration (syqfc/秦风, deleted after test) into
随缘客栈 with look/score/quit OK. debug.log: the only runtime error
was /topten/source: lstat failed (caught; §7.11 missing-runtime-dir
class — work/topten/ is gitignored churn; created
work/topten/source/ locally). Removed the runtime-regenerated
adm/etc/banned_name (the lib rewrites it from its built-in list on
demand — NOT the yueyingqiyuan shipped-content case; nothing was
deleted from git).
Flow gotcha documented for future scripting: after the GB/BIG5
answer there is a hidden "Press Enter to Continue..." input_to
(easily lost in the mudlist banner) — the first line sent after gb
is swallowed by it.
Retrofit: fail-closed loopback check (2026-07-24)
The loopback-allow gates above were originally written per the (now
superseded) defensive instruction to also treat an empty/non-string/
malformed query_ip_number() result as loopback, since older WASM
driver builds returned garbage. That driver bug is now fixed upstream
(query_ip_number()/resolve() return real values under WASM too), so
the "malformed IP = trust it" fallback was a fail-open bypass with no
remaining justification. Tightened every gate listed above to the
strict pattern: loopback is ONLY ip == "127.0.0.1", ip == "::1", or
a leading "127." prefix — a non-string/empty/malformed IP is now
treated as untrusted/remote and subject to the gate normally, not
silently allowed through. Retested: fluffos login (127.0.0.1, real
value under the current driver) still passes every gate; debug.log
stayed clean of denied/undefined function/error in error handler.
WASM 修复摘要(迁移自 meta.json 的 group_note)
状态已从过时的 limited 修正——这份档案自己的 README 里从未记录过任何缺陷说明,本轮重新测试也没有发现:管理员登录干净正常:GB/BIG5 选择→一个带自己"按 Enter 继续……"关卡的姊妹站泥潭列表画面→id+密码→"目前权限:(admin)"。
深度功能测试(§10.7,2026-08-04)
原生 driver(端口 40088)跑了一遍超出注册流程的完整游玩。这份档案 每次连线都要先选 GB/Big5 编码(发给 UTF-8 客户端时这一步已经是安 全的空操作,选哪个都行),紧接着还有一个泥潭列表画面自带的"按 Enter 继续……"关卡,测试脚本要多算一步空发送,容易漏掉。
主动检查命中 2 处,都在 adm/daemons/logind.lpc:单一姓名输入
路径(没有随机取名分支)紧挨在 ob->set("name", arg) 之前的
printf("%O\n", ob) 调试残留(§7.34);enter_world() 里食物/饮
水初始化用错对象的经典 §8.9 bug(ob->query("age") 应为
user->query("age"),紧跟在 user->setup() 之后)。两处都已修
复;注册后食物/饮水显示 280/280(满值),确认 §8.9 修复生效。
command_hook 有两份拷贝(feature/command.lpc 是 F_COMMAND 宏
实际指向的活文件,u/ybl/command.lpc 是巫师私人目录下未被引用的
死拷贝),两份都是干净的 nomask,不是 bug。
注册与游玩:注册测试角色(秦水 / id qinshui),天赋可以自选
一项数值、其余系统随机(或全部 0=随机),落在"随缘客栈","李寻
欢"(古龙小说角色)作为新手向导 NPC 出场讲解基本指令,角色自带专
属邮箱。
发现并修复 §7.68 的又一实例,外加一个更严重的全新变体:这份档
案的死亡系统有 d/death/npc/{wgargoyle,bgargoyle}.lpc(活的,
DEATH_ROOM 宏指向 d/death/gate.lpc,摆的是 npc/wgargoyle)——
1. wgargoyle.lpc(白无常,真正在游戏里生效)有标准的
if (!ob || !present(ob)) return; §7.68 守卫,已按已验证的修法
拆分修复。现场完整验证:被"欧阳克"(金庸小说反派,本轮是第
四个独立血统里发现的同一个反复出现的固定布景角色,之前已经在
jyqxc/yhyxs/yanhuangwuhun 里见过)一击致死,落到"鬼门关"
见到"白无常",没有主动打断复活序列,重连确认角色已复活、站在
"武庙",精神/气息 31/100(死亡惩罚,正在恢复中)、食物/饮水基
本无损、潜能减半——本轮系列测试第四次现场完整验证 undisturbed
路径正确性。另外确认死亡的鬼魂无法移动("你已经没有力气再
走路了,休息一下吧。"),这意味着 d/death/gateway.lpc
(摆着 npc/bgargoyle)在正常玩法里实际上不可达——虽然技术上
被一个房间的 exit 引用着,鬼魂状态下走不过去。
2. 一个比 §7.68 更严重的全新变体,在 bgargoyle.lpc(黑无常)里
发现:init() 正常调度了 call_out("death_stage", 5,
previous_object(), 0),但 death_stage() 函数本体整个被
/* ... */ 注释掉了!这意味着这个 call_out 永远静默地调用一个
不存在的函数——没有任何报错,没有任何提示,任何走到黑无常面前
的对象都会被永久晾在原地,复活对话一句都不会说,reincarnate()
永远不会被呼叫。已把整段函数体取消注释并按标准修法拆分守卫,恢
复成和 wgargoyle.lpc 对等的可用状态。因为鬼魂物理上走不到黑无
常面前(见上),这个修复没能现场触发真实的复活对话,只验证了恢
复后的代码能正常编译、不再报错——诚实记录为未现场复现的修复。
d/death/wgargoyle.lpc(不带 npc/ 子目录的裸路径重复文件,
已确认无任何引用,是被 d/death/npc/wgargoyle.lpc 取代的旧
副本)里也有同样"整个 death_stage() 被注释掉"的写法,但因为这
份文件是双重死代码(既未被引用,函数体又被注释),修复它不会产
生任何实际效果,故未做改动,只记录在案。
3. d/shaolin/npc/yu-zu2.lpc(少林地牢"狱卒"关禁闭机制,和
jyqxc 发现的同名同形状 bug 一致)——确认是被
d/shaolin/npc/yu-zu.lpc(没有任何监狱机制的简化版)取代的死代
码,仍按已验证的修法拆分修复(成本很低)。
发现并修复两个全新的、和死亡系统无关的独立 bug:
4. feature/alias.lpc 的防刷屏踢人逻辑(process_input()):连续
发送 30 次以上相同指令会触发 command("quit") 把玩家踢下线,但
quit 会销毁 this_object(),之后紧接着第 34 行还有一句
this_object()->query_temp("disable_inputs"),在已销毁的物件上
呼叫方法,每次踢人都会在 debug.log 里留下一条
Bad argument 1 to EFUN call_other() 运行时错误(物件显示为
0)。虽然玩家看到的踢出效果本身是对的,但这是一处真实的、每
次触发都会留痕的运行时错误。已在 command("quit") 后补上
return,修复后现场用连续 35 次 look 重新触发踢人验证,
debug.log 干净,不再报错。
5. u/bsd/npc/christmas-man.lpc("圣诞老人",实际摆在"扬州广场",
不是纯粹的巫师私人测试内容)的 create() 里
carry_object("/u/bsd/obj/silver-cloth")->wear() 没有做存在性
检查——/u/bsd/obj/silver-cloth.lpc 这个文件在整个归档里完全不
存在(包括 raw 原始压缩包,不是转码遗漏,是内容本身就缺失;
u/bsd/obj/ 目录下只有另外三个不相关的物件),carry_object()
返回 int 0,对 0 呼叫 ->wear() 触发同样的
Bad argument 1 to EFUN call_other(),每次这个 NPC 被克隆(进
入"扬州广场"、地图重置时)都会报错一次。没有编造替代物品,改成
先判断 carry_object() 是否真的返回了物件再穿。修复过程中的
一个教训:第一次尝试用 if (object cloth = carry_object(...))
这种内联声明写法,通过了 lpc-syntax 格式化工具的解析,但实际
driver 编译报语法错误("unexpected L_IDENTIFIER, expecting
L_COLON_COLON or '('")——这个 driver 的 LPC 方言不支持 if 条件
内联变量声明,格式化工具的解析器比实际 driver 更宽松,不能只靠
它验证语法,必须重启 driver 实际编译才能确认。改成先单独声明变
量再赋值后编译通过,现场重连并走到"扬州广场"确认"圣诞老人"正
常出现、ask laoren about liwu 触发圣诞祝福对话,debug.log 干
净。
发现并修复一个和 yhyxs/yanhuangwuhun 会话完全同类的 extensionless
GBK 文本残留 bug,但这次是配置数据而不是帮助文档:adm/etc/
banned_name(禁止注册使用的姓名黑名单)在原始压缩包里是一份真正
的 137 行列表(包含大量特定历史时期的敏感政治词汇/职务名称——领导
人姓名、政府机关职务、"台独"相关词汇等,是这类 2000 年前后中文泥
巴常见的内容审核配置),但从未被转码进 work/(同样是无扩展名文
件,转码流程的已知盲区)。logind.lpc 的 check_legal_name() 有
一个"文件不存在就用硬编码的 6 个代词兜底,并把兜底列表写回磁盘"
的自我播种逻辑(第 979-986 行)——本轮测试连线时,这个自我播种逻辑
真的触发了,在 work/ 里创建了一个只有"自己/它/她/他/我/你"六项
的弱化版名单,掩盖了原本 137 项的真实内容审核名单从未存在这个事
实。用 iconv -f GB18030 -t UTF-8 转换 raw 归档里的原始文件(137
行全部转换成功,人工核对是通顺的中文),替换掉刚被自动生成的弱化
版,重启验证:banned_name 文件行数恢复到 137 行,用"你"注册仍
然正确触发"对不起,这种名字会造成其他人的困扰。"的拒绝提示,确
认文件被正确加载而不是被兜底逻辑覆盖。
quit 正常退出,driver 全程存活未崩溃。debug.log 全程没有真实
的 error:/denied/Too deep recursion 行(Bad argument 1 to
EFUN call_other() 的两处已在本轮修复并现场确认消失)。formatter
检查(所有改动的 .lpc 文件均已是干净格式或首次接触触发全文件重
排版,语义改动已逐一核对)、git status --short libs/syxjl/ 复查
均确认改动范围干净——六处 .lpc 源码修改 + 一份新增的 banned_name
配置数据文件是跟踪变更,测试角色的新存档保持未跟踪、未提交。
更正(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 崩溃)
BULLETIN_BOARD、WIZ_BULLETIN_BOARDinherit+ 多余replace_program()致命形状(AGENTS.md §7.86,post命令崩溃):全档案 36 处命中,已删除多余的replace_program(...)调用(保留inherit),逐文件保留原有行尾格式(CRLF/LF 按文件原样)。本次为跨库 §7.86 扫描修复(触发原因:该 bug 已在 6+ 个互不相关的血统家族独立确认,属于近乎普遍的拷贝粘贴模式),仅做编译检查(驱动干净启动、端口正常监听),未做完整 §10.7 深度游玩测试。
深度功能测试(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,CRLF 行尾档
案)已经在更早一轮(引用注释里的"AGENTS.md #15w")正确修复过,管
理员账号(fluffos/Mud@2026,adm/etc/wizlist 已有
fluffos (admin) 且存档已提交,README 本身已经准确记录了 GB/BIG5
+"Press Enter to Continue"这两步登录细节)也已经全部正确,本轮只
发现并修复了 log_file() 一处。
发现并修复的 PROGRAMMING bug
1. log_file()(adm/simul_efun/file.lpc,CRLF 行尾档案)完全没
有 assure_file() 保护(AGENTS.md §7.11-class 的又一确认实
例):cmds/std/{drop,give,put}.lpc/cmds/app/update.lpc 等
文件多处 log_file("static/...", ...) 调用依赖对应子目录存
在——其中 static/update 这一条每次巫师执行 update 指令都
会触发,本轮的 update 验证步骤本身就顺带验证了这个修复。注
册/登录本身只写 log_file("USAGE"/"loginnum", ...)(无子目
录,本来就存在),不受影响。已补上
assure_file(LOG_DIR + file);(含前向声明,用 Python 字节级替
换保留原 CRLF 行尾格式)。
Proactive checks(无需改动)
win_times修复确认存在且正确:d/city2/npc/refereew.lpc:368。- 未发现
message()simul_efun 包装函数——不适用 message()-missing-varargs 这一类 bug。
实测过程
用已提交的 fluffos/Mud@2026 登录(gb 选码 → "Press Enter to
Continue" → 密码),score/update /adm/simul_efun/file(就是本
轮改过的文件,同时验证了上面提到的 static/update 日志路径)确认
可正常重新编译,零诊断刷屏。log/debug.log 时间戳全程未变化
(Jul 23,早于本次会话),确认无新增未捕获运行期错误。登录本身
产生的存档时间戳类微小 diff 已用 git checkout 撤销,不提交。驱
动最终按精确 PID kill,ps -p 确认已退出。
§7.100 房间基类 replace_program() 扫尾修复(2026-08-19)
ROOM 宏(/inherit/room/room)在本档案 2,073 处房间文件的
create() 里紧跟 inherit ROOM; 之后又多余调用了一次
replace_program(ROOM);——AGENTS.md §7.100 记录的同一个休眠 bug。
用 fix_710_room.py 扫过 work/,删除全部 2,073 处标准形状,与脚
本自报数字、git diff --stat 净删行数完全吻合。clone/misc/
roommaker.lpc(本档案的房间建造工具)确认从未含有这个 bug(两处
ROOM_CODE/字符串拼接模板都只有 setup();,没有多余的
replace_program),无需修复。修复后 work/ 下 0 处存活残留,剩
余 118 处均为转档之前已注释掉的 // 行,原样保留;work/data/
下没有真实 .lpc 源码命中。
驱动干净启动(零新增编译错误、端口 40088 正常监听、debug.log
无任何"cannot replace"/"cannot bind"行)。管理员 fluffos/
Mud@2026(先选 gb 编码、"Press Enter to Continue")实机登录成
功,look/score/quit 均正常,全程 debug.log 保持干净。管理
员存档的时间戳漂移已用 git checkout HEAD -- 还原,未提交。驱动
按精确 PID 结束。
§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.
深度功能测试(2026-09-04,round three,shop + 拜师)
新角度:醉仙楼购物 + 丽春院空空儿拜师。2026-08-13 第二轮只测了战斗/
死亡和 log_file,没有买东西、也没有拜师。这是 ES II 随缘洗剑录
(混有金庸门派),端口 40088。第一输入是 GB/BIG5 选单,发 gb,然后
「Press Enter to Continue」发空行,再英文 id。密码 Mud@2026。
实测过程
管理员 fluffos / Mud@2026(权限 (admin))。clone
/clone/money/gold 可用。
goto /d/city/zuixianlou(醉仙楼,店小二源码
kungfu/class/npc/xiaoer.lpc,F_VENDOR_SALE;现场显示名「独孤宝贝」
是摊位易主,不是缺 NPC)。list 烤鸡腿八十文铜板 / 包子五十文铜板。
cmds/std/buy.lpc 靠 is_vendor() 自动选中摊主,buy jitui 成功
(「你向独孤宝贝买下一根烤鸡腿」)。当场 i 是九十九两白银 + 二十文
铜板 + 一两黄金 + 烤鸡腿。F_DEALER 店铺对丐帮拒绝购买,必须先买再拜;
本轮买的是 F_VENDOR_SALE 摊,没有踩到那条门。随缘客栈自己的店小二只卖
灯笼/火把,不是食物摊。
goto /d/city/lichunyuan,空空儿(kungfu/class/gaibang/kongkong.lpc)
对 combat_exp < 2000 的局外人无门槛收徒。apprentice kong 一次成功:
恭喜成为丐帮第二十代弟子,score 称谓「丐帮一袋弟子」、师傅空空儿。
同室左全(/d/gaibang/inhole)只收已经是丐帮且袋数够的弟子,不要拿
他当新手拜师点。cmds/usr/save.lpc 真正写盘(「【存盘精灵】档案储存
成功」)。save 后杀驱动冷启动再登录,称谓/师傅/银子铜板/布袋都在。烤
鸡腿未进 autoload。
本轮没有新的 programming bug。
深度功能测试(§10.7,2026-10-04)— negative range ends
scripts/lpc_fix_negative_ranges.py: 4 line(s) in 1 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: 1 here-document block(s) repaired (1 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: cmds/arch/examine.lpc. 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-04)— paths named in another case
The archive comes from a case-insensitive host: files are stored as BAGUA0.lpc, longjing.C, d/SHAOLIN/, the code names them in lower
case (__DIR__ "bagua0", "tea/longjing", "/d/shaolin/..."), so the rooms, NPCs and items behind them could not be loaded (a .C file is
not an .lpc file; KB 03 §4.5). scripts/lpc_case_paths.py --convert --apply syxjl: 19 file(s) renamed to lower case (.C -> .lpc,
.H -> .h) and 50 path reference(s) in 2 file(s) rewritten to the new spelling; 0 skipped, 0 ambiguous. Load check of the 24 objects that were renamed, edited or name a renamed path (HEAD against the working tree, an object is the same under any spelling of its path): 5 PASS -> 24 PASS, 0 that loaded before fail now, 19 more load.
19 files moved (19 .lpc); mostly under d/death/HELLZhen (18), d/jingzhou/jianyuguodaO2.lpc (1). A rescan with scripts/lpc_warnings.py syxjl is still due: the renamed files are compiled for the first time.
深度功能测试(§10.7,2026-10-05)— room base survives a raising NPC
scripts/lpc_resilient_room.py --apply: make_inventory() of inherit/room/room.lpc loads each inventory object as if (catch(ob = new(file)) || !objectp(ob)) return 0;. new() of a file that is not there returns 0 (the room just lacks that NPC), but new() of a file whose create() raises (a skill file for set_skill() this archive never had, a carry_object() item that is not there, a header that never shipped) raised inside the room and the room did not load at all. The wrong-case renames of this lib (the section above) make the NPCs behind them reachable for the first time, so a room that holds one with such a content gap would have gone from "NPC missing" to "room missing"; now it loads without that NPC, as it did before. The room base compiles and loads with the change (HEAD against the working tree). KB 03 §4.5.
深度功能测试(§10.7,2026-10-05)— 任务表里的 .c 路径与任务守护进程的防护
scripts/lpc_dynamic_rows.py:task/dynamic_location 里 997 行写的是原档案的 .c 路径。转档时文件已改名 .lpc,而显式后缀按原样解析,load_object("/d/x.c")、new("/d/obj/quest/x.c") 返回 0 且不报错(KB 03 §4.2,KB 06 §7.220),所以 adm/daemons/taskd.lpc 读到的每一行都加载不出来:随机任务和任务物品从未生成,在 create() 里直接对结果调用 tar->set() 的版本还会崩溃,连带加载它的 cron 守护进程和 give 的任务钩子。这些行已改为 .lpc。
scripts/lpc_dynamic_quest_guard.py:1 处 spread_quest() 调用(init_dynamic_quest() 的循环里)包进 catch(),缺失的任务物品或编译不过的房间只跳过那一个任务,守护进程照常加载、其余任务照常生成。
验证:adm/daemons/taskd.lpc在新进程里加载(HEAD 一次,工作树三次,选房是随机的):HEAD 通过 1 个,工作树三次分别通过 1、1、1 个(共 1 个),无回退。
深度功能测试(§10.7,2026-10-05)— 房间列出的物件缺档时房间照常加载
房间基类 inherit/room/room.lpc:reset() 的 case 1: 拿到 0 就跳过这一项(if (!objectp(ob[list[i]])) break;)。档案里没有的 NPC 或物品(或 create() 出错的物件)原先会让列出它的房间整个加载失败(Bad argument 1 to environment(),或对 0 的 call_other()),连带这个房间后面的区域;现在房间照常加载,只是少了那个物件,下次 reset() 再试(KB 05 §7.25;scripts/lpc_resilient_room.py、scripts/lpc_room_reset_guard.py)。
验证:探针(scripts/lpc_room_reset_probe.py:房间基类列出一个不存在的物件,再调用 reset())HEAD 单件 崩溃、多件 OK,工作树 单件 OK、多件 OK。
深度功能测试(§10.7,2026-10-07)— 空的 if (current_water == 0) {}
3 个房间的 valid_leave() 里有一行什么也不做的 if (current_water == 0) {}(编译警告 Expression has no side effects),删去,行为不变:d/xingxiu/nanjiang2.lpc、d/xingxiu/nanjiang3.lpc、d/xingxiu/shanjiao.lpc。
深度功能测试(§10.7,2026-10-08)— 编译警告整理
scripts/lpc_warnings.py syxjl --fix 加 scripts/lpc_fix_no_effect.py --apply,共改动 144 个 .lpc 和 3 个 .h(多为删去未用的局部变量)。HEAD 与工作树分别加载(新进程):126 -> 126 通过,无回退;改过的头文件的 4 个包含者 2 -> 2 通过。启动时警告 9 -> 0;新进程登录(输入名字)正常。
- 2026-10-10:编译警告第二轮(按驱动报告逐条修):按位 & 改逻辑运算 10 处,返回类型/原型 30 处,NPC+F_UNIQUE 的 init() 0 个,带初始化的未用局部变量 3 个,只在 #if 分支用的声明移进分支 0 个文件;改动 36 个文件,HEAD 与工作树各载入一次无回退(36 objects; HEAD PASS 34, tree PASS 34; regress 0; newly loading 0),这些文件的警告 52 -> 10。
编译警告收尾(2026-10-13)
scripts/toolkit_fix.sh 一轮去掉 8 处多余继承,其余手工,能编译的文件警告清零;改动的 17 个对象在 HEAD 与工作树各载入一次:HEAD PASS 13,tree PASS 13,regress 0。
u/linghu/ground.h的三张表被ground0.lpc和层层继承它的ground1/2/3.lpc、ground.lpc各包含一次:表格包进#ifndef GROUND_TABLES_INHERITED,继承方在包含前定义它(同 xyj2000 的d/kaifeng)。- 书库三间(
d/city/library.lpc、d/city2/library.lpc、u/aeolus/city/library.lpc)自己的STORY_DIR覆盖globals.h的同名宏,先#undef;kungfu/skill/eff_msg.h开头连写两行同样的/*注释开头,删去一行。
- 2026-10-14:新驱动(FluffOS 970d9f09)报
Float value truncated to int(#1426)。3 个文件 3 处:赋值、初始化、return 改写成to_int(...)(值不变,只是写明截断)。改动的对象新进程各载入一次,无回退(scripts/lpc_fix_float_trunc.py,KB 04 §6.10)。
- 2026-10-14:3 个文件用了颜色宏(
HIW、NOR)却没有#include <ansi.h>(首个错误syntax error, unexpected L_STRING);开头补上(KB 04 §6.1、§6.3)。新进程比对 HEAD 与工作树:6 个对象,新增载入 4,回退 0。
内力/精力当作伤害种类(2026-10-15,KB 06 §7.241 第二类)
本库 feature/damage.lpc 的 receive_damage() 不接受 jingli/neili/force 等种类,me->receive_damage("jingli", 30) 之类在练功、绝招、吸取时报 F_DAMAGE: 伤害种类错误。25 处改为 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,而不是作者写好的提示。10 处在声明行加上 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),共 4 个文件。
其他体系的属性名(2026-10-15,KB 06 §7.241 第三类,--any-file)
另有 5 个文件(绝招、状态、物品、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)
mapping fam = (mapping)me->query("family");(带类型转换的写法)同样直接取下标,1 处补上 if (!mapp(fam)) fam = ([ ]);。
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.246)
perform 指令允许直接点名招式(如 perform stick.ban),这些绝招读了 me->query_temp("weapon") 却从不检查,空手时 weapon->name() 报错(有的已先扣了内力)。在赋值后补 if (!objectp(weapon)) return notify_fail("你必须手持兵器才能使用这一招。\n");(scripts/lpc_fix_perform_weapon.py):huanhua-jian/snow。
把经验、属性、内力当技能读(2026-10-15,KB 06 §7.247)
经验、属性、内力上限不是技能,xkx/ES 的 query_skill() 对它们只返回 0(风云的还会去载入同名技能文件而报错)。改为 query("...")(scripts/lpc_fix_pool_as_skill.py):武穆遗书 /clone/book/wumu(正气门槛 query_skill("shen", 1) < 20000 永远不过,书读不了)。
技能名拼错(2026-10-15,KB 06 §7.249)
query_skill() 里的技能名拼错了,或用的是本库改名前的旧名;本库没有这个技能,调用永远得 0:门槛(< N 就拒绝)永远过不去,相关功夫或绝招学不了、用不了;内功互斥(> N 就拒绝)从不生效;公式里这一项一直是 0。经汉字名(提示文字或中文名词典)或纯拼写差异(_/-、少一个连字符、相邻字母颠倒)核对后,改为本库的技能名(scripts/lpc_fix_skill_typo.py):beimin-shengong→beiming-shengong(/d/mj/skill/jiuyang-shengong、guiyuan-dafa、honghua-shengong、jiuyang-shengong、tiangang-zhangqi、tiangang-zhengqi 等 8 个文件);douzhuan-xignyi→douzhuan-xingyi(/d/mr/npc/obj/shu1、/d/mr/obj/shu1);yihua-jimu→yihua-jiemu(yihua-jiemu)。
文件首行注释少了一个斜杠(2026-10-15)
首行的说明注释只剩一个 /(如 /kuangwu.c金蛇狂舞、/ cloth.txt //),文件第一行就语法错误、编译失败:全真教的布衣 /d/quanzhen/obj/cloth、/d/quanzhen/npc/obj/cloth 因此从来载入不了。补回斜杠成为 // 注释,现在都能载入。
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,而不是得到拒绝。15 处(13 个文件)改为 dbase 路径查询 query("family/master_name"):有门派时值相同,没有时得 0;原有的判断照常生效(scripts/lpc_fix_family_index.py)。给映射赋值的写法未动。
血刀刀法「祭血神刀」正神时报错(2026-10-15,KB 06 §7.241)
xue-dao/shendao 的伤害是 random(shen / -1000) + shen / -3000,越邪恶伤害越高;正神的人算出负数,receive_damage() 报“伤害值为负值”。补 if (damage < 0) damage = 0;,设计不变(正派用不出伤害),不再报错。
玉女剑法「合壁」用一次就永久改动经验和剑法(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() 结束时还原并清除标记,没成亲的人经验和剑法不变(kungfu/skill/hebi.lpc 是放错位置的同一文件,不在绝招路径上,一并改正)。
NPC 带着本库没有的物品,载入失败(2026-10-15,KB 06 §7.73)
25 个文件、27 处在 create() 里 carry_object("<本库没有的文件>")->wear()(或 wield()、set_amount()):carry_object() 得 0,接着的调用报 Bad argument 1 to EFUN call_other(),NPC 根本载入不了,该有它的房间里就少了这个人。多是从别的系统搬来的 NPC 用了原系统的物品路径(最常见:/clone/cloth/cloth、/u/skinys/yihua/obj/jinlvyi、/u/wry/obj/wrysword)。每处改为 { object carried_ob = carry_object(...); if (carried_ob) carried_ob->wear(); }(scripts/lpc_guard_carry_object.py):NPC 照常出现,只是不带这件东西;文件补回来(或是虚拟对象)照样会带上。载入检查:改动的文件改前能载入 0 个,改后 24 个(24 个原来载入不了),没有退步;其余 1 个另有原因(多为 set_skill() 了本库没有的武功)。
水潭里 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/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(2 个文件)。(scripts/lpc_restore_macros.py)改后用 lpcc 逐个载入这些对象:2 个里 2 个通过。
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 载入不了,刷出它的房间也少一个人。本库有 8 个对象设了本库没有文件的武功(9 个名字,最多的是 kongmingquan、tiangang-jian、xingxiu-duzhang)。三处都改成 return:这一门武功不给、不映射,对象照常载入,只是少了它(缺的武功本身仍是内容缺口)。抽样载入这些对象:8 个里 8 个通过。(scripts/lpc_guard_set_skill.py)
通向不存在房间的出口,按对面房间的回头出口改正(2026-10-18,KB 06 §7.257)
房间出口 "west": __DIR__"xxx" 指向的文件本库没有,玩家走过去就被卡住(笔误、改过名的房间,或者没带进档案的编号房间)。对面的房间存在、并且它相反方向的出口正好指回这个房间,说明出口原本就是通向它:/d/honghua/damen 的 up:/u/ybl/honghua/room/zoulang → /d/honghua/zoulang;/d/honghua/zoulang2 的 eastdown:/u/ybl/honghua/room/zoulang → /d/honghua/zoulang;/d/huoshan/hssl2 的 east:shamo1 → hssl1;/d/huoshan/hssl2 的 west:hssl3 → hssl1;/d/huoshan/hssl2 的 north:shamo1 → hssl1;/d/huoshan/hssl5 的 west:shamo1 → hssl4;/d/huoshan/hssl6 的 north:shamo1 → hssl5;/d/huoshan/hssl7 的 east:shamo1 → hssl6;/d/kunlun/liangong 的 south:sanshengtang → shanshengtang;/d/mingjiao/jmqshulin6 的 west:jmqjiguan → jmqshenmu。改动后每个出口都能解析到本库的文件(scripts/lpc_fix_dead_exits.py;目标在运行时本来就能载入的库——虚拟房间——不动)。
补回本库没有的基类文件(2026-10-18,KB 04 §6.15)
下面这些基类本库没有,继承它们的对象(房间、NPC、物品)整批载入不了(inherit XXX; 的宏没定义,或者 inherit "/std/…"; 的文件不在)。同系的库里有同名文件,两库有大量逐字节相同的文件(亲缘关系),所以从那边原样拷来,缺的宏补进全局头文件 include/globals.h:/inherit/weapon/pin(宏 PIN)←yxcs,2 个对象继承它,抽样 2/2 载入;/inherit/weapon/stick(宏 STICK)←wmkj,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 映射不到,门派弟子用普通轻功/拳脚)。按核对过的对照表改正,共 10 处、6 个文件:kongmingquan→kongming-quan(10 处)。(scripts/lpc_fix_skill_names.py)
区域物件的零碎修正(2026-10-19,KB 06 §7.267–§7.271)
d/biwu/wudao4.lpc删掉"/u/lzd/biwu_b"->foo();(巫师的留言板不在档案里,调用失败会让房间载入不了)- 33 个 NPC 文件、48 处
create()里的this_player()->carry_object(改成carry_object((没人在场时this_player()是 0,NPC 载入不了;有玩家在场时衣服武器落到玩家手里) d/honghua/npc/xutianhong.lpc第 63 行ob - query("family/master_id")改成ob->query(...)(手误,物件编译不过)
逐个物件与 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 文件。
补回丢失的标点(2026-10-19,KB 03 §4.6)
转换时丢掉的分号、逗号、引号或文件末尾的 },共 2 个文件,修前 HEAD 载入失败。别的库里同路径的完好副本只比这里少几个标点,按它补回(括号里是那个库):/d/baituo/npc/obj/bowl.lpc(cctx)、/d/baituo/obj/bowl.lpc(cctx)。修后与 HEAD 逐个对比载入:这 2 个物件全部载入,没有退步(scripts/lpc_restore_from_twin.py、lpc_fix_eaten_quote.py --comma、lpc_fix_eof_braces.py)。
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)。改动:/d/mingjiao/shanmen.lpc(1 处)。
call_out_info() 的每一项只有 3 个元素(2026-10-20,KB 06 §7.287)
驱动返回的是 ({ 物件, 函数, 延迟 }),不带 call_out 的参数,旧代码读第 4 项 info[i][3](callouts 指令、calloutd、cod 工具)一读就报 Array index out of bounds,指令从第一行起什么也打印不出来。改为 (sizeof(info[i]) > 3 ? info[i][3] : 0)(scripts/lpc_fix_callout_info.py)。改动:/cmds/arch/callouts.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,共 2 处)。改动:/adm/daemons/logind.lpc(2 处)。
socket / dumpsocket 指令:dump_socket_status() 驱动里没有(2026-10-20,KB 06 §7.291)
这些巫师指令 write(dump_socket_status());,MudOS 的 efun 在 FluffOS 里不存在,指令编译不过。在模拟 efun 文件里补了 dump_socket_status():用 socket_status() 排出同样的表(没有 sockets 包的构建,比如 WASM,只有表头;scripts/lpc_add_sefun.py dump_socket_status)。
登录密码超过 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)。
sefun cat():缺文件时 write(0) 报错(2026-10-20,KB 06 §7.297)
void cat(string file) { write(read_file(file)); }:文件不存在(压缩包没带的欢迎/公告文件,或只有运行中的 mud 才会写的日志)时 read_file() 回 0,write(0) 在本驱动里报 Bad argument 1 to receive(),调用者(登录对话、cat 指令)被中断;老驱动什么也不打印。改成 write(read_file(file) || "");(scripts/lpc_fix_cat_unchecked.py)。改动:/adm/simul_efun/file.lpc。
翻页器 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。
skills1、cha1(cmds/skill):一个少掉的分号和一个多出来的 x(2026-10-21,KB 04 §6.25)
skills1.lpc 是 skills.lpc 的改版(加了 LDJ.NEW 横幅):横幅那句 str += "\n━━━...LDJ.NEW" NOR "━━━━━━\n" 后面没有 ;,下一行 str += ... 成了语法错误;cha1.lpc 同一位置有 x str += ...(skills.lpc 里没有那个 x)。补分号、删 x,两个命令都加载(HEAD 0/2、树 2/2)。没有改:cmds/app/qadd、qlist(QUEST_OB 和 chinese_time() 都不存在)、cmds/std/shoot(ROOM_D、ARROW_D 不存在),都是没写完的功能。
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 个文件)。
news:新闻版的 location 是 archive 里没有的 /u/bsd/workroom(2026-10-21,KB 06 §7.269 的同类)
cmds/usr/news.lpc 是一块兼作命令的 BULLETIN_BOARD:create() 里 set("location", "/u/bsd/workroom"),bboard.setup() 就把它 move() 到那个房间;巫师 bsd 的工作室不在 archive 里(log/static/editfile 里还记着他编辑过 /u/bsd/workroom.c),每次载入这个命令都是 call_other() couldn't find object '/u/bsd/workroom'(第二遍扫描里 news 那一行)。命令本身不需要房间(main()、do_post() 都不看 environment()),所以只在房间文件存在时才设 location。实测:news 没有控制台输出。同一次重扫(chat() 守卫之后,KB 06 §7.334)里,原先几乎每个命令都带一行的 Array index out of bounds(35 行)没有了。
存档里的 .c 文件名改成 .lpc(2026-10-21,KB 03 §4.2 第 9 项)
存档里写着 "/d/city/npc/wei.c" 这样的文件名;extract 时源文件已经全部改成 .lpc,而驱动对带扩展名的路径只认字面,new() / load_object() / move() 都找不到它,调用方多半把失败当成「没有这个东西」悄悄跳过。本库 2 个存档共 2 处按 scripts/lpc_fix_save_dotc.py 改成 .lpc(只改 .lpc 存在而 .c 不存在的字符串;玩家存档、备份、留言板、巫师目录和文件索引缓存不动)。改动:/d/shaolin/npc/obj/kat.o(1 处)、/d/shaolin/obj/kat.o(1 处)(共 2 个存档)。
blockade / recover:data/keep 不存在,解封之后世界仍然锁着(2026-10-21,KB 06 §7.340)
管理员扫描里 blockade 报 Error copying file from /data/user/f/fluffos.o to /data/keep/fluffos, Error: No such file or directory,随后的 recover 在第一个 cp() 上死于 */data/keep/fluffos: lstat failed,来不及执行最后的 LOGIN_D->set_madlock(0):封锁解不开。data/keep/ 是运行时目录,git 克隆里没有空目录。blockade 在第一次写之前 if (file_size("/data/keep") != -2) mkdir("/data/keep");(mkdir() 失败答 0,不抛错),recover 对没有保存档的玩家 if (file_size(src) < 0) continue;,其余照常恢复、照常解锁(scripts/lpc_fix_keep_dir.py,hy5 上实测:没有保存档时 recover 答“时空解封完毕”,blockade 建出 data/keep 并保存,recover 取回并删除)。改动(2 个文件):/cmds/adm/blockade.lpc、/cmds/adm/recover.lpc。
selfthinking、qlian:缺乏实战经验的提示读了不存在的老师(2026-10-21,KB 06 §7.348)
自创武功的自习指令在“技能等级³/10 大于实战经验”时打印 printf("也许是缺乏实战经验,你对%s的回答总是无法领会。\n", ob->name())。这一句是从 learn 抄来的,ob 是老师;自习没有老师,object ob; 从没赋值,ob->name() 抛 call_other() ... Got: int(0)。改成 你对「%s」的疑问总是无法领会 加 to_chinese(skillname),去掉没用的 object ob;。改动:/cmds/skill/selfthinking.lpc。
persuade(渡世济人):ob->query("no_fight") 的 ob 没赋值(2026-10-21,KB 06 §7.348)
峨嵋弟子用 persuade 一律在第三个判断抛错;其余 146 份同类指令写的是 environment(me)->query("no_fight")。这里的 ob 还是后面 call_out("compelete_dushi", 3, me, victim, ob, ..) 传下去的第三个参数(compelete_dushi 没用它),所以在判断前加 ob = environment(me);。改动:/cmds/std/persuade.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.,同一个动词的其他处理函数不再尝试(不是最新的一条就悄悄跳过)。删除了 44 条注册(35 个文件,scripts/lpc_fix_dead_add_action.py),动词留给别的处理函数:/d/biwu/wudao.lpc(do_heal、do_life)、/d/city/npc/aqingsao.lpc(do_kill)、/d/kunlun/npc/banshuxian.lpc(do_decide)、/d/kunlun/npc/hetaichong.lpc(do_decide)、/d/kunlun/npc/hezudao.lpc(do_decide)、/d/kunlun/zhongt.lpc(do_ci)、/d/quanzhen/npc/haodatong.lpc(do_decide)、/d/quanzhen/npc/mayu.lpc(do_decide)、/d/quanzhen/npc/qizhicheng.lpc(do_decide)、/d/quanzhen/npc/sunbuer.lpc(do_decide) 等共 35 个文件。最多的函数名:do_send 15 处、do_decide 10 处、do_check 2 处、do_convert 2 处、do_deposit 2 处。
对象路径里的 ..: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")。
缺失物品的 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 都被跳过。1 个文件里 1 处(new)改成 { object new_ob = new(路径); if (new_ob) new_ob->move(...); }(scripts/lpc_guard_carry_object.py --new:路径按这个文件自己看到的宏解析,宏名冲突、虚拟对象路径一律跳过)。 对这 1 个改动文件做加载检查(HEAD 与工作区对比):HEAD 能加载 1 个,现在 1 个(新增可加载 0 个,回归 0 个)。
调用了、但这个库自己的守护进程里没有的函数(2026-10-22,KB 06 §7.354)
MACRO->函数() 调用的函数在这个库的守护进程里不存在:call_other() 对不存在的函数不报错、只返回 0,所以这些功能(时间显示、昼夜事件、名字检查、价格文字……)一直没起作用。同一血统另一个库的同名守护进程里有这些函数,原文照抄到本库守护进程末尾(scripts/lpc_port_function.py;调用处传的参数个数、函数体用到的函数 / 全局变量 / 宏 / 字符串键都在本库里有,已核对;守护进程在 HEAD 和工作区都能加载,每个函数用固定参数各调用一次:HEAD 返回 0,现在返回正常的值):/adm/daemons/chinesed.lpc ← aoxiangtianji:chinese_month()(2 处调用);/adm/daemons/chinesed.lpc ← fengyun434:check_chinese()(5 处调用)。
(: 函数 :) 指针指向对象自己没有定义的函数(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。 还剩 1 个函数没有补(item_desc 1):原型还在函数体丢了、或者根本没写过,没有可以直接补回的捐赠(别的库同一路径的文件里没有这个函数,或者它还要用本库没有的辅助函数、签名不同),不编造:/d/yihua/lianhuachi.lpc:look_CAI。
读不到的留言板:"/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 条单独成行的语句(/d/board/songshan_b、/clone/board/kedian6_b;/d/songshan/chanyuan.lpc、/d/xiangyang/kedian.lpc)注释掉并写明原因(别的房间里同样的语句本来就是作者自己注释掉的)。证明和 45 个库的整体加载检查见 KB 06 §7.357。
(: 函数名 :) 指针指向本库没有的函数:只含这个指针的行加了注释(2026-10-22,KB 06 §7.355 补充)
inquiry / item_desc / chat_msg* 里的 (: 函数名 :) 指向本对象(含包含文件、继承的父类)没有函数体的函数:用到时(ask、look、NPC 闲聊)驱动抛 *Undefined lfun pointer called: 函数名,这一拍心跳的后半段被跳过。这些函数没有可以补回的来源(别的库同一路径的文件里没有,或者它还要用本库没有的东西),所以 1 个文件里 1 行只含这个指针的行("CAI": (: look_CAI :),)加了注释,原文保留并写明原因,这一项当作没有这个话题 / 物品 / 闲聊条目(scripts/lpc_fix_dangling_lfun.py;#include 的文件在库里缺失的对象、指针不在整行上的写法没动)。 前提(function_exists())和加载检查(HEAD 与工作区对比,本库改动的 .lpc 文件)的结果见 KB 06 §7.355:没有一个回归。
汉字按字节切片的老写法没有换成按字符:改法名 "澄" + name[2..3]、辈分判断 name[0..1] == "澄" 等 35 处(2026-10-22,KB 06 §7.360)
原档按字节算字符串区间(一个汉字 2 字节):name[2..3] 是名字的第二个字,name[0..1] == "澄" 问名字是不是以「澄」开头。转成 UTF-8 之后,这个驱动的区间和 strlen() 都按字符算(strlen("澄观") 是 2,"澄观"[0..1] 是两个字),老算术原样留着、意思全变:拜入少林 / 武当 / 峨嵋等派的玩家被改成错误的法名(二字名 张三 变成一个字的 澄,更长的名字取到第三个字);各派掌门的辈分判断(name[0..1] == "澄")永远不成立。
本库 35 处(29 个文件):拼名字的赋值 26 处、与汉字常量比较 9 处。例:name[2..3] → name[1..1](/d/emei/houshan/npc/miejue.lpc:240);name[0..1] → name[0..0](/d/emei/npc/wenxu.lpc:106);name[0..3] → name[0..1](/kungfu/class/taohua/huang.lpc:121)。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,不要重跑。
长度检查按字节写,旁边的提示按汉字写:10 处(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 你好吗)。本库 10 处(4 个文件):if ((strlen(name) < 2) || (strlen(name) > 12)) {(/cmds/skill/creatskill.lpc:618);if ((strlen(name) < 2) || (strlen(name) > 40)) {(/d/city/npc/caifeng.lpc:335)。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 区间 7 个文件。证明(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 三向均可加载。
巫师区出口 faceoff / rence / niulang / yihua(2026-10-23,KB 06 §7.372)
/u/f/faceoff/、/u/r/rence/、/u/onskyer/niulang/、/u/skinys/yihua/ 对应区域已在 /open/world1/faceoff/bird/、/open/prayer/、/d/niulang/、/d/yihua/。scripts/lpc_fix_wizard_area_exits.py 在目标存在时改写,仍缺失的出口行删除。本库 3 处。证明:dreamofseven wood5 四向可加载;xlqy_new2007 天河东西向 niulang;kxkj kitchen7 → prayer。
中文名 / 验证码仍按 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。
doc/build devil 丢分号/粘连 inherit(2026-10-27,KB 04 §6.25 Also)
doc/build/devil.lpc(建档示例倭寇)被格式化弄坏:inherit NPC void create() 粘在一起,语句之间的 ; 全丢,还有嵌套坏掉的 set("con", set("con", 10)。按原意重写成带 setup() 的完好 NPC(原 /obj/blade、/obj/cloth 在多数库不存在,示例里去掉携带以免 create 炸)。证明:HEAD 加载失败;改后加载成功。
d/city/obj/book 引号剥离 ← xiandan(2026-10-27,KB 04 §6.25 Also)
d/city/obj/book.lpc(注释仍写 xiandan)丢了几乎所有引号与分号(set_name(HIY 仙丹 NOR, ({ dan, ...})),驱动报 unexpected L_BASIC_TYPE。用本库完好的 clone/gift/xiandan.lpc 覆盖(含 u/aeolus 同内容副本)。证明:HEAD 加载失败;改后加载成功。
shaqianli glued inherit+decl(2026-10-27,KB 04 §6.25 Also)
d/wudujiao/npc/shaqianli 一行写成 inherit NPC string ask_job();。拆成 inherit NPC; 与原型。证明:HEAD 失败;改后加载。
huoba / flute2 / liuyun·lunyun(2026-10-27,KB 04 §6.25 Also)
d/xingxiu/obj/huoba 把 set("remaining", 1) 写成了 mapping 碎片 "remaining" : 1,;npc/obj/flute2 的 message_vision 缺分号与 this_player();kungfu/skill/liuyun 与 kunlun-zhang/lunyun 首行丢了 //,且 lunyun 整文件粘贴了两遍。与 ldtx/ldtxii 同形一并修。证明:HEAD 失败;改后均加载。
skill 基类补 F_SSERVER(2026-10-27,KB 04 §6.16 Also)
inherit/skill/skill 只 inherit F_CLEAN_UP,kungfu/skill/baituo-shezhang 等调用 offensive_target 时报未定义。书剑系手足基类写 inherit F_SSERVER(其内再继 F_CLEAN_UP)。照改。证明:HEAD 失败;改后加载。
jmqshenmu 截断 init(2026-10-27,KB 04 §6.25 Also)
d/mingjiao/jmqshenmu 在 void init() { 处文件结束。补上 } 使房间可加载(本库未收齐 climb/jmqdating 时不做内容补写)。证明:HEAD 失败;改后加载。
hanbing `random 反引号(2026-10-27,KB 04 §6.25 Also)
hanbing-mianzhang / hanbing-mianzhang2 在 random( 前多了一个反引号,驱动按模板字面量读到 EOF。删掉。证明:HEAD 失败;改后加载。
flute1 message_vision(2026-10-27,KB 04 §6.25 Also)
d/xingxiu/npc/obj/flute1 的多行 message_vision 缺结尾 ", this_player());(与 flute2 同形)。补上。证明:HEAD 失败;改后加载。
深度功能测试(2026-10-27,§6.25 ZHAOSHI 截断玩家技能)
玩家自创武功在 // ZHAOSHI : 0 处截断(EOF),无法加载。按同系完整 moming-blade 补一招 + valid_*/query_*/practice(2):kungfu/skill/fuhu-unarmed.lpc, kungfu/skill/fulong-unarmed.lpc。
深度功能测试(2026-10-27,§6.25 haoshu 粘贴损坏)
u/ybl/honghua/npc/haoshu 本应是红花心法书(同目录完好的 force_book),却被粘成半截书 + 房间残片,驱动报 unexpected L_STRING;room/haoshu 同形,以本库 d/shaolin/beilin3 为骨架重写并保留本地出口与 npc/haoshu 物件。NPC 侧用 force_book 覆盖。证明:HEAD 加载失败;改后书与房间均加载。
深度功能测试(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… 行。