info.html · 介绍 · play.html · 游玩 · llms.txt · 下载与本地运行 · ZIP · GitHub
本压缩包对应"金庸群侠传"(ES II 引擎)家族的"2008超豪华版"这一内容版本,md5sum 确认与本项目中的"2008加强版"(`jqxz2008`)、"2008标准版"(`jqxz2008std`)核心引擎(master、安全、登录等关键文件)逐字节相同,这支血脉还延伸到 `xiakexing3`/`xiakexing2017` 两个更远的快照;本作在门派 NPC、战斗数值配置、部分地图场景上有独立的内容调整,文件规模也是四个 2008 系版本中最大的一个。与兄弟版本一样,新角色从店小二看店的路边茶馆起步,可经中央广场的树洞暗语加入丐帮拜入左全门下,也可走白驼山使者按资质招人的另一条路线;深度测试里走通了完整的拜师→改投另一位师父的真实"叛门"流程,验证了一次真实商店交易(扣款并拿到实物),以及一次完整的战斗死亡→黑无常鬼门关→转生复活。
English
The "Deluxe" build of this project's 金庸群侠传/"Jin Yong Heroes Gathering" (ES II engine) family -- md5sum-confirmed byte-identical core engine (master, security, login, Chinese-text daemons) to sibling jqxz2008 and jqxz2008std, but the largest actual content build of the three (3,811 raw files vs. jqxz2008's 3,773), with its own sect-NPC roster and combat-number tuning (the city2 imperial-palace-gate district some earlier notes flagged as Deluxe-only is actually present in all four editions, file-count-verified -- not a genuine difference). Shares the same tea-house starting point, Beggars'-Sect passphrase-hideout join, and White Camel Mount recruiter path as its siblings.
README
内容亮点
- 以金庸武侠小说世界观为背景:少林、武当、丐帮、明教、桃花岛等门派 悉数登场,玩家从"客店"起步拜师习武、行走江湖。
在线试玩
https://mudlibs.fluffos.info/jqxz2008dlx/
管理员账号 / Admin account
- 账号 id:
fluffos密码:Mud@2026中文名:浮浮 - 权限:
(admin)(本 mudlib 的最高巫师等级),通过adm/etc/wizlist数据文件授予。
警告:Mud@2026 是本地游玩用的公开默认密码。若要正式对外开放主机,请先修改此密码(或从 wizlist 中删除该账号)。
本地运行
cd libs/jqxz2008dlx
~/src/fluffos/build-debug/src/driver config.fluffos游戏端口:40085。
NOTES · 移植与修复记录
jqxz2008dlx — 金庸群侠传 (Jin Yong Heroes Gathering, deluxe)
Archive: archives/金庸群侠传2008超豪华版.rar ("Jin Yong Heroes Gathering 2008,
super deluxe edition"). Extracted mudlib root: raw/jy/ (a single top-level
jy/ directory inside the archive, same layout as archive #91). Port:
40085. Status: done (boots clean, full registration flow verified
3 times with real Chinese names, post-login look/score/quit verified
working each time).
What this is / lineage (confirmed via md5sum BEFORE doing anything else)
config.cfg's name field (GB18030-decoded: bd f0 d3 b9 c8 ba cf c0 b4
ab -> 金庸群侠传) matches the archive title exactly.
Confirmed byte-identical core engine to jqxz2008 (archive
#91, libs/jqxz2008/), checked via md5sum on the raw
archives before any conversion, per the task brief's lineage-check
instruction:
| file | md5 vs #91 | md5 vs xiakexing3(#44) |
|---|---|---|
| adm/obj/master.c | identical | identical (matches #91's own prior finding) |
| adm/single/master.c | identical | identical |
| adm/daemons/logind.c | identical | identical |
| adm/daemons/securityd.c | identical | differs (matches #91's prior finding that only securityd/config differ vs xiakexing3) |
| adm/simul_efun/chinese.c | identical | identical |
| adm/daemons/chinesed.c | identical | identical |
So this archive is confirmed to be the same underlying engine core as
#91, exactly as the task brief predicted (title-family: xiakexing3(#44),
#91, #92, #93, #94 all share the 金庸群侠传/侠客行 lineage). Per the task's
explicit instruction, all of #91's proven fixes to these byte-identical
files were ported directly rather than rediscovered from scratch (see
below) — verified line-by-line via diff against #91's already-fixed
work/ copies before applying each one, not assumed.
However, this is NOT a duplicate/near-duplicate of #91's overall content
— it's a genuinely different content snapshot on the same engine (the
same relationship as "different game version, same server software").
diff -rq of the two raw archives shows: file count differs (3773 raw
files in #91 vs 3811 here), and dozens of zone/NPC/room files differ
byte-for-byte between the two (combatd.c has different combat-formula
tuning, chard.c/updated.c/several d/ zone files differ, several
files exist only in one archive or the other e.g. clone/board/
mingjiao_b.c only here, d/mingjiao/guangmingding.c only in #91, etc).
This matches the established shujian2008/sjtx2 and
zhongjidiyu-family precedent: same engine, different content build.
Cross-check note for later archives (per task brief): archive #92
(金庸群侠传2008版.rar, being processed concurrently by a sibling agent
into libs/jqxz2008std/ at the time of this writing) and
archive #94 (金庸群侠传2015版.rar, not yet started) were NOT
cross-checked against this lib (concurrent/not-yet-processed, per the task
brief's own caveat) — whoever processes or reviews #94 next should
md5sum its adm/obj/master.c/adm/daemons/logind.c/adm/simul_efun/
chinese.c/adm/daemons/chinesed.c against both #91's and this lib's raw
copies; given the pattern held for #91 vs xiakexing3 vs this lib, there's
a real chance #94 is yet another same-engine snapshot.
Small-to-medium lib: 3,811 raw files, 3,171 .lpc/.c files sweepable by
lpcc_check.sh.
Fixes applied (with why) — ported from #91 after confirming applicability
For every fix below, the underlying file was diffed against #91's pre-fix/post-fix state first; only fixes confirmed applicable (identical buggy pattern actually present in this archive's copy) were applied. Nothing was applied blindly on lineage-assumption alone.
1. AGENTS.md §15h (is_chinese / check_legal_name — GBK byte-range
checks silently wrong under UTF-8 strings). Confirmed via diff that
adm/simul_efun/chinese.lpc and adm/daemons/logind.lpc were BYTE-FOR-
BYTE identical to #91's own pre-fix originals (not just "similar") —
ported #91's exact fix verbatim:
- chinese.lpc's is_chinese(): GBK lead-byte range (str[0] > 160 &&
str[0] < 255, strlen>=2) → CJK Unified Ideographs codepoint range
(str[0] >= 0x4e00 && str[0] <= 0x9fff, strlen>=1).
- logind.lpc's check_legal_name(): byte-count bound strlen(name) <
2 || > 12 → character-count bound < 1 || > 6; dropped the
i%2==0 && even-byte-offset gate.
- Verified working: real Chinese names "秦风", "秦风二", "秦风三"
all accepted on the first try across 3 separate registration runs.
2. AGENTS.md §15ae (private nomask command-hook breaks every
post-login command silently): feature/command.lpc's command_hook
was private nomask (same as #91); home/command.lpc's copy was
already correct (nomask only, no private) — same split as #91.
Dropped private from the feature/ copy. Verified: look and
score both work correctly post-login in all 3 test runs.
3. AGENTS.md §15t (variant 1 + variant 3, combined): combatd.lpc
DIFFERS from #91's copy in its combat-formula numbers (this is the
deluxe edition's own balance tuning), but the include/inherit-ordering
bug was present in BOTH: #include </quest/quest.h> (absolute path
inside angle brackets, never resolved by this driver's inc_open())
placed AFTER inherit F_DBASE; in source order but the file-scope
global quest_name it defines textually preceded the inherit once
included — a fatal "Illegal to inherit after defining global
variables". Fixed identically to #91: moved inherit F_DBASE; above
all #includes, and changed #include </quest/quest.h> to the quoted
absolute form #include "/quest/quest.h". Verified: score (which
needs combatd) works cleanly post-fix; before the fix this would have
thrown *No program in object '/adm/daemons/combatd'! exactly as it
did in #91.
4. The same capitalize()-on-0 robustness bug in feature/name.lpc:
byte-identical to #91's pre-fix short(int raw) fallback (capitalize
(query("id")) with no guard). Applied the identical stringp(id)
guard fix. Not independently re-triggered via a live crash this time
(the tea-house board /clone/board/kedian_b in this archive also has
no "short" set, same as #91, so this WOULD have crashed look there
without the fix — pre-emptively fixed before first boot per the task's
explicit "apply proactively before first boot" instruction, then
confirmed look works cleanly with the fix in place).
5. d/city/npc/guidao.lpc's is_killing(who) direct-call type
mismatch: byte-identical bug to #91 (is_killing(who) instead of
is_killing(who->query("id"))). Fixed identically.
6. The "tang"-family NPC template's new used as a bare variable name:
present identically in the same 7 files as #91 (d/quanzhou/npc/{tang,
tang1,tang2,tang3}.lpc, d/taishan/{tang2,tang3,xingtang}.lpc).
Renamed the local variable new → newob throughout (declaration +
both usages) in all 7 files, exactly as in #91 — the actual new(...)
efun calls are untouched.
7. AGENTS.md §15ac (bare SAVE_EXTENSION instead of
__SAVE_EXTENSION__): found in the SAME 6 files as #91 —
include/net/ftpdsupp.h, adm/daemons/network/netmail.lpc,
cmds/arch/purge.lpc, d/quanzhou/npc/tang.lpc, d/quanzhou/npc/
tang3.lpc, d/taishan/tang3.lpc. Fixed identically. Left alone
(same as #91): clone/npc/meng-zhu.lpc and u/jackyboy/TOKEN.C, which
both #define SAVE_EXTENSION ".o" locally.
8. kungfu/class/mingjiao/mingjiao.h's string-literal-adjacent-to-
macro-expansion syntax error (== HIG "明教" NOR with no +
operators): present identically. Fixed to HIG + "明教" + NOR. A
genuine divergence from #91 found here: this archive's raw copy of
kungfu/class/mingjiao/mingjiao.h ALREADY had #include <ansi.h> at
the top (confirmed via the raw, pre-conversion .c file, not just the
converted copy) — #91's raw copy was missing it and needed it added.
So only the syntax-error half of #91's two-part fix applied here; the
<ansi.h>-add half was already unnecessary. Also found and fixed the
SAME syntax bug in a SECOND, separate d/mingjiao/npc/mingjiao.h file
(different file, same bug, not mentioned in #91's notes — possibly #91
didn't have this second copy hit by its lpcc sweep, or this is new
deluxe-only content; either way it's the identical fix).
9. d/mingjiao/npc/changjinpeng.lpc's wrong absolute #include path
(#include "/kungfu/class/mingjiao/tanzhu.h" — doesn't exist; real
file is d/mingjiao/npc/tanzhu.h): present identically, fixed
identically (#include "tanzhu.h").
10. d/mingjiao/npc/{fenggongying,baiguishou}.lpc's
#include __DIR__"tanzhu.h": present identically in both files,
fixed identically to plain quoted #include "tanzhu.h".
11. d/baituo/ouyangfeng.lpc, the same two independent pre-existing
typos as #91: (a) missing semicolon after write("...") inside a
switch case 0: block; (b) object me=this-player(); (subtraction
typo for this_player()) in the LIVE inquiry_map() function. Fixed
both. Note: this file also has a second, commented-out (/* ...
*/) copy of inquiry_map() containing the SAME this-player() typo
at line 95 — left untouched since it's dead code inside a comment
block, confirmed by reading the full comment span before deciding.
12. d/shaolin/obj/shuitan.lpc: ging_cost typo for the declared
variable jing_cost: present identically at the same call site
(me->receive_damage("jing", ging_cost)). Fixed identically. Note:
this archive ALSO has a second, different shuitan.lpc at
d/shaolin/shuitan.lpc (not present in #91) — checked it separately
and confirmed it does NOT have this typo (already uses jing_cost
correctly throughout) — left untouched, no fix needed there.
13. d/mingjiao/jmqshenmu.lpc genuinely truncated in the raw archive
itself: confirmed via diff that this archive's raw .c file is
byte-identical to #91's raw .c file (both 26 lines, ending mid-
void init() { with no closing braces) — the exact same pre-existing
truncation, not a conversion artifact, not something specific to this
archive. Closed with an empty body exactly as in #91.
New fixes found in THIS archive (not part of #91's list — genuinely new
content/bugs specific to the deluxe edition's differing files)
14. d/baituo/obj/bowl.lpc and d/baituo/npc/obj/bowl.lpc (2 files,
both named bowl.lpc in different directories, same content bug):
set_name("海口大碗", "bowl") — second argument to set_name()
must be an array of id strings (every sibling file in the same
archive, e.g. d/baituo/npc/xiaoqing.lpc, correctly uses
({ "id1", "id2" })), but these two pass a bare string, which this
driver's static type checker rejects (Bad type for argument 2 of
set_name (string * vs string)) — the whole file failed to compile.
Fixed to set_name("海口大碗", ({ "bowl" }) ) in both files. Neither
file exists in #91's archive (deluxe-only content).
15. d/city2/npc/zhengmen.lpc genuinely truncated in the raw archive
itself, in a DIFFERENT way than jmqshenmu.lpc (missing closing
braces mid-function rather than mid-statement): confirmed via diff
that this archive's raw .c is byte-identical to #91's raw copy of
the SAME file (both 77 lines, valid_leave()'s nested if(dir==
"north"){ ... } else { ... } block and the function itself are never
closed) — this exact same truncation also exists, unfixed, in #91's
shipped work/ copy (confirmed via diff against #91's raw and
work directories — #91's own conversion never caught this one; it's
not in #91's NOTES.md's fix list at all). Fixed here by adding the 3
missing closing braces (traced brace depth line-by-line with a small
Python script to get the count right — first attempt under-added by
one brace, caught by a second lpcc compile and corrected). This
file is in a side zone (d/city2, the imperial-palace-gate NPC/room),
not on the tested registration/look/score path, so it wasn't a
registration blocker either way — found via the lpcc_check.sh sweep,
not a live-boot crash. Cross-check flag: since #91 has this exact
same latent bug still unfixed in its shipped work/ copy, this is
worth a follow-up patch to libs/jqxz2008/work/d/city2/
npc/zhengmen.lpc too, though that's out of scope for this archive's
own task.
- After the brace fix, the file compiles but its create() still hits
a runtime *Bad argument 1 to EFUN call_other() ... Got: int(0)
while trying to populate its "objects" mapping
(/d/city/npc/wujiang, /d/city/npc/bing — both files genuinely
exist on disk) — same shape/category as the m_weapon/luguanji.lpc
"call_other on 0" cases below (§6b-style isolated-compile artifact,
not chased further); the syntax fix alone is the meaningful
improvement (file went from "doesn't compile at all" to "compiles,
loads, one populate-step artifact identical to an established
benign category").
Confirmed NOT needed (byte-identical core files inherited the "not
needed" verdict from #91's own reading of the same file; independently
re-verified via diff that the file text is unchanged, not just assumed)
- §4 (master's lazy security-daemon recursion):
master.lpcidentical to #91's already-fixed/confirmed-clean copy (diffagainst #91'swork/adm/obj/master.lpc= empty). Same for §7, §8c, §15l, §15n/§15o, §15u, §15r, §15x, §15ao — all live inmaster.lpc/securityd.lpc, both confirmed byte-identical to #91's clean copies. - §15p (DNS/intermud daemon in preload):
adm/etc/preloadhas the same 11-entry list as #91, nonetwork/dns_master— confirmed by direct read, not inferred from lineage. - §15al (
crypt(str, 0)footgun):logind.lpcidentical to #91's already-confirmed-clean copy. - §8e (
tail()not a real efun): same single harmless hit as #91, in the same unused admin commandcmds/wiz/tail.lpc. - §15/§15b (simul_efun-based dbase architecture bug): confirmed this lib uses the same
inherit F_DBASEarchitecture as #91/xiakexing3/ rzrmud, no globalset/query/deletesimul_efuns. - Duplicate
inherit F_UNIQUE;(§91's item 7): checkedd/mingjiao/npc/{yinwushou,yinwulu,yinwufu}.lpcdirectly — only ONEinherit F_UNIQUE;in each file here, NOT duplicated in this archive (a genuine divergence from #91, where it was duplicated) — no fix needed. - A LOOKALIKE duplicate-inherit false positive, checked and confirmed harmless:
clone/misc/{roommaker,objmaker}.lpceach containinherit ITEM;/inherit ROOM;2-3 times when grepped, but on reading the actual file these are inside a@OBJ_CODE ... OBJ_CODE/@ROOM_CODE ... ROOM_CODEheredoc STRING LITERAL (a wizard tool that writes template.lpcfiles to disk for new objects/rooms) — not real compilation-unit inherits at all. Same false-positive shape as #91 (not flagged there either). - §15z (
#define nosave staticshim): none found. - Uppercase
.Cfiles: same 4 as #91, allu/jackyboy/{TOKEN, WIZ_CLOA,CLOTH1,GLASS}.C, already UTF-8, simply renamed to.lpc.
Content gaps confirmed as real archive gaps, not bugs (AGENTS.md §13)
d/mingjiao/yuan/*(9 named "yuan" NPCs — 郑七灭/王八衰/赵敏/周五输/ 吴六破/孙三毁/钱二败/赵一伤/李四摧) reference two genuinely-missing kungfu skill files (xuanyuan-arrow,liangyi-jian), same as #91.d/mingjiao/npc/monkey.lpcreferences an undefined race (走兽, "beast"), same as #91. New in this archive:d/mingjiao/gudi3.lpc/d/mingjiao/gudi4.lpc(rooms, not in #91's list) ALSO fail loading their room-embedded monkey NPC (bigmonkey) for the same undefined-race reason (走兽/走畜) — same root cause, different call sites.d/wudang/taoyuan/{tyroad4,5,6,7}.lpc: same confirmed ORPHANED early-draft duplicates of the working top-leveld/wudang/tyroad{4,5, 6,7}.lpcfiles as #91 (broken#include, no NPC spawns, unreferenced anywhere in the tree).u/liujun/quest/{leftkiller,rightkiller}.lpcreference missing skills (six-chaos-sword,stormdance) — wizard scratch quest content, same category as #91's finding (onlyleftkillerwas in #91's archive;rightkilleris new here, same shape).u/editer/tie-luohan.lpc: broken/unfinished wizard scratch draft (garbled variable namesnamei), same as #91.adm/daemons/network/*(11 files:ping_q,mudlist_a,ms,userid,pingtcp,name_server,mail_serv,netmail,telnetd,pingd,inetd): confirmed not inadm/etc/preloadand not referenced by anything outside this subdirectory — dead intermud subsystem, same category as #91 (11 here vs #91's ~16 — this deluxe build simply ships fewer of these dead files).adm/daemons/network/services/mudlist_a.lpcindependently has the SAME reserved-word bug as the tang-family (mapping new, old;) but it's unreachable dead code — not fixed, same judgement call as leavingtail()alone.home/simul_efun.lpc: same pure sweep artifact as #91 (stray backup copy in a/homesandbox, not the configured simul_efun).clone/board/*corrupted save data: 11 board.ofiles failrestore_object()with either "Illegal file format" or "Invalid utf8 string while restoring dbase" (wudang_b,xingxiu_b,tiandihui_b,towiz_b,kedian_b,bonze_b,huashan_b,gaibang_b,gaibang_r,wiz_b,taohua_b) — same class of pre-existing corrupted seed data as #91's finding (also exactly 11 boards); each board'ssetup()already wraps the failure gracefully, confirmed non-fatal via the livelooktest atkedian_b(which just starts empty, exactly as in #91).adm/daemons/chinesed.lpc'sdata/e2c_dict.orestore also fails identically to #91 (same "Illegal file format" pre-existing corrupted seed data, caught non-fatally bymaster.lpc'spreload()wrapper).d/npc/m_weapon/weapon/{m_club,m_blade,m_whip,m_sword,m_staff}.lpc: samethis_player()-is-null-during-isolated-compile §6b artifact as #91 (5 files, identical shape).- New content-gap findings, not in #91's archive:
- d/city2/obj/luguanji.lpc's carry_object(__DIR__"obj/diaopi")->
wield() fails with the same "call_other on 0" shape even though
diaopi.lpc itself compiles cleanly standalone (confirmed via a
direct isolated lpcc run) — same §6b isolated-compile-context
artifact class as the m_weapon files, just via carry_object()
instead of a direct this_player() call.
- d/city2/lilishi.lpc references /d/city/obj/tudao, which genuinely
does not exist anywhere in this archive — a real missing-content gap
(§13), not an isolated-compile artifact.
- d/xingxiu/npc/btshan.lpc references d/xingxiu/npc/ke.lpc, which
doesn't exist (§13 content gap); its sibling snake.lpc DOES exist.
- d/shaolin/cangku.lpc references d/shaolin/obj/{jitui,jiudai}.lpc,
neither of which exists (§13 content gap).
- d/shaolin/obj/{houdian,bailongdong}.lpc reference NPCs via
__DIR__"npc/..." (i.e. d/shaolin/obj/npc/...), but the actual NPC
files live one level up at d/shaolin/npc/{seng-bing3,xiang-ke}.lpc
— a genuine relative-path mismatch (the NPCs exist, just not where
these two rooms look for them). Left as a documented content/path
bug rather than fixed, since the "right" fix (change __DIR__ to
__DIR__+".." or similar) needs a judgement call about original
intent and this is a single side-zone, not on the registration path.
- d/wudang/fuzhen5.lpc references /u/fcxy/songqing.lpc, which
doesn't exist (§13 content gap; there's even a commented-out
alternate reference in the same line via CLASS_D("wudang"),
suggesting the original author knew this NPC's location was in flux).
- d/mingjiao/npc/yinsusu.lpc, d/taohua/npc/shoumu.lpc,
d/xingxiu/npc/btshan.lpc (room-self, separately from its ke.lpc
NPC-population issue above) each hit a "call_other on 0" during their
own create() — not individually root-caused further (side-zone
NPCs, not on the registration/look/score path); documented as the
same general content-gap/§6b-adjacent category.
- d/taohua/taohua_b.lpc (a bulletin board) tries to move() itself
into /tmp/jungu/dating, which doesn't exist — a genuine missing
room/zone reference (§13).
- d/huashan/map.lpc: NOT real LPC code at all — it's a plain-text
ASCII map (confirmed via file: "Unicode text... with CRLF, LF line
terminators", and its content is garbled box-drawing/tile characters,
not a program) that happens to carry a .c→.lpc extension from the
original archive; confirmed via grep that nothing in the tree ever
references d/huashan/map as an object path — dead/inert data file,
not a bug, not fixed.
- doc/build/devil.lpc, doc/efuns/shiwu.lpc: unreferenced anywhere
(grepped), genuinely-broken example/tutorial scripts under doc/
(missing semicolons, a bare do_close where a string "do_close"
was clearly intended for call_out) — never loaded in real gameplay,
left as-is per the same judgement as other wizard-scratch content.
- cmds/usr/to.lpc / cmds/wiz/to.lpc (2 files, identical bug): a
real driver-compat compile error, NOT a content gap — me->edit( (:
this_object(), ({ "do_to", me, arg }) :) ) fails with "Illegal to
use local variable in functional" (this driver forbids capturing a
local variable inside an unbound (: ... :) closure literal the way
old-style MudOS code here does it). Other ->edit() call sites in
this same lib (bboard.lpc, mailbox.lpc) pass a plain function-name
symbol and this_player()/parameter-only args and compile fine, so
this is specific to to.lpc's particular this_object(), array
calling convention. This is a real, understood bug — but it's a
non-critical wizard/player utility command (composes a multi-line
message via the line editor), not on the registration/look/score
path, and fixing it correctly would require restructuring the
closure (e.g. to a bound lambda) rather than a one-line patch, so per
AGENTS.md's "prioritize breadth over depth" policy it's documented
here as a known, real, unfixed compile bug rather than patched.
Interactive test result — full registration + post-login flow
Driver booted clean (setsid nohup ... & disown, PID 922298, launched
from libs/jqxz2008dlx/ so log/debug.log resolves
correctly per AGENTS.md §6). Zero fatal errors in log/debug.log across
the whole session — only the 2 expected non-fatal caught corrupted-
save-data errors (chinesed's e2c_dict.o, kedian_b's board data,
both documented above) and ordinary compile *warnings* ("Unused local
variable", "Illegal to declare nosave function").
Ran the full registration flow 3 separate times in 3 separate
continuous mudclient.py connections, with 3 different real Chinese
names, confirming the fix is robust and not a one-off:
1. qinfengjy (English id) → y (confirm new character) → "秦风"
→ password → confirm → accept gift stats (y) → email → gender
(m) → enters game world at 客店 → look → score → quit. All
steps succeeded; look re-rendered the room cleanly; score showed
the full character sheet (title 平民, age/gender/birthdate, 膂力/悟性/
根骨/身法 stats, 精/气 bars, 食物/饮水 bars, kill count, 潜能/实战经验);
quit saved and discononected cleanly with the "丢下一件布衣" message
(unequipped default item on quit, expected).
2. qinfengjyer → "秦风二" → same full flow, same success.
3. qinfengsan → "秦风三" → same full flow, same success (this was
the FINAL post-all-fixes confirmation run, done after the bowl.lpc/
zhengmen.lpc lpcc-sweep fixes, to make sure nothing in the late round
of fixes destabilized the core path).
Sample transcript (run 1, abbreviated to the state-changing prompts):
您的英文名字:使用 qinfengjy 这个名字将会创造一个新的人物,您确定吗(y/n)?
请输入您的高姓大名,...
您的中文名字:(accepted 秦风 first try — before §15h fix this would loop-reject forever)
请设定您的密码:
请再输入一次您的密码,以确认您没记错:
...膂力[23], 悟性[19], 根骨[19], 身法[19]
您接受这一组天赋吗?
您的电子邮件地址:
您要扮演男性(m)的角色或女性(f)的角色?
目前权限:(player)
[1;36m客店[2;37;0m -
这是一家价钱低廉的客栈,生意非常兴隆。...
这里明显的出口是 west 和 up。
/clone/board/kedian_b [ 没有任何留言 ]
店小二(Xiao er)
你上次连线是从0 on Wed Dec 31 16:00:00 1969
> 店小二用脖子上的毛巾抹了抹手,说道:这位小兄弟,请进请进。
[1;36m客店[2;37;0m - (look re-rendered cleanly)
> [1m【 平 民 】[2;37;0m普通百姓 秦风(Qinfengjy)
你是一位十四岁的男性人类,...
膂力:[ 23] 悟性:[ 19] 根骨:[ 19] 身法:[ 19]
<精> ■■■■... <气> ■■■■...
战斗攻击力 1 (+0) 战斗防御力 1 (+1)
食物:□□□... 饮水:□□□...
你到目前为止总共杀了 0 个人,其中有 0 个是其他玩家。
神: 0 潜能: 99 (1%) 实战经验: 0
> 你丢下一件布衣。
因为这样东西并不值钱,所以人们并不会注意到它的存在。
当你下次连线进来时,会从这里开始。
欢迎下次再来!Note (same test-script gotcha as #91): the English id must be fresh
letters-only each retry — a digit anywhere in the id (e.g. qinfengjy2)
gets rejected by the English-name-must-be-letters check and, since
mudclient.py sends its whole --send list regardless of prompt state,
the rejection loop consumes all the scripted follow-up sends as more id
attempts. Not a bug, just something to remember when re-testing.
lpcc sweep
Ran 3 times across the fix-iteration cycle via scripts/lpcc_check.sh:
- First sweep (after all core-engine + content fixes ported from #91, before discovering the deluxe-specific bowl.lpc/zhengmen.lpc bugs): 3104/3171 pass (97.9%).
- After fixing bowl.lpc (x2) and a first zhengmen.lpc brace attempt: 3106/3171 (97.95%) — zhengmen.lpc still failed (one brace short, caught by a Python brace-depth trace and fixed on the second attempt).
- Final: 3106/3171 pass (97.95%), same numeric pass count as the second sweep since zhengmen.lpc's remaining failure mode changed from a hard syntax error to a benign runtime "call_other on 0" content-gap artifact (documented above) rather than newly passing outright.
Remaining 65 failures were triaged by category (AGENTS.md §6b), all
confirmed via direct source reading (not guessed): 11 corrupted
pre-existing board saves, 11 dead network/intermud daemon files (not
preloaded, not referenced), ~13 genuinely missing zone/skill/race/NPC
content (mingjiao/yuan x9, monkey/gudi3/gudi4 undefined-race,
wudang/taoyuan x4 orphaned drafts, lilishi→tudao, btshan→ke,
cangku→jitui/jiudai, fuzhen5→songqing, taohua_b→missing
/tmp/jungu/dating), 3 wizard-scratch quest/tool files (u/liujun/
quest/{left,right}killer, u/editer/tie-luohan), 1 dead-code-only
reserved-word bug (network/services/mudlist_a.lpc, unreachable), 1
sweep artifact (home/simul_efun.lpc), 1 known-unfixed-efun hit
(cmds/wiz/tail.lpc, §8e), 2 non-content-gap real driver-compat bugs
left unfixed as non-critical (cmds/usr/to.lpc/cmds/wiz/to.lpc's
closure-capture error), 2 non-LPC/dead data files (d/huashan/map.lpc,
plus the 2 doc/ example scripts), 6 §6b isolated-compile-context
artifacts (5 m_weapon files + luguanji.lpc's carry_object()->
wield()), a path-mismatch pair (houdian/bailongdong → their own
npc/ subdir that doesn't exist), and zhengmen.lpc's now-syntax-clean
but still content-gap-flavored remainder. None of these affect
registration, look, or score — all confirmed via direct source
reading, not guessed.
Memory stayed healthy throughout all 3 sweeps (free -h showed ~11-19GB
available before/after each run, well clear of pressure; no other
lpcc/driver sweeps were running concurrently at sweep time).
Process notes
- Driver launched via
setsid nohup ~/src/fluffos/build-debug/src/driver config.fluffos > boot_stdout.log 2>&1 & disownfrom withinlibs/jqxz2008dlx/(required forlog/debug.logto resolve correctly, per AGENTS.md §6). Booted once, kept running through all 3 registration tests and both post-fix lpcc sweeps (the later bowl.lpc/zhengmen.lpc fixes only affect side-zones never visited by the live driver session, so no reboot was needed to validate them — thelpcc_check.shsweep independently re-reads files from disk each run). Killed by its own exact PID (922298) at the end — verified gone viaps -pandss -tlnpno longer showing port 40085 — never used a broadpkillpattern (per the explicit standing warning about other agents' concurrent drivers sharing the same command line). - Scratch files (
boot_stdout.log,lpcc_batch_raw.log) removed from the lib's top-level directory before finishing, per instructions; keptlpcc_fail.log(matches #91's own convention of keeping this one file). - Port 40085 chosen per the task brief's explicit instruction (40084 reserved for the concurrent archive #92 agent; TODO.md's own "next free port" counter said 40084 at the time this task started, so 40085 is the next port after that reservation).
2026-07-23 re-verification pass (driver rebuild + formatter + WASM)
- LPC reformat: ran
format-corpus.mjsover all ofwork/(3,171.lpcfiles) — 3,151 written, 0 already-idempotent, 20 refused (self-checked round-trip failures on messy legacy syntax, expected). - Native retest against the freshly-rebuilt driver: booted clean on port 40085, zero fatal preload errors. Full registration flow with a fresh real Chinese name ("秦风肆"/
qinfengjysi, distinct from all prior test ids on this lib) through the complete wizard (id → confirm → Chinese name → password → confirm → gift accept → email → gender) into the actual game world (客店);look,score(correct stats/combat-power/HP/potential), andquit(correct item-drop + clean save) all verified with real output, zero runtime errors in the session. No regressions from the reformat or the new driver binary. - WASM test (
scripts/wasm_client.jsagainstbuild-wasm/src): boots cleanly, same preload warnings as native. Full registration + login + look + quit all work end-to-end under WASM, same as #91/ #92 — this codebase doesn't gate login onquery_ip_number()'s format, so the documented WASM IP-check limitation doesn't apply. Same harmless cosmetic artifact as the other two variants: a fresh registration's "上次连线" timestamp shows the Unix epoch ("Wed Dec 31 16:00:00 1969") under WASM's synthetic clock — not a functional issue.
WASM-enablement pass (2026-07: loopback-allow + admin seeding)
Standard pass per AGENTS.md §1.3b/e + §1.5 (applied identically across the three jqxz2008 builds — engine files are byte-identical in this group):
adm/daemons/band.lpc:39is_banned(): short-circuitreturn 0for loopback (127.0.0.1/127.*), empty, or non-string site values before the regexp ban-list scan.logind.lpc:67'sBAN_D->is_banned(query_ip_name(ob))gate inlogon()is thereby loopback-proof (and robust against the WASMquery_ip_number()/query_ip_name()garbage-return bug).- No
uptime()startup-grace gate and no per-IP anti-flood/registration throttle exist in this lineage (checkedlogind.lpc's full input_to chain; the only other connection gate is the in-memorymad_lockadmin lockdown flag, default off — left alone).
Admin account: fluffos / Mud@2026 / 浮浮, registered through the
real native flow (id → y → Chinese name → password ×2 → gift y → email
→ gender m). Granted (admin) via adm/etc/wizlist (file was shipped
empty; now contains fluffos (admin)), which securityd.lpc reads at
create(). Verified after restart: login shows 目前权限:(admin),
update /cmds/usr/score prints 重新编译成功. Save files (must be
committed): work/data/user/f/fluffos.o, work/data/login/f/fluffos.o.
Retest: fresh registration (秦风/ceshizhe) end-to-end + look/score/quit clean; fluffos login + wizard update clean; debug.log shows only the known pre-existing corrupted-save restore errors (chinesed e2c dict / kedian board) documented above — zero new errors; test character saves removed.
Dual-mode verification pass (2026-07-24)
- Native (port 40085): fresh registration
ceshier/秦风 end-to-end into 客店 + look/score/quit all correct;fluffos/Mud@2026login shows(admin),update /cmds/usr/scoreprints 成功. debug.log: only the two documented pre-existing corrupted-save restore errors (caught by the lib's handler) — zero new errors. Driver killed by exact PID. - WASM (build-wasm with query_ip_number/resolve fixes): fresh registration
wasmceshi/秦风 end-to-end + look/score/quit all correct; second invocation:fluffosadmin login(admin)+update成功. Verdict: native OK + wasm OK. No fixes needed this pass. Test character saves removed; fluffos.o timestamp churn reverted.
深度功能测试(§10.7,本轮):移植同引擎兄弟档案 jqxz2008 已确认的 4 个 bug
这份档案自己的 README 已经说明和"2008 加强版"(jqxz2008)、"2008 标
准版"(jqxz2008std)是完全相同的服务端引擎核心,只在门派 NPC、战斗
数值、部分地图内容上有独立调整。jqxz2008 自己已经做过一轮扎实的
§10.7 深度测试并记录了 4 个真实 bug——既然引擎核心相同,这轮直接逐一
核对这些 bug 是否也存在于 jqxz2008dlx(而不是重新从零排查),四个
全部确认存在且未修复:
1. adm/daemons/chinesed.lpc(§7.7:损坏存档数据把全局 mapping 清
零)。 data/e2c_dict.o 是损坏的二进制垃圾数据(不是合法的 mapping
字面量),create() 原本是 seteuid(getuid()); restore();——
restore() 抛出的运行时错误没有在 create() 内被捕获,会让 create()
在那一行直接中止,mapping dict 被清零。第一次真正用到
chinese()/to_chinese() 的地方(战斗/技能提示大量使用)就会崩溃。
修法和 jqxz2008 完全一致:catch(restore()); if (!mapp(dict)) dict
= ([]);——单独加 mapp() 判断而不加 catch() 是不够的,因为不加
catch() 那一行代码根本不会被执行到。
2. adm/daemons/combatd.lpc/cmds/std/kill.lpc/cmds/skill/{bai,
apprentice}.lpc(§7.11:缺失的 /log/nosave/ 目录让 write_file()
静默中止一个多步骤清理函数)。 work/log/nosave/ 目录在这份档案里
同样不存在。最严重的是 combatd.lpc 的 killer_reward()——这个函数
在每一次死亡时都会跑到,中间不加保护地 write_file("/log/nosave/
KILLRECORD", ...),一旦目录不存在就会抛出未捕获异常,让 die() 在
那一行永久中止:角色的死亡清理(尸体、鬼魂状态、移动到死亡场景)全部
不会执行,角色变成"活着但气血精气归零"的破损状态,而且这个崩溃会在
之后的每一次 heart_beat() 都重新触发一次,变成死循环。用真实驱动
让测试角色(沈十)被"欧阳克"这个 NPC 杀死做了实测验证:你死了 →
干净地进入"鬼门关"死亡场景,NPC"白无常"正常打招呼,全程 debug.log
保持空白(十秒以上的心跳观察也没有延迟复现)。修法沿用 jqxz2008 已
验证过的 assure_file()(这份档案自己的 adm/simul_efun/file.lpc 里
已经有这个函数),在全部四处 write_file("/log/nosave/...", ...) 调
用前各加一行 assure_file(...);顺手也给 bai.lpc/apprentice.lpc
里的 read_file() 结果加了 stringp() 判断(避免 atoi(0))。
3. cmds/skill/bai.lpc/cmds/skill/apprentice.lpc(一处括号位置
错误,把 == 比较写进了 query() 的参数列表内)。 这两个完全相同
的档案里都有:
if (((string)me->query("family/master_id" == "feng qingyang")) || ...)== 比较被夹在 query(...) 的参数括号内,所以传给 query() 的实际
是一个布尔/整数值(永远是 0),不是想要的属性名字符串——这个用来检
测"是否从风清扬门下叛出"的分支永远不可能触发。已改成先呼叫
query("family/master_id"),再拿它的返回值和字符串比较(和同一档案
里其它所有正确写法一致)。触发条件很窄(角色确实拜风清扬为师后又叛
出),本轮没有专门构造这个场景做实测,但代码结构本身已经明确证明这
是笔误而非设计判断。
以上四个 bug 全部对应到既有的 AGENTS.md §7.7/§7.11/§7.9 类别,不是新 分类,只是在同一引擎的另一个具体档案上再确认一次——这也进一步印证了 "共享同一底层引擎的多个档案(内容版本不同)值得直接核对已知 bug 列 表,而不是每份都从零排查"这条经验(和这个会话里 NT/nitan 家族的 §7.78 系列发现是同一个模式)。
未继续测试的部分
时间关系,除了已经验证的注册、战斗、死亡流程外,没有测试拜师
(bai/apprentice)本身、购物、以及触发风清扬叛出这个罕见分支——
bai/apprentice 的两处修复已经通过代码对照(逐字节对比两个档案确
认改动一致)验证,未做额外的实机拜师测试。
补充发现(来自对同引擎兄弟档案 jqxz2008std 的深度测试):第 5 个 bug,§8.9 食物/饮水初始化检查错了对象
adm/daemons/logind.lpc 的 enter_world() 里:
if (!user->query("food") && !user->query("water") && ob->query("age") == 14) {age 是角色本身(user)的属性,不是登录物件(ob)的属性——
ob->query("age") 永远是 0,这个分支从来没有真正执行过,每个新
角色的食物/饮水从创建起就永远是空的(score 显示空白状态条),静
默、无报错。已改成 user->query("age") == 14,用真实驱动重新注册
验证过(沈叁),score 正确显示食物/饮水两条状态全满。这个 bug 在
标准版(jqxz2008std)先发现,确认加强版/超豪华版/标准版三份档案
里 logind.lpc 这一行逐字节相同,一并同步修复。
WASM 修复摘要(迁移自 meta.json 的 group_note)
同一引擎,不同内容构建版本。
§7.86 跨库扫描修复(留言板 post 崩溃)
BULLETIN_BOARDinherit+ 多余replace_program()致命形状(AGENTS.md §7.86,post命令崩溃):全档案 19 处命中,已删除多余的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)已经在更早一
轮(引用注释里的"AGENTS.md #15w")正确修复过,管理员账号
(fluffos/Mud@2026,adm/etc/wizlist 已有 fluffos (admin))
也已经用真实注册流程创建并提交过,本轮只发现并修复了 log_file()
一处(和同引擎兄弟档案 jqxz2008 同一形状)。
发现并修复的 PROGRAMMING bug
1. log_file()(adm/simul_efun/file.lpc)完全没有 assure_file()
保护(AGENTS.md §7.11-class 的又一确认实例):注册/登录本身只
写 log_file("USAGE", ...)(无子目录,本来就存在),不受影响,
但 nosave/CRASHES/nosave/PURGE/nosave/CALL_PLAYER 等管理指
令路径会在首次使用时未捕获抛出。已补上
assure_file(LOG_DIR + file);(含前向声明)。
Proactive checks(无需改动)
win_times修复确认存在且正确:d/city2/npc/refereew.lpc:176; 姊妹文件u/wind/refereew.lpc:176/refereew2.lpc:184同样已修。- 未发现
message()simul_efun 包装函数——不适用 message()-missing-varargs 这一类 bug。 - 本次未观察到
jqxz2008那份档案独有的data/e2c_dict.o存档损 坏问题——开机 preload 阶段和log/debug.log均干净,两份档案虽 然同引擎但各自数据文件的完整性状态并不共享。
实测过程
用已提交的 fluffos/Mud@2026 登录,score 确认"目前权限:
(admin)",update /adm/simul_efun/file(就是本轮改过的文件)确认
可正常重新编译。log/debug.log 时间戳全程未变化(Aug 5,早于本
次会话,且文件本身为空),确认无新增未捕获运行期错误。登录本身产
生的存档时间戳类微小 diff(data/{login,user}/f/fluffos.o 的
last_on 字段)已用 git checkout 撤销,不提交。驱动最终按精确
PID kill,ps -p 确认已退出。
(data/{login,user}/s/shenten.o 是此前会话遗留的未提交测试存档
——Aug 5 mtime,早于本次会话,未受本轮任何操作影响,未触碰。)
§7.100 扫描修复(ROOM 基类多余 replace_program())
#define ROOM "/inherit/room/room":删除 826 处多余的、独立成行的
replace_program(ROOM);(保留 inherit ROOM;)。本库自带的房间
建造工具 clone/misc/roommaker.lpc(与 jqxz2008/jqxz2008std
同一血统的"寒山寺"结构)"造一间空房间"的 heredoc 模板本来就干净,
但"克隆我所在的房间"命令的字符串拼接模板把同一枚多余的
replace_program(ROOM); 烤进了每一个新克隆的房间,已同步修正。已
用 build-debug 驱动干净启动验证(0 个新增编译错误,端口正常监
听);未做完整 §10.7 深度游玩测试。
§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.
深度功能测试(§10.7,round four):三个此前未实机测试的分支全部实测
补齐本档案自己 NOTES.md 之前标记的"未继续测试的部分"——拜师
(bai/apprentice)本身、商店购买、风清扬弟子叛出——三项全部用真
实驱动、真实指令实机验证,全程 debug.log 保持空白(无新增
error:/crash)。测试角色:shensi(沈肆,男,登记密码已略去不
记录)。
标准检查清单快速确认(应已修复,仅确认不重新排查):
- §7.90(eval-cost):档案顶层
config.fluffos(实际开机用的 config,不是work/config.cfg)maximum evaluation cost已经是5000000,work/config.cfg里较低的300000是未使用的 legacy 副本。确认无需改动。 - §7.100(
ROOM多余replace_program()):已在更早一轮修复 (见上方章节),本轮未重新排查。 - §7.111(
standard_trace()对error["object"]==0崩溃):adm/obj/master.lpc/adm/single/master.lpc都已经是objectp(error["object"]) ? file_name(error["object"]) : "(driver)"的正确写法。确认无需改动。 - §7.112(
death_stage()重入保护):d/death/npc/ {newgargoyle,wgargoyle,bgargoyle}.lpc、d/shaolin/npc/yu-zu2.lpc逐一读过全部death_stage()函数体,每一个提前return的分支 (目标消失、非鬼魂反被杀、最终转生)都正确地先delete_temp("death_stage_active")再返回,没有发现遗漏的分支。 确认无需改动。 - §7.79(裸 2 参数
addn()/addn_temp()):全档案work/树内零命中,不适用。 - §7.108(踢出重登录后指令失效):
clone/user/user.lpc:110的reconnect()已经无条件在最前面enable_commands();,修复已 存在。 - §7.30(
feature/skill.lpc未初始化 mapping accessor):见上 一节,本轮 corpus 扫描已覆盖。 combatd.lpc的bounce除零 bug:grep -n 'bounce' adm/daemons/combatd.lpc零命中,这份档案的combatd.lpc根本没 有bounce变量,不适用。
1. 拜师(bai/apprentice)——已实机验证,多次成功,无崩溃,
师承/头衔正确更新:测试角色先在 /d/huashan/buwei2 对入门弟子路
线的岳不群 bai yue(门槛低:shen≥1000+query_int()≥25),成功
——score 确认"华山派第十四代弟子",师父岳不群;随后移动到 /d/
huashan/houshan 对风清扬 bai feng(门槛高:剑法/紫霞神功/身法/
文学等技能≥130~150、shen≥100000、query_int()≥41、随机 kar
检定),管理员用 call shensi->set(...)/set_skill(...) 赋予测试
角色对应属性/技能后(任务允许的"管理员捷径进场景,真实指令走真实
代码"手法),成功——score 确认"华山派第十三代弟子",师父风清
扬。全程无崩溃,family_name/master_id/头衔(第N代弟子)均正确
更新,验证了本档案自己 NOTES.md 里之前只做过代码对照、从未实机触
发过的 bai.lpc/apprentice.lpc 两处修复(§7.11 assure_file()
+ stringp() 判断、§7.9 类的括号错位修复)在真实驱动下运行正确。
2. 商店购买——已实机验证,价格扣除+实物到手全部正确:d/city/
zahuopu.lpc(杂货铺)用 list/buy 两个指令,NPC 杨永福
(d/city/npc/yang.lpc)用 F_DEALER 混入。管理员 clone /clone/
money/coin + call coin->set_amount(500) + give coin to shensi
(任务允许的"clone+give 该档案真实货币物件"标准手法,give 需要
admin 和目标角色在同一房间才能成功,一开始漏了 goto 导致"这里没
有这个活人",补上 goto /d/city/zahuopu 后成功)给测试角色 500 文
铜板;list 确认价目表,buy budai(麻布袋,标价一两白银=100文,
注意商品的 buy 用的是 set_name() 里的别名"budai",不是档案名
"mabudai",用错名字会被 do_buy() 正确拒绝为"你想买什么?"而非崩
溃)购买成功,i 确认物品到手(麻布袋)且找零正确(四两白银,
500-100=400=4两,数学验证一致)。无编译错误/运行时崩溃/debug.log
报错。
(过程中发现一个值得记录、但确认是设计而非 bug 的机制:feature/
dealer.lpc 的 do_buy() 第一行就有 if ((fam =
this_player()->query("family")) && fam["family_name"] == "丐帮")
return notify_fail("你是个穷叫化,买什麽东西!\n");——丐帮弟子被
硬性禁止在普通商店购物,这正是任务说明里"non-beggar test
character"这条要求的真正来源。测试角色因为先做风清扬叛出测试而暂
时加入了丐帮,商店测试前特意再实机 bai yue 一次把门派切回华山
派,才能通过这道设计关卡;notify_fail 走的是正常拒绝路径,没有
任何错误信号,按本 session 的 scope 纪律不作修改。)
3. 风清扬弟子叛出——已验证,真实触发,命中此前只做过代码对照的
apprentice.lpc 修复分支:读 cmds/skill/apprentice.lpc(第 55
行 if ((object)ob->query_temp("pending/recruit") == me),本档案
自己 NOTES.md 记录的括号错位修复处)确认触发条件——目标已经对我方
pending/recruit(即目标已经用 recruit 指令点名收我为徒、只等
我回拜),且我方当前 family/family_name 与目标不同才会触发"背叛
师门"文案;若我方当前 family/master_id == "feng qingyang",还会
额外命中一段读写 /log/nosave/FENG 计数文件的分支(本档案自己
NOTES.md 记录的另一处 §7.11 assure_file() 修复,此前也只做过代
码对照,从未实机跑过)。
实测路径:先用管理员 possess feng+recruit shensi(这一步之所
以能立即完成拜师而不是仅仅"挂起",是因为测试角色此前有一次被风清
扬本人 attempt_apprentice() 正常拒绝的 bai feng 尝试——即使被
拒绝,apprentice.lpc 也已经在拒绝之前无条件地把
pending/apprentice 挂在了测试角色身上,recruit 指令检测到这个
挂起状态会直接完成拜师,不需要再走 attempt_apprentice() 的门槛
检查),确认测试角色 family/master_id 变为 "feng qingyang"
(score 显示"华山派第十三代弟子",师父风清扬)。随后管理员移动测
试角色到 /d/gaibang/inhole,possess zuo(左全,丐帮),执行
recruit shensi——这次确认真正挂起(左全对测试角色还没有
pending/apprentice)——输出"你想要收沈肆为弟子",正确进入
recruit.lpc 的"挂起"分支而非"立即完成"分支。退出附身后,测试角色
真实执行 bai zuo:命中目标分支,输出"风清扬现在共有0个徒弟。"
(确认 /log/nosave/FENG 被 assure_file() 正确建立且未崩溃,文
件确认内容为"0")、"你决定背叛师门,改投入左全门下!!"、"恭喜您成
为丐帮的第二十代弟子。"——family_name 从"华山派"变为"丐帮",
master_id 从风清扬变为左全,score 确认师承信息正确更新。全程
debug.log 保持空白。这是本档案自己 NOTES.md 明确记录"逐字节代码
对照验证、未做实机测试"的两处修复(括号错位分支本身 + 嵌套的 FENG
计数器写入)第一次真正被驱动执行到,确认运行时行为完全符合预期,
没有发现新 bug。
测试方法论备注(供后续同引擎档案参考):recruit 指令的
"挂起 pending/recruit" 分支只有在目标此前没有已经对我方挂起
pending/apprentice 时才会触发;如果顺序反过来(我方已经因为一次
被拒绝的 bai 挂起了 pending/apprentice),管理员 possess 目
标后执行 recruit 会直接完成拜师(走 recruit.lpc 自己的分支),
不会经过 apprentice.lpc 里那处待验证的 pending/recruit 分支
——本轮测试头几次尝试就踩到了这个顺序问题(用 call
feng->recruit_apprentice(shensi) 直接注入也不可行,call 指令的
参数解析器只认字面量/带引号字符串,裸标识符 "shensi" 会被当成字符
串传入触发 call_other() couldn't find object 'shensi' 运行时报
错——这是 call 这个管理指令自身已知的语法限制,不是 mudlib
bug),最终靠"先用一次会被拒绝的真实 bai(这一步真实无害地挂起
了 pending/apprentice),再用管理员 recruit 补上"的顺序绕开,
才干净地复现了目标分支。
驱动进程按精确 PID 结束(kill -TERM,确认 cwd 匹配后操作),测试
角色 shensi/管理员 fluffos 的存档增量(师承变化、FENG 计数器
从 0 到 1、fluffos.o 的正常时间戳类增量)按既有约定一并提交,未
触碰此前会话遗留、未提交的 shenten.o。