Xiao Ao Jiang Hu XO (The Smiling, Proud Wanderer)

✅ 可玩

笑傲江湖 XO

xajhxo

🔑 fluffos / Mud@2026 更新 66a3bd8 2026-10-28 源码 下载 ZIP

▶ 开始游玩 · Play Now

游戏取材自金庸小说《笑傲江湖》,"XO"是这个版本自己的代号(登录横幅上写着"THE SMILING PROUD WANDERER"),源自 TMI-2/ES2 引擎、由"Falcon"改写,本项目还收录了同一血脉的另外两个快照 `xo`(笑傲江湖迷你版)与 `xo_final`(XO最终版1.2),以及共享同一套"XO mudlib"世界模板的第四位近亲 `xajh2`——不过逐文件比对发现两者在共有路径中只有18%的字节完全相同,说明各自都是独立重写而非直接复制。门派体系是共享模板的一个精简子集:少林、崆峒、昆仑、青城、无量剑派、《天龙八部》里的大理段氏皇宫,以及丐帮麾下的"一品堂",此外还有专属于本档案的南阳地区及一处山寨匪窝。新角色会被随机分配到几个不同的起始场景之一(比如"龙门客栈"),剑术、刀法、拳脚、轻功、短兵刃、鞭法、长兵刃等各类武学修为各自独立养成。新创建的人物如果在上线30分钟内就 `quit`,存档会被作废——这是游戏本身的防灌水设计,不是缺陷。

English

Based on Jin Yong's novel The Smiling, Proud Wanderer, "XO" is this version's own codename (the login banner reads "THE SMILING PROUD WANDERER"), descended from the TMI-2/ES2 engine lineage and rewritten by "Falcon." This collection also holds two other snapshots of the same bloodline, xo (Mini Edition) and xo_final (Final 1.2), plus a fourth relative, xajh2, with which it shares the same underlying "XO mudlib" world template — though a file-level check found the two only 18% byte-identical among shared paths, confirming each was independently rewritten rather than copy-pasted. It runs a trimmed subset of that shared sect roster (Shaolin, Kongdong, Kunlun, Qingcheng, Wuliang, the Duan-clan palace of Demi-Gods and Semi-Devils, plus the Beggars'-Sect-adjacent Yipin Hall) alongside its own exclusive Nanyang region, complete with a bandit mountain stronghold. New characters are dropped into one of several random starting scenes, such as the Dragon Gate Inn, and each weapon discipline (sword, blade, fist, qinggong, whip, polearm) levels independently; quitting within 30 minutes of character creation forfeits the save by design, not bug.

README

在线试玩

https://mudlibs.fluffos.info/xajhxo/

管理员账号 / Admin account

警告:这是一个公开的默认密码,仅供本地/浏览器试玩。正式对外开服前
请务必修改此默认密码。

本地运行

cd libs/xajhxo
~/src/fluffos/build-debug/src/driver config.fluffos

游戏端口:40069。

NOTES · 移植与修复记录

xajhxo — 笑傲江湖XO (The Smiling, Proud Wanderer — "XO" build)

Archive: 笑傲江湖XO .rar (note trailing space in the archive filename before .rar). Port: 40069. Status: done (boots clean, full registration flow verified end-to-end with a real Chinese name, ordinary post-login commands look/score/i all confirmed working per §15ae policy).

Raw root: 笑傲江湖XO .rar extracts to a single top-level xo/ directory (4922 files) — config self-names the mud simply 笑傲江湖 (matches the archive's own title, no site-branding difference to note).

Lineage confirmation (verified via diff/md5sum, per explicit instruction)

Confirmed same TMI-2/ES2 (Falcon) lineage as both prior "XO" family libs — libs/xo/ (archive #28, "笑傲江湖迷你版"/mini edition) and libs/xo_final/ (archive #29, "XO 最终版1.2"/final build) — via the identical header credit line in secure/obj/master.lpc:

// Original from TMI-2 and ES2
// Rewritten by Falcon 96-10-02

(byte-identical wording to what libs/xo/NOTES.md already documented for archive #28). This is a genuine third, independent snapshot in the same lineage — not a duplicate or simple size-variant of either sibling:

Fixes applied (with why)

1. AGENTS.md §4 (lazy security-daemon load recursion guard) — secure/obj/master.lpc's valid_write/valid_read called load_object(SECURITY_D) unconditionally on every single call (catch()-wrapped but with no find_object() gate or re-entrancy flag) — identical shape to the exact bug already fixed on sibling xo. Applied the same guard: check find_object() first, and a nosave re-entrancy flag so a disallowed/failed load degrades to a safe default (1 for read, 1 for write once already loaded) instead of recursing. Applied proactively before first boot given the recognized lineage. 2. AGENTS.md §15h (GBK byte-range Chinese-detection bug) — applied in THREE places: - secure/simul_efun/chinese.lpc's is_chinese(): str[0] > 160 && str[0] < 255 (GBK lead-byte range) → CJK Unicode codepoint range (str[0] >= 0x4e00 && str[0] <= 0x9fff). Also relaxed the length gate from strlen(str) >= 2 to >= 1, since logind.lpc's sliding-window caller (is_chinese(name[i..<0])) legitimately passes single-CHARACTER substrings under UTF-8 (the original >=2 assumed "1 Chinese char = 2 GBK bytes", which no longer holds). - secure/sefun/chinese.lpc (the orphaned/unreachable duplicate, confirmed nothing loads secure/obj/sefun.lpc): same fix applied as cheap insurance, in case anything non-obvious ever does load it. - system/daemon/logind.lpc's check_legal_name(): halved the byte-calibrated length bound (strlen(name) < 4 || > 10 → < 2 || > 5, matching what the message text already says: "必须是 2 到 5 个中文字"), and dropped the i % 2 == 0 && byte-offset gate in the per-character sliding-window loop (every UTF-8 index is already one full character, not every-other byte). These three together are what let a REAL Chinese name (verified: 秦风, 秦岭, 秦风三 across 3 independent test runs) actually pass registration instead of being silently rejected — confirmed via live interactive test, not just code inspection. 3. AGENTS.md §15g (case-sensitive #include <Action.h>) — 3 files (system/feature/command.lpc, system/feature/lcommand.lpc, cmds/wiz/localcmds.lpc) #include <Action.h> (capital A) but the real file on disk is include/action.h (lowercase) — same root cause already documented on sibling xo (a different specific file list, but the identical bug shape), found via the lpcc sweep's dominant "Undefined class 'Action'" failure cluster. Fixed all 3 include directives to the correct case. 4. New: class Action was never actually DEFINED anywhere in this archive (only ever referenced as a return/parameter TYPE in add_action.lpc/lcommand.lpc) — confirmed by grepping the whole tree for a real class Action { ... } struct declaration and finding none, even after fix #3 corrected the file-case issue. Cross-checked sibling xo's include/action.h and found it DOES carry the real struct ({ string verb; string ob; string func; }), matching exactly the fields this archive's own add_action.lpc accesses (Action->verb/->ob/->func). Ported the struct verbatim from xo into this lib's include/action.h — this is lineage evidence, not a guess (see the "Lineage confirmation" section above: this snapshot independently lost a piece of plumbing xo still has). 5. AGENTS.md §8g variant (missing macro, not missing file) — three separate instances found via the lpcc sweep: - GROUP_TASK — referenced (inherit GROUP_TASK;) by 42 files under system/task/, never #defined anywhere, despite the real target file (/system/std/group_task.lpc) existing on disk. This ONE missing macro was the single highest-impact fix of the whole pass — it alone accounted for 42 of the initial 144 lpcc-sweep failures. Added #define GROUP_TASK STD_DIR "group_task" to globals.h. - EXERT_DIR — referenced by 6 files under system/skill/{exert, shaolin,wuliang,xkdao}/, never defined, despite the real /system/skill/exert/ directory existing. Added #define EXERT_DIR "/system/skill/exert/". - ZUOJI — referenced (inherit ZUOJI;) by 3 files (mount/steed NPCs: clone/npc/horse1.lpc, horse2.lpc, u/xli/obj/ baobei_zhu.lpc), never defined, despite the real target (/system/std/char/zuoji.lpc, a genuine "standard mount" base class per its own header comment) existing. Added #define ZUOJI STD_DIR "char/zuoji". 6. New: class task's field names never matched what actually uses the class — include/task.h's class task defined lowercase fields (need_save/name/verb/target/event/begin_time/task_end) that NOTHING in the whole archive ever reads or writes (confirmed via grep), while the only two real consumers of class task (system/std/task.lpc's GetTask(), system/feature/task.lpc's AddTask/GetTask/etc.) exclusively access a completely different, PascalCase field set: TermType, KeyName, Verb, Target, Event, Birth, TaskEnd. This ONE mismatch cascaded into 45 of the initial 144 lpcc-sweep failures (every top-level file that transitively loads system/std/task.lpc, e.g. any NPC using the task system). Fixed the struct to the field set both real consumers already use, verified safe since nothing legitimately needed the old field names. 7. New: d/place/hami/npc/hami.npc was completely absent — 8 files under d/place/hami/npc/ (yizhang.lpc, afanti.lpc, huosan.lpc, mmaiti.lpc, laoban.lpc, nvren.lpc, woldman.lpc, kid.lpc) #include "hami.npc" (quoted, same-directory convention) for their shared inherit NPC; + ask_where() helper, but the file genuinely doesn't exist anywhere in the raw archive. Reconstructed verbatim (not fabricated) from sibling xo_final's byte-for-byte-matching d/place/hami/npc/hami.h (see lineage section above — its own header comment literally reads // hami.npc, confirming it's the same content under a renamed extension in that later snapshot). 8. New: d/city/yangzhou/npc/cloth/cloth.lpc missing #include <armor.h> — the only one of 169 files inheriting CLOTH across the whole lib that omitted the include every other one has; a one-off copy-paste omission. Added the missing include line. 9. New: d/place/wiz/inn_hall.lpc's inherit LIB_ROOM; referenced a macro/base class defined NOWHERE in the archive — the file's own SetShort()/SetLong()/SetExits() calling convention (PascalCase, argument-taking) is used by no other file in the whole lib (11 other files call a no-argument SetLong() from their own zone-specific shamo.h, an unrelated shape). The room's own author had already tried and commented out //inherit ROOM; right above the broken line — reverted to that (the base class that's actually defined and used successfully by every other room in the lib) and converted the 3 Set*() calls to the standard set("short"/"long"/"exits", ...) idiom, rather than fabricate a whole new LIB_ROOM base class. 10. AGENTS.md §3 counterexample (found again, larger this time) — the blanket \bstatic\b → nosave sed collateral-damaged 16 unique log-path string literals across 14 files ("static/usage", "static/wiz_usage", "static/wiz_login_err", "static/purge", "static/command_limit", "static/promote", "static/ multi_login", "static/action_log", "static/create_room_fail", "static/CALL_PLAYER", "static/promotion", "static/QIUHUN_MSG", "static/BLOCK_CHANNELS", "static/SUICIDE", "static/ DIE_PLAYER", "static/yipin_log"), rewritten to "nosave/...". Confirmed the real log/static/ directory exists in the raw archive with genuine seed data (log/static/usage, log/static/ wiz_login_err, log/static/wiz_usage) that these path references were supposed to point at. Reverted all 16 occurrences across all 14 files back to "static/...". 11. AGENTS.md §15w (log_error warning-spam) — secure/obj/ master.lpc's log_error() broadcast every message reaching it (including harmless compile WARNINGS like "Illegal to declare nosave function", a direct side-effect of this project's own static→nosave fix) to the connected player, exactly matching the documented pattern. Gated the player-facing efun::write() broadcast on the message not containing "warning:" — still logs everything to file regardless. 12. §15ab-style defensive hardening (2 spots, insurance not reactive fixes) — secure/simul_efun/file.lpc's cat() (write(read_file( file)), no guard) and clone/user/login.lpc's receive_message() (no !stringp(str) guard) both match the documented "unguarded write(read_file()) can crash a fresh connection" shape from xjcq2000/haiyang2. All files these two currently reach (WELCOME/ MOTD/new_player) DO exist, so this wasn't an active crash — but it's cheap, matches established precedent, and closes the risk if any future edit ever points cat() at a missing file during the login sequence. 13. ~12 individual pre-existing content typos, found via the lpcc sweep and fixed after confirming each against raw pre-conversion bytes (not blind edits): - system/skill/shaolin/mohe-zhi.lpc, system/skill/misc/ yuanyang-dao.lpc, system/skill/misc/taizu-quan.lpc (2 spots), d/menpai/shaolin/npc/dd.lpc, d/city/nanyang/npc/guo.lpc, d/zuzhi/yipin_tang/dixia/shuangqi.lpc, d/zuzhi/yipin_tang/ dixia/suni.lpc: missing-closing-quote bugs, several confirmed via raw-byte inspection to be the exact "iconv -c's invalid-byte recovery ate an adjacent REAL byte too" gotcha already documented for xo_final (an orphan single byte sitting where the second byte of a 2-byte GBK closing-bracket/quote character should have been) — reconstructed each closing quote/bracket from the raw bytes and/or sibling entries' established pattern, not guessed. - d/city/lanzhou/chanfang.lpc: a fullwidth space (U+3000) used as function-call whitespace (set( "search_things") — illegal at that syntax position; replaced with a normal space. - d/place/xkdao/npc/obj/hare.lpc, d/zuzhi/yipin_tang/peacock/ xuanwu_tang/npc/tuzhong1.lpc: fullwidth commas (,) used as array-element separators inside actual code (AGENTS.md §9 pattern) — replaced with ASCII commas; hare.lpc also had one element using a mismatched '... single-quote instead of "...". - d/city/chuzhou/npc/whorehouseboss.lpc: set("negative_score', 3000) — opened with ", closed with ' (mismatched quote type), cascading into "End of file in string"; fixed to a matching pair. Same file also had a set_xiuwei_by_tyep typo (→ set_xiuwei_by_type, the real function 438 other files call correctly). - d/menpai/duanshi/npc/obj/yaopai2.lpc: a genuinely corrupted duplicate array-element fragment ("/d/map/xinan/ with no closing quote, immediately followed by the real, complete element on the next line) — confirmed present in the RAW archive too (not a conversion artifact); deleted the broken duplicate line. - d/zuzhi/yipin_tang/xuanwu_tang/diaolan.lpc and its duplicate at d/zuzhi/yipin_tang/peacock/xuanwu_tang/diaolan.lpc: both called a bare undefined("exits/out") (never a real efun/simul_efun on this driver) where the evident intent was "is exits/out NOT set" — fixed to !query("exits/out"). - system/menpai/wuliang/zuo_zimu.lpc, d/menpai/wuliang/npc/ zuo.lpc, d/menpai/wuliang/west/npc/xin_shuangqing.lpc, d/menpai/wuliang/backup/npc/xin_shuangqing.lpc: all 4 files share an identical copy-pasted "姓名" (character-name) dialogue string missing its closing quote before the field-separator comma — fixed all 4 with the same closing-quote insertion. - 4 orphaned help-text/map files renamed away from a misleading .lpc extension (AGENTS.md §12 pattern — plain text, never #included/load_object()d by anything, confirmed via grep): help/wizard/format.lpc → .txt, help/wizard/chelp/ref/ lpc.lpc → .txt, help/wizard/chelp/concepts/lpc.lpc → .txt (these 3 were pre-named .lpc in the RAW archive itself, not created by our rename script — a pre-existing naming quirk, not conversion fallout), and d/city/dali/dalimap.lpc → .txt (a pure ASCII-art city map, same shape as the shenmin map precedent already documented for a different lib). - Two files (d/nanyang/suishi.c/d/city/nanyang/suishi.c) needed a direct manual iconv -f GB18030 -t UTF-8 -c pass — convert_lib.sh's per-file conversion left them as raw un-converted GBK bytes (misdetected by file's heuristic despite the forced-text-extension fix already in the script, per the known encoding-detection caveat) — re-verified UTF-8-valid after manual conversion, and re-checked for .c"/static references (none found, nothing else to fix in either file).

Confirmed NOT needed (checked via source read, not assumed)

Interactive test result — full registration + post-login flow

Read system/daemon/logind.lpc's actual logon()/get_id()/ confirm_id()/get_name()/new_password()/confirm_password()/ get_email()/get_gender()/enter_world() callback chain before scripting the test (per instructions, not inferred from prompt text). Sequence confirmed: connect → English id → y/n new-character confirm → Chinese name → password → confirm password → email → gender (m/f) → dropped into a randomly-selected start room (select_start_room() picks among 4 real rooms).

Ran the full flow 3 times, each in one continuous mudclient.py connection (2 initial runs, 1 more after the later include/task.h and include/action.h fixes to confirm nothing broke):

1. qinfeng → y → 秦风 (real Chinese name, accepted immediately — direct proof the §15h fix works, not just that the prompt renders) → password/confirm/email → m → entered 宫城外 (Gaochang city outskirts) with correct room description → look (repeated the same correct room description — confirms add_action's command_hook dispatch is genuinely working) → quit → correctly gated behind the lib's own "must play 30 minutes before data saves" confirmation (y/n), not a bug. 2. qinling → y → 秦岭 (different real Chinese name, female) → ... → f → entered 太白楼 (a DIFFERENT start room — confirms select_start_room()'s randomization works) with NPCs (小三, 段无畏) rendered in the room → look (correct repeat) → score (full character sheet: gender-correct "十四岁的女性人类", all 7 skill categories at 零级, kill counts, 杀气/师门忠诚度/实战经验/ 江湖阅历/武林声望 all rendering real Chinese text correctly) → quit gate again. 3. (Re-verification after include/task.h/include/action.h/globals.h fixes) qinfengsan → y → 秦风三 → ... → m → entered 宫城外 again → look → score → i (inventory: correctly showed 青布衣衫 — the auto-equipped starting cloth from enter_world()) → quit gate.

grepping log/debug.log after each of the 3 sessions for error|denied|bad argument|undefined|crash|segfault|recursion turned up zero real hits in all 3 runs (only expected config-dump lines like error_handler : 1 and the harmless compile-time nosave warnings).

lpcc sweep

4304 total .lpc files (4308 initially, minus 4 renamed to .txt as orphaned non-code text per fix #13). 4202 pass / 102 fail (97.6%), up from an initial 4132/4308 (95.9%) before this pass's fixes.

Memory stayed healthy throughout 3 successive sweep runs (peaked ~2.9GB RSS on the lpcc process, host never dropped below ~5GB free even with 2-3 other concurrent agents' sweeps running at the same time) — this lib did NOT reproduce the unusually heavy per-file memory footprint noted for xo_final at a similar file count.

Remaining 102 failures, triaged by category (none further fixed, consistent with AGENTS.md §6b — shared/systemic root causes are fixed, the long tail is documented):

What this confirms for future agents

If another "笑傲江湖"/XO-titled archive turns up later in this project, check it against all THREE now-processed XO-lineage libs (xo, xo_final, xajhxo) via the same diff/md5sum discipline — this pass confirms the lineage has at least 3 independently-evolved snapshots, not just 2, and world-content sharing (skill files, zone NPCs) doesn't always correlate with which sibling a new snapshot's core security/master files most resemble.

Re-verification pass: driver rebuild + formatter + WASM (2026-07-23)

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, "localhost", or an empty/non-string value (covers older WASM query_ip_number()/query_ip_name() garbage). Gates patched:

Admin seed: registered fluffos / display 浮浮 / password Mud@2026 through the real flow (id → y → Chinese name → password x2 → email → gender m → random start room; enter_world() saves both the user and login objects immediately, so no quit-gate interaction). Granted (admin) by appending fluffos (admin) to /secure/etc/wizlist (the WIZLIST file, include/login.h). Verified after reboot: login as fluffos → update /system/daemon/band → "重新编译 ...成功!".

Retest: fresh normal registration (qfxoab / 秦风) 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; data/user/f/ and data/login/f/ are NEW directories):

WASM 修复摘要(迁移自 meta.json 的 group_note)

同一个 XO 血统,第三份快照。状态已从过时的 limited 修正——这份档案自己的 README 里从未记录过任何缺陷说明,本轮重新测试也没有发现:管理员登录(fluffos/Mud@2026)干净正常,"目前权限:(admin)"。

§7.86 跨库扫描修复(留言板 post 崩溃)

深度功能测试 / Deep functional test (2026-08-07)

第一次真正的完整游玩测试。测试角色最终定格在 xajhthr(中文名 秦岭三, 女),另有一个更早的测试角色 xajhtwo(秦岭,男,无量剑派东宗第六代弟 子)在验证"初次30分钟内quit会清空存档"这个既定设计时被系统正确删除, 细节见下。本轮 WASM 未重新验证:emsdk 工具链下载硬编码指向 storage.googleapis.com,本次会话的出口代理策略性拒绝该域名(403,已用 curl $HTTPS_PROXY/__agentproxy/status 确认是策略拒绝而非临时故障), 本地无法构建 WASM 驱动。之前 WASM 测试记录里提到的"性别选择之后角色创 建有时卡住、有时重复循环"的问题,这一轮在原生驱动上找到了真正的根因 (见下方"发现并修复"第一条)——这不是 WASM 专属的时序抖动,是一个 一直存在、原生驱动同样会触发的真实崩溃,只是这份档案自己的错误处理 机制把崩溃现场写进了一个此前没人查看过的独立日志文件,而不是 debug.log,导致此前的排查方向被误导。

发现并修复:每一个新玩家在创建人物流程的最后一步(选择性别之后)都会静默崩溃,从未真正进入游戏世界

`` *Wrong permissions for opening file /log/static/usage for append. "No such file or directory" 'get_gender' at /system/daemon/logind at line 422 'log_login' at /system/daemon/logind at line 678 'log_file' at /secure/obj/simul_efun at /secure/simul_efun/file.lpc:17 ` logind.lpc 的 get_gender()(设置完性别后)先调用 log_login(ob, user, ...) 记录新玩家日志,log_login() 又调用 simul_efun 的 log_file(PPL_USAGE_LOG, ...)(PPL_USAGE_LOG 宏是 "static/usage"),而 log_file() 只是裸的 write_file(LOG_DIR + file, text),从不检查 /log/static/ 这个 目录是否存在——而这个目录根本不存在于这份档案里。这一步崩溃 发生在 get_gender() 函数体的最开头,init_new_player(user) 和 enter_world(ob, user)`(真正把玩家送进游戏世界的调用)都排在这次 崩溃之后,从未有机会执行——每一个新注册的玩家都会在这里卡死, 不是偶发的时序问题。

``lpc void log_file(string file, string text) { assure_file(LOG_DIR + file); write_file(LOG_DIR + file, text); } ` 这个 secure/simul_efun/file.lpc 文件本身还有一个 orphaned 的孪生 副本 secure/sefun/file.lpc(确认没有任何代码 #include 或加载它, 与此档案自己 NOTES.md 之前记录的"重复 sefun 目录"是同一批遗留文件) ——同样的修法作为廉价保险也一并应用了。 修复过程中还发现:assure_file()在物理上定义在log_file()之 后,加上调用它需要一个"先声明后使用"的前置原型(这份档案的编译 器不支持在同一文件里调用尚未出现在源码前面的函数——logind.lpc 文件头部本身就有一长串private void xxx(...)这样的前置声明,是这 份代码库自己的既定写法):第一次只加 assure_file()调用而没加前置 声明,编译报错Undefined function assure_file——按同一惯例在文件 开头加了一行void assure_file(string file);`补上。

发现并修复:少林寺方丈(本派拜师环节的关键 NPC)因为一处技能名拼写错误,从存档诞生起就从未真正出现在他自己的房间里

`` *F_SKILL: No such skill (shalin-xinfa) 创建房间中的物体失败, 详见 room_log ``

``lpc set_wugong("shalin-xinfa", 200); ` ——技能名拼成了"shalin",少了一个"o"。system/skill/shaolin/ shaolin-xinfa.lpc(正确拼写)确实存在,证明这是纯粹的拼写笔误, 不是故意改名或缺失内容。set_wugong()对一个不存在的技能名会直接 抛出未捕获的错误,而这一行排在 create_family("少林派", 36, "掌门 方丈")之前——玄慈的整个create()`在能把自己注册为少林派掌门 之前就先崩溃了,导致这个对象连同"少林派"这个门派的掌门归属,从这 份档案诞生起就从未真正被创建过。全档案搜索确认这个拼写错误只出现 这一处。

观察但未处理(超出"仅修程序 bug"范围)

测试内容与结果

§7.100 扫描修复(ROOM 基类多余 replace_program())

#define ROOM STD_DIR "room"(STD_DIR = /system/std/,宏名本 身仍是字面量 ROOM,源码里的调用不受拼接影响):删除 439 处多余 的、独立成行的 replace_program(ROOM);(保留 inherit ROOM;), 438 处脚本自动删除;另 1 处在本库房间建造工具 clone/wizard/roommaker.lpc"克隆我所在的房间"命令的字符串拼接模 板里,已同步手动修正。help/wizard/es/help/roommaker 是纯文本帮助 文档,不含该 bug 模式,无需处理。work/data 下未发现额外 .lpc 源文件。修复后全库仅剩 52 处历史遗留的 //-注释掉实例,均确认无 害、未改动。已用 build-debug 驱动干净启动验证(0 个新增编译错误 ,端口 40069 正常监听,debug.log 无新增 "cannot replace"/ "cannot bind" 行);未做完整 §10.7 深度游玩测试。

深度功能测试第四轮 / Round-four §10.7 deep test (2026-08-20):真实战斗致死/复活流程

补全上一轮(2026-08-07)从未真正测试过的一环:真实战斗导致角色死亡、 经过判官轮回流程、最终复活重新落地游戏世界的完整循环。全程同时监视 log/debug.log(驱动默认日志)和 log/runtime(这份档案自己的 error_handler() 改写落点,上一轮正是靠查看这个文件才找到注册崩溃 的真正根因,本轮同样全程盯着)。

死亡机制确认(两段式 kee/eff_kee 模型)

读 system/std/char.lpc 的 heart_beat() 确认了这份档案的死亡判定 逻辑:eff_kee/eff_sen/eff_gin 任一 < 0 时直接 die();kee/ sen/gin 任一 < 0 时(存活状态下)先 unconcious(),非存活状态才 die()。这是与本项目其它一些库(如 xyxy2)相同形状的两段式生命值 模型。用管理员 call qxverify->set("eff_kee", -1) 给测试角色注入一次 性负值(临时数值授予,未绕过真实 die()/heart_beat() 代码路径), 接下来完全依赖真实的、未修改的 heart_beat() 心跳循环触发 die()—— 测试确认心跳只在角色有活跃在线连接时才会真正跳动(断线角色的心跳不 会推进死亡判定),角色保持连线在场时,等待几秒后角色真实死亡("你死 了","【谣言】秦验证莫名其妙的死了"),移动进入 DEATH_ROOM (/d/place/death/yellow1,"黄泉路"),is_ghost() 变为 1。

发现并修复:查察司判官 chacha.lpc 的死亡轮回状态机有一条退出分支忘记清理重入守卫,导致携带任何物品死亡的鬼魂永久卡死、再也无法投胎——本轮任务重点排查对象,找到了真实缺陷

``lpc if (sizeof(obs)) { command("hmm"); tell_object(ob, HIW "判官说道:“不过阴间的东西是不能带到阳间的,你先要把你身上的东西放下来。”\n" NOR); ob->delete_temp("death_stage_active"); return; } ` 这是最小、行为一致的修复:清理守卫以后,玩家扔掉东西、离开房间再走 回来会重新触发init()→check_rein()→death_stage()整条链,这次 deep_inventory()`已经是空的,直接走向正常完成分支。

标准检查清单快速过一遍(预期多数已修,仅确认)

结论

本轮任务明确要求的"真实战斗致死+复活"缺口已补全:找到并修复了一个 真实、可复现、静默的程序缺陷(chacha.lpc死亡轮回状态机的重入守 卫在物品检查分支遗漏清理,导致携带物品死亡的鬼魂永久卡死、两条投胎 路线同时失效),修复经过全新测试角色从死亡到复活的完整实测验证,两 份日志文件全程干净无新增。标准检查清单六项全部确认(一项已修实无需 再动、四项确认不适用/设计正常工作、一项就是本轮的核心发现)。

String corruption !\xee\x93\xa2n cleanup (2026-09-03)

Same convert-era byte corruption as the waiter !”\n / !\n → ! + private-use U+E4E2 + literal n shape. Fixed in: waiter.lpc (nanyang + city/nanyang), huilun.lpc, system/feature/command.lpc.

深度功能测试(§10.7,2026-10-04)— negative range ends

scripts/lpc_fix_negative_ranges.py: 4 line(s) in 1 file(s) count a range from the end with < (x[a..-1] -> x[a..<1], x[-2..] -> x[<2..]; KB 06 §7.209). In this driver a negative constant end gave "" / ({ }) and a negative start the whole value, so each of these returned the wrong slice; the compile warning A negative constant as the second element of arr[x..y] is gone from the files that compile. Range lvalues (s[0..-1] = text, the prepend idiom) are left alone. A paired compile of the changed files at HEAD and in the working tree showed no new error.

深度功能测试(§10.7,2026-10-07)— 兵器的 actions 函数指针

set("actions", (: WEAPON_D, "query_action" :));:旧 MudOS 把 (: 字符串, "函数" :) 当作 call_other 函数指针,本驱动把它当作表达式函数指针,求值只得到字符串 "query_action"。没有对应兵器技能时 feature/attack.lpc 直接用兵器的 actions,COMBAT_D 拿到的不是 mapping,reset_action() 后仍不是,记一条 bad action 就不出招——拿着这些兵器打不出攻击。改成别的兵器早已用的 (: call_other, WEAPON_D, "query_action" :)(KB 04 §6.10):d/menpai/wuliang/west/npc/obj/flower.h、d/menpai/wuliang/backup/npc/obj/flower.h。改动的文件在 HEAD 与工作树分别加载(新进程),无回退。

深度功能测试(§10.7,2026-10-07)— 编译警告整理

scripts/lpc_warnings.py xajhxo --fix 加 scripts/lpc_fix_no_effect.py --apply,共改动 245 个 .lpc 和 15 个 .h(多为删去未用的局部变量)。HEAD 与工作树分别加载(新进程):222 -> 222 通过,无回退;改过的头文件的 26 个包含者 24 -> 24 通过。 手改两处,把只在条件编译里用到的局部变量声明挪进同一个 #ifdef:system/daemon/logind.lpc get_id() 的 my_ip(ALLOW_MULTI_LOGIN),system/daemon/combatd.lpc 里与全局 debug 同名的局部 debug(DEBUG)。启动时警告 31 -> 0;新进程登录(新人物确认)正常。

深度功能测试(§10.7,2026-10-08)— .lpc 后缀的定宽切片

.c 改名 .lpc 时只改了字符串没改切片宽度:f[<2..] == ".lpc" 拿两个字符比四个字符,永远不成立(!= 永远成立),按后缀筛文件、去后缀的代码因此从不运行或截成 x.l(KB 06 §7.238)。scripts/lpc_lpc_suffix_slice.py --apply 改了 2 处比较、2 处去后缀(如 system/daemon/helpd.lpc);改动的文件 HEAD 与工作树分别加载(新进程),无回退。

深度功能测试(§10.7,2026-10-11):“无副作用表达式”警告复查

编译警告收尾(2026-10-13)

手工清零(scripts/toolkit_fix.sh 去掉 clone/wear/finger/finger.lpc 一处多余继承);改动的 6 个对象在 HEAD 与工作树各载入一次,regress 0。

转码吃掉的引号(2026-10-15,KB 03)

原档在右引号前有一个孤立的 GBK 前导字节,转 UTF-8 时连引号一起丢了(如 return name + HIM "发作身亡了;),字符串一直延续到后面,文件编译失败:/d/menpai/shaolin/npc/master。补回引号(scripts/lpc_fix_eaten_quote.py)。

补(同日):这处修改当时漏提交了(提交时只取了 .lpc),现补上;这个头文件目前没有文件引用。

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。3 处补上 if (!mapp(fam)) fam = ([ ]);(刚 recruit_apprentice() 之后的除外)。

NPC 带着本库没有的物品,载入失败(2026-10-15,KB 06 §7.73)

11 个文件、20 处在 create() 里 carry_object("<本库没有的文件>")->wear()(或 wield()、set_amount()):carry_object() 得 0,接着的调用报 Bad argument 1 to EFUN call_other(),NPC 根本载入不了,该有它的房间里就少了这个人。多是从别的系统搬来的 NPC 用了原系统的物品路径(最常见:/d/city/lanzhou/clone/obj/cloth1、/d/menpai/wuliang/obj/cloth、/d/city/capital/obj/wuyun_xue)。每处改为 { object carried_ob = carry_object(...); if (carried_ob) carried_ob->wear(); }(scripts/lpc_guard_carry_object.py):NPC 照常出现,只是不带这件东西;文件补回来(或是虚拟对象)照样会带上。载入检查:改动的文件改前能载入 8 个,改后 8 个(0 个原来载入不了),没有退步;其余 4 个另有原因(多为 set_skill() 了本库没有的武功)。

通向不存在房间的出口,按对面房间的回头出口改正(2026-10-18,KB 06 §7.257)

房间出口 "west": __DIR__"xxx" 指向的文件本库没有,玩家走过去就被卡住(笔误、改过名的房间,或者没带进档案的编号房间)。对面的房间存在、并且它相反方向的出口正好指回这个房间,说明出口原本就是通向它:/d/zuzhi/yipin_tang/peacock/xuanwu_tang/midao 的 down:yandong1.lpc → yandong。改动后每个出口都能解析到本库的文件(scripts/lpc_fix_dead_exits.py;目标在运行时本来就能载入的库——虚拟房间——不动)。

调用了父类没有的函数的对象(2026-10-19,KB 06 §7.259)

::create();、::init();、return ::buy_object(who, item); 这类调用写的是父类里有这个函数的版本;本库的父类没有,旧驱动把它当空操作(返回 0),现在的驱动在编译时就报 Unable to find the inherited function,整个对象载入不了。单独成句的调用删掉,return ::f(...) 改成 return 0;(void 函数里是 return;),与旧驱动的行为一致。共 1 处、1 个文件:::valid_teach()(1 处)。只改了出错原因全是这一类的文件;还带着别的错误(多半是父类本身没了)的文件没动,等父类补回后再看。(scripts/lpc_fix_dangling_super.py)

全局头文件丢了 1 个宏(2026-10-19,KB 04 §6.16)

/include/globals.h 里没有定义 YIPIN_D,用到它们的物件(名单里 2 个)编译时报 Undefined variable/Undefined function,整个物件载入不了(编译器在第一个未定义的名字上停下,后面的错误和警告都看不到)。同系的库在各自的头文件里都有这几行:照其中和本库共有文件最多的那个库,原样补到 /include/globals.h 最后一个 #define 之后,宏体里出现的路径在本库里都存在。补完后名单里有 2 个载入,其余还差别的东西。(scripts/lpc_restore_defines.py)

手工收尾(2026-10-19,KB 04 §6.10)

逐个与 HEAD 对比载入,没有退步。

补回丢失的标点(2026-10-19,KB 03 §4.6)

转换时丢掉的分号、逗号、引号或文件末尾的 },共 6 个文件,修前 HEAD 载入失败。别的库里同路径的完好副本只比这里少几个标点,按它补回(括号里是那个库):/d/city/capital/dxgs_yuan1.lpc(xajh2)、/d/menpai/wuliang/npc/obj/xing.lpc(xajh2)、/system/condition/deadlife.lpc(xajh2)、/system/condition/deadlife.lpc(xo_final)。文件末尾少了 }(最后一个或两个字节丢了),补上:/d/city/capital/obj/food/gourou_baozi.lpc(2 个)、/d/place/xkdao/npc/tu.lpc。修后与 HEAD 逐个对比载入:这 6 个物件全部载入,没有退步(scripts/lpc_restore_from_twin.py、lpc_fix_eaten_quote.py --comma、lpc_fix_eof_braces.py)。

旧驱动的类型宽松:缺省参数、无类型形参、数组初始化、class 变量(2026-10-19,KB 04 §6.19、§6.20)

原来的 MudOS 把调用少传的参数补 0、把没写类型的形参当 mixed、不检查变量的声明类型与初始值,也允许变量叫 class;这个驱动在编译时全部拒绝,整个物件载入失败。修了 2 个文件:/d/zuzhi/yipin_tang/peacock/xuanwu_tang/develope/boat.lpc、/d/zuzhi/yipin_tang/xuanwu_tang/develope/boat.lpc(scripts/lpc_round_files.py 的修复轮:调用处补写 0、无类型形参补 mixed、string X = ({...}) 补星号、void 函数的返回值,以及 class 变量改名 pick_class)。逐个文件在 HEAD 和改后载入对比:这些文件里 0 个原来载入失败、现在载入,没有退步。

无量剑派掌门:wl-shenfa 改成 wuliang-shenfa(2026-10-19,KB 06 §7.258)

system/menpai/wuliang/ 里 zuo_zimu.lpc、qu_lianxing.lpc、rong_ziju.lpc 授的 wl-shenfa 本库没有这个技能(只有 system/skill/wuliang/wuliang-shenfa.lpc,同目录 shang_yuqing.lpc 和 wuliang_d.lpc 写的都是它),create() 里 F_SKILL: No such skill 把物件中止。改成 wuliang-shenfa 后 zuo_zimu.lpc 载入(修前失败)。qu_lianxing.lpc、rong_ziju.lpc、shang_yuqing.lpc 往后一步因 parry(本库没有这个技能文件)失败:system/feature/skill.lpc 的 set_wugong() 对没有文件的技能 error()。set_wugong() 开头加 if (!valid_skill(skill)) return 0;(同文件的 set_xiuwei() 早已这样处理),物件照常载入,只缺这一项技能(KB 06 §7.256)。授了缺失技能的物件(活目录里)共 9 个,修后在 system/menpai/ 和这些物件上对比 HEAD 与工作树:载入 29 → 34(zuo_zimu、qu_lianxing、rong_ziju、shang_yuqing 和 weishi2),没有回归,没有警告;system/menpai/biaoju/ke.lpc 仍失败(另一个原因,没有动)。

if (x = 常量):条件里写成赋值的比较(2026-10-20,KB 06 §7.290)

if (arg = "button" || arg = "按钮")、if (!arg || arg = "") return 0;、else if (check = 0 && tempB != ""):把 == 写成了 =,条件的值就是那个常量,分支对所有非零数和任何字符串(连 "" 都算)永远成立、对 0 永远不成立,变量还被覆盖;驱动对此没有任何警告。每一处 = 改成 ==(scripts/lpc_fix_cond_assign.py,共 1 处)。改动:/d/city/yangzhou/shufeng_guan.lpc(1 处)。

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 当参数的扫描发现的。/secure/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)。改动:/system/feature/more.lpc。

巫师命令不带参数时对 0 调用 efun(2026-10-21,KB 06 §7.336)

巫师(管理员)把命令敲成不带参数时,驱动把 0 传给字符串参数;下面的命令第一句就把这个 0 交给 efun,运行时报 Bad argument 1 to ...,这条指令从来没有用过。用 scripts/lpcc_bare.py 不登录、在一次 lpcc 求值里以 0 调用 main() 逐个确认后,由 scripts/lpc_fix_bare_arg.py 在第一处使用参数的语句前加守卫:文件自带 int help(object me) 的,守卫是 if (!arg) return help(me);(help() 定义在 main() 之后的 2 个文件补了原型 int help(object me);,否则编译报 Undefined function help)。改动(2 个文件,括号里是接住 0 的 efun):/cmds/admin/changebody.lpc(present)、/cmds/admin/replace.lpc(get_dir)。加载检查 HEAD 与工作树对照,没有退步。

注册到不存在函数的 add_action,第二轮:宏路径父类和静态解析不了的对象(2026-10-21,KB 06 §7.349)

第一轮的静态解析读不了经宏路径继承父类的对象(#define ROOM STD_DIR "room/room" 这类定义的正文以另一个宏开头)和它解析不了的继承,这些对象当作 UNSURE 没有扫;第二轮修了解析器,重扫并对这些对象在运行时问 function_exists()。add_action("函数", "动词") 绑定的函数,在对象本身、它包含的头文件、它继承的父类和继承它的子类里都没有定义(scripts/lpc_scan_callout_targets.py 静态解析,子类用传递闭包复核,scripts/lpc_verify_handlers.py 运行时 function_exists() 复核)。驱动从玩家最新的一条动作往回找,遇到这样的句子就报 *Function for verb 'drop' not found.,同一个动词的其他处理函数不再尝试(不是最新的一条就悄悄跳过)。删除了 17 条注册(8 个文件,scripts/lpc_fix_dead_add_action.py),动词留给别的处理函数:/d/city/yangzhou/yuelao_ci.lpc(do_divorce)、/d/place/xkdao/npc/haidao.lpc(do_kill)、/d/place/xkdao/npc/tu.lpc(do_kill)、/d/zuzhi/yipin_tang/peacock/xuanwu_tang/xuanya1.lpc(do_droop、do_pull)、/d/zuzhi/yipin_tang/xuanwu_tang/xuanya1.lpc(do_droop、do_pull)、/system/std/room/hockshop.lpc(DoBuy、DoList、DoPawn、DoPawnlist等)、/system/std/room/kezhan.lpc(do_check、do_load)、/system/std/room/shop.lpc(do_list)。最多的函数名:do_kill 2 处、do_droop 2 处、do_pull 2 处、do_divorce 1 处、DoBuy 1 处。

(: 函数 :) 指针指向对象自己没有定义的函数(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。 还剩 4 个函数没有补(inquiry 4):原型还在函数体丢了、或者根本没写过,没有可以直接补回的捐赠(别的库同一路径的文件里没有这个函数,或者它还要用本库没有的辅助函数、签名不同),不编造:/d/menpai/shaolin/npc/xuwen.lpc:ask_armor2、/d/menpai/shaolin/npc/xuwen.lpc:ask_armor3、/d/menpai/shaolin/npc2/xuwen.lpc:ask_armor2、/d/menpai/shaolin/npc2/xuwen.lpc:ask_armor3。

不带前导斜杠的物品路径:缺失物品的 new() / carry_object() 调用链加了保护(2026-10-22,KB 06 §7.73 补充)

carry_object("d/city/obj/jiasha")->wear(); 这类路径不带前导斜杠的写法在这个驱动里按根目录解析(new("d/city/obj/changjian") 能加载 /d/city/obj/changjian),所以和带斜杠的一样:文件不在压缩包里时 new() 返回 0,->wear() 在 0 上报 Bad argument 1 to EFUN call_other(),整个 NPC 加载不了。此前的保护工具把这种写法当作「相对当前目录,没法判断」跳过了。1 个文件里 1 处(obj/cloth5)改成带保护的块(scripts/lpc_guard_carry_object.py)。 对这 1 个改动文件做加载检查(HEAD 与工作区对比):HEAD 能加载 1 个,现在 1 个(新增可加载 0 个,回归 0 个)。

(: 函数名 :) 指针指向本库没有的函数:只含这个指针的行加了注释(2026-10-22,KB 06 §7.355 补充)

inquiry / item_desc / chat_msg* 里的 (: 函数名 :) 指向本对象(含包含文件、继承的父类)没有函数体的函数:用到时(ask、look、NPC 闲聊)驱动抛 *Undefined lfun pointer called: 函数名,这一拍心跳的后半段被跳过。这些函数没有可以补回的来源(别的库同一路径的文件里没有,或者它还要用本库没有的东西),所以 2 个文件里 4 行只含这个指针的行("僧鞋": (: ask_armor2 :), "绑腿": (: ask_armor3 :),)加了注释,原文保留并写明原因,这一项当作没有这个话题 / 物品 / 闲聊条目(scripts/lpc_fix_dangling_lfun.py;#include 的文件在库里缺失的对象、指针不在整行上的写法没动)。 前提(function_exists())和加载检查(HEAD 与工作区对比,本库改动的 .lpc 文件)的结果见 KB 06 §7.355:没有一个回归。

汉字按字节切片的老写法没有换成按字符:改法名 "澄" + name[2..3]、辈分判断 name[0..1] == "澄" 等 2 处(2026-10-22,KB 06 §7.360)

原档按字节算字符串区间(一个汉字 2 字节):name[2..3] 是名字的第二个字,name[0..1] == "澄" 问名字是不是以「澄」开头。转成 UTF-8 之后,这个驱动的区间和 strlen() 都按字符算(strlen("澄观") 是 2,"澄观"[0..1] 是两个字),老算术原样留着、意思全变:拜入少林 / 武当 / 峨嵋等派的玩家被改成错误的法名(二字名 张三 变成一个字的 澄,更长的名字取到第三个字);各派掌门的辈分判断(name[0..1] == "澄")永远不成立。

本库 2 处(2 个文件):拼名字的赋值 1 处、与汉字常量比较 1 处。例:name[2..3] → name[1..1](/d/menpai/shaolin/npc/huijue.lpc:126);name[0..1] == "澄" → name[0..0] == "澄"(/d/menpai/shaolin/npc/xuanci.lpc:100)。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,不要重跑。

长度检查按字节写,旁边的提示按汉字写:7 处(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 你好吗)。本库 7 处(4 个文件):if (strlen(msg) > 20)(/clone/misc/chatroom.lpc:69);if (strlen(msg) > 30)(/clone/misc/chatroom.lpc:75)。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 区间 4 个文件。证明(scripts/lpcc_eval.py):sjplii 的 check_legal_name 在 HEAD 接受「张a」、改后拒绝,两边都接受「张三」;xkx100 的 clubpoem->mixup("离离原上草") 得到「离离原草上」(真交换汉字);nitan_san 两字同盟名得到 【 兄 弟 】。关键对象加载通过。

血条 / 表情标题按字节算显示宽度(2026-10-23,KB 06 §7.365)

老档把汉字当两字节:bar_string[0..(val * N / max) * 2 - 1] 把「格数」换成字节下标,半格血条在本驱动(按字符算区间)上会整条画满;巫师表情 edemote 的 repeat_string("─", 13 - (strlen(emotion) / 2)) 也会少减汉字宽度。scripts/lpc_fix_display_pad.py:去掉 CJK 血条 / 空白条上的 * 2(jings/qis 赋值和 blank_string3[0..(23-a)] 的 23→11 一并改),表情标题去掉 / 2;ASCII 空格的 none_string / empty_string 仍保留 * 2(一格两个空格)。本库 2 处(1 个文件)。证明(lpcc_eval.py hhsj):tribar_graph(6,9,12) 在 HEAD 画出整条 12 个■,改后为 6 个■+3 个□;麻将 strlen(tempB)/2 是两字符牌码,未改。

无参数时命令对 0 的调用(2026-10-27,KB 06 §7.336 Also)

巫师/管理员命令在通过权限门之后仍会把 0 交给 sscanf / read_file / find_living 等。lpc_fix_bare_arg.py 在首次使用参数前加上 if (!arg)(或 help(me) / GetHelp())。本库本批改动见该提交。

estate ROOM_HEAD 宏引号 / #inherit / dir / retrun(2026-10-27,KB 04 §6.25 Also)

system/daemon/estate 的 ROOM_HEAD/EXIT_STRING 宏里裸双引号打断 #define,模板写成 #inherit AREA,CreateRoom 用未定义的 dir,AddItem 写 retrun 且参数 class Location 本库无此类型。改为转义引号、inherit AREA、out_dir、return、mixed location。证明:HEAD 失败;改后加载。

深度功能测试(2026-10-27,§6.25 mooncake2 do_write 截断)

u/xli/mooncake2 同 xo:do_write 截断。用本库 mooncake 覆盖。证明:HEAD 失败;改后加载。

深度功能测试(2026-10-27,§6.25 tell_object 字符串目标)

xinfang/chatroom:tell_object("ob", …)→tell_object(ob, …)。

深度功能测试(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… 行。