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。