info.html · 介绍 · play.html · 游玩 · llms.txt · 下载与本地运行 · ZIP · GitHub
属于"夕阳再现"引擎家族(与 xyzxfk、xyzxfy2、 wmkj、jhfy 同宗,核心工具文件字节级相同),作者自述基于"夕阳再现-江湖风云 2-风云再起"开发而成。这一支和另一轮处理过的 `xyzx`(夕阳再现)/`jhfy3`(江湖风云3)/`xajh4gkb`(笑傲江湖4公开版)/ `xyzxyl201412`(夕阳再现-炎龙20141231)是同一个真正的"夕阳再现"血统(`d/city/sj.lpc` 逐字节相同)——注意本项目里还有另一批同样打着"夕阳再现"招牌、但地图其实是完全不同的"天涯"家族的档案(`xysylmhb`/ `xyzxiiylzymh`/`yzxiiizylfy`/`xyzx3`/`tianxiawuxue`/ `yxcs`),品牌名称不能作为判断血统的依据。
English
Part of the "Sunset Reborn" engine family shared with several sibling archives in this project, built, per the author, atop "Sunset Reborn – Jianghu Storm 2 – Storm Resurgent." New characters are placed at random into one of several starting towns across a jianghu spanning Jiaxing, Yangzhou, and other locales, with gender-specific scene descriptions and a full underworld resurrection subsystem shared with sibling games in the same engine family.
README
内容亮点
- 江湖跨越嘉兴、扬州等多个地点,新角色会随机分配到其中之一(如"铁枪 庙""北疆小镇"等)作为起点,场景描写按性别区分称谓(如"少年侠士"/ "妙龄少女"),细节比较讲究。
- 注册流程独立设置"管理密码"与"普通密码"两组口令,管理密码专用于找回 丢失的普通密码。
- 天赋分配环节允许针对单项属性重投,也可以一次性全部随机,系统会展示 结果并请求二次确认。
- 死亡后有完整的鬼门关/白无常复活体验,与同一 ES2 大家族的
yszz/bmxkx2001共享同一套阴曹地府子系统;不少 NPC 是 friendly 属性、fight指令会被拒绝,但kill指令可以绕过这层同意判定直接开战。
- 更正(2026-08-05):上面提到的"7.68 复活软锁"修复已经撤销——经重新评估,鬼魂"不在场"时放弃复活流程更可能是有意的游戏设计(多数这类档案里鬼魂本身就无法自行移动,离开是一种游荡机制,回来时 init() 会重新触发流程),不是需要强制重试的 bug;详见 NOTES.md。
深度功能测试新发现的 bug(详见 NOTES.md)
adm/daemons/logind.lpc 里有两处调试用的 printf("%O\n", ob)
(AGENTS.md §7.34,两条平行的姓名输入路径各一处)和一处食物/饮水初
始化误判对象的 bug(ob->query("age") 应为 user->query("age"),
AGENTS.md §8.9)——已全部修复。另外在死亡/复活系统里发现并修复了
AGENTS.md §7.68 归档的复活软锁死 bug 类的又一实例:d/death/npc/
{wgargoyle,bgargoyle}.lpc 的 death_stage() 用 if (!ob ||
!present(ob)) return; 同时处理"对象已销毁"和"此刻不在场"两种情况,
后者本该重试却被当成永久放弃处理,导致复活序列一旦被打断就会让角色
永久卡成鬼魂。已按已验证的修法拆分为两段判断,此刻不在场改为 5 秒后
重试。
在线试玩
https://mudlibs.fluffos.info/bixiecanyang/
管理员账号 / Admin account
- ID:
fluffos - 密码 / Password:
Mud@2026(登录密码);管理密码(wizpwd):Wiz@2026(本游戏注册时要求单独设置一组"管理密码",找回/重置密码时使用) - 中文名 / Display name:浮浮
- 权限 / Level:
(admin)(ACL 表使用的最高常用等级) - 授权方式:
adm/etc/wizlist加入fluffos (admin)一行(保留原有 afei/addisjeams/akai 条目)。
警告:Mud@2026/Wiz@2026是本地游玩用的公开默认密码。若要正式对
外开放主机,请先修改。
本地运行
cd libs/bixiecanyang
~/src/fluffos/build-debug/src/driver config.fluffos游戏端口:40065。启动后请稍等几秒再连接。
NOTES · 移植与修复记录
bixiecanyang — 碧血残阳 之「豪侠晚歌」
Archive: 碧血残阳之豪侠晚歌.rar (archive #71). Port: 40065. Status:
done (boots clean, full registration flow verified end-to-end
including a real Chinese name reaching the actual game world).
What this is
"碧血残阳" ("Blood on the Setting Sun"), subtitle "「豪侠晚歌」" ("Ballad
of the Gallant Hero"), domain akai.isme.net, dual-port config (ZMUD 6666 /
TOMUD 8888 in the raw config; reassigned to a single port 40065 here).
adm/obj/{master,simul_efun} layout. The bundled 碧血残阳说明.txt
(author's own readme) explicitly states this lib is built on top of
"夕阳再现-江湖风云2-风云再起" ("Sunset Reappears - Jianghu Fengyun 2
- Storm Rises Again") — i.e. this is a member of the same **夕阳再现
(Xiyangzaixian)** lineage as archives #46 (xyzxfk), #47
(xyzxfy2), #55 (wmkj), and #59
(jhfy), not a standalone codebase.
Lineage confirmed via md5sum, not just the readme's claim:
adm/simul_efun/chinese.c: byte-identical (md5961d77af057bb93db320af05be5883fc) across all 5 archives (#46/#47/#55/#59 and this one).adm/daemons/securityd.c: byte-identical (md5032452f57e844ff416d4747b12b85d27) specifically toxyzxfy2(#47)'s copy — closest sibling in this family.adm/obj/master.candadm/daemons/logind.care each distinct from every sibling (own md5sums, different line counts) — same pattern as every other pair of forks in this family: shared engine utility files, divergent site-specific daemons.
Cross-check against dtsl2 (#49) — required by task instructions
libs/dtsl2/NOTES.md documents that its raw config file's own
name field contained the exact string "碧血残阳 之 豪侠晚歌" — this
archive's own title — as a confirmed-stale copy-paste leftover, not a sign
that dtsl2 is secretly a duplicate of this archive. Verified the
reverse direction too, as instructed, via direct md5sum/diff on both
raw archives (not work copies):
adm/simul_efun/chinese.c: differs — this archive's md5 is961d77af...(the 夕阳再现-family shape:strlen(str)>=2 && str[0] > 160 && str[0] < 255, 14 lines); dtsl2's isa619b926...(a different GBK-range formula:str[0] < 176 || str[0] > 247+str[1]checks, 19 lines). Not the same file at all.adm/obj/master.c: differs substantially — this archive's is 342 lines with aTOMUD_PORT/get_player_fname()backup-login-object fallback mechanism and a"change by Fan@wanxia"credit header, none of which appear in dtsl2's (302-line, no TOMUD/backup-login logic, no Fan@wanxia credit) — full diff is 646 lines of changes out of ~342, i.e. almost entirely different content past the sharedconnect()/compile_object()skeleton wording.adm/daemons/logind.c: 1007 lines here vs 917 in dtsl2 — different.- Interesting second piece of evidence for the copy-paste theory: dtsl2's raw archive's own config file is also literally named
config.bxcy(verified:libs/dtsl2/raw/DTSL/config.bxcyexists) — the same filename as this archive'sconfig.bxcy. This means not just thenamefield's *text* but the config file's *filename convention itself* was copy-pasted from a bixiecanyang-lineage template into whatever base dtsl2 forked from, while the actual mudlib code (chinese.c/master.c/logind.c) diverged completely.
Conclusion: confirmed NOT related in either direction. This archive is squarely 夕阳再现/Xiyangzaixian-lineage (shares chinese.c/securityd.c with #46/#47/#55/#59); dtsl2 is squarely dtsl(#8)/大唐双龙-lineage (shares chinese.c/F_UNIQUE-macro-gap/diamond-inherit-bug with #8/#18). The coincidence is purely a copy-pasted config template/field, confirmed twice over (stale name field + stale filename convention), never a sign of shared mudlib content.
Fixes applied (ported/cross-checked against #47's proven fix list where lineage matches, applied proactively before first boot)
1. AGENTS.md §15h (adm/simul_efun/chinese.lpc's is_chinese()): GBK
lead-byte range check (strlen(str)>=2 && str[0] > 160 && str[0] < 255)
→ CJK Unicode codepoint range check (strlen(str)>=1 && str[0] >= 0x4e00
&& str[0] <= 0x9fff).
2. AGENTS.md §15h (adm/daemons/logind.lpc's check_legal_name()):
byte-count bound strlen(name) < 2 || > 10 → character-count bound
< 1 || > 5 (matches the message's own stated "1 到 5 个中文字"); the
sliding-window gate i%2==0 && !is_chinese(name[i..<0]) had its
i%2==0 && dropped so every character position is checked (the
name[i..<0] slice itself needed no change since is_chinese() only
ever inspects index 0 of whatever's passed to it — a full-length
suffix slice starting at i is functionally equivalent to a
single-character check either way).
3. AGENTS.md §15z (5 files: include/globals.h, adm/obj/master.lpc,
adm/obj/simul_efun.lpc, adm/obj/simul_efun_bak.lpc,
u/isle/ToMud/globals.h): each carried an
#ifndef __SENSIBLE_MODIFIERS__ / #define nosave static / #define
protected static compatibility shim (this driver never defines
__SENSIBLE_MODIFIERS__, so the shim is always active). convert_lib.sh's
blanket static→nosave sed rewrote the shim's own lines too, turning
#define protected static into #define protected nosave — silently
aliasing protected to nosave instead of leaving it as its own
distinct, correctly-behaving keyword. Fixed to #define protected
protected (self-map, matching the already-correct #define nosave
nosave sibling line) in all 5 files.
4. AGENTS.md §3 counterexample (22 files): the same blanket sed also
hit log_file("static/XXX", ...) string literals (a real on-disk log
subdirectory name, unrelated to the static/nosave keyword),
rewriting them to "nosave/XXX" and orphaning the archive's real seed
data at log/static/ (confirmed present on disk: archive,
banned_sites, CALL_PLAYER, CRASHES, EAT_DAN, etc.). Reverted all
22 occurrences (clone/misc/dan.lpc, cmds/{arch,adm}/{call,purge,setskill}.lpc,
cmds/wiz/call.lpc, cmds/std/suicide.lpc, adm/simul_efun/override.lpc
×5, adm/daemons/securityd.lpc, adm/obj/master.lpc ×5) back to
"static/XXX".
5. AGENTS.md §14 (adm/obj/master.lpc's valid_override): upgraded
from the 2-arg signature to the documented 3-arg
(file, name, main_file) form, checking main_file == SIMUL_EFUN_OB ||
main_file == MASTER_OB in addition to the original file check — this
lib's simul_efun.lpc is a pure #include composer (pulls in
object.lpc/message.lpc/wizard.lpc/etc., several of which contain
efun:: overrides like object.lpc's destruct()), so file alone
(the physically-containing fragment) never equals SIMUL_EFUN_OB for
those. No live boot/registration failure was observed from the 2-arg
gap (consistent with AGENTS.md's note that this may never surface on a
real boot, only under isolated lpcc checks) but applied as free
insurance per the catalog's standing guidance.
6. AGENTS.md §15p: /adm/daemons/network/dns_master was present (live,
uncommented) in adm/etc/preload — commented out proactively before
the first boot attempt. Checked every other preload entry's own source
(securityd, virtuald, logind, rankd, preload, commandd,
chinesed, emoted, aliasd, fingerd, autosaved, channeld,
natured, monitord, storyd) for socket_create/resolve() calls —
none found, confirmed safe to leave active. httpd was already
commented out in the shipped preload file.
7. AGENTS.md §15s (adm/simul_efun/message.lpc's tell_room()): the
common 2-arg call form (tell_room(ob, str), confirmed via grep to be
the overwhelmingly dominant call shape across ~155 files in this
archive) leaves the varargs object *exclude parameter as its default
int 0, which then flows straight into message("tell_room", str, ob,
exclude) — this driver's message() efun declares its 4th argument
void | object | object * (a real type union, not "any"), so a literal
int 0 is rejected at runtime (Bad argument 4 to message()) the
first time any room's heartbeat/emote broadcast calls the wrapper with
only 2 args. Fixed at the single shared root: message("tell_room",
str, ob, exclude || ({}));. (File is CRLF-terminated — used a
byte-exact Python replace rather than a line-oriented sed/Edit to
avoid the line-ending pitfalls documented elsewhere in AGENTS.md.)
Confirmed NOT needed (verified by reading source, not by hitting a crash)
- §4 (lazy security-daemon
load_objectrecursion invalid_read/valid_write):master.lpc'svalid_writeonly everfind_object(SECURITY_D)(returns0if absent, never lazily loads it);valid_readdoes the same plus an earlyreturn 1for callers with no resolvableprevious_object(). Noload_object()call anywhere in either apply — no reentrancy guard needed. - §7 (
get_root_uid/get_bb_uid): both present and correct (return ROOT_UID;/return BACKBONE_UID;). - §15l (
destruct(SIMUL_EFUN_OB)in master'screate()):create()is a one-linewrite("master: 成功加载.\n");— no destruct/reload dance present at all. - §15n (custom
securityd.lpcACL denying "(player)"-status reads under/adm//cmds, blocking mid-connection lazy compiles): this lib'ssecurityd.lpc(byte-identical to #47's, confirmed above) IS a genuinely custom ACL with realexclude_read/trusted_readtables, but — read directly, not assumed from the sibling's writeup —exclude_readnever lists"(player)"in any of its directory entries (adm/d/data/userdata/feature/cmds/u/clone/include/inherit/kungfu/quest/logall key off wizard-tier statuses only), andvalid_readitself returns1early whenever the caller has no resolvable euid/status (if( !euid ) return 1;) and again whenever the file's author matches root (author_file(...)==ROOT_UID). The §15n failure mode genuinely cannot trigger here. Confirmed further by the clean interactive test — zero "Read access denied" anywhere indebug.log. - §15u (dormant "phone-home license check" self-destruct function): grepped
securityd.lpc/master.lpcforchecking_status/mass deletion/shutdown()-gated-on-opaque-check shapes — none found. - §8d/§15o (
get_include_path()/ local<header.h>-next-to-its-user angle-bracket includes):convert_lib.sh's automatic local-include-to- quotes pass already converted 57 such includes to quoted form during conversion (quotes resolve regardless of VM context, unconditionally fixing this whole class) — nomaster.lpc get_include_path()addition needed on top of that. - Nitan-family simul_efun-dbase architecture bug (§15): not present.
adm/obj/simul_efun.lpcis a pure#includecomposer with no bareset/query/deletedefinitions anywhere in its included fragments;feature/dbase.lpc(F_DBASE, widely inherited) implements real localset/query/deletemethods directly. Correct inherit-based architecture. - No
named.lpcdaemon exists in this lib at all (grep came up empty) — the deep §15hPATH()/sliding-window fix doesn't apply;chinesed.lpconly handleschinese_number()/dictionary translation, not name validation. - §8e (
tail()missing-efun bug):adm/simul_efun/file.chas notail()call anywhere. - §15x (hardcoded
MUD_PORTmismatch silently rejecting every connection):master.lpc'sconnect(int port)does have a hardcoded#define TOMUD_PORT 8888constant, but it's only used to conditionally set an optional"tomud"temp flag (if (port == TOMUD_PORT) login_ob->set_temp("tomud", 1);) — it never rejects a connection on a port mismatch. Since this project's assigned port (40065) never equals 8888, the flag is simply never set; confirmed no rejection occurs via the successful end-to-end interactive test. - A related §15q-shaped hidden gate DOES exist but is provably inert here:
logind.lpc'slogon()hasif (ob->query_temp("tomud")) { ... input_to("get_version", ob, ip_cnt); }—get_version()checks the input against a hardcoded literal"2060"(a TOMUD client-handshake code) and disconnects on any mismatch, exactly like the gate documented in §15q onxyzx3. But this branch is itself gated behind the sameTOMUD_PORT-only flag described above, which (per the point just above) never gets set on this project's assigned port — so the gate is present in the source but structurally unreachable for our single-port setup. Confirmed by the transcript: no"2060"prompt appeared at any point,get_idwas reached directly after the banner as expected.
Interactive test result — full registration flow
Read logind.lpc's actual input_to callback chain before testing (not
assumed from a sibling lib). Flow: logon() → (no get_version, per
above) → English id (get_id, 3-14 bytes / a-z only) → y/n
create-confirmation (confirm_id) → Chinese name (get_name,
1-5 characters, NO separate y/n confirmation for a typed name — the y/n
loop in get_resp only fires for the auto-generated random_name() path,
triggered by submitting an empty name) → 管理密码/wizpwd (new_wizpwd,
≥5 chars) → confirm wizpwd (confirm_wizpwd) → real login password
(new_password, ≥5 chars) → confirm password (confirm_password) →
attribute-gift selection (select_gift, 0-4; 0 = system random via
get_gift's y/n reroll loop) → email (get_email, [email protected] format
required) → gender (get_gender, m/f) → enter_world().
banned_name list: 你/你的/我/我的/自己/屁/他/他的/她/她的/它/它的/鬼王/
风云/流氓/爸/妈/祖先/祖宗/爷/奶/毛泽东/邓小平/江泽民/【/】/马克思/恩格斯/
列宁/抄/手淫/老百姓 — checked before testing, "秦风" doesn't match any
entry (note "风云" alone is banned, but "秦风" isn't a substring match for
it in either direction as tested — the real driver accepted it cleanly).
Verified the complete registration path in one continuous
mudclient.py connection:
""→ correctly rejected ("必须是 3 到 10 个英文字母"), confirmingcheck_legal_idis live and the empty-input retry loop works.qinfeng→ accepted, "您确定吗(y/n)?" prompt.y→ confirms new character, shows the "give yourself a name" banner.秦风(real Chinese name) → accepted silently, no rejection, proceeds straight to "请设定您的管理密码:" — confirms the §15h fix works correctly end-to-end, not just at the prompt-rendering level.pass1234/pass1234(wizpwd + confirm) → accepted.pass5678/pass5678(real password + confirm) → accepted, shows the attribute-gift explanation banner (膂力/悟性/根骨/身法/福缘/容貌).0→ system-random gift roll (rolled 膂力18/悟性22/根骨22/身法18).y→ accepts the rolled gift.[email protected]→ accepted as email.m→ male gender.- Character actually entered the game world, landing in
/d/city/wumiao("武庙"/Wumiao — Yue Fei Temple, one of the 4 configuredstart_rooms), saw NPCs render correctly (紫衣神女小玲儿, 千里眼, 阿凯哥哥) and the bulletin board object.CHANNEL_Dbroadcast "听说又来了一位叫做秦风的 少年侠士" (new-player channel announcement) with the correct Chinese name embedded, confirming the character record itself carries the real name, not just the prompt accepting it. look→ re-displayed the room correctly.quit→ dropped a starting item ("布衣") and disconnected gracefully with "欢迎下次再来!" ("welcome back next time").
Zero real error: lines, zero "Read access denied"/"Bad argument"/"Too
deep recursion"/segfault signatures anywhere in debug.log across the
whole session — only the same cosmetic 编译时段错误:... warning:
Unknown #pragma, ignored lines seen in xyzxfy2 (this
lib's own error_handler()/log_error() mislabels compile-time
*warnings* as "compile-time errors" in its Chinese message text; harmless,
matches every other lib in this lineage family).
Second independent registration-flow verification (different session, different name/gender)
Rebooted the driver fresh (new PID) after the lpcc-sweep-driven fixes below
(several of which touched adm/simul_efun/message.lpc, a preload-critical
file) to make sure nothing regressed. Ran a second, independent
mudclient.py test with a different id/Chinese name/gender combination in
one continuous connection:
- id
linfeng→ confirmy→ real Chinese name林风→ accepted silently, straight to wizpwd prompt. wizpass12/wizpass12(wizpwd+confirm) → accepted.realpass34/realpass34(password+confirm) → accepted.0→ random gift roll,y→ accepted.[email protected]→ accepted.f→ female gender this time (previous test used male) → correctly set"gender"to女性.- Character entered the game world in a different start room this time,
/d/xingxiu/beijiang("北疆小镇"/Beijiang Town — one of the same 4 configuredstart_rooms, picked by the lib's own random selection logic), saw 2 "维吾尔族妇女" (Uyghur woman) NPCs, one of which reacted interactively ("维吾尔族妇女看着你笑了起来" / "the Uyghur woman looks at you and smiles").CHANNEL_Dbroadcast "听说又来了一位叫做林风的妙龄 少女" (note: correctly used the female-appropriate honorific "妙龄少女" /"young maiden", not the male "少年侠士" from the first test — confirms gender-conditional text is also working correctly). look→ re-displayed the room.quit→ dropped a starting item ("粉红绸衫") and disconnected gracefully.
Zero real error:/"Read access denied"/"Bad argument"/"Too deep
recursion"/"Undefined function" lines in debug.log for this second run
either — confirms the message.lpc/simul_efun.lpc changes made during the
lpcc-sweep triage (below) didn't regress anything.
lpcc sweep
13,560 files initially (.lpc/.c count after rename — matching
xyzxfy2's file count almost exactly, same-generation
snapshot of a similar world size); 13,559 after reclassifying 2 non-LPC
files (below).
First full sweep (after only the proactive pre-boot fixes above, before any sweep-driven triage): 13,355 / 13,560 pass (98.5%), 205 failures.
Triaged the 205 failures and fixed every genuine driver-compat/typo bug found (leaving only true content-gap/context-dependent noise, per AGENTS.md §6b's "verify against the real boot log before trusting an lpcc-only failure" guidance and its "fix genuine one-off typos, don't chase call_other/couldn't-find-object noise" triage method):
1. 3× missing-opening-quote typos (d/quanzhen_old/hudi4.lpc,
hudi6.lpc) and 1× missing-both-quotes typo (hudi5.lpc) in
set("long", <bare Chinese text>) calls — same §10 shape documented
project-wide. Confirmed pre-existing in the raw archive (not a
conversion artifact) via direct byte inspection.
2. 1× missing-closing-quote typo (kungfu/skill/qingyi-jian.lpc):
"skill_name" : "大悲式, → "skill_name" : "大悲式", (file has
unusual \r\r\r\n line endings — fixed via exact byte-level Python
replace, not a line-oriented sed/Edit).
3. 1× dropped-closing-quote typo mid-string-concat
(kungfu/skill/kunlun-zhang.lpc): a Chinese sentence ending in the
opening bracket "「" with no closing quote before the following comma —
added the missing " (left the "「" as-is rather than guess at the
sentence's real missing continuation, per AGENTS.md's "don't fabricate
content" principle).
4. 1× missing-semicolon typo (kungfu/skill/huang.lpc):
set_skill("yuxiao-jian", 550) (no ;) merged into the next
statement, causing "unexpected map_skill". Now compiles clean but
still shows "Fail to load object" for an unrelated context-dependent
reason (NPC create() logic) — moved from a real compile bug to the
same benign "Fail to load object" bucket as everything else below.
5. 1× stray leading character (kungfu/skill/xixi-unarmed.lpc): a
bare c on line 1 (before the file's own header comment) made
inherit SKILL; a few lines later illegal ("inherit after defining
global variables"-shaped error, AGENTS.md §15t#3's failure mode from a
different root cause). Removed the stray character.
6. 1× broken for loop + 1× same-file duplicate function
(clone/misc/objmaker.lpc): for(i=0; i if(...) continue; was
missing its condition/increment clause and opening brace (confirmed
pre-existing in the raw archive) — restored to
for(i=0; i<sizeof(name1); i++) { matching this codebase's universal
idiom; separately, a duplicate int query_autoload() { return 1; }
later in the same file (harmless copy-paste, same shape as objmaker's
two query_autoload originally, see #9 below) was removed.
7. 1× missing comma between mapping-array elements
(quest/murong/qlist3.lpc): a ]) closing one quest entry wasn't
followed by a comma before the next ([ entry.
8. 1× stray backtick typo (kungfu/skill/hanbing-mianzhang2.lpc):
` random(...) ` — a leading backtick before a random() call
(confirmed pre-existing in the raw archive) caused "End of file in
template literal" since the lexer treated it as an unterminated
literal. Removed the stray backtick.
9. Same-file/base-class query_autoload() duplicate-definition
cluster (5 files: d/obj/quest/{chai,chai1,chai3}.lpc,
clone/book/{lbook5,pixie_book}.lpc): chai.lpc/chai1.lpc/
chai3.lpc each #include "task.h" (a per-directory local header that
ALREADY defines query_autoload()) and then redundantly redefined the
identical function themselves; lbook5.lpc/pixie_book.lpc each had
the exact same one-liner defined twice within their own file. Removed
the redundant copy in each of the 5.
10. 1× duplicate create() function (d/npc/m_weapon/weapon/m_bian.lpc):
a full, content-rich create() (name/weight/messages/init_whip) was
followed later in the same file by a second, generic stub create()
(missing all the specific weapon details) — clearly a copy-paste
template leftover. Removed the redundant stub, kept the real one.
11. 2× lossy-conversion-shaped "End of file in text block"
(d/quanzhen_old/manglin1.lpc, manglin2.lpc): the @LONG ... LONG
text block's closing LONG tag was merged onto the end of the
preceding text line with no newline — confirmed via the raw
pre-conversion archive bytes that this is a PRE-EXISTING authoring
typo, not an iconv/lossy-conversion artifact (unlike the similar-
looking cases documented elsewhere in AGENTS.md) — the original GBK
bytes already had "...耳际。LONG\r\n" with zero separator. Inserted
the missing newline before LONG in both files.
12. message_combatd() — a 3rd message_vision-family alias gap
(called live by kungfu/skill/yunv-xinfa/roar.lpc, 2 more call sites
commented out elsewhere): never defined anywhere in this archive,
same "§15b-style called-everywhere-defined-nowhere" gap already fixed
on xzyx/wmkj for the identical function
name. Added as a thin alias to message_vision() in
adm/simul_efun/message.lpc. Hit the exact §15aa/§8b trap while
adding it: an earlier attempt placed the alias BEFORE
message_vision's own textual definition in the same file, which
made adm/obj/simul_efun.lpc itself fail to load
("Undefined function message_vision") — moved the alias to AFTER
message_vision's closing brace, which fixed it immediately. Re-ran
the FULL boot + registration test after this specific change (since it
touches a preload-critical file) to confirm no regression — see below.
13. 2 non-LPC files caught by the blind .c→.lpc rename (AGENTS.md
§12): doc/mudlib/efuns.lpc (a plain columnar list of efun names —
pure documentation, not compilable code, nothing references it) and
d/huashan/map.lpc (a pure ASCII-art room-layout map, not a single
line of LPC, nothing references it either). Both renamed to .txt to
keep the sweep's pass/fail signal meaningful.
14. 1 genuine typo, unrelated context (doc/mudlib/efuns/shiwu.lpc,
an example/tutorial room under doc/): call_out(do_close,0); —
do_close used as a bare unquoted identifier instead of the string
literal call_out() requires ("do_close"`). Fixed; the file now
compiles (still shows "Fail to load object" for the same
context-dependent reason as ordinary room files below, not a compile
bug anymore).
Second full sweep (after all fixes above, and after reclassifying the 2 non-LPC files so the total file count is 13,559): 13,374 / 13,559 pass (98.6%).
Remaining ~185 failures, triaged by category, confirmed as expected noise (not fixed further):
- ~49× generic "Fail to load object" with no compile-error text at all (
d/migong/lev*/dong*— 35 deep-dungeon-maze rooms;clone/gem/ring*— 11 loot rings whosesetup()/init_sockets()chain callsthis_player(), which is null inlpcc's barefind_object()load context; several individualkungfu/skill/*,kungfu/class/*,clone/npc/*,clone/misc/*,quest/*items/NPCs). Confirmed via the real boot+interactive-testdebug.logthat NONE of these paths are ever touched (grep -i "migong\|clone/gem"on the log came up empty) — none are on the preload/registration path, matching the exact category documented inxyzxfy2's own NOTES.md for the same shape of failure. Standalonelpccre-checks of a sample (e.g./clone/gem/ring4, whoseinherit/gems/ring.lpcbase class itself compiles clean standalone) confirm this is a bare-test-context limitation (no real player/room graph), not a genuine bug. - ~8×
/u/snow/wudujiao/...Cannot #include globals.h: the exact same personal-wizard-scratch-directory VM-context-dependent include gap already documented (and left unfixed, for the same reason) inxyzxfy2's own NOTES.md — this world content is shared between the two forks. Not on the registration/preload path. feature/vendor_sale.lpc: significantly corrupted in the RAW archive itself (confirmed via direct byte comparison, not a conversion artifact) — dozens of missing semicolons/parens and what looks like a fragment of a DIFFERENT function'sifclause spliced into the middle of a string literal, spanning ~60 lines. This goes well beyond a single-line typo fix; reconstructing the intended shop-transaction logic would mean fabricating business logic, not restoring a known-correct original — left as a documented, unfixed content- corruption gap (matches AGENTS.md §13's "missing/broken content is a real archive gap" philosophy). Confirmed unreachable: nothing in the treeinherits or otherwise references this file at all (dead code as far as this archive goes).d/player/ltsh/npc/saveme.lpc:exert_function(10)passes an int literal where every other ~60 call sites in this archive pass a function-name STRING (e.g.exert_function("recover"),(: exert_function, "recover" :)), perinherit/char/npc.lpc'sint exert_function(string func)signature. Genuine isolated typo, but the "correct" intended string can't be recovered without guessing — a single obscure healer-NPC'schat_msgconfig, not on any critical path. Left as a documented, unfixed typo.clone/weapon/panguanbi.lpc:inherit PEN;—PENis never#defined anywhere (include/weapon.hdefines every other weapon-type macro — AXE/BLADE/DAGGER/FORK/HAMMER/SWORD/STAFF/CLUB/THROWING/WHIP/RING — but never PEN), and no/inherit/weapon/penfile exists either. Exact same shape as the already-documentedCLUB/WEAPON_COMBO/BBS_BOARDgaps ondtsl2(#49) — a missing macro with no clear matching target file to point it at, so guessing a mapping (e.g. toSTICK) would be fabricating behavior rather than restoring a documented gap. Left unfixed, single file affected.- 3×
d/heimuya/{shenggu,tang}.lpc,d/heimuya/npc/tang.lpc: "End of file in text block" — all 3 were also flaggedLOSSY conversionduring the encoding pass, matching the genuine iconv-eaten-newline variant documented in AGENTS.md's Encoding section (as opposed to #11 above, which was confirmed pre-existing in the raw bytes) — not chased further given the small scope (3 files, none on the registration path). - Remainder (~20 files) is the usual long tail of scattered one-off undefined variables/functions, a
Bad type for argumentonset_name()(string vs string*, 2 files), aRedeclaration, and a couple more isolated syntax errors in unrelated content files (quest NPCs, weapon templates) — consistent with every other lib in this project's own long tail, not triaged file-by-file per AGENTS.md §6b.
Memory stayed healthy throughout every sweep pass on this 23GB host,
though two of the three sweep runs briefly hit low-availability windows
(<1.2GB) caused by OTHER concurrently-running agents' own lpcc sweeps on
different libs (confirmed via ps aux — not this lib's own process) —
the affected runs were killed and cleanly retried once the concurrent
load eased, per AGENTS.md §6b's monitoring guidance.
How to run
cd libs/bixiecanyang
~/src/fluffos/build-debug/src/driver config.fluffos
python3 ../../scripts/mudclient.py 127.0.0.1 40065 --timeout 25 --idle 1.5 \
--send "" --send "<newid>" --send "y" --send "<中文名字>" \
--send "<wizpwd>" --send "<wizpwd>" \
--send "<password>" --send "<password>" \
--send "0" --send "y" \
--send "[email protected]" --send "m" \
--send "look" --send "quit"Retroactive fix (QA re-verification pass, 2026-07-23): log_error() compile-warning spam (AGENTS.md §15af)
Found (proactively, before the first re-verification boot — same shape as
several sibling libs in this project's ES II/夕阳再现-adjacent families)
during a routine re-verification pass: adm/obj/master.lpc's
log_error() showed the raw compiler diagnostic text to ANY connected
player, not just wizards — no wizardp() gate at all — for every compile
diagnostic funneled through APPLY_LOG_ERROR, including harmless "Unused
local variable" warnings triggered by the first lazy compile of an
ordinary room/command file. Fixed proactively before booting (same pattern
as dtsl/dtsl2/dfgs2/wuhanzhan/shenzhou): only
show the full diagnostic to a wizard; only alarm an ordinary player with
the generic default error message for a genuine compile error (gated
on absence of "warning:" in the message) — #include <runtime_config.h>
was already present, so no additional include was needed here.
Re-verified with a fresh full registration (real name 秦湖, following the
documented wizpwd→password→gift→email→gender flow) reaching the actual
game world (铁枪庙 starting room), then look/score both producing
correct, clean output with zero compiler-warning spam and zero real
error:/denied/too deep recursion lines in debug.log.
Re-verification pass (2026-07-23): driver rebuild + LPC formatter + WASM build
- Formatter: ran
format-corpus.mjsover all ofwork/(13,558 files, 13,459 written/reformatted, 37 already-clean, 62 refused with an error — expected on legacy code, not chased individually). - Native retest against rebuilt driver (
build-debug/src/driver, rebuilt from latest upstream master): clean boot, zero fatal errors indebug.log. Full registration re-verified end-to-end on the now-reformatted source with a fresh real Chinese name (秦岳), reaching the actual game world (武庙 starting room);look/score/quitall produced correct output (score's full character-sheet box rendered correctly), zero real errors indebug.log. No regressions from the reformat or the fresh driver build. - WASM build: preload completes and prints
Initializations complete.cleanly. Login is blocked by two issues, neither of which is a mudlib bug and both already anticipated by this project's known-limitations list: 1.adm/daemons/logind.lpc'slogon()enforces an intentionaluptime() < 30post-boot grace period (an anti-crash-loop safeguard, same pattern this lib already needed natively — see the 30s config-startup message players see for real). The stockscripts/wasm_client.jscallsfluffos_connect()immediately after boot with no delay, so it always trips this gate before any--sendis even processed (logon()runs at connect time, before the first line of input). Confirmed this is purely a harness-timing artifact, not a WASM defect, by testing with a scratch variant of the harness that adds a real 31s delay before callingfluffos_connect()— after that delay, login proceeds past this check. 2. Past that point, login hitsadm/daemons/band.lpc'sis_banned(), which doessscanf(site, "%s.%s.%s.%s", ...) != 4onquery_ip_number(ob)and treats a non-matching result as banned — this is exactly the documentedquery_ip_number()WASM-mode limitation (AGENTS.md's post-conversion-tooling section): the wasm build's loopback connection doesn't format as a real dotted-quad, so the sscanf never matches 4 parts and every login is rejected as "banned" (你的地址在本 MUD 不受欢迎...). Not a mudlib bug — do not patch; this lib is a second concrete example of the same driver-side gapbxsj'ssited.lpcdemonstrates.
- Verdict: boots cleanly under WASM; login cannot complete due to
the driver's documented query_ip_number() limitation (once the
unrelated 30s harness-timing artifact is worked around). Not a
regression, not a mudlib bug.
WASM-enablement pass (2026-07 standard: loopback-allow, uptime bypass, admin seed)
Gates patched:
adm/daemons/logind.lpclogon()(~line 80): theuptime() < 30startup-grace destruct now applies only to real remote dotted-quad addresses; loopback and malformed/empty IPs (current WASM driver behavior) are exempt. (Previously documented as a WASM blocker; now bypassed per the standing §1.3e policy.)adm/daemons/band.lpcis_banned()(~line 108): loopback /127.prefix / empty / non-string / non-dotted-quad → return 0. This also supersedes the original "malformed IP => banned" behavior that was the second documented WASM blocker for this lib.- The per-IP cap in
get_id()(ip_cnt > 8) counts users sharing the connecting IP; under loopback-only local play this could in theory trigger with 9+ tabs, butip_cntis computed inlogon()before the gate and the limit is generous; left unpatched (wiz_level>=2 and welcome-listed users are already exempt; fluffos is admin). Note if 9-tab local testing is ever needed, add a loopback exemption here.
Admin account: id fluffos, login password Mud@2026, wizpwd Wiz@2026
(this lineage's separate "管理密码" asked during registration), display
name 浮浮, (admin) via adm/etc/wizlist. Because wizlist was seeded
before registration, the account came out of registration already with
wizard view; verified update /d/quanzhou/tieqiang → 成功 on re-login.
Save files for the orchestrator to force-add:
libs/bixiecanyang/work/data/user/f/fluffos.o and
libs/bixiecanyang/work/data/login/f/fluffos.o (untracked dirs).
Retest: fresh normal registration (id ceshisan, name 秦风, female)
end-to-end into the world, look/score/quit correct, 0 new errors in
debug.log; test char saves removed.
Retrofit (2026-07-24): fail-closed loopback check (security correction)
The loopback-allow gate patched above originally also treated a
non-string/empty/malformed query_ip_number() result as loopback (a
defensive stand-in for the WASM driver bug). That driver bug is now fixed
upstream, so this was tightened to fail-closed: only an exact
"127.0.0.1" / "127."-prefix / "::1" match bypasses the gate; a
malformed or non-string address now falls through to the original gate
logic (treated as untrusted/remote) instead of being auto-allowed.
Re-verified fluffos login still works after tightening.
WASM 修复摘要(迁移自 meta.json 的 group_note)
基于"夕阳再现"衍生引擎的独立游戏。状态已从过时的 limited 修正——这份档案自己的 README 里从未记录过任何缺陷说明,本轮重新测试也没有发现:一次完整的 WASM 注册流程(英文 id 仅限小写字母 → 确认 → 中文名字 → 管理密码+确认 → 登录密码+确认 → 天赋摇点,0 为随机 → 接受 → 电子邮件,需 id@address 格式 → 性别)全程无错误地进入"武庙"起始区域("你连线进入这个世界,开始了自己的江湖生涯"),预先播种的管理员账号(fluffos/Mud@2026)也能正常登录("您目前权限:(admin)")。
深度功能测试(第二轮,2026-08-04)
按 §10.7 方法论用原生 driver(端口 40065)跑了一遍超出注册流程的完整游玩 ——移动、战斗、死亡/复活体系,并在此过程中主动核对了 AGENTS.md 已归档 的几类高发 bug。
主动检查命中 3 处,全部在 adm/daemons/logind.lpc 里:
1. printf("%O\n", ob)(§7.34)——随机接受姓名的分支,紧挨在
ob->set("name", Rname);("请设定您的管理密码:"提示之前)。
2. printf("%O\n", ob)(§7.34)——手动输入姓名的分支,同样紧挨在
ob->set("name", arg); 之前,与上一条是同一 bug 的两条平行路径
(加入 AGENTS.md §7.34 的"两条平行路径"分组,与 hc/yxjh/
xkyx3b/mnhf 同类)。
3. if (ob->query("age") == 14) { ... }(§8.9)——user->setup() 之后
的食物/饮水初始化判断,用的是登录桩对象 ob 而不是玩家本体
user 的 age(只有 user 会在 update_age() 里被设成 14),错的
对象上永远读不到 14,食物/饮水永远不会走到这段初始化逻辑里。这是
AGENTS.md §8.9 的第五个独立血统实例(前四个是 cctx/niaoren 共祖对、
yxjh、ldtxii/ldtx 共祖对),用的是 yxjh 那种精简写法(裸
if,没有额外的 !user->query("food") 门槛)。
三处一次性改完,跑了 formatter(首次接触触发全文件重排版,用
git diff | grep -B2 -A2 "printf\|query(\"age\")" 核实过只有这三处语义
改动,其余全是空白/大括号风格规整)。修完后注册新角色食物/饮水条显示
满格(16/16),确认 §8.9 修复生效。
注册流程本身有几个容易搞反的细节(本轮踩过坑,供后续参考): 双密码系统里,第一组输的是"管理密码"(wizpwd),第二组才是真正登录 用的"普通密码"——用第一组去登录会被强制要求重设普通密码 ("您输入的是管理密码,请重新设定您的普通密码");天赋分配菜单要走 "0"(系统随机)再 "y"(确认接受),漏掉任一步都会卡在原地重问。
游玩内容:注册成功的测试角色(沐豪侠 / id bxcyfu)从"北疆小镇"
出发,逛了赛马场("姑娘追"维吾尔族特色内容)、草原、峡谷——沿途遇到
的 NPC 全是 attitude "friendly",fight 指令一律被判定不同意开战。
确认 kill 指令能绕开这层 friendly 同意门槛,对赛马场的"阿拉木罕"
(combat_exp 5000)直接 kill,触发了一整套战斗流程并以测试角色死亡
告终。
死亡后发现死亡/复活系统与 bmxkx2001/yszz 同宗:死亡后被送到
"鬼门关",NPC 是"白无常",判词、场景描述、death_stage() 的多阶段
call_out 结构与 d/death/npc/{wgargoyle,bgargoyle}.lpc 几乎逐字一致
——这是 AGENTS.md §7.68 已归档的复活软锁死 bug 类的又一实例。核对
wgargoyle.lpc/bgargoyle.lpc,两个文件都是同样的
if (!ob || !present(ob)) return;——只要复活序列进行中的任意一瞬间
present(ob) 判假(哪怕只是暂时不在场,不是真的走了),整个复活流程
就会被无声永久放弃,角色卡成鬼魂再也无法复活,没有任何报错提示。
按 §7.68 已验证过的修法,把守卫拆成两段:!ob(对象真的已销毁)才
永久放弃;!present(ob)(此刻只是不在场)改为 5 秒后重试同一阶段,不
再放弃。两个文件应用完全相同的改法,formatter 跑完确认 diff 干净(各
9 ++++++++-,非全文件重排)。
验证:重启 driver 让改动生效后,用新一轮 kill guo jing(郭靖,
北大街的另一个高战力 NPC)复现了一次死亡,角色被送到鬼门关的白无常
处。这次没有主动制造"复活序列进行中被挪走"的中断场景(不像
bmxkx2001 当时是被一个无关 NPC 的强制移动撞上),而是让连接在等待
过程中断线重连——call_out 链本来就不依赖网络连接是否在线,所以这个
测试严格来说只验证了"正常、未被打断"路径在改动后仍然完整走完:断线
期间复活序列在服务端自行跑完,重新连线时角色已经复活、站在起始房间
"武庙",score 显示"你共死亡:1 次"、精/气条降到一半(符合死亡惩罚),
食物/饮水满格,没有任何异常。也就是说,这个具体实例上的修复是照搬
已证实的 bug 类模式应用的,没有在 bixiecanyang 里独立复现出"中途被
打断导致永久卡死"的原始故障场景——诚实记录:如果以后有更方便强制
挪动鬼魂 NPC 的手段,值得回来专门验证一次中断场景。
git status --short libs/bixiecanyang/ 复查干净:只有三个源文件的修改
是跟踪变更,测试角色的新存档(data/{user,login}/b/)保持未跟踪状态,
未纳入提交(沿用本项目约定,测试角色存档不提交,只有预置的 fluffos
管理员账号存档例外)。
更正(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_BOARDinherit+ 多余replace_program()致命形状(AGENTS.md §7.86,post命令崩溃):全档案 100 处命中,已删除多余的replace_program(...)调用(保留inherit),逐文件保留原有行尾格式(CRLF/LF 按文件原样)。本次为跨库 §7.86 扫描修复(触发原因:该 bug 已在 6+ 个互不相关的血统家族独立确认,属于近乎普遍的拷贝粘贴模式),仅做编译检查(驱动干净启动、端口正常监听),未做完整 §10.7 深度游玩测试。
深度功能测试(2026-08-14,round two,新驱动重测)
针对驱动升级(quest_times/win_times %-operator 修复 + Warning/warning
大小写回退兼容)做的重测,逐项独立核对了本 session 新确立的检查
项(不只是信任 NOTES.md 已有记录):log_error() 确认已经有更精
细的巫师/玩家分流+严重度判断(§15af 记录的修复);§8.9、printf 泄
漏、§7.68 撤销均确认代码状态和记录一致;feature/dbase.lpc 未发
现密码写保护,不适用 tybxjh/wlhd 那一类 bug;win_times 的
%-operator 也已用 to_int(query("win_times")) % 5
(d/city2/npc/refereew.lpc:146)。
本轮新发现并修复的 PROGRAMMING bug
1. log_file()(adm/simul_efun/file.lpc)本身缺少
assure_file() 保护(AGENTS.md §7.11-class):已加上前向声明
+ assure_file(LOG_DIR + file);。
2. cat()(同一文件)对不存在文件的空指针式崩溃,主动加固:
未在本档案现场触发,属主动加固,改成 write(read_file(file) ||
"");。
实测过程
管理员 fluffos/Mud@2026(此前已注册,(admin) 权限此前已确
认)真实重连两次:第一次专门用 update /adm/simul_efun/file 确认
写权限仍然生效("重新编译 /adm/simul_efun/file.lpc:成功!"),第
二次单独验证密码重连本身。均成功登录,存档数据一致。全程
debug.log 无运行时错误。驱动按精确 PID 结束;测试期间产生的存
档时间戳增量已 git checkout -- 还原。
Round three deep functional test (2026-08-18)
Registered a fresh character (killguoj) and ran it through a full
死亡/复活 playthrough — combat kill by a d/death/npc/{bgargoyle,
wgargoyle}.lpc (鬼门关) death sequence — with a deliberate mid-chain
disconnect/reconnect, mirroring the reconnect-race scenario documented
in AGENTS.md §7.112.
Bug found and fixed: AGENTS.md §7.112 (duplicate death_stage() call_out chain on reconnect)
Both d/death/npc/bgargoyle.lpc and d/death/npc/wgargoyle.lpc had the
textbook vulnerable shape: init() unconditionally scheduled a 5-stage
death_stage() call_out chain with no re-entry guard. Because
enable_commands() re-broadcasts init() to every object in the room
and this lib's clone/user/user.lpc::reconnect() calls
enable_commands() on every reconnect, any ghost sitting in 鬼门关 who
reconnects even once mid-sequence would get a second, independent copy
of the whole chain stacked on top of the first — the two chains racing
to move/reincarnate the player, potentially double-applying the death
penalty or misrouting the revival.
Fix (matches the reference shape from dtsl/sj/yueyingqiyuan etc.
in §7.112): added a per-victim set_temp("death_stage_active", 1) /
query_temp(...) guard around the call_out() scheduling in init(),
cleared at every exit point of death_stage() (early return on
!present(ob), the aggressive-living-player branch, and the final
reincarnation branch).
Live-verified: registered killguoj, walked to 铁枪庙, picked a
fight with 乌鸦 to die, landed in 鬼门关 with 白无常
(wgargoyle.lpc). Deliberately dropped the connection ~2s after the
death-stage chain had already started, then reconnected as the same
character mid-chain (which re-triggers init() via
enable_commands()). Post-fix behavior: each of the 5 death_msg[]
lines appeared exactly once, in order, 5 seconds apart, with no
interleaving or duplication; the final stage reincarnated the character
exactly once (moved to 武庙, startroom reset, inventory dropped) and
score afterward showed "你共死亡:1 次" — a single, correctly-counted
death, not a doubled one. Confirms the guard suppresses the duplicate
chain without breaking the normal single-chain path.
Standing round-three checklist — other items checked
- §7.111 (
master.lpcstandard_trace()crash onerror["object"] == 0): already fixed in this lib —adm/obj/master.lpc:221already guards withobjectp(error["object"]) ? file_name(error["object"]) : "<none>". Clean, no action needed. - §7.113 (netdead reconnect never restores
heart_beat): checked the real reconnect path (adm/daemons/logind.lpc::reconnect()→clone/user/user.lpc::reconnect()). Unlikeshzs, this lib's actual reconnect function correctly callsset_heart_beat(1)(clone/user/user.lpc:198), matching itsnet_dead()'sset_heart_beat(0). Clean, not applicable. - §7.90 (eval-cost too low for this lib's NPC-creation cost):
config.fluffosalready setsmaximum evaluation cost : 50000000, far above the 700000 template default that triggers this class of bug. Nocost limit reachedaborts observed anywhere in this session's testing (combat, room movement, death, reincarnation, two full reconnects). Clean, not applicable. - §7.11 nosave-dir pattern / logind.lpc save path: this lib's
log_file()simul_efun was already hardened withassure_file()in the round-two pass above, so everylog_file()call site inlogind.lpc(registration id-creation log, etc.) is covered. Separately checkedadm/daemons/toptend.lpc::topten_save()'s unguardedwrite_file(f_name, ...)(thenitan_ceshi-class non-fatal §7.11 variant) — its target directory/topten/ships with the archive and is present (rich.txt,exp.txt, etc. all exist), so this write path is not broken here.logind.lpc's otherwrite_file()calls (users,maxonline,idusercounters) target its ownadm/daemons/directory, which obviously exists. Registration itself was live-verified working end-to-end (new character reachedscoresuccessfully). Clean, not applicable.
Test hygiene
Driver ended by exact PID. Test-character save files (killguoj,
deathtst, deathwu and their .o twins under data/{login,user}/)
were left untracked and deleted, not committed — only the two source
fixes (bgargoyle.lpc, wgargoyle.lpc) are part of this commit, per
this project's convention that test-character saves never get
committed.
§7.100 跨库扫描修复(ROOM 冗余 replace_program() 关闭包炸弹,2026-08-19)
同一形状覆盖到几乎所有房间基类(机制详见 AGENTS.md §7.100)。本库属
于该扫描已知最大规模的 10 个库之一。二进制模式脚本机械删除了 5241
处独立、未注释的 replace_program(ROOM); 整行。另外手工清理了造房工
具代码生成模板里内嵌的同一形状,本库有两份完全同形状的拷贝
(clone/misc/roommaker.lpc、u/fyue/misc/roommaker.lpc,各 1 处
字符串拼接,和同一 XYZX 血统的 longyunmeng/xyzxfk/xyzx 完全一样的形
状)。删除总计 5243 行,与本次扫描 FINDINGS.md 记录的 bixiecanyang
存活命中数完全一致。
验证:干净启动一次真实调试驱动,端口 40065 正常监听,
work/log/debug.log 全程无新增内容。用已播种的 fluffos/Mud@2026
管理员账号连线,在北疆小镇/巴依家庭院/巴依家客厅之间往返走了十余个
房间(含 NPC 互动),look/score/who 均正常(score 首次惰性编译
adm/daemons/combatd.lpc 打印了一条无害的 Unknown #pragma 警告,与
本次修复无关),未见任何 "cannot replace"/"cannot bind" 或崩溃迹
象。测试产生的 data/{login,user}/f/fluffos.o 存档时间戳 diff 已
git checkout 撤销,不提交。驱动按精确 PID kill。
§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-04 / 2026-08-14 / 2026-08-18
三轮覆盖了注册、战斗、死亡/复活和 log_file,没有买东西、也没有拜师。
这是真正的夕阳再现/江湖风云血统(d/city/sj.lpc 与 xyzx 逐字节相同),
不是天涯家族;拜师路线仍是扬州树洞左全,不是华山。TOMUD 的 2060 握手
只在 query_temp("tomud") 时走 get_version(),标准端口 40065 第一
输入就是「请输入您的英文名字:」,不要发 2060。
实测过程
管理员 fluffos / Mud@2026(wizpwd Wiz@2026 不是登录密码)。落地
北疆小镇 /d/xingxiu/beijiang。游戏内时间是「盛夏的清晨」,醉仙楼
F_DEALER 在 night/midnight/dawn 会打烊,本轮赶上可买窗口。
goto /d/city/zuixianlou,list 烤鸡腿八十文钱 / 牛皮酒袋一两白银 /
包子五十文钱(jitui value 80,不是 xyzxfk 那种八十两黄金标价)。
clone /clone/money/gold 后 buy jitui 成功(「你向店小二买下一根烤
鸡腿」)。当场 i 就是九十九两银子 + 二十个铜板 + 烤鸡腿,黄金条目
已消失(找零 10000−80 = 9920)。F_DEALER 对丐帮拒绝购买(穷叫化),
必须先买再拜。
goto /d/gaibang/inhole,左全源码是 kungfu/class/gaibang/zuo-qu.lpc
(文件名少一个 n),apprentice zuo 一次成功:左全收徒,score 「丐
帮第二十代弟子」、师傅左全。cmds/usr/save.lpc 真正调用两个 save()
(60 秒内再 save 会假「档案储存完毕」不写盘,本轮只 save 一次)。
user.o 立刻带上 family_name":"丐帮" / master_name":"左全" /
generation":20。断线后再连(「重新连线完毕」),称谓/师傅/银子还在。
左全只收男性。烤鸡腿未进 autoload 列表(身上还在是因为这次是 linkdead
重连,不是冷启动读档)。
本轮没有新的 programming bug。巫师账号登录时 score 刷了一条
combatd.lpc Unknown #pragma,是 2026-07-23 §15af 已记录的「巫师看全
部诊断、玩家只看真正错误」分流,不是漏网。live debug.log 是
libs/bixiecanyang/log/debug.log(Boot Time Fri Sep 4 02:01:32 2026),
无 error: / Too deep recursion。error_handler 把轨迹交回驱动
debug.log。work/log/log 只有编译期 pragma/unused 警告;move.bug
停在 2026-07-22。管理员存档未提交。