info.html · 介绍 · play.html · 游玩 · llms.txt · 下载与本地运行 · ZIP · GitHub
游戏全名《夕阳再现III之炎龙封印》,2006 年由"阿凯工作室"(AKAI Studio)制作,登录后能看到的实际站点名叫"江湖风云",是国产 MudOS 老武侠 Mud 里比较有代表性的一支,风格偏经典门派、内功修炼的江湖养成玩法——玩家从长安城一带的客栈开始闯荡江湖,围绕门派、内功、武学修为逐步成长,留言板、门派系统、任务链都比较齐全。这份档案和另一轮处理过的 `xysylmhb`(夕阳三-炎龙美化版)几乎完全一致(`.lpc` 文件总数、`d/` 目录结构、`d/city/sj.lpc` 内容都逐一核对相同),标题也几乎一样,很可能是同一个原始压缩包在本项目里被拆分成两份档案;地图本身其实是"天涯"家族血统,而不是真正的"夕阳再现"(真血统另见本项目 `xyzxfk`/`xyzxfy2`/`xyzxyl201412` 等档案的说明),品牌名称在这批档案里不能作为判断血统的依据。
English
The full title is "Sunset Reappears III: Seal of the Fire Dragon," made in 2006 by AKAI Studio; the actual site name shown on login is "Jianghu Storm." It's a representative example of classic domestic MudOS wuxia MUDs, built around traditional sects and internal-power cultivation. This archive is nearly identical to the sibling archive xysylmhb — matching .lpc file counts, directory structure, and map content — and was likely split from the same original package into two separate archives here; its map actually belongs to the unrelated "Tianya" lineage rather than the true Sunset Reappears bloodline, a reminder that shared branding doesn't reliably indicate shared code in this batch of games.
README
内容亮点
- 连线时有一道隐藏的客户端版本暗号校验(固定输入
2060),是当年 Tomud/笑傲江湖 WWW 客户端的握手代码,与本项目另收录的多部同期作品 共享这一机制。 - 本地/回环连接(含 WASM 浏览器连线)已无条件放行,不再受封禁名单和 IP 数量限制影响。
在线试玩
https://mudlibs.fluffos.info/xyzx3/
管理员账号 / Admin account
- id:
fluffos - 密码 / password:
Mud@2026 - 显示名 / display name: 浮浮(Fluffos)
- 权限 / level:
(admin)—— 通过/adm/etc/wizlist名单授予 (fluffos (admin))。登录时记得先输入客户端暗号2060。
警告:这是一个公开的默认密码,仅供本地/浏览器试玩。正式对外开服前
请务必修改此默认密码。
本地运行
cd libs/xyzx3
~/src/fluffos/build-debug/src/driver config.fluffos游戏端口:40042。
NOTES · 移植与修复记录
xyzx3 — 夕阳再现III之炎龙封印
Archive: 夕阳再线III之炎龙封印.rar. Port: 40042. Status: done (boots
clean, full registration flow verified end-to-end including a real
Chinese name, character entered the actual game world).
What this is
"夕阳再现III" ("Sunset Reappears III: Seal of the Flame Dragon"), by
AKAI Studio (阿凯工作室, http://akai.isme.net/), copyright 2006. adm/obj/
layout (master file : /adm/obj/master, simulated efun file :
/adm/obj/simul_efun), MudOS 0.9.20-era config. The mudlib root was
nested two directories deep plus a world/ subdirectory inside the
archive (raw/夕阳再现III/夕阳再现III/world/) — confirmed via
config.xyzx's own mudlib directory : ./world setting, relative to
the config file one level up. ~9,360 raw files, 8,302 after the
.c→.lpc rename.
chinese.c's is_chinese was byte-identical to tianxiawuxue
(archive #51, processed in parallel by a sibling agent this same
session) — same standard single-first-character GBK-byte-range shape,
suggesting shared lineage or a common code pool, though this wasn't
otherwise investigated deeper (not depended on).
Fixes applied
1. AGENTS.md §15h, standard shape, applied proactively per the
assignment brief:
- adm/simul_efun/chinese.lpc's is_chinese(): GBK lead-byte check
(str[0] > 160 && str[0] < 255, strlen>=2) → CJK codepoint check
(str[0] >= 0x4e00 && str[0] <= 0x9fff, strlen>=1).
- adm/daemons/logind.lpc's check_legal_name(): byte-count bound
< 2 || > 10 → character-count bound < 1 || > 5; removed the
i%2==0 && even-byte-offset gate so every character position is
checked.
2. AGENTS.md §15p: /adm/daemons/network/dns_master was in
adm/etc/preload — removed proactively before the first boot
attempt. No other preloaded daemon does synchronous socket setup
(checked every preload entry for socket_create/socket_bind/
resolve(); only files under adm/daemons/network/ — none of which
besides dns_master are preloaded — reference sockets at all).
3. Confirmed NOT needed, via source reading: master.lpc's
valid_write/valid_read only find_object(SECURITY_D) (no lazy
load_object, so no §4 recursion risk); no destruct() on
SIMUL_EFUN_OB/MASTER_OB in create() (no §15l crash risk);
get_root_uid()/get_bb_uid() both present (no §7 gap); no
named.c daemon exists in this lib at all; securityd.c's
valid_read is a bare return 1; (no §15n custom-ACL gap, no §8c
this_player()-override footgun).
4. NEW finding — missing WQA_ROOM macro, 81-file cascade:
include/globals.h never defined WQA_ROOM, despite 81 files across
quest/game/ doing inherit WQA_ROOM; — confirmed genuinely absent
in the raw archive too (not a conversion artifact). The intended
target, /quest/game/wqa_room.c (a lottery/"官运亨通" quest-room base
class), does exist on disk, just never had its macro defined anywhere.
Fix: added #define WQA_ROOM "/quest/game/wqa_room" to globals.h
next to the other ROOM-family macros. This single-line fix resolved
81 of the lpcc sweep's original 230 failures in one shot (matches
AGENTS.md §8g's "one shared dependency, not N independent bugs"
pattern, just via a missing #define rather than a broken shared
file).
5. NEW finding — iconv -c's lossy-byte-drop can eat an adjacent
legitimate newline, not just the genuinely invalid byte(s): three
files (d/heimuya/tang.c, d/heimuya/shenggu.c, d/heimuya/npc/tang.c)
were flagged by convert_lib.sh as "LOSSY conversion (invalid bytes
dropped)". Root-caused via raw hex inspection: each file has a
genuinely corrupt GBK byte sequence in the ORIGINAL archive right at
the boundary between the room's @LONG ... LONG heredoc body and its
closing LONG tag — two consecutive illegal GBK lead-byte fragments,
the second of which unluckily consumes the very newline that
separated the Chinese description text from the closing tag. With
iconv -c, both illegal pairs get silently dropped, merging what were
two lines into one (...奕奕.LONG ); instead of ...奕奕.\nLONG );),
which breaks the heredoc parser (error: End of file in text block)
since FluffOS requires the closing identifier alone on its own line.
Two more files (d/quanzhen/manglin1.c, manglin2.c) had the exact
same "closing tag glued onto the last text line" shape but WITHOUT
any accompanying lossy-byte-drop warning — i.e. this exact authoring
mistake (or one indistinguishable from it) also occurs as a genuine
pre-existing typo, independent of the lossy-conversion mechanism.
Fix, all 5 files: inserted the missing newline before the closing
LONG tag. Worth adding to AGENTS.md's encoding section: any file
flagged lossy AND using a @TEXT...TEXT-style heredoc is worth a
quick manual check that the closing tag is still on its own line —
the -c fallback's byte-drop isn't guaranteed to be "just" the
invalid byte(s), it can eat a legitimate adjacent byte (here, a \n)
too when two illegal sequences abut a real character.
6. Pre-existing typos, unrelated to conversion (confirmed present in
the raw archive by direct byte inspection before fixing):
- kungfu/skill/hanbing-mianzhang2.lpc: a stray backtick before
random(...) inside apply_condition(...) turned the rest of the
file into an unterminated "template literal" (error: End of file
in template literal). Removed the backtick.
- kungfu/skill/iceforce/chillgaze.lpc: an if(...) return
notify_fail(...); single-statement guard was immediately followed
by a stray extra }, silently closing the function early and
leaving the rest of the body as invalid top-level statements
(skill/damage used without declaration, -> arrow at file
scope). Fix: removed the stray } and added the missing int
skill, damage; declaration (the file already had an unused,
seemingly-leftover object *ob; declaration hinting the original
declaration line had been damaged/replaced at some point).
- d/city2/npc/zhengmen.lpc: valid_leave() was missing its final
two closing braces (confirmed via brace-depth counting — file ends
at depth 2, needs to return to 0). Added the two missing }.
- kungfu/skill/guxing-sword.lpc and quest/baituo/qlist3.lpc
(twice): classic §10 missing-closing-quote-before-concatenation /
missing-comma-in-array-literal typos. Fixed each.
7. Documented, not fixed — pre-existing severe corruption, out of
scope for a quick fix:
- feature/vendor_sale.lpc (inherited by 21 shop-NPC files): from
roughly the halfway point of the file onward, virtually every
statement is missing its terminating ; and/or closing )/{
(confirmed byte-identical to the raw archive — not something our
pipeline introduced). This is far beyond a single-token typo;
reconstructing correct intent for ~180 lines of shop/deposit/
price-setting logic was judged not worth the time for one feature
file not on the boot/registration path. Never reached during the
verified boot+registration+room-entry test.
- d/city/sj.lpc (a "jump off the summit" easter-egg room): every
string literal argument in do_out()/look_out() is missing its
quotes entirely (message_vision($N大喊...\n, me) instead of
message_vision("$N大喊...\n", me), me is also never assigned
this_player()), confirmed identical in the raw archive. Same
"not worth reconstructing intent for a non-critical isolated room"
call as vendor_sale.lpc above.
- quest/mmid/* (9 qlistNNNN.lpc files): all #include "query.h",
but no query.h exists anywhere in that directory (confirmed
genuinely absent from the raw archive; a sibling directory,
quest/upr/, has its own copy defining a generic query_quest()
helper). A real content gap (AGENTS.md §13), not fabricated.
- clone/weapon/panguanbi.lpc inherits a PEN macro that's never
defined anywhere and has no corresponding base-class file on disk
at all (unlike WQA_ROOM above, there's nothing to point the
macro at) — one missing weapon subtype, a genuine content gap.
- adm/daemons/network/* (userid, telnetd, pingd, pingtcp, ms,
netmail, mail_serv, inetd, ...): the whole intermud/DNS network
daemon family has several missing headers (uid.h, mailer.h,
daemons.h, config.h) and simul_efun-override errors. None of
these are preloaded (only dns_master was, and that's now
excluded per §15p) — pure dead/unreachable code in this
environment, matching the standing policy of not chasing this
daemon family.
- /adm/obj/simul_efun_bak.lpc and /adm/simul_efun/file.lpc: the
former is a stray .bak copy caught by the blanket rename (§12-
style, never loaded); the latter is a #include-only fragment of
simul_efun.lpc (confirmed via grep) that only fails standalone
under lpcc because efun::ed/cp/rm overrides are file-identity-
sensitive — the classic §6b/§14 false-positive shape. Real boot
loaded simul_efun.lpc (which #includes this fragment) with zero
errors.
- d/city2/npc/liling2.lpc and d/city2/npc/zhengmen.lpc (post-
brace-fix): both still report a bare Fail to load object from
lpcc with no accompanying error/warning text at all even
after removing the eval-cost-limit noise (see next item) — tried
re-running standalone multiple times, checked brace/paren balance
(both balanced), found no lead. Neither object is preloaded or
touched by the verified boot+registration+room-entry test; treated
as an unexplained lpcc-only artifact per §6b rather than chased
further given the two rounds of investigation already spent.
Config tuning
Bumped maximum evaluation cost from the raw config's 400000 to
5000000, matching what's now the de facto standard across this
project's recent libs (xianlvqiyuan, xlqyzdb,
xjcq2000, xkxz2, xiakexing100, shujian2008,
zhonghua2 all already use 5000000). Confirmed this actually matters
here: d/city2/npc/liling2.lpc spuriously failed under the raw
400000-microsecond real-time budget (Eval interrupted: ... cost
limit reached, limit: 400000 usec) purely from compiling its own
(large, 1500+ line) inheritance chain, with zero relation to any real
bug — after bumping to 5000000 that specific "Eval interrupted"
message disappeared (the file still fails for the separate,
unexplained reason noted above, but the eval-cost false-positive itself
is gone). Worth flagging generally: any lib whose original config
still has a low maximum evaluation cost should get this bump
proactively, since this driver interprets the value as literal
real-time microseconds (vm/internal/eval_limit.cc), not an
instruction-count budget the way classic MudOS did — a value tuned for
the old semantics can be far too tight now.
Interactive test result — full registration flow
Read logind.lpc's actual logon()/get_id/get_id1/confirm_id/
get_name chain before testing (not assumed). Hidden pre-id gate
found: the very first prompt is captioned "请输入您的英文名字:" ("please
enter your English name") but the first input_to callback (get_id)
actually checks the literal string against a hardcoded client-protocol
version code, "2060" — rejecting anything else with "你的客户端非
Tomud或者非笑傲江湖WWW客户端" and disconnecting. Only after receiving
exactly "2060" does it advance to get_id1, which validates the real
English id (check_legal_id: lowercase letters only, length 3-14). A
failed check_legal_id loops back to get_id (i.e. the "2060" gate
must be re-satisfied on every retry, not just once) — a subtlety that
produced a confusing false rejection ("你的客户端非Tomud...") on a first
test attempt using an id containing a digit, until re-read carefully.
Verified the complete flow in one continuous connection:
"2060" → qinfengwu (English id) → confirm y → real Chinese name
秦风五 (accepted — no rejection, no political/banned-name hit;
banned_name here includes politically-sensitive names like 毛泽东/
邓小平/江泽民 plus a few generic pronouns/profanity, not novel-character
names) → password abc12345 (twice) → gift selection 0 (random) →
confirm y → email → gender m → entered the actual game world
(room "铁枪庙" near 嘉兴), look rendered a full room description with
NPCs, quit exited gracefully with "欢迎下次再来!". No crashes, no
mangled text, no unexpected disconnects anywhere in the chain.
lpcc sweep
8,302 files, 8,161 pass / 141 fail (98.3%) after all fixes above. Memory stayed healthy throughout every sweep run (multiple sibling agents' lpcc sweeps were running concurrently on this host at various points; free memory dipped to a low of ~16GB free out of 23GB total at worst, never remotely close to the kill threshold).
Remaining failure categories (all triaged, none individually chased
further — see "Documented, not fixed" above for the ones with a clear
story): 9× "Cannot #include query.h" (quest/mmid content gap), 9×
"Invalid simulated efunction override" + assorted "Cannot #include
uid.h/mailer.h/daemons.h/config.h" (dead intermud network-daemon code,
unreachable), ~21 files cascading from vendor_sale.lpc's pre-existing
corruption, plus a long tail of one-off "Undefined variable/function"
hits in individual quest/skill files not reached by the verified boot
path.
Re-verification pass: driver rebuild + formatter + WASM (2026-07-23)
- LPC formatter applied to all
work/*.lpc(8302 files): 8215 reformatted, 33 already-clean/unchanged, 54 self-checked errors (skipped, expected on legacy code). - Native re-test against the rebuilt driver (
~/src/fluffos/build-debug/src/driver): booted clean (only pre-existing compile warnings, no fatals). Full registration flow re-verified end-to-end with a fresh real Chinese name ("秦风廿六") — remembered the"2060"client-version gate must be re-sent after *every*get_id1rejection, not just once (bit by this exact subtlety on a first retry using an id containing a digit, exactly as this file already warned) —"2060"→ English id (pure letters) → confirmy→ Chinese name → password ×2 → gift0→ confirmy→ email → gender → entered the real game world (北疆小镇);look/score/quitall produced correct Chinese output,log/debug.logclean of real errors. Reformat + new driver build introduced no regressions. - WASM test (
scripts/wasm_client.jsagainstbuild-wasm/src): boots cleanly (no fatal preload errors; this lib'sdns_masteris already excluded from preload per an earlier fix, so nosocket_*undefined-function noise either). Registration proceeds correctly through the"2060"gate and the English-name prompt, but is then rejected byBAN_D->is_banned(query_ip_number(ob))inlogind.lpc("你的地址在本 MUD 不受欢迎。") — this is the documentedquery_ip_number()WASM limitation exactly as described in AGENTS.md/docs/build-wasm.md(same shape asbxsj'sadm/daemons/sited.lpc): the welcome banner's own IP line already shows blank instead of127.0.0.1under this WASM build, andBAN_D's ban-list lookup on that malformed value spuriously matches as banned. Not a mudlib bug — not patched, per this pass's instructions. Verdict: boots under WASM, registration reaches the English-name step, but login is gated by the known IP-format limitation before a Chinese name can even be entered.
WASM-enablement pass (2026-07, loopback/uptime/throttle + admin seed)
Standard WASM-first pass per AGENTS.md §1.3(b)/(e) and §1.5. Loopback =
127.0.0.1, any 127. prefix, or an empty/non-string/malformed IP
(covers older WASM query_ip_number() garbage). Gates patched:
adm/daemons/band.lpc::is_banned()(~line 108): loopback short-circuitreturn 0at the top; ALSO changed the malformed-IP branch (sscanf(site, "%s.%s.%s.%s") != 4) fromreturn 1(banned!) toreturn 0— this was the exact gate that spuriously rejected every WASM connection ("你的地址在本 MUD 不受欢迎", see the earlier WASM verdict above, now obsolete).adm/daemons/band.lpc::vaild_allow_address()(~line 361): loopback connections now always pass the per-account allowed-address check.adm/daemons/logind.lpc::get_id1()(~line 219): the per-IP connection cap (ip_cnt > 18destruct) is now loopback-exempt.- No
uptime()startup-grace gate in this lib (the only non-cosmeticuptime()use isnatured.lpc:368, a 2-day in-game world-event timer — game content, kept per policy). - The
"2060"client-version gate is NOT an IP/hosting gate (it is a documented flow quirk) — left as is.
Admin seed: registered fluffos / display 浮浮 / password Mud@2026
through the real flow (2060 → id → y → Chinese name → password x2 →
gift 0 → y → email → gender m). Granted (admin) by appending
fluffos (admin) to /adm/etc/wizlist (read by
securityd.lpc::create()). Verified after reboot: login as fluffos →
update /adm/daemons/logind → "重新编译 ...成功!" (and the account now
re-logs into the wizard start room 北疆小镇).
Retest: fresh normal registration (qfxyzx / 秦风) re-verified
end-to-end into 客店 with look/score/quit correct; test saves
removed. No new errors in log/debug.log.
Save files for the orchestrator to add (both paths tracked, not gitignored):
libs/xyzx3/work/data/user/f/fluffos.olibs/xyzx3/work/data/login/f/fluffos.o
WASM 修复摘要(迁移自 meta.json 的 group_note)
状态已从过时的 limited 修正——这份档案自己的 README 和 group_note 里从未记录过任何缺陷说明,本轮重新测试也没有发现:需要 Tomud '2060' 客户端版本握手作为第一行(和 xajhzcjh 同一家族的模式)——已现场确认:2060→id→密码→'★ 您目前权限:(admin)',quit 正常。
§7.86 跨库扫描修复(留言板 post 崩溃)
BULLETIN_BOARDinherit+ 多余replace_program()致命形状(AGENTS.md §7.86,post命令崩溃):全档案 93 处命中,已删除多余的replace_program(...)调用(保留inherit),逐文件保留原有行尾格式(CRLF/LF 按文件原样)。本次为跨库 §7.86 扫描修复(触发原因:该 bug 已在 6+ 个互不相关的血统家族独立确认,属于近乎普遍的拷贝粘贴模式),仅做编译检查(驱动干净启动、端口正常监听),未做完整 §10.7 深度游玩测试。
深度功能测试 / Deep functional test (AGENTS.md §10.7)
先读 README.md/group_note 已知:本档案虽带"夕阳再现"招牌,但地图血统实
为"天涯"家族(与 xysylmhb/xyzxiiylzymh/yzxiiizylfy 同源),不是真正
的"夕阳再现"世系(xyzxfk/xyzxfy2 那支)——品牌名不可靠,本轮以
d/city/sj.lpc 字节比对方式独立确认过,细节见 README。同为 AGENTS.md §11
"XYZX/炎龙封印分支"(xyzx3/ylfyxa3/longyunmeng)的另一已深测同门是
longyunmeng;对照读过它的 §10.7 记录作为路线图,但两者代码已明显分叉(见
下方"分支不完全同源"一节)。
登陆需要先发送隐藏的 Tomud/笑傲江湖 WWW 客户端版本暗号 "2060" 作为连接后
第一行输入(logind.lpc::get_id()),随后才是正常的英文 id 流程;输错或漏
发直接被断线,这是本档案自己的合法握手机制,不是缺陷。
修复的程序性 bug
1. §7.11(log_file() 未确保目录存在,注册必崩):adm/simul_efun/
file.lpc 的 log_file() 直接 write_file(LOG_DIR + file, text),
/log/login/、/log/nosave/ 在 work/ 里并不存在;logind.lpc::
get_gender() 在 init_new_player()/enter_world() 前调用
log_file("login/newid.log", ...),本会导致每次新注册崩溃。按本 session
已确立的修法:把 assure_file() 挪到 log_file() 之前(本驱动的编译器
要求同文件内被调函数需先声明/定义),并让 log_file() 内部先调用
assure_file(LOG_DIR + file)。一次修复覆盖全档案所有 log_file()
调用点。本回合是本 session 内本类 bug 第 4 次连续命中(继 jqxz2015→
xyzxfk→xyzxfy2 之后),且跨越了互不相关的世系(ES II 系 / 夕阳再现真系 /
本档案的天涯系),说明这个"忘记 assure_file()"的 log_file() 写法在
这一代中文 MudOS 代码库里几乎是通病,与"血统"无关。
另外 4 处同类隐患一并修:adm/daemons/combatd.lpc(PK 死亡记录
KILL_PLAYER,本档案允许玩家间 PK,此路径可达)、cmds/adm/
shutdown.lpc/reboot.lpc(LASTCRASH)、cmds/adm/restoredata.lpc
(RESTORE_PLAYER)、cmds/usr/helpbbs.lpc(留言注册日志)——均加
assure_file()。
2. §8.9(食物/饮水初始化检查错对象):logind.lpc::enter_world() 用
ob->query("age")(登录桩对象,永远没有 age 字段)判断是否新号,应为
user->query("age")(真正的玩家 body)——导致新角色食物/饮水条永远是
空的。改 ob 为 user,与本 session 内 5+ 例同类修法一致。
3. §7.94(命令文件丢失 .lpc 扩展名,命令静默不存在)新增确认实例:
cmds/adm/setskill.c.org——管理员技能授予快捷命令,唯一候选(无竞争草
稿,不构成内容判断),复制为 cmds/adm/setskill.lpc 使其重新可被驱动派
发。恢复过程中在同一文件里又发现一个独立的拷贝粘贴 bug:单技能
level == 0 分支的提示信息误引用了 all 分支专用、此处未初始化的
skills[i] 数组,应为局部变量 skill——原样触发会是运行时错误
(setskill <目标> <单个技能> 0 必现)。已改用 skill。已在
AGENTS.md §7.94 补充了这第二例确认实例的说明。
4. cat() 对不存在文件的空指针式崩溃(新发现,未归入既有编号):
adm/simul_efun/file.lpc::cat(string file) 在 file_size(file) == -1
(文件不存在)时仍会走 write(read_file(file)) 分支,read_file()
对不存在的文件返回 0(非字符串),传给 write()/receive_message()
触发运行时错误 *Bad argument 1 to receive() Expected: string or
buffer Got: 0。现场复现:get_id() 的 "2060" 校验失败分支会
cat("/adm/etc/new.txt"),而该文件在 work/ 里并不存在,每次输错客户
端暗号都会命中。修法:write(read_file(file) || ""),不猜测/新增
new.txt 的内容(那属于内容判断,超出本项目范围)。重启驱动后现场复测
两次错误握手,debug.log 未再新增该错误(新驱动进程下错误计数保持不
变)。注意:本档案的 simul_efun 实际编译单元是 adm/obj/
simul_efun.lpc(config.fluffos 的 simulated efun file 指向此
处),它通过 #include "/adm/simul_efun/file.lpc" 预处理拼入 —— 该
include 型 simul_efun 只在驱动启动时编译一次,不会像普通对象那样按
需热重载,因此这条修复必须重启驱动才能生效(前面 3 条也是同一物理文件,
同样受此约束,但因为是在驱动首次启动前就已编辑完成,所以首次启动即
生效,未受影响)。
分支不完全同源(未误移植 longyunmeng 的修复)
longyunmeng 那轮深测在其 inherit/room/room.lpc 的 reset()/
xyzx_system_clean_up() 里发现并修了一个 filter_array()+闭包在
replace_program(ROOM) 提交前被绑定导致的驱动级崩溃相关错误。直接读取
xyzx3 自己的 work/inherit/room/room.lpc 确认:new_clean_up()/
reset() 用的是 all_inventory() + 手写 for 循环,完全没有 filter_array()
闭包写法,结构上就不是同一份代码——因此没有移植该修复到本档案,这不是
遗漏,是确认了"§11 同分支标签 ≠ 代码字节甚至结构相同",与本 session 之前
的观察一致。
测试覆盖
- 注册:
2060→ 英文 idxyzxdeep→ 中文名 秦风廿七 → 密码abc12345(×2)→ 天资随机0(膂力21/悟性18/根骨22/身法19)→ 邮箱 → 性别m→ 落地北疆小镇(星宿海系新手村)。look/score/i均正常;score面板显示食物、饮水满格,确认 §8.9 已修复;i正确列出新手赠品 (布衣、魔法传送帖)。全程未见 debug.log 新增运行时错误,确认 §7.11 修 复解决了注册必崩问题(/log/login/newid.log成功写入并核对内容)。 - 安全切磋:
fight.lpc自带 help 明确写"点到为止,因此只会消耗体力, 不会真的受伤"。木人陪练在d/shaolin/wuchang.lpc(少林练武场),但少林 山门有knock gate+valid_leave()的俗家弟子拒入逻辑("本寺不接待俗 人",正常设计,非 bug),测试角色未入少林门派,无法进入——改用已确认(admin)身份(fluffos/Mud@2026)goto /d/shaolin/wuchang现场验 证木人机制本身:fight mu ren完整跑完一轮判定文本、死亡: 0 次(no_die生效)、冷却期内再次fight正确被拒绝("你刚跟这个木人练过 功!")。木人机制经确认工作正常,仅因门派门槛借用了管理员身份,如实记 录。 - 拜师+学艺(正规路径):
trans hs直达华山派练武场(未设门槛,与少 林形成对比),apprentice yue一次成功,score确认"华山派第十四代弟 子"/师傅"岳不群"。learn <技能> from <某人>语法下learn unarmed from yue成功(岳不群内部技能huashan-ken通过map_skill("unarmed", "huashan-ken")映射,直接用huashan-ken当技能名反而学不到——这是设 计内的映射机制,非 bug,是我自己第一次测试时的用法错误)。skills确 认"基本拳脚(unarmed) 1/0"。 - 学艺(管理员快捷路径):
setskill.lpc修复后现场验证:setskill xyzxdeep force 1成功写入,玩家端skills确认"基本内功 (force) 1/0"。 - 退出/重连:
quit正常结算(丢弃不值钱物品,存档写入data/user/x/xyzxdeep.o/data/login/x/xyzxdeep.o)。logind.lpc的 重连防抖冷却是 50 秒(本档案比 longyunmeng 的 10 秒更长);等待约 75 秒 实际时间后重连,2060→ id → 密码成功进入,score/skills确认门派 头衔、师傅、两项技能、潜能消耗(99/1%)均完整保留。 - 未测试/超出范围:完整 900 秒
NET_DEAD_TIMEOUT净断线软测试(本轮 时间预算内未做,§10.8 类驱动级崩溃若存在未复现);商店购买全流程(未 找到可达且未测试的商铺);30 分钟内退号删档的计时器——grep未在cmds/usr/quit.lpc找到此逻辑,本档案似乎没有这个机制(与 longyunmeng 不同)。
WASM 未验证说明
按本 session 约定:emsdk 固定从 storage.googleapis.com 拉取,被本
session 出站代理策略拒绝(curl -sS $HTTPS_PROXY/__agentproxy/status
返回 403),WASM 编译/运行验证本轮继续跳过,仅做原生驱动(linux-debug
预设,ASAN/UBSAN)下的完整 §10.7 测试。
深度功能测试(2026-08-13,round two,新驱动重测)
针对驱动升级(quest_times/win_times %-operator 修复 + Warning/warning
大小写回退兼容)做的重测。上面记录的所有修复(§7.11 log_file()、
§8.9 食物/饮水、§7.94 setskill.lpc、cat() 空指针)逐项核对代码
仍然生效,win_times 的 %-operator 也已用
to_int(query("win_times")) % 5(d/city2/npc/refereew.lpc:146);
未发现新的 printf 调试残留,feature/dbase.lpc 未发现 tybxjh/wlhd
那种密码写保护,均不适用。管理员 fluffos/Mud@2026(含"2060"握
手)真实重连验证:落地此前保存的"客店",score 显示"【天界总
管】"头衔,食物/饮水满格,debug.log 全程干净。驱动按精确 PID 结
束;测试期间产生的存档时间戳增量已 git checkout -- 还原,本轮无
需新代码改动。
深度功能测试(round four,2026-08-19)——商店流程 + 完整净断线超时测试
针对 round three 遗留的两项未测内容做的专项补测:完整真实等待的
NET_DEAD_TIMEOUT 净断线软超时、以及一套可达且可完整走通的商店购买
流程。原生驱动(build-debug),管理员 fluffos/Mud@2026。
商店购买流程 — 已找到并完整测试通过,未发现程序性 bug
Round three 说"未找到可达且未测试的商铺",原因是它只看到
feature/vendor_sale.lpc(round one/two 已记录的、从文件中段开始几
乎每条语句都缺分号/括号的严重损坏文件)。本轮重新排查发现这份档案
其实有两套商人 mixin:
feature/vendor_sale.lpc(F_VENDOR_SALE宏):严重损坏,只有 一个文件kungfu/class/npc/xiaoer.lpc继承它——本轮未见其被摆 放到任何房间的objects里(grep未命中任何引用),大概率是死 代码,不影响正常游戏内容。feature/dealer.lpc(F_VENDOR宏):完整无损,被 21 个 NPC 文件继承(d/village/npc/seller.lpc、d/city2/npc/jia.lpc等),是这份档案真正在用的商人系统。
选了两个可达的真实商铺现场走通完整交易:
1. 普通杂货铺(d/village/ehouse1.lpc「草棚」,NPC
d/village/npc/seller.lpc「小贩」):goto 抵达后 clone
/clone/money/coin 现场造币、call coin->set_amount(500) 设为
500 文钱(管理员专用手段,等价于给测试角色发钱,不是内容判定)。
list 正确列出价目(手杖一两白银=100文、麻鞋150文、水壶100
文、五香茶叶蛋50文)。buy stick:铜板扣除、找零正确换算为四两
白银(500-100=400=4两),手杖进入物品栏。buy 2 egg:白银从4两
扣到3两(400-100=300,两颗蛋各50文),物品栏正确出现两颗蛋。全
程金额换算(文→两白银→两黄金三级进位)与 feature/dealer.lpc::
pay_player()/value_string() 的实现完全吻合,无一处算错。
2. 当铺(贾老六,d/city2/dangpu.lpc):value stick 正确估价
("卖断可得八十文钱"),sell stick:手杖移除、铜板+80(=
100*80/100,与代码 value*80/100 吻合)。pawn spicy egg(蛋值
50<100)被拒绝("你当我这是垃圾店…")——这是 do_pawn()
if (value<100) return notify_fail(...) 的设计内下限门槛,不是
bug,随后改用刚买的手杖(值=100,恰好压线通过下限)成功
pawn stick:典当后铜板+60(=100*60/100),check 正确列出典当
记录,redeem stick:扣钱赎回,手杖回到物品栏——买/卖/典/赎四
种交易全部现场走通,金额、库存变化全部核对无误。
买断 vs 典当赎回的两级商人设计:额外 grep 全档案 add_action
同时挂 buy 又挂 sell/pawn 的文件,只有 11 处(多数命名含
boss/dangpu/xiaoer2/xiaoer3 等"当铺/大掌柜"角色),其余大
多数商人 NPC(含本轮实测的 seller.lpc)只挂 buy/list,sell/
value/pawn 等命令对它们返回"什么?"(未知命令)——这与项目已知
的 hell/§7.52 教训完全一致的两级设计(普通商铺只卖不收,当铺/估价
NPC 才收购),已现场用两套不同 NPC 分别验证两级设计各自都按预期
工作,不是 bug,未做任何修改。
测试完毕后用 dest 逐一销毁现场造出的铜板/银子/手杖/蛋,fluffos
物品栏还原为初始的布衣+魔法传送帖(i 核对,autoload 也确认为
空),无遗留测试道具。
完整 600 秒 NET_DEAD_TIMEOUT 净断线超时测试
先读代码确认预期行为:本档案 include/user.h 定义的是
NET_DEAD_TIMEOUT 600(10分钟),不是 900 秒——grep -rn
NET_DEAD_TIMEOUT 全档案确认这是唯一定义,clone/user/user.lpc(真
正在用的玩家 body,LOGIN_D 走 make_body()→ 这份文件)的
net_dead() 在断线时 set_heart_beat(0) + call_out("user_dump",
NET_DEAD_TIMEOUT, DUMP_NET_DEAD);user_dump() 在 600 秒后触发会
tell_room(...断线超过10分钟,自动退出这个世界...) + command
("quit"),预期效果是玩家 body 被正常 quit 流程销毁+存档。据此本
轮按这份档案的真实值(600秒)而非任务描述里泛用的 900 秒去测试,
并在下方如实注明。
现场步骤:注册全新测试小号 ndtestxy/中文名"测试小号"(英文 id 全
字母,避免踩 round one/two 记录过的"含数字 id 触发 2060 暗号需要重
发"的坑),完整走完 2060→id→确认→中文名→密码×2→天赋0→确认→邮
箱→性别,落地"客店"房间确认注册成功。随后直接关闭 TCP 连接(不
发送 quit)模拟真实断线,用管理员 call ndtestxy->query_temp
("netdead") 确认驱动侧 net_dead() 已触发(返回 1)。记录断线
时刻(date +%s ≈ 1787150605,即北京时间约 07:43,ndtestxy.o 存
档 mtime 后续验证与此吻合)。
真实阻塞等待了完整 600+ 秒(未用后台 Monitor 挂起等待,而是在
主循环内用阻塞式 python3 -c "time.sleep(...)" 调用持续等待,符合
"这类真实等待就该真等"的要求;等待期间同步完成了标准检查清单核对,
见下文),目标时刻设在断线时刻+660秒(留60秒余量)。到达目标时刻
后现场验证:
call ndtestxy->query_temp("netdead")返回"找不到指定的物 件"——ndtestxy的玩家 body 已不存在,说明user_dump()已经 触发并把它销毁掉了(不再是 netdead 挂起态,而是彻底不在游戏世界 里了)。ulist只剩fluffos一个在线,ndtestxy确认已下线。work/data/user/n/ndtestxy.o的 mtime 是 07:53,与断线时刻 07:43 恰好相差 10 分钟,与NET_DEAD_TIMEOUT=600精确吻合, 确认存档正是被user_dump()→command("quit")这条路径正常写入 的,不是异常崩溃或提前掉线。debug.log全程无新增错误/trace(只有驱动启动时的既有 warning), 确认整条净断线超时链路(net_dead()→call_out→user_dump()→command("quit")→正常退出存档流程)无崩溃、无报错。- 之后用
ndtestxy/abc12345重新连线验证:走的是全新登录流程 ("你连线进入这个世界,开始了自己的江湖生涯"提示再次出现,落地 一个新的随机新手出生点"北疆小镇",而不是恢复到断线前的"客 店")——证实超时后账号已完全脱离旧会话,reconnect()/netdead 恢 复分支不会被误触发,后续正常登录路径工作正常。quit正常退出。
结论:NET_DEAD_TIMEOUT 机制在本档案里完全按预期工作,无程序性
bug,超时自动退出、存档、清理全部正常,无需任何代码改动。测试用
临时小号 ndtestxy 的两个存档文件(未被 git 跟踪的新增文件)测试
后已直接删除。
标准检查清单核对(§7.90/§7.111/§7.112/§7.113/§7.114/§7.115)
等待净断线超时期间同步完成,逐项现场核对源码(均已在此前各轮修复 过,本轮只做"确认没有异常"的抽查,未发现任何新问题):
- §7.90(eval-cost 过低):
config.fluffos的maximum evaluation cost已是5000000(round one 已修),确认无回退。 - §7.111(
standard_trace()对error["object"]==0未加保护):adm/obj/master.lpc:224已是objectp(error["object"]) ? file_name(error["object"]) : "<none>"的加保护形态,干净。 - §7.112(
init()无重入保护的call_out链,重连时重复叠 加):grep call_out("death_stage"命中d/death/npc/ wgargoyle.lpc/bgargoyle.lpc/d/shaolin/npc/yu-zu2.lpc三个文 件,逐一读取确认三个init()都已带if (...->query_temp("death_stage_active")) return;重入保护 (对应的death_stage()也在每个终止分支正确delete_temp("death_stage_active")),已是修复后的形态,干净。 另一处d/shenlong/npc/pang.lpc用的是不同机制 (remove_call_out("kill_ob")后再call_out),本身自带幂等保 护,不属于此条模式。 - §7.113(净断线重连未恢复
heart_beat,导致永久卡在无法满血 转生的软死锁):adm/daemons/logind.lpc::reconnect()(第754行起) 确认调用user->reconnect()(非死代码,301/382两处调用点都 在真实执行路径上),clone/user/user.lpc::reconnect()内确认无 条件执行set_heart_beat(1),是标准正确形态,干净。 - §7.114(
private修饰的input_to回调经 mixin 继承后静默失 效,导致留言板/邮件多行输入从第二行起失效):grep -rn "private.* input_line"全档案零命中;feature/edit.lpc里input_line()本身就没有private修饰,干净(且此条已知全库仅 4 个受影响的 库,xyzx3不在其中)。 - §7.115(
QUEST宏指向不存在的全局任务钩子文件,give/ask崩溃):include/globals.h的QUEST宏指向/inherit/quest, 确认该文件真实存在于work/inherit/quest.lpc(385字节,非空), 且此条已知全库仅aoxiangtianji一例,xyzx3不在其中,干净。
本轮清理
驱动按精确 PID(367813)结束。测试期间新增的临时文件:ndtestxy
两个存档(已删除,未跟踪文件);fluffos 存档因商店测试+净断线测
试产生的游戏时间/食物饮水/last_on 等增量已用 git checkout --
还原,git status 确认工作区干净,无遗留 diff。本轮全程未修改任何
源代码文件。
§7.100 房间基类 replace_program() 扫尾修复(2026-08-19)
ROOM 宏(/inherit/room/room)在本档案 2,070 处房间文件的
create() 里紧跟 inherit ROOM; 之后又多余调用了一次
replace_program(ROOM);——AGENTS.md §7.100 记录的同一个休眠 bug,
和手足档案 yzxiiizylfy/xyzxiiylzymh 同源(同一双 roommaker 副
本血统)。用 fix_710_room.py 扫过 work/,删除 2,068 处标准形
状;两份房间建造工具(clone/misc/roommaker.lpc、d/huanggon/obj/
roommaker.lpc)各剩 1 处字符串拼接变体,手工改成 str += "\n\t
setup();\n}\n";。修复后 work/ 下 0 处存活残留,work/data/ 下
没有真实 .lpc 源码命中。git diff --stat 显示 2068 个文件净删
2070 行、增 2 行,与脚本自报数字 + 2 处手工编辑吻合。
驱动干净启动(零新增编译错误、端口 40042 正常监听、debug.log
无任何"cannot replace"/"cannot bind"行)。管理员 fluffos/
Mud@2026('2060' Tomud 客户端握手)实机登录成功,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.
深度功能测试(§10.7,2026-10-04)— negative range ends
scripts/lpc_fix_negative_ranges.py: 5 line(s) in 2 file(s) count a range from the end with < (x[a..-1] -> x[a..<1], x[-2..] -> x[<2..]; KB 06 §7.209). In this driver a negative constant end gave "" / ({ }) and a negative start the whole value, so each of these returned the wrong slice; the compile warning A negative constant as the second element of arr[x..y] is gone from the files that compile. Range lvalues (s[0..-1] = text, the prepend idiom) are left alone. A paired compile of the changed files at HEAD and in the working tree showed no new error.
深度功能测试(§10.7,2026-10-05)— 任务表里的 .c 路径与任务守护进程的防护
scripts/lpc_dynamic_rows.py:d/obj/quest/dynamic_location、d/obj/quest/dynamic_quest、quest/dynamic_location 里 151 行写的是原档案的 .c 路径。转档时文件已改名 .lpc,而显式后缀按原样解析,load_object("/d/x.c")、new("/d/obj/quest/x.c") 返回 0 且不报错(KB 03 §4.2,KB 06 §7.220),所以 adm/daemons/questd.lpc、adm/daemons/taskd.lpc 读到的每一行都加载不出来:随机任务和任务物品从未生成,在 create() 里直接对结果调用 tar->set() 的版本还会崩溃,连带加载它的 cron 守护进程和 give 的任务钩子。这些行已改为 .lpc;另有 36 行指向的文件两种后缀都不存在(档案缺内容),保持原样。
scripts/lpc_dynamic_quest_guard.py:2 处 spread_quest() 调用(init_dynamic_quest() 的循环里)包进 catch(),缺失的任务物品或编译不过的房间只跳过那一个任务,守护进程照常加载、其余任务照常生成;cmds/std/look.lpc 夜间检查的 !present("fire", this_player()) 前加 objectp(this_player()) &&(房间 reset() 销毁物品时 /feature/move.lpc 的 remove() 会调用 look_room(),此时没有 this_player(),present(…, 0) 报 Bad argument 2 to present())。
验证:adm/daemons/questd.lpc、adm/daemons/taskd.lpc和 cron 守护进程在新进程里加载(HEAD 一次,工作树三次,选房是随机的):HEAD 通过 2 个,工作树三次分别通过 2、2、2 个(共 3 个),无回退;adm/daemons/taskd.lpc 在 HEAD 与工作树都加载失败,另有原因,与本次无关。
验证:改动过的 adm/daemons/questd.lpc、adm/daemons/taskd.lpc、cmds/look.lpc、cmds/std/look.lpc 在新进程里加载,HEAD 通过 3 个、工作树通过 3 个(共 4 个),无回退。
深度功能测试(§10.7,2026-10-05)— 房间列出的物件缺档时房间照常加载
房间基类 inherit/room/room.lpc:make_inventory() 用 catch() 包住 new(file),做不出来就返回 0;reset() 的 case 1: 拿到 0 就跳过这一项(if (!objectp(ob[list[i]])) break;);reset() 的 default: 拿到 0 就跳过这一项(if (!objectp(ob[list[i]][j])) continue;)。档案里没有的 NPC 或物品(或 create() 出错的物件)原先会让列出它的房间整个加载失败(Bad argument 1 to environment(),或对 0 的 call_other()),连带这个房间后面的区域;现在房间照常加载,只是少了那个物件,下次 reset() 再试(KB 05 §7.25;scripts/lpc_resilient_room.py、scripts/lpc_room_reset_guard.py)。
验证:探针(scripts/lpc_room_reset_probe.py:房间基类列出一个不存在的物件,再调用 reset())HEAD 单件 崩溃、多件 崩溃,工作树 单件 OK、多件 OK。
深度功能测试(§10.7,2026-10-07)— 空的 if (current_water == 0) {}
5 个房间的 valid_leave() 里有一行什么也不做的 if (current_water == 0) {}(编译警告 Expression has no side effects),删去,行为不变:d/gaochang/room11.lpc、d/gaochang/room12.lpc、d/gaochang/room13.lpc、d/gaochang/room14.lpc、d/xingxiu/shanjiao.lpc。
深度功能测试(§10.7,2026-10-08)— 编译警告整理
scripts/lpc_warnings.py xyzx3 --fix 加 scripts/lpc_fix_no_effect.py --apply,共改动 329 个 .lpc 和 3 个 .h(多为删去未用的局部变量)。HEAD 与工作树分别加载(新进程):313 -> 313 通过,无回退;改过的头文件的 34 个包含者 34 -> 34 通过。启动时警告 8 -> 0;新进程登录(输入名字)正常。
(本库只接受 Tomud/笑傲江湖客户端,裸 telnet 输入名字得到“你的客户端非Tomud……”,与 HEAD 相同。)
深度功能测试(§10.7,2026-10-08)— .lpc 后缀的定宽切片
.c 改名 .lpc 时只改了字符串没改切片宽度:f[<2..] == ".lpc" 拿两个字符比四个字符,永远不成立(!= 永远成立),按后缀筛文件、去后缀的代码因此从不运行或截成 x.l(KB 06 §7.238)。scripts/lpc_lpc_suffix_slice.py --apply 改了 1 处比较、0 处去后缀(如 cmds/wiz/ls.lpc);改动的文件 HEAD 与工作树分别加载(新进程),无回退。
- 2026-10-10:编译警告第二轮(按驱动报告逐条修):按位 & 改逻辑运算 11 处,返回类型/原型 22 处,NPC+F_UNIQUE 的 init() 0 个,带初始化的未用局部变量 0 个,只在 #if 分支用的声明移进分支 1 个文件;改动 34 个文件,HEAD 与工作树各载入一次无回退(34 objects; HEAD PASS 34, tree PASS 34; regress 0; newly loading 0),这些文件的警告 34 -> 0。
编译警告收尾(2026-10-12)
scripts/toolkit_fix.sh 一轮(冗余继承 7 处)后,从 tianxiawuxue 同日的整理(3b32800e67a)搬来四个文件:d/city/library.lpc、d/city2/library.lpc、d/emei/user-room/host/home.lpc 有意改 STORY_DIR,前加 #undef;kungfu/skill/huashan-jian.lpc 招式表后多余的 ;。能编译的文件警告清零。改动的对象连同撤回的那些 HEAD 与工作树各载入一次:18 个,regress 0。
- 注意:
lpc_twin_port.py adopt还会把 tianxiawuxue 删掉的inherit F_SAVE;(inherit/char/npcsave.lpc、clone/npc/fa-e.lpc等)一起搬来——那边的 NPC 基类本身带 F_SAVE,本库的CHARACTER不带,删了就找不到save()/restore(),5 个对象载不进来。这些文件已撤回,只留上面四个。
- 2026-10-14:新驱动(FluffOS 970d9f09)报
Float value truncated to int(#1426)。2 个文件 5 处:赋值、初始化、return 改写成to_int(...)(值不变,只是写明截断)。改动的对象新进程各载入一次,无回退(scripts/lpc_fix_float_trunc.py,KB 04 §6.10)。
- 2026-10-15:
kungfu/skill/guangming-blade.lpc(光明刀法)是从五虎断门刀抄来的,query_action()里仍按wuhu-duanmendao的等级挑招式:没练五虎断门刀的人出招时一招都匹配不上,a_action为 0,接着赋值报错。改为按guangming-blade自己的等级。(武功运行期探针发现。)
内力/精力当作伤害种类(2026-10-15,KB 06 §7.241 第二类)
本库 feature/damage.lpc 的 receive_damage() 不接受 jingli/neili/force 等种类,me->receive_damage("jingli", 30) 之类在练功、绝招、吸取时报 F_DAMAGE: 伤害种类错误。12 处改为 add(type, -N)(scripts/lpc_fix_damage_calls.py 第二步)。
无门派玩家的 family 映射(2026-10-15,KB 05 §7.30 第三种)
mapping fam = ob->query("family"); 之后直接 fam["family_name"]:没有门派(新人或叛师后)的玩家在学习、练功、拜师、进入门派房间时报 Value being indexed is zero,而不是作者写好的提示。3 处在声明行加上 if (!mapp(fam)) fam = ([ ]);(scripts/lpc_fix_family_guard.py)。
东方故事/西游记体系的技能文件(2026-10-15,KB 06 §7.241 第三类)
这些 kungfu/skill 文件来自 gin/kee/sen/force 体系,本库人物只有 jing/qi/neili:receive_damage("kee", 30) 报 伤害种类错误,query("force") 永远为 0,技能学不了也练不了。按 kee→qi、gin/sen→jing、force→neili、max_force→max_neili、force_factor→jiali 改了属性名(scripts/lpc_port_es_props.py),共 1 个文件。
治疗/疗伤的属性名(2026-10-15,KB 06 §7.241)
receive_heal()/receive_curing() 也只接受本库的种类。5 个文件(多为只调用 receive_heal/receive_curing 的药物、NPC)来自其他体系,按本库的属性名改名(scripts/lpc_port_es_props.py --any-file)。
family 映射(再补)(2026-10-15,KB 05 §7.30)
mapping fam; fam = (mapping)ob->query("family");(先声明后赋值)和泥潭式的 query("family", me) 同样直接取下标:无门派的新人拜师(attempt_apprentice/recognize_apprentice)、NPC 的 greeting、房间的 valid_leave、ask_me 等报 Value being indexed is zero。5 处补上 if (!mapp(fam)) fam = ([ ]);(刚 recruit_apprentice() 之后的除外)。
技能按另一门武功的等级取招(2026-10-15,KB 06 §7.243)
这些技能文件是从别的武功复制改名来的,query_action() 仍用原武功的等级查招式表:只会本技能的人等级为 0,取不到招,每次出招都报错。改为读本技能自己的等级(scripts/lpc_fix_action_level.py):quanzhen-jian。
把经验、属性、内力当技能读(2026-10-15,KB 06 §7.247)
当前内力、精这类名字有时指的是内功技能,逐处读过后手改:落英缤纷 luoying-shenjian/lybf:自己的注释说成功率由“精神高低”决定,两处 query_skill("jing") 改为 query("jing")。
碧海生潮曲空手报错(2026-10-15,KB 06 §7.246)
iceforce/roar(碧海生潮曲)先 ob = me->query_temp("weapon"),再直接拿 base_name(ob) 判断是不是玉箫;空手 exert roar 时 base_name(0) 报错,提示“你必须先找一只玉萧来才可以吹--曲”根本出不来。条件前补 !objectp(ob) ||。
技能名拼错(2026-10-15,KB 06 §7.249)
query_skill() 里的技能名拼错了,或用的是本库改名前的旧名;本库没有这个技能,调用永远得 0:门槛(< N 就拒绝)永远过不去,相关功夫或绝招学不了、用不了;内功互斥(> N 就拒绝)从不生效;公式里这一项一直是 0。经汉字名(提示文字或中文名词典)或纯拼写差异(_/-、少一个连字符、相邻字母颠倒)核对后,改为本库的技能名(scripts/lpc_fix_skill_typo.py):beimin-shengong→beiming-shengong(tiangang-zhengqi、xiantian-gong);douzhuan-xignyi→douzhuan-xingyi(/d/mr/npc/obj/shu1、/d/mr/obj/shu1);jinwu-dao→jinwu-daofa(jinwu-daofa);mizongxinfa→mizong-xinfa(longxiang/fanchang);yihua-jimu→yihua-jiemu(yihua-jiemu);zhenfen-xinfa→zhenfeng-xinfa(zfwy-bu)。
技能名拼错:技能文件里拼错自己的名字(2026-10-15,KB 06 §7.249)
技能自己的文件(或它的绝招目录)里,query_skill() 读的是差一个字母的自己的名字,永远得 0:“基本功夫要高过本技能”之类的限制从不生效,按等级取招、计算伤害的那一项一直是 0。改为本技能的名字(scripts/lpc_fix_skill_typo.py 的 self 判据):hujian-daofa→hujia-daofa(hujia-daofa);jinggang-quan→jingang-quan(jingang-quan);xuantie-jiafa→xuantie-jianfa(xuantie-jianfa);xuanxie-jianfa→xuantie-jianfa(xuantie-jianfa)。
family 映射内联取下标(2026-10-15,KB 05 §7.30)
ob->query("family")["master_name"]、me->query("family")["family_name"](泥潭式为 query("family", ob)[...])直接对门派映射取下标:没有门派的人(新玩家、叛师者、大多数 NPC)在 NPC 的打招呼和问话、绝招的门派判断、房间的 valid_leave 里报 Value being indexed is zero,而不是得到拒绝。6 处(5 个文件)改为 dbase 路径查询 query("family/master_name"):有门派时值相同,没有时得 0;原有的判断照常生效(scripts/lpc_fix_family_index.py)。给映射赋值的写法未动。
移进不存在的巫师房间(2026-10-15,KB 06 §7.251)
用完的物品、要“离开”的 NPC、掷在空中的兵器被移进巫师的工作室(/u/llm/、/u/wind/),本库没有这些房间。本库的 move() 用 call_other(dest, "???") 载入目的地,找不到文件就报 call_other() couldn't find object,后面的语句都不执行:被雇来打晕或杀人的李凌(d/city2/npc/liling2)办完事要离开时报错,留在原地(d/city2/npc/liling2 本身还载入不了:create() 里 carry_object() 的物品文件缺失或编译失败,见 KB 06 §7.73,另行处理);婚礼最后一步(d/nanyang/npc/meipo 的 last_marry)先把月老送走,在这里报错:新人不会被送上花轿去迎宾楼,喜宴没有了;喜宴结束、礼金付出之后,喜来福(d/nanyang/npc/xi-laifu)退回内堂时报错,留在楼上。3 个文件改为移进本库的虚空房间 VOID_OB(/clone/misc/void),与原作把它们“停放”在巫师房间的用意相同(haiyang2 的维护者把月老送进 /d/city/empty,也是同样的做法)。
玉女剑法「合壁」用一次就永久改动经验和剑法(2026-10-15,KB 06 §7.253)
收尾的 hebi() 声明时没有参数(void hebi() { object me, target, env; int i, j, o, p, count; ...),call_out 传进去的人和数值全被同名的局部变量(0)挡住,开头的 if (!me && !target) return; 每次都返回:合壁的攻击、闪避加成和 hebi 标记要到重新登录才消失。更糟的是夫妻判断写成了 target->querry("id")(没有这个函数,得 0),没成亲的人 marry/id 也是 0,于是人人都被当成夫妻:自己的玉女剑法和经验乘以玉女素心功的级数/80(至少变成浮点数,160 级以上翻倍),随后给对方 set_skill("combat_exp", ...) 时报 No such skill,收尾的 call_out 也就没排上,乘过的等级和经验永远不还原。测试里用一次合壁,经验 100000 变成 200000.0、剑法 100 变成 200.0。改正:hebi() 按它自己再次 call_out 时传的八个参数声明,perform 的 call_out 去掉多余的 h, k,querry 改为 query,给对方的 set_skill("combat_exp") 改为与上一行一样的 set("combat_exp")。测试里加成照常生效,hebi() 结束时还原并清除标记,没成亲的人经验和剑法不变。
NPC 带着本库没有的物品,载入失败(2026-10-15,KB 06 §7.73)
15 个文件、19 处在 create() 里 carry_object("<本库没有的文件>")->wear()(或 wield()、set_amount()):carry_object() 得 0,接着的调用报 Bad argument 1 to EFUN call_other(),NPC 根本载入不了,该有它的房间里就少了这个人。多是从别的系统搬来的 NPC 用了原系统的物品路径(最常见:/d/city2/obj/killerbian、/obj/cloth/cloth、/obj/weapon/blade)。每处改为 { object carried_ob = carry_object(...); if (carried_ob) carried_ob->wear(); }(scripts/lpc_guard_carry_object.py):NPC 照常出现,只是不带这件东西;文件补回来(或是虚拟对象)照样会带上。载入检查:改动的文件改前能载入 0 个,改后 13 个(13 个原来载入不了),没有退步;其余 2 个另有原因(多为 set_skill() 了本库没有的武功)。
物品清单把名字的第一个字吃掉(2026-10-18,KB 07 §8.1)
inventory、房间的物品列表(feature/move)和部分 look 把同名物品合并计数,键是 query("unit") + short(),只有一件时按 key[2..] 去掉量词。量词是一个汉字,在原来的 GBK 里占 2 字节,[2..] 正好去掉量词;转成 UTF-8 以后一个汉字只占一个下标,这一刀把名字的第一个字也切掉了(「把长剑」只显示「剑」,带颜色的名字切掉的是转义序列开头)。改为 [1..](scripts/lpc_fix_unit_cut.py):cmds/usr/sssinventory.lpc、feature/ymove.lpc。
去掉的预定义宏 SAVE_EXTENSION(2026-10-18,KB 04 §6.11)
老版 MudOS 给每个 LPC 对象预先定义了 SAVE_EXTENSION(".o");FluffOS 的 ChangeLog(COMPAT_BUSTER 一条)把它删了,改用 __SAVE_EXTENSION__。本库没有自己 #define 这个宏,用到它的文件一律 Undefined variable 'SAVE_EXTENSION',整个对象载入不了。改成 __SAVE_EXTENSION__(scripts/lpc_fix_predefined_macro.py):adm/daemons/network/netmail.lpc。netmail 是网络邮件守护进程(本库缺 mailer.h 等头文件,改后仍载入不了)。改后用 lpcc 逐个载入这些对象:0 个通过,1 个还有别的错误(adm/daemons/network/netmail:/adm/daemons/network/netmail.lpc:17: error: Cannot #include mailer.h)。
水潭里 ging_cost 是 jing_cost 的笔误(2026-10-18)
shuitan 先算 jing_cost,倒水时却扣 receive_damage("jing", ging_cost),ging_cost 从没声明过:Undefined variable 'ging_cost',整个物件载入不了。改成 jing_cost:d/shaolin/npc/obj/shuitan.lpc。改后用 lpcc 逐个载入这些对象:1 个通过。
全真心法 valid_learn() 里没声明的 lvl(2026-10-18)
kungfu/skill/quanzhen-xinfa.lpc 的 valid_learn() 判断 me->query("gender") == "无性" && lvl > 49,可是函数里只有 nk、nf、nh、ns 四个变量,没有 lvl:Undefined variable 'lvl',这门心法的文件载入不了,学它、用它都失败。nh 正是全真心法的等级(nh = query_skill("quanzhen-xinfa", 1)),改成 nh > 49。改后用 lpcc 逐个载入这些对象:1 个通过。
set_skill() 遇到本库没有文件的武功不再抛错(2026-10-18,KB 06 §7.256)
feature/skill.lpc 里的 set_skill()、map_skill()、prepare_skill() 碰到没有武功文件的名字就 error("F_SKILL: No such skill (…)"),调用它们的 NPC create() 整个中断:NPC 载入不了,刷出它的房间也少一个人。本库有 6 个对象设了本库没有文件的武功(4 个名字,最多的是 yiyang、hunyuan-force、ruyi-blade)。三处都改成 return:这一门武功不给、不映射,对象照常载入,只是少了它(缺的武功本身仍是内容缺口)。抽样载入这些对象:6 个里 6 个通过。(scripts/lpc_guard_set_skill.py)
武功名拼错的 NPC(2026-10-19,KB 06 §7.258)
set_skill("kunlun-shnfa", …)、map_skill("dodge", "shaolin-shnfa") 这样的调用把武功名拼错了:本库没有这个武功文件,有的是拼对的那个。以前这种 NPC 在 create() 里报 No such skill 载入不了;武功缺失时跳过之后它们能载入,可是少了那门武功(set_skill 被跳过,map_skill 映射不到,门派弟子用普通轻功/拳脚)。按核对过的对照表改正,共 17 处、16 个文件:yan-fly→yanfly(3 处)、xinxiu-duzhang→xingxiu-duzhang(2 处)、tiaji-jian→taiji-jian(2 处)、kongmingquan→kongming-quan(2 处)、taiji-shenfong→taiji-shengong(2 处)、lingbo-weibu→lingboweibu(2 处)、poyu-qua→poyu-quan(1 处)、hanbing-mainzhang→hanbing-mianzhang(1 处)等共 10 个名字。(scripts/lpc_fix_skill_names.py)
删掉 exert_function(整数)(2026-10-19,KB 06 §7.266)
/u/zjb/saveme.lpc create() 里的 exert_function(10); 把整数传给了要字符串的直接调用(让 NPC 闲聊时自己运功),驱动报 Bad type for argument 1 of exert_function ( string vs int ),整个 NPC 载入不了。这是存档里的笔误,不知道作者想传哪个字符串,删掉这一句(只影响闲聊时的运功表现)。chidi 的同一个 NPC 早先就是这样处理的。
区域物件的零碎修正(2026-10-19,KB 06 §7.267–§7.271)
/d/board/mingjiao_b.lpc的location从不存在的/d/mj/guangming-ding改成/d/mingjiao/guangming-ding(载入明教留言板失败会让光明顶房间载入不了)- 2 个 NPC 文件、2 处
create()里的this_player()->carry_object(改成carry_object((没人在场时this_player()是 0,NPC 载入不了;有玩家在场时衣服武器落到玩家手里)
逐个物件与 HEAD 对比载入,没有退步。
开封擂台头文件的重复全局变量(2026-10-19,KB 04 §6.10)
d/kaifeng/ground.h 里的 modes、mode_hints、families 三张表被 ground0.lpc 和继承它的 ground1/2/3.lpc、ground.lpc 各包含一次,每次 inherit 都报 Redeclaration of global variable。表只放在 ground0.lpc 里:头文件用 #ifndef GROUND_TABLES_INHERITED 包住表,继承的几个程序在 #include "ground.h" 前 #define GROUND_TABLES_INHERITED(与 xiyouji 系其余库同一改法)。改后警告消失,与 HEAD 逐个对比载入,没有退步。
RANK_D 对 0 的称呼(2026-10-19,KB 06 §7.273)
adm/daemons/rankd.lpc 的 query_respect()、query_rude()、query_self()、query_self_rude() 里 4 个函数开头补上 if (!objectp(ob)) ob = this_object();。NPC 在 create() 里写 "…" + RANK_D->query_respect(this_player()) + "…"(inquiry 对话、chat_msg),驱动自己跑 reset() 时没有人在场,this_player() 是 0。旧驱动里 0->query("age") 返回 0,称呼走默认分支;新驱动直接报 Bad argument 1 to EFUN call_other(),房间的 make_inventory() 吞掉错误,被打死的 NPC 再也刷新不回来。用 scripts/lpc_reach_census.py --walk 找到(xkx100 的武当弟子、一灯、汴梁书生…);修在守护程序里,不动 1,800 个 NPC 文件。
玩家打造兵器模板被 NPC 带上(2026-10-19,KB 06 §7.275)
/d/npc/m_weapon/weapon/m_club.lpc、/d/npc/m_weapon/weapon/m_sword.lpc(共 2 个)的 create() 用 this_player() 读打造数据(me->query("weapon/lv") 等)。NPC 的 weapon 属性是兵器文件名(字符串),NPC 在别的 NPC 的命令环境里 carry_object() 这个模板时,set_desc() 里 switch (w_lv) 拿到的是那个字符串,驱动报 Bad argument 1 to switch,房间和 NPC 都载入不了(旧驱动里 switch 落到 default)。把 if (me) { 改成 if (me && mapp(me->query("weapon"))) {,玩家打造的流程不变。
玩家打造兵器模板没有打造者时(2026-10-19,KB 06 §7.275)
/d/npc/m_weapon/weapon/m_bian.lpc、/d/npc/m_weapon/weapon/m_staff.lpc、/d/npc/m_weapon/weapon/m_whip.lpc、/d/quanzhen/npc/obj/m_sword.lpc、/d/quanzhen/obj/m_sword.lpc(共 5 个)的 create() 开头 me = this_player(); 之后无条件读 me->query("weapon/name") 等打造数据。房间刷新时没有人在场(me 为 0),或者 NPC 在别的 NPC 的命令环境里 carry_object() 这个模板(NPC 的 weapon 属性是文件名字符串),旧驱动里读出来是 0 或字符串,switch 照样落到 default;新驱动报 Bad argument 1 to EFUN call_other() / Bad argument 1 to switch,NPC 和它所在的房间载入不了(--walk 普查里一个玩家走进房间就触发)。在 //读入数据 之后加 if (!me || !mapp(me->query("weapon"))) { setup(); return; }:没有打造者就留一个没有名字的空模板,玩家打造的流程不变。
补回丢失的标点(2026-10-19,KB 03 §4.6)
转换时丢掉的分号、逗号、引号或文件末尾的 },共 5 个文件,修前 HEAD 载入失败。别的库里同路径的完好副本只比这里少几个标点,按它补回(括号里是那个库):/d/baituo/npc/obj/bowl.lpc(cctx)、/d/baituo/obj/bowl.lpc(cctx)、/d/quanzhen/hudi6.lpc(bixiecanyang)、/kungfu/skill/huang.lpc(bixiecanyang)、/quest/murong/qlist3.lpc(bixiecanyang)。修后与 HEAD 逐个对比载入:这 5 个物件全部载入,没有退步(scripts/lpc_restore_from_twin.py、lpc_fix_eaten_quote.py --comma、lpc_fix_eof_braces.py)。
玩家买店用的 feature/vendor_sale.lpc 补回(2026-10-19,KB 03 §4.6 第四轮)
/feature/vendor_sale.lpc(/kungfu/class/npc/xiaoer.lpc 继承它)从 pay_back 起约 160 行的行尾丢了最后一个字符(; ) { },else { 只剩 els,msg 只剩 ms),另有一行 if(wizardp(who) || getuid(who)==owner_id) 被拼进了前面的 log_file( 调用里。文件载入失败,继承它的物件也跟着失败。别的库(ldtx、ldtxii、xhcii、syxjl、hy3)里有这个文件的完好副本,但那是另一个版本:没有作者后来加的投标公告(string mesg; 和 message("channel:chat", ...))。所以按完好副本补回丢失的字符(scripts/lpc_restore_from_twin.py --diff --extra),公告两段原样保留;被拼到别处的 if(...) 放回完好副本里它所在的 write("\n盈利 之前;message_vision("channel:chat", ...) 多出来的第一个参数删掉(message_vision 的签名是 (string, object, object),每次 bid 在扣完款之后都会报错)。补完后文件和继承它的物件都能载入,没有警告,也没有退步(HEAD 上两个都载入失败)。
== !"字符串" 多出来的 !(2026-10-19,KB 06 §7.280)
!"taoist" 是整数 0,x == !"taoist" 就是“x 等于 0”,作者为其余所有人写的那一支永远走不到。具体是:龙女对古墓弟子的机关暗门提示永远给不出来(5 处);孙婆婆的“你去吧”只对 class 没设置的人生效;性别检查(“你不是女的,无法领会其中至阴之理”)永远不拦人,男的照样能学玉女心法。全部改成 != "字符串"(scripts/lpc_fix_not_literal_cmp.py):/kungfu/class/gumu/long.lpc(5 处)、/kungfu/class/gumu/sunpopo.lpc(1 处)、/kungfu/skill/yunu-xinfa.lpc(1 处)。同样的行在 xkx 一系的 35 个库里都有。
x != "a" || x != "b" 和 x == "a" && x == "b":同一个值的比较链永远成立/永远不成立(2026-10-20,KB 06 §7.282)
if (arg != "wan" || arg != "丸") return notify_fail(...) 对任何 arg 都为真,dir == "south" && dir == "north" 永远为假:条件下面的守卫要么永远拦、要么永远不拦。作者要的是“既不是 A 也不是 B”(&&)或“是 A 或 B”(||)。!= 链的 || 改成 &&(仅当条件下面是 return 的拒绝/守卫),== 链的 && 改成 ||(scripts/lpc_fix_cmp_chain.py)。具体是:客栈小二从不拦住付了房钱又往南/往北走的客人。改动:/d/changan/ca2.lpc(1 处)、/d/haojie/npc/tianshaxing.lpc(1 处)。
浩劫系统 verdict_time():领头玩家已经离线时 lead->name() 报错,戒严不解除(2026-10-20)
三十分钟后收场时 lead(接战书的玩家)若已退出游戏就是 0,lead->name() 在宣布战果的 message() 里报错,后面的 LOGIN_D->set_madlock(0) 不再执行,戒严一直保持,quit 指令因此对所有人关闭。改为 (lead ? lead->name() : "各派豪杰")。改动:/feature/disaster.lpc(2 处)。
socket / dumpsocket 指令:dump_socket_status() 驱动里没有(2026-10-20,KB 06 §7.291)
这些巫师指令 write(dump_socket_status());,MudOS 的 efun 在 FluffOS 里不存在,指令编译不过。在模拟 efun 文件里补了 dump_socket_status():用 socket_status() 排出同样的表(没有 sockets 包的构建,比如 WASM,只有表头;scripts/lpc_add_sefun.py dump_socket_status)。
tail 指令:tail(file) 驱动里没有(2026-10-20,KB 06 §7.291)
cmds/*/tail.lpc 调用 MudOS 的 tail() efun,FluffOS 没有,指令编译不过。模拟 efun 文件里补了 tail(file)(Discworld 家族的兼容版:文件最后约 20 行,从完整的一行开始,存在返回 1;scripts/lpc_add_sefun.py tail)。
登录密码超过 255 字节:crypt() 抛错(2026-10-20,KB 06 §7.294)
驱动的 crypt() 对超过 255 字节的密钥直接报错(Error in crypt(), check your salt),老驱动则按任意长度散列。在登录提示符下输入 256 字节以上的密码,密码检查那一行就抛错,连线停在一个裸的 > 提示符上,登录走不完(password 指令的旧密码检查同样);用 300 个 x 当参数的扫描发现的。/adm/obj/simul_efun.lpc 里补了一个同名的 simul_efun crypt(key, salt):只有超长的密钥才被截短(先截到 255 个字符,再逐字符截到 sizeof(to_buffer(key)) <= 255,限制按字节算,一个汉字占三个字节),再交给 efun::crypt();普通密码原样散列,已存的密码散列不受影响(scripts/lpc_add_sefun.py crypt)。
翻页器 start_more(read_file(...)):文件缺失时 explode(0)(2026-10-20,KB 06 §7.300)
东方故事系的翻页器 void start_more(string msg) { ... explode(msg, "\n") ... } 被这样调用:start_more(read_file(HELP_DIR + "help/topics"))、start_more(read_file(NEWS))。压缩包没带的文件使 read_file() 回 0,explode(0, ...) 在本驱动里报 Bad argument 1 to explode()(不带参数的 help 指令就是这样出错的),老驱动把 0 当空文本。在 start_more 开头加了 if (!stringp(msg)) return;(scripts/lpc_fix_start_more.py)。改动:/feature/more.lpc。
wabaod 的藏宝线索按双字节算(2026-10-20,KB 06 §7.307)
天书的线索由 adm/daemons/wabaod.lpc 在房间描述里挖空若干个字:desc = long[begin..begin + 60](按 GB 的 61 字节)、desc[b..b + 1] = "■"(两个字节换两个字节)。驱动的字符串是 UTF-8,区间按字符数:窗口成了 61 个字符,每次替换把两个字符换成一个,字符串越换越短,后面的偏移越界,启动时 push_lvalue_range: invalid ind2(随机出现,init_xunbao 的每次 call_out 也会)。改成按字符算:30 个字符的窗口,每处挖一个字(scripts/lpc_fix_wabaod.py)。
NPC 的 chat() 在 chat_msg 为空数组时下标越界(2026-10-21,KB 06 §7.334)
NPC 基类的 chat() 是 if (arrayp(msg = query(...))) { if (random(100) < chance) { rnd = random(sizeof(msg)); if (stringp(msg[rnd])) ...,不检查列表是否为空。本库现有的 NPC 文件里没有字面写成空 chat_msg 的(扫描只认 set("chat_msg", ({ })));守卫挡的是运行时才为空的列表和以后新增的 NPC。在 random(100) < chance 前面加 sizeof(msg) &&(scripts/lpc_fix_chat_empty.py;if (random(100) > chance) return 0; 的写法是 !sizeof(msg) ||)。改动:/inherit/char/npc.lpc(共 1 个文件)。
quest/dynamic_room 的 .c 行:任务守护进程加载不了(2026-10-21,KB 06 §7.341)
任务守护进程(adm/daemons/taskd.lpc)的 create() 读 /quest/dynamic_room(琉璃庄的 19 个房间,/d/llzhuang/lou0.c ……),clear_room() 对每一行 load_object() 再 room->reset():显式的 .c 按原样解析(KB 03 §4.2),档案里的房间是 .lpc,load_object() 答 0,0->reset() 让 create() 中止,守护进程没有加载(HEAD 加载失败,改后通过)。2026-10-05 的 .c 行扫描只认 dynamic_location* 和 dynamic_quest* 两种表,dynamic_room 和 dynamic_npc_quest 没有扫到;scripts/lpc_dynamic_rows.py 现在认四种,这 19 行改成 .lpc(本库档案里没有的行照旧不动)。
不带参数的指令对 0 调用 efun:不在 wiz / adm 目录里的指令(2026-10-21,KB 06 §7.336)
指令敲成不带参数时,驱动把 0 传给字符串参数;下面的指令第一句就把这个 0 交给 efun,运行时报 Bad argument 1 to ...。它们在 cmds/std、cmds/usr、cmds/bos、cmds/app 这类目录里,上一轮的扫描只看巫师目录。用 scripts/lpcc_bare.py 不登录、在一次 lpcc 求值里以 0 调用 main() 逐个确认后,由 scripts/lpc_fix_bare_arg.py --all-dirs 在第一处使用参数的语句前加守卫:没有 help() 的是 return notify_fail("…\n");。改动(1 个文件,括号里是接住 0 的 efun):/cmds/std/actionavailable.lpc(sscanf)。加载检查 HEAD 与工作树对照,没有退步。
谷物加工厂 goldwork2/3/4:工作太久被赶出去时 ob->move(..)(2026-10-21,KB 06 §7.348)
working() 在连续工作次数超过 60+random(100) 时,运气低于 25 的人被送回广场:if ((int)me->query("kar") < 25) ob->move("/d/city/guangchang");,ob 声明了没赋值(同一目录的 goldwork.lpc、goldwork5.lpc 写的是 me->move)。抛错在 me->set_temp("working", 0) 和 cot-- 之前,房间里的工人计数漏掉一个,三次之后“人手已经够了”永远不再收人。改成 me->move(..),去掉 object ob;。改动:/d/city/goldwork2.lpc、/d/city/goldwork3.lpc、/d/city/goldwork4.lpc。
香烟 smoke.lpc:do_smoking() 读没赋值的 me(2026-10-21,KB 06 §7.348)
smoke 指令的第一句是 jing = me->query("jing"),me 声明了没赋值,每次抽烟都抛 Bad argument 1 to call_other()。补 me = this_player();(后面的 this_player() 调用不变)。改动:/d/emei/user-room/melodies/smoke.lpc。
注册到不存在函数的 add_action(2026-10-21,KB 06 §7.349)
add_action("函数", "动词") 绑定的函数,在对象本身、它包含的头文件、它继承的父类和继承它的子类里都没有定义(scripts/lpc_scan_callout_targets.py 静态解析,子类用传递闭包复核,scripts/lpc_verify_handlers.py 运行时 function_exists() 复核)。驱动从玩家最新的一条动作往回找,遇到这样的句子就报 *Function for verb 'drop' not found.,同一个动词的其他处理函数不再尝试(不是最新的一条就悄悄跳过)。删除了 34 条注册(30 个文件,scripts/lpc_fix_dead_add_action.py),动词留给别的处理函数:/d/city/chatroom2.lpc(do_jump)、/d/city/npc/wei.lpc(do_sell)、/d/city2/qishi.lpc(do_pass)、/d/city3/npc/sister.lpc(do_vendor_list)、/d/player/yysz/hupan.lpc(do_han)、/d/quanzhen/npc/haodatong.lpc(do_decide)、/d/quanzhen/npc/mayu.lpc(do_decide)、/d/quanzhen/npc/qizhicheng.lpc(do_decide)、/d/quanzhen/npc/sunbuer.lpc(do_decide)、/d/quanzhen/npc/wangchuyi.lpc(do_decide) 等共 30 个文件。最多的函数名:do_send 15 处、do_decide 7 处、do_faint 5 处、do_jump 1 处、do_sell 1 处。
对象路径里的 ..:new(__DIR__ "../obj/x") 报 Read access denied(2026-10-22,KB 06 §7.351)
__DIR__ 是当前文件所在目录(带结尾斜杠),__DIR__ "../obj/x" 就是 /d/zhiye/npc/../obj/x;驱动的 legal_path() 不接受带 .. 的路径,new() / load_object() 直接抛 *Read access denied.(实测,find_object() 对它答 0)。走库自己的 carry_object() / 房间 objects 表的路径,库的基类会先规范化,能用;直接把路径交给 new() / clone_object() / load_object() / move() 的不行,调用到那一步才报错。改成规范化后的绝对路径(scripts/lpc_fix_dotdot_dir.py --direct):/d/wudang/npc/xiaocui.lpc(__DIR__ "../obj/nuerxiang" → "/d/wudang/obj/nuerxiang")。
缺失物品的 new() / carry_object() 调用链加了保护(2026-10-22,KB 06 §7.73 补充)
new(路径)->move(...); / carry_object(宏("x"))->wear(); 这类语句,路径指向的文件在这个压缩包里没有:new() 返回 0,->move() 在 0 上报 Bad argument 1 to EFUN call_other()。在 create() 里这个对象永远加载不了,在 reset() 里第一个缺失物品之后的刷新每次 reset 都被跳过。1 个文件里 1 处(new)改成 { object new_ob = new(路径); if (new_ob) new_ob->move(...); }(scripts/lpc_guard_carry_object.py --new:路径按这个文件自己看到的宏解析,宏名冲突、虚拟对象路径一律跳过)。 对这 1 个改动文件做加载检查(HEAD 与工作区对比):HEAD 能加载 1 个,现在 1 个(新增可加载 0 个,回归 0 个)。
调用了、但这个库自己的守护进程里没有的函数(2026-10-22,KB 06 §7.354)
MACRO->函数() 调用的函数在这个库的守护进程里不存在:call_other() 对不存在的函数不报错、只返回 0,所以这些功能(时间显示、昼夜事件、名字检查、价格文字……)一直没起作用。同一血统另一个库的同名守护进程里有这些函数,原文照抄到本库守护进程末尾(scripts/lpc_port_function.py;调用处传的参数个数、函数体用到的函数 / 全局变量 / 宏 / 字符串键都在本库里有,已核对;守护进程在 HEAD 和工作区都能加载,每个函数用固定参数各调用一次:HEAD 返回 0,现在返回正常的值):/adm/daemons/chinesed.lpc ← aoxiangtianji:chinese_month()(2 处调用);/adm/daemons/natured.lpc ← aoxiangtianji:room_event_fun()(9 处调用)。
(: 函数 :) 指针指向对象自己没有定义的函数(2026-10-22,KB 06 §7.355)
item_desc / inquiry / chat_msg_combat 里的 (: 函数名 :) 指向本对象(含包含文件、继承的父类)没有函数体的函数:编译不报错,用到时驱动报 *Undefined lfun pointer called: 函数名(look 某物、ask NPC about 话题 直接出错,战斗 / 闲聊里的指针在 NPC 的 chat() 里出错,这一拍心跳的后半段被跳过)。scripts/lpc_scan_callout_targets.py --kinds=lfun。 还剩 3 个函数没有补(inquiry 2, item_desc 1):原型还在函数体丢了、或者根本没写过,没有可以直接补回的捐赠(别的库同一路径的文件里没有这个函数,或者它还要用本库没有的辅助函数、签名不同),不编造:/d/city/npc/zhuziliu.lpc:give_job、/d/city/npc/zhuziliu.lpc:task_ok、/d/yihua/lianhuachi.lpc:look_CAI。
(: 函数名 :) 指针指向本库没有的函数:只含这个指针的行加了注释(2026-10-22,KB 06 §7.355 补充)
inquiry / item_desc / chat_msg* 里的 (: 函数名 :) 指向本对象(含包含文件、继承的父类)没有函数体的函数:用到时(ask、look、NPC 闲聊)驱动抛 *Undefined lfun pointer called: 函数名,这一拍心跳的后半段被跳过。这些函数没有可以补回的来源(别的库同一路径的文件里没有,或者它还要用本库没有的东西),所以 1 个文件里 1 行只含这个指针的行("CAI": (: look_CAI :),)加了注释,原文保留并写明原因,这一项当作没有这个话题 / 物品 / 闲聊条目(scripts/lpc_fix_dangling_lfun.py;#include 的文件在库里缺失的对象、指针不在整行上的写法没动)。 前提(function_exists())和加载检查(HEAD 与工作区对比,本库改动的 .lpc 文件)的结果见 KB 06 §7.355:没有一个回归。
写死的 "/路径"->函数() 指向库里没有的文件:改成现存的同名文件(2026-10-22,KB 06 §7.359)
1 处语句级的 call_other 字面量路径,库里没有这个文件(区域改了名 / 大小写不对 / 差一个字母 / 文件挪了地方):"/d/mj/obj/baihong-jian"->move()(/d/mingjiao/npc/yingwang.lpc)→ "/d/mingjiao/obj/baihong-jian"。call_other() 对不存在的对象抛 couldn't find object,所在函数当场中断。改成库里现存、并且定义了被调用函数的文件(scripts/lpc_fix_call_path.py;巫师目录、备份目录、名字不同的兄弟文件都不算候选)。 其中殷天正(白眉鹰王)的 do_answer():玩家念对暗语(answer 怜我世人,忧患实多;保护教主,同抗外敌)时把白虹剑 move 给玩家,区域目录改名 mingjiao 之后这个路径没跟着改,回答暗语只得到 couldn't find object,剑永远发不出来。
汉字按字节切片的老写法没有换成按字符:改法名 "澄" + name[2..3]、辈分判断 name[0..1] == "澄" 等 20 处(2026-10-22,KB 06 §7.360)
原档按字节算字符串区间(一个汉字 2 字节):name[2..3] 是名字的第二个字,name[0..1] == "澄" 问名字是不是以「澄」开头。转成 UTF-8 之后,这个驱动的区间和 strlen() 都按字符算(strlen("澄观") 是 2,"澄观"[0..1] 是两个字),老算术原样留着、意思全变:拜入少林 / 武当 / 峨嵋等派的玩家被改成错误的法名(二字名 张三 变成一个字的 澄,更长的名字取到第三个字);各派掌门的辈分判断(name[0..1] == "澄")永远不成立。
本库 20 处(15 个文件):拼名字的赋值 12 处、与汉字常量比较 8 处。例:name[2..3] → name[1..1](/kungfu/class/emei/jingxin.lpc:101);name[0..1] → name[0..0](/kungfu/class/shaolin/qing-fa.lpc:100);name[0..3] → name[0..1](/quest/imp/xquest.h:97)。scripts/lpc_fix_gbk_slice.py 把下标按字符重算(社区的 UTF-8 版 xkx100utf8 里就是同样的写法,作对照);没有改的:截断(name = name[0..7],现在最多 8 个字,只是放宽)、ASCII 的区间(fname[0..3] == "room"、ctime(time())[4..19])和上下文看不出是汉字的区间。证明(scripts/lpcc_eval.py,bixiecanyang;其余各库是同一份文本):让澄字辈掌门 attempt_apprentice() 一个名叫「张三」的访客,HEAD 的法名是 慧,改后是 慧三;抽样 28 个库的 HEAD / 工作树加载对比 0 退步。工具不幂等([0..3] 折半得 [0..1],又是对齐区间),改过的文件记在 scripts/gbk_slice_converted.txt,不要重跑。
长度检查按字节写,旁边的提示按汉字写:10 处(2026-10-22,KB 06 §7.362)
老档的 strlen() 数字节(一个汉字 2 字节),转成 UTF-8 后它数字符:提示写「必须是 2 到 6 个中文字」的检查还是 strlen(name) < 4 || strlen(name) > 12,于是两三个字的房名、帮会名、群名、聊天室名、称号被提示自己说允许的那句话拒绝,上限却是提示的两倍;留言板的标题检查 i < 4 || i > 24 || i % 2 还会拒绝所有奇数个字的标题(post 你好吗)。本库 10 处(5 个文件):if ((strlen(name) < 2) || (strlen(name) > 12)) {(/cmds/bakcmds/csc.lpc:611);if (strlen(arg) < 2 || strlen(arg) > 30)(/d/player/fan_room.lpc:115)。scripts/lpc_fix_strlen_gate.py 以提示为准:条件里每个 strlen 门槛都恰是提示所说数字的两倍才折半,存长度的变量(i = strlen(arg);)的门槛和 || i % 2 奇偶项、其后循环的 i % 2 == 0 && 一并处理;提示里有英文 / 字母 / 字节的不动。证明(scripts/lpcc_eval.py,bxsj 的留言板,求值对象继承 NPC 并重写 edit() 记录调用,command("post 标题")):HEAD 拒绝「你好」和「你好吗」、放行 23 个字的标题;改后接受前两个、拒绝第三个;shenmo 的 named.lpc invalid_new_name("张三"):HEAD 回 名字只能是2-4个中文字。,改后回 0。抽样 24 + 15 个库的 HEAD / 工作树加载对比 0 退步。
按字节写的汉字循环、茶馆猜诗和同盟频道标题(2026-10-23,KB 06 §7.363)
老档按字节做「一个汉字」:while (i--) if (i % 2 == 0 && !is_chinese(name[i..<0])) 只检查偶数下标,奇数位上的拉丁字母(张a)会过;茶馆猜诗 mixup() 用 strlen(str)/2 再 j=j+j、str[k..k+1] 交换两字节;泥潭系 channeld 的 switch (strlen(fname)) case 4/6/8/10 和 strlen(family)==4/6 按字节长度给同盟 / 门派名加空格。本驱动的 strlen() 和区间都按字符算。scripts/lpc_fix_byte_char.py:去掉奇偶项、把区间改成 name[i..i],按字符重写 mixup() 并把 strlen(first)>=14 折成 7,频道标题的 case / 门派长度改成字符数(对照 aoxiangtianji)。本库 汉字循环 / is_chinese 区间 6 个文件。证明(scripts/lpcc_eval.py):sjplii 的 check_legal_name 在 HEAD 接受「张a」、改后拒绝,两边都接受「张三」;xkx100 的 clubpoem->mixup("离离原上草") 得到「离离原草上」(真交换汉字);nitan_san 两字同盟名得到 【 兄 弟 】。关键对象加载通过。
血条 / 表情标题按字节算显示宽度(2026-10-23,KB 06 §7.365)
老档把汉字当两字节:bar_string[0..(val * N / max) * 2 - 1] 把「格数」换成字节下标,半格血条在本驱动(按字符算区间)上会整条画满;巫师表情 edemote 的 repeat_string("─", 13 - (strlen(emotion) / 2)) 也会少减汉字宽度。scripts/lpc_fix_display_pad.py:去掉 CJK 血条 / 空白条上的 * 2(jings/qis 赋值和 blank_string3[0..(23-a)] 的 23→11 一并改),表情标题去掉 / 2;ASCII 空格的 none_string / empty_string 仍保留 * 2(一格两个空格)。本库 4 处(2 个文件)。证明(lpcc_eval.py hhsj):tribar_graph(6,9,12) 在 HEAD 画出整条 12 个■,改后为 6 个■+3 个□;麻将 strlen(tempB)/2 是两字符牌码,未改。
Beyond 出口仍指向 /u/beyond(2026-10-23,KB 06 §7.368)
宁波 / 苏州 / 慕容等区域已进 /d/ningbo、/d/suzhou、/d/mr、/d/hz,出口与任务物路径仍写 /u/beyond/…。scripts/lpc_fix_beyond_exits.py 在目标 .lpc 存在时改写(murong→mr)。本库 1 处。证明:sjplii xikou HEAD 西向 /u/beyond/ningbo/aywsi,改后 /d/ningbo/aywsi 可加载;bxsj hubian1 三向均可加载。
死巫师出口 gold/dock、sunrise、mei(2026-10-23,KB 06 §7.370)
/d/wanjiegu/road4 东向 /u/g/gold/dock、峨眉寿星居南向 /u/xinyue/sunrise_room、玩家卧室通往 /u/mei/… 均无对应房间。scripts/lpc_fix_drop_dead_u_exits.py 删除这些出口行,并去掉同方向的 create_door(否则 create_door 无出口会炸)。本库 5 处。证明:zxty08nxgbb 的 road4 HEAD 有东向,改后没有;mei_room1 可加载。
中文名 / 验证码仍按 GBK 取「两字节一字」(2026-10-23,KB 06 §7.373)
pname = pname[(random(sizeof(pname)) & 0xFFFE)..<1]; pname = pname[0..1]; 在按字符计下标时会取出两个汉字。scripts/lpc_fix_pname_slice.py 去掉掩码并把收尾改成 [0..0](pname/pname2/sec_name/str/str1)。本库 4 处。证明:nt1 生成名长度 2–4;HEAD 常见 3–5。
set("long" 丢引号(2026-10-27,KB 04 §6.25 Also)
set("long", 后直接跟汉字(无 " / @LONG),驱动报 Illegal character。用同路径完好手足覆盖(fyue_room←jhfy;hudi5/6←zxty08nxgbb;quanzhen_old/hudi*←xyzxfy2)。证明:HEAD 失败;改后加载。
深度功能测试(2026-10-27,§6.25 d/city/sj 去引号)
d/city/sj 整文件去引号(add_action(do_out, out) 等);按 jhfy 完整副本替换。
深度功能测试(2026-10-27,§6.25 zhongling tell_object 引号错位)
d/wanjiegu/npc/zhongling(及同路径副本)的 tell_object("who, 钟灵脱下一双绣花鞋。\n") 把对象参数写进了字符串;改为 tell_object(who, "…")。证明:原文错位;改后加载,语料残渣 0。
深度功能测试(2026-10-27,§6.25 one-arg message_vision)
message_vision("…") 补第二参(me / TP / this_player())。
深度功能测试(2026-10-27,§6.10 未知 pragma save_binary/optimize)
删除本库中 FluffOS 不认的 #pragma save_binary / #pragma optimize… 行。