The Smiling, Proud Wanderer (Mini Edition)

✅ 可玩

笑傲江湖(迷你版)

xo

🔑 fluffos / Mud@2026 更新 ac2a177 2026-09-03 源码 下载 ZIP

▶ 开始游玩 · Play Now

笑傲江湖(迷你版)是以金庸小说《笑傲江湖》为背景的武侠 MUD,属于 TMI-2/ES2(Falcon 系)引擎家族,是"笑傲江湖"系列里体积最小、内容最精简的一个版本(作者称之为"mini xo"):地图刻意做得极简,只有扬州城和一座码头小镇两座城市,可加入的门派也只有无量派一家,很适合用来体验这套引擎最原始、最基础的玩法框架;同批的"笑傲江湖最终版"(xo_final)与本档几乎逐文件沿用同一张地图、同一个无量派设定(差异只在少量文件的细节修改),再在此基础上大幅扩充出 10 座城市、16 大门派的更大世界。

English

A wuxia MUD set in Jin Yong's "The Smiling, Proud Wanderer," the smallest, most minimal build in this collection's xo series — the author's own "mini xo." The map is deliberately bare-bones: two cities (Yangzhou and a wharf town) and a single playable sect, the Wuliang (Boundless) Sect, making it a good look at this ES2/"Falcon"-family engine's basic framework stripped of content. Its sibling archive, the Final Edition (xo_final), reuses this same map and sect almost line-for-line (only minor per-file edits differ) while expanding it into a much larger world with 10 cities and 16 sects.

README

内容亮点

在线试玩

https://mudlibs.fluffos.info/xo/

管理员账号 / Admin account

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

本地运行

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

游戏端口:40023

NOTES · 移植与修复记录

xo — 笑傲江湖迷你版 (The Smiling, Proud Wanderer — Mini Edition)

Archive: xo.zip. Port: 40023. Status: done (boots clean, connects, plays through login into "create new character?" confirmation with zero crashes).

What this is

A different, smaller lineage from everything else processed so far in this batch: secure/daemon/master.c header says "Original from TMI-2 and ES2, Rewritten by Falcon 96-10-02" — TMI-2 ("The Mud International 2") is another classic MudOS-era mudlib base, distinct from the "ES II"/nitan families seen in archives #21-#26. Uses the secure/daemon/{master, sefun} path convention (not adm/obj/ or adm/single/). Small lib — 1395 .c files, "mini edition" as the name says. No set/query/ delete global simul_efun defined (like rzrmud/xkx2001) — every object provides its own via inheritance, the architecturally correct pattern (see AGENTS.md §15).

Fixes applied

1. AGENTS.md §4 (lazy security-daemon load): secure/daemon/ master.lpc's valid_write/valid_read called load_object(SECURITY_D) unconditionally on every single call (not gated behind find_object() first), wrapped in catch() but with no re-entrancy guard. Added the full guard (nosave flag + find_object() check before attempting load_object()) per the established §4 fix shape, applied proactively before the first boot attempt given the exact matching pattern. 2. New bug (case-sensitivity, Windows-origin archive on a case-sensitive Linux filesystem): 3 files (system/feature/char/ command.lpc, cmds/arch/ll.lpc, cmds/arch/localcmds.lpc) #include <Action.h> (capital A), but the actual file on disk is include/action.h (lowercase) — silently resolves on Windows' case-insensitive filesystem, hard-fails here. This was responsible for the overwhelming majority of the initial lpcc sweep's failures (762 "Undefined class 'Action'" + 155 "Cannot #include Action.h" out of 1395 files, cascading from just those 3 root includes via inheritance) — fixing the 3 #include lines dropped the failure count from 209 to 72 in one shot (85.0% → 94.8% pass). Checked the whole tree for any other same-shape case-only filename mismatches (find -iname + case-insensitive dedup) — none found, this was the only instance.

Interactive test result

Boots clean, connects; welcome message + "last modified 1999.11" credit line render correctly, empty input at the username prompt correctly triggers a polite disconnect ("欢迎下次再来" — not a bug), new + a valid English name reaches the "create new character?" (y/n) confirmation with zero crashes. Did not create a full character or play further (out of scope).

lpcc sweep

1395 files, 1323 pass / 72 fail (94.8%, after the Action.h fix). Remaining 72 failures are the usual long tail (a handful of syntax typos in individual files, a few missing daemons like TASK_D/SendToUser/ SendToMud referenced but not present in this "mini" trimmed-down archive) — not triaged individually, consistent with AGENTS.md §6b/§13.

Post-hoc fix: UTF8-native is_chinese/registration (AGENTS.md §15h)

Applied in a later batch pass across the whole project: is_chinese/is_chinese2 in the shared chinese.lpc simul_efun fragment used GBK byte-range checks that silently never match real Chinese text once strings are UTF-8 (this driver's str[i] returns a Unicode codepoint, not a GBK byte). This broke character registration specifically -- any real Chinese name was rejected. Fixed the range check to test the CJK Unicode block instead, and halved the GBK-byte-calibrated length bounds in check_legal_name to match. See AGENTS.md §15h for the full writeup; confirmed via a real interactive registration test (Chinese surname + given name reaching the next prompt).

2026-07-23: driver rebuild retest + LPC formatter + WASM check

2026-07-23 (integrity review): WASM world-entry hang RESOLVED — was the harness, not the mudlib

Re-ran the full WASM registration flow (new → id → confirm → Chinese name → password ×2 → email → gender) against the same build-wasm binary but with the FIXED scripts/wasm_client.js (the copyDir() log-directory recursion fix landed in the final commit of the previous pass, AFTER this lib's WASM test had been run). Result: enter_world() now completes normally under WASM — MOTD banner, 小秦淮客寓 start room, look, and the quit save-gate prompt all appear exactly as in the native run. No mudlib race exists in xo's enter_world path; the earlier "reproducible world-entry hang" was the old harness failing to recreate the lib's nested log/ subdirectory shape in the WASM in-memory FS (this lib's log/ has 6 nested subdirs — acct/catch/log/room_log/runtime/static), so an early uncaught write_file()/log_file() during enter_world threw ENOENT and silently aborted the flow — precisely the harness gap class described in that commit's message. Verdict: fully playable under WASM; the previous NOTES entry's "possible WASM-specific gap isolated to this lib" flag is closed.

Also noted (pre-existing, original-author code, left as-is): system/ daemon/logind.lpc's enter_world() contains two leftover debug printf("beforee exec...") / printf("before setup...after exec..") lines that print to every player at world entry — present since the raw archive (verified in the initial conversion commit), cosmetic only.

WASM-enablement pass (loopback-allow / gate bypass / admin seed)

Standard WASM-first pass per AGENTS.md §1.3b/e and §1.5. Gates patched:

Admin account seeded: id fluffos, pw Mud@2026, name 浮浮, granted (admin) via fluffos (admin) appended to secure/etc/wizlist. Verified: real registration (ENTER/new/fluffos/y/浮浮/pw×2/email/m → landed in 小秦淮客寓), then relogin as fluffos → update /system/daemon/logind → 成功, score correct. Retest: fresh normal registration (秦风, f) end-to-end with look/score correct (quit shows the original 30-min new-account retention prompt — content timer, kept per policy); test char save removed; zero new debug.log errors. Save file: work/data/user/f/fluffos.o (NOT gitignored — normal add, no force-add needed).

Fail-closed retrofit for the loopback-allow gate (2026-07-24)

The loopback helper above was originally written matching the project-wide convention at patch time (AGENTS.md §1.3b), which also treated an empty/non-string/malformed query_ip_number() result as loopback, defensively, because the WASM driver used to return garbage there. That underlying driver bug is now fixed (fluffos commits e33bb5da "fix: query_ip_number() returned uninitialized garbage under WASM" and 007bb863 "feat: synthetic resolve() on WASM instead of raising an LPC error", both 2026-07-23; the locally-built build-debug/build-wasm binaries already postdate both commits), so treating unparseable IPs as trusted is a fail-open gap with no remaining justification. Retrofitted to fail-closed: loopback is now strictly ip == "127.0.0.1" || ip == "::1" || ip[0..3] == "127." (with a stringp() guard before the slice) — a malformed/empty IP now falls through to the NORMAL gate instead of being treated as local. Retested after tightening: fresh driver boot clean, fluffos loopback login and its wizard update command both still work; zero new debug.log errors.

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

First real *playthrough* pass on this lib (all prior passes verified only registration + look/score/quit + admin login). This "mini" archive has no help newbie/help intro file at all (help/user/ contains only a single sect help page and no topics index — a genuine content gap in this trimmed archive, not a conversion bug; help with no argument literally prints 0 to the player, see Bug 8 below), so the test path was derived entirely from reading room/NPC source: register → 小秦淮客寓 (start room, Yangzhou) → walk to 崇雅书院/至止堂 and learn literate from the teacher NPC 增城湛 via qingjiao → (admin-assisted, see below) reach 无量剑派东宗's hall and join via apprentice/kneel → a real fight → a real death → the death-realm/reincarnation flow → a shop purchase → quit/reconnect testing. Found and fixed eight distinct programming bugs (compile errors, a driver-API-misuse crash, and a silent-stranding move() bug), one of which is a well-established project bug class (§7.25) and most of the rest are one-off typos of a kind AGENTS.md already tracks (§6.6/§8.5-adjacent); also captured a driver-level SEGFAULT, corroborating the §10.8 "ambient background processing can crash the whole process, invisible to debug.log" class with a genuinely different C++-level mechanism (a dangling shadowed object pointer walked during the periodic reset() sweep) than either of the two prior occurrences.

Note on this pass's scope: partway through this session the orchestrating session clarified that only genuine *programming* bugs are in scope for live fixes (compile errors, driver-API misuse, missing null/objectp checks around calls that can crash, obviously-wrong references) — game-balance/content/design questions are explicitly OUT of scope, even when they look surprising. One thing found live (a "safe" sect mirror-spar that turned out to deal lethal, real damage — see "Observed, not fixed" below) falls squarely in that excluded bucket and was deliberately left untouched, documented only.

Wuliang sect is not reachable by ordinary walking in this archive: d/menpai/wuliang's only outbound connection to the rest of the map (shanjiao.lpc's northwest exit) points at /d/map/xinan/jiangbian, and /d/map/ doesn't exist anywhere in this "mini" archive (confirmed: d/map is entirely absent). No city room links into d/menpai/wuliang either. This means the sect content described in the lib's own README ("目前只有扬州城和无量派两大门派") is real and functional but currently has no in-game path to it at all — every sect-related test below (apprentice/kneel, the mirror-spar, qingjiao) was reached via admin goto/summon, not by walking. This looks like a genuine map-connectivity gap from the archive trim (not something we fixed — no defensible "correct" reconnection point exists, and fabricating one would be a content decision) but is worth flagging prominently since it's a bigger blocker to real play than any single bug below.

Test characters (kept as evidence, not cleaned up):

Verified working

Not verified live (explicitly)

Bugs found and fixed

1. Unterminated string literal (×3, same shape, different files) — AGENTS.md §6.6-adjacent (pre-existing authors' typo, not a new bug class): a Chinese-text string literal missing its closing " before the trailing comma, causing the driver to keep consuming subsequent lines as string content until it hits the next " (usually inside a //-commented line, since the comment marker means nothing once already inside an unterminated string) and then throwing a cascade of "Illegal character" / UTF-8-mid-codepoint errors once the accidental early-close lands mid-multibyte-character. - d/menpai/wuliang/npc/zuo.lpc:69this one is the single most impactful fix in this pass: 左子穆, the sect's own leader/master, failed to compile entirely, so d/menpai/wuliang/dating.lpc's room population silently dropped him (caught by std/room.lpc's already- catch()-guarded make_inventory() — this lib is NOT vulnerable to the unguarded §7.25 crash shape, just the graceful-degradation side of it) — meaning the ENTIRE sect-join mechanism was inert (no master NPC to apprentice) until this fix. ``lpc // BEFORE: "姓名" : "嗯,你既知我姓左,怎会不知在下便是无量东宗掌门人左子穆?, // AFTER: "姓名" : "嗯,你既知我姓左,怎会不知在下便是无量东宗掌门人左子穆?", ` - system/skill/misc/yuanyang-dao.lpc:33 (the "鸳鸯刀法" weapon skill's 4th combat move) — same shape, fixed identically. - system/skill/misc/taizu-quan.lpc:181` (the "太祖长拳" unarmed skill's "英雄独立" move) — same shape, fixed identically.

2. Undefined-macro inherit (×2 files): d/city/yangzhou/waifang.lpc and d/city/yangzhou/woshi.lpc (both real, reachable rooms — a courtesan-house's outer/inner room, linked from meixiang_yuan.lpc) did inherit DOOR_ROOM;DOOR_ROOM is never #defined anywhere in this archive (no door_room.lpc base class exists at all), a hard compile error (expecting L_STRING or '('). Every other room in this lib that needs a door (e.g. d/menpai/wuliang/damen.lpc) just inherits plain ROOM and calls create_door(), which std/room.lpc already provides directly — DOOR_ROOM was never real content, just a stale reference. Fix: inherit ROOM; in both files.

3. Malformed function declaration swallowed into a comment: system/skill/basic/kongshou.lpc:37-38 — the base "unarmed combat" skill, needed on literally every unarmed combat round for every character. The Chinese explanatory comment and the following function signature were on the same physical line with no separating newline, so the ENTIRE function header got absorbed into the // comment, leaving a bare orphaned { on the next line (syntax error, unexpected '{'). Reproduced live: fighting as an unarmed disciple spammed a "Compiling error .../kongshou.lpc ... *No program in object" message to the player on every single combat round (both attack and parry attempts), since skill.lpc's combat dispatch tries to load this file fresh every time it's referenced and it never successfully compiles. ``lpc // BEFORE: // 这个函数用来区别这种天生的技能与其他后天学习的技能int is_native_skill() { return 1; } // AFTER: // 这个函数用来区别这种天生的技能与其他后天学习的技能 int is_native_skill() { return 1; } ` Checked the other 4 sibling files in system/skill/basic/ with the same is_native_skill() pattern (wuqi.lpc, horsedodge.lpc, dodge.lpc, yeshou.lpc`) — all correctly formatted, this was an isolated one-off typo, not a copy-pasted class.

4. Missing #include <armor.h> (×2 files) — AGENTS.md §6.1: d/city/yangzhou/npc/cloth/cloth.lpc (the base clothing template) and d/menpai/wuliang/npc/obj/choushan.lpc (a sect disciple's robe, worn by the live npc/qyz.lpc... which itself turns out to be dead/ commented-out content, see below — fixed anyway since it's a one-line, zero-risk fix and the exact §6.1 shape) both did inherit CLOTH; without #include <armor.h> (where CLOTH is #defined). Every sibling cloth file in the same directory has the include; these two were just missing it. Fix: add #include <armor.h> above the inherit. - cloth.lpc also had a second, independent bug on the same pass: set("value",); — a call with a dangling comma and no second argument (Wrong number of arguments to 'set', expected: 2, got: 1). Every sibling cloth file's equivalent line reads set("value", 800)-shaped; fixed to set("value", 0) (a sensible zero default for what is explicitly a base/template object, per its own empty set_name("", ...) treatment elsewhere in the same create()).

5. Driver-API misuse: missing objectp() guard after a move() call that can legitimately self-destruct its argument — matches AGENTS.md §7's "missing objectp()/stringp() checks" class, closest existing relative is §7.25's shape (a call that can legitimately fail/vanish, with no guard on the caller side). cmds/verb/drop.lpc:57's do_drop() calls obj->move(environment(me)), checks only the integer return value, then unconditionally calls further methods (obj->is_character(), obj->query("unit"), obj->value()) on the same obj reference. d/menpai/wuliang/npc/obj/sword.lpc's own move() override (a soulbound-weapon "剑在人在,剑亡人亡" mechanic) legitimately destruct(this_object())s itself and returns 1 (success) when dropped outside a valid ownership context — a fully intentional, working design (see sword.lpc:33-52), but do_drop() has no way to know that and dereferences the now-destructed obj immediately after. Reproduced live: drop sword (as a disciple standing in the death realm, where the sword's ownership check fails) printed the correct in-fiction "剑转眼间断成了数块,不见了。" message, immediately followed by an uncaught *Bad argument 1 to EFUN call_other() Expected: object, string, array, Got: int(0) runtime error (visible in log/runtime), aborting the rest of do_drop() mid-function. ``lpc // BEFORE: if (obj->move(environment(me))) { if (obj->is_character()) // AFTER: if (obj->move(environment(me))) { // obj->move() can legitimately destruct obj as a side effect (e.g. // a bound/soulbound weapon shattering when dropped outside its // valid owner context -- see d/menpai/wuliang/npc/obj/sword.lpc's // own move() override) -- guard before touching it further. if (!objectp(obj)) return 1; if (obj->is_character()) ` This is a general, call-site-independent fix (guards the ONE shared do_drop() used by every drop invocation, including the amount- split and drop all` paths), not specific to the sword.

6. Silent-stranding move() to nonexistent content in the death/ reincarnation flow — same shape as AGENTS.md §7.18 (hardcoded path into content missing from THIS archive), new file/lineage instance: d/place/death/npc/chacha.lpc's death_stage() — the 判官 NPC that finalizes reincarnation — picks a random(3) destination for a newly -reincarnated ghost. Only branch case 0 (/d/city/yangzhou/kuixing_ge) resolves to real content in this trimmed archive; case 1 (/d/map/zhongyuan/nanmen/d/map/ doesn't exist anywhere in this archive) and case 2 (/d/city/lanzhou/guangchanglanzhou doesn't exist either) both silently fail. Confirmed the failure mode live (via goto on the admin account, which has its own explicit existence check and reported "没有这个玩家、生物、或地方" without moving): move()'s own implementation (system/feature/base/move.lpc:74-80) already gracefully notify_fail()s rather than crashing for a target that doesn't exist at all (as opposed to one that exists but fails to compile, which throws) — but chacha.lpc never checks move()'s return value, and notify_fail() from a call_out-driven context with no active command dispatch never surfaces to anyone. Net effect: 2 out of 3 times, a reincarnating ghost's ghost flag gets cleared (reincarnate() already ran) but they're never actually relocated — permanently stuck in 阎罗大殿, a death-realm-only room with (per 鬼门关's own room text) no way back to the living world through ordinary movement. Also checked the "西域"/gaochang special-case branch one line above — /d/city/gaochang/center doesn't exist either, but confirmed (via logind.lpc's own start_rooms array, where the gaochang entry is commented out) that no character in this archive can ever actually be tagged hydra/desert/from=="西域" in the first place, so that branch is already-dead and left alone. ``lpc // BEFORE: switch (random(3)) { case 0: ob->move("/d/city/yangzhou/kuixing_ge"); break; case 1: ob->move("/d/map/zhongyuan/nanmen"); break; case 2: ob->move("/d/city/lanzhou/guangchang"); break; } // AFTER: (both dead branches repointed to the one confirmed-live // destination already used by case 0, matching AGENTS.md #7.18's // fix pattern -- see the file for the explanatory comments kept in // place) switch (random(3)) { case 0: ob->move("/d/city/yangzhou/kuixing_ge"); break; case 1: ob->move("/d/city/yangzhou/kuixing_ge"); break; // was the dead /d/map/ path case 2: ob->move("/d/city/yangzhou/kuixing_ge"); break; // was the dead lanzhou path } ` Verified live end-to-end after the fix: dropped all items (a prerequisite the same NPC enforces earlier in its dialogue), re- entered 阎罗大殿, sat through 判官's full multi-stage dialogue, and was moved to 小秦淮酒楼` (a real, live room) successfully.

7. Operator-precedence + typo bug, NOT observed live (dead code given current data, fixed proactively since it's a trivial and clearly unintentional pair of mistakes): cmds/skill/study.lpc:127-128if (bonus = book["bonus_jibie"] > 0) me->improvve_jibie(...). Two independent bugs stacked: = binds looser than > in this grammar, so bonus was being assigned the BOOLEAN result of the comparison (0 or 1) rather than the actual configured bonus amount (contrast with the parallel bonus_jilei branch a few lines up, which correctly does bonus = book["bonus_jilei"] then checks it); and improvve_jibie (double-v) is a typo for the real function improve_jibie (defined in system/feature/char/skill.lpc:351, used correctly by name everywhere else including 3 lines below in the same function's else branch) — an Undefined function error waiting to happen the moment it's ever reached via ->. Not reachable with current data: grepped every book/skill data file in this archive and none of them ever set "bonus_jibie" to a positive value, so book["bonus_jibie"] > 0 is always false and this exact branch never executes today — but the fix is one-line-obvious and harmless, so applied proactively rather than left as a landmine for the first book that ever sets that key. ``lpc // BEFORE: if (bonus = book["bonus_jibie"] > 0) me->improvve_jibie(book["name"], bonus); // AFTER: if ((bonus = book["bonus_jibie"]) > 0) me->improve_jibie(book["name"], bonus); ``

8. Cosmetic, not fixed (too minor/ambiguous to count as a real programming bug, documented only): cmds/comm/help.lpc's main() does cat(HELP_DIR + "topics") when called with no argument; help/user/topics doesn't exist anywhere in this trimmed archive (genuine content gap, not a conversion bug). secure/sefun/file.lpc's cat() is write(read_file(file)); read_file() of a missing file returns int 0, and write() coerces that to the literal string "0" — so a bare help with no topic just prints 0 to the player instead of a message like "没有说明文件". Left as-is per the "don't fabricate missing content" policy (the fix would require deciding what a proper topics index should say, a content question) — but flagged here in case a future content pass wants to add a real topics file, at which point this stops mattering entirely.

Observed, not fixed (design/content, out of scope per this pass's corrected instructions)

Driver segfault (corroborates AGENTS.md §10.8, new immediate mechanism)

~26 minutes into this session, during ordinary ambient play (not triggered by a specific command — the crashing call stack is entirely inside the driver's own periodic reset() sweep, backend.cc's look_for_objects_to_swap()), the native driver process died outright with a SIGSEGV. debug.log showed absolutely nothing — identical to both prior §10.8 occurrences (xjcq2000, shiji), reinforcing that this class of failure is genuinely undetectable by log-watching alone; only the redirected driver stdout (captured per the standing recommendation from that section) had anything.

Captured backtrace (driver build fluffos-20260721-25c87bbc):

backend_run_one_gametick -> look_for_objects_to_swap -> reset_object
  -> safe_apply(APPLY_RESET) -> apply -> apply_low -> eval_instruction
  -> f__call_other -> apply -> apply_low [SIGSEGV]
src/vm/internal/apply.cc:201, in apply_low:
  while (ob->shadowed && ob->shadowed != current_object &&
         (!(ob->shadowed->flags & O_DESTRUCTED))) {   // <- crash here

This is a different immediate C++-level mechanism than either prior occurrence (both of those were FATAL: Object ... ref count 0, but not destructed internal-consistency aborts from free_svalue(); this one is a raw segfault dereferencing ob->shadowed, apparently a dangling pointer, while a reset()-triggered call_other() walks the shadow chain) — but the same broad category (driver-level object-lifecycle memory corruption surfacing later, during unrelated background activity, as a process-ending crash). Not mudlib-fixable; not root- caused to a specific LPC source pattern (the corruption, whatever it was, had already happened before this crash — the reset cycle just happened to be the next code to touch the bad pointer). Driver was restarted (fresh PID, confirmed via readlink -f /proc/<pid>/cwd before doing anything with it) and testing continued; no second occurrence in the remaining ~30 minutes of this session. This is now the third independent occurrence of "background driver processing crashes the whole process, invisible to debug.log" across three unrelated libs/lineages — per §10.8's own escalation note, worth promoting to a driver-level (~/src/fluffos) investigation rather than continuing to treat each new occurrence as a per-lib mudlib finding, if this keeps recurring.

lpcc sweep

Baseline (start of this pass) 1323/1395 pass (94.8%). After this pass's fixes: 1331/1395 pass (95.4%). Remaining 64 failures are the already-documented long tail: genuinely corrupted/non-LPC content under d/menpai/wuliang/east/ (plain-text poem fragments, garbled binary, a "By XO team... since 1997 April." credits blob — not LPC source at all, pre-existing archive corruption, not a conversion bug, and this whole subtree turns out to be unreachable anyway per the map-connectivity gap noted above), missing daemons (TASK_D, BET_D, SendToUser, NBUG) consistent with this "mini" archive's documented trimming, and a handful of dead/superseded duplicate files (system/menpai/wuliang/zuo_zimu.lpc etc. — confirmed via grep to be shadowed by a live npc/-subdirectory version and never referenced by any room's objects mapping, left alone per the project's "leave dead code alone" convention) — not triaged further as none are live/reachable.

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

笑傲江湖 XO/TMI-2/ES2/Falcon 基础版(迷你版)。状态已从过时的 limited 修正——这份档案自己的 README 和 group_note 里从未记录过任何缺陷说明,本轮重新测试也没有发现:这份压缩包没有随附管理员存档(只有一条 wizlist 阶层授权)——已改为用一次全新的 'new' 注册(fluffos/Mud@2026)来验证,干净地进入起始区域(小秦淮客寓),并以正常的告别信息 quit。

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

深度功能测试第二轮 / Deep functional test round two (2026-08-15, post driver-upgrade re-test)

驱动于 2026-08-12 升级后的重测。标准检查清单发现并修复四处问题:

1. cmds/app/update.lpc(AGENTS.md §7.106):完全没有 environment(me) 空值防护(if (obj = present(file, environment(me)))),补上 if (environment(me) && (obj = present(file, environment(me))))。 2. secure/sefun/file.lpclog_file() 没有 assure_file() 目录预建保护,补上调用及前向声明;cat() 补上 read_file() || "" 空值防护。 3. secure/daemon/master.lpc::log_error()(AGENTS.md §7.10 大小写 坑的又一实例,与本轮在 xlqy_new2007 上发现的一样)strsrch(message, "warning: ")(小写、带尾随空格)逐字节对不上 本驱动实际吐出的大写 Warning: ,等于完全没有过滤——本档案这处 还额外没有 wizardp() 分流(对所有连线玩家一视同仁广播),改成 不含开头 w/W 的 "arning:" 子串匹配(§7.10 标准写法)后即可正常 过滤警告,未额外新增巫师分流(不在本轮范围内,且原代码本就没 有这层区分)。 4. clone/user/user.lpcclone/user/wizard.lpcreconnect() (AGENTS.md §7.108,第十六条独立确认的血统):两个档案各自独 立定义 reconnect()wizard.lpc 覆写而非继承 user.lpc),均 缺少 enable_commands()system/daemon/logind.lpc 有同款 exec(old_link, user); 踢掉重复登录写法。按 §7.108 记录的写法 预防性修复两处,现场用两个真实连线复现"保持第一个连线不断开→ 第二个连线登录→答 y 踢掉旧连线"验证:score 修复后立即正常显 示完整角色档案。

现场验证摘要

驱动干净启动,管理员 fluffos/Mud@2026 登录(回车进入→id+密码) 成功进入游戏世界,update /system/daemon/logind 成功验证真实写入 权限,现场未观察到编译警告泄漏(确认 log_error 修复生效)。踢掉重 复登录重连路径现场验证通过(见上)。debug.log 全程干净(216 行, 无真实错误)。

本轮修改的文件

§7.100 sub-threshold instance (2026-08-20)

Found during the §7.100 tail-sweep (below the original 166-lib survey's

=100-occurrence threshold, never checked). 73 live

replace_program(ROOM); occurrences across 73 room files — mostly a large d/menpai/wuliang/*.lpc sect-zone cluster (68 rooms including a west/ subdirectory), plus d/city/matou/mache.lpc/kechuan.lpc and a d/place/death/*.lpc cluster of 8 rooms. No room-building tool exists in this lib. 4 pre-existing already-//-commented instances left untouched. Fixed by deleting the redundant lines. Verified via a clean native driver boot (zero new debug.log errors, port listening, killed by exact PID after ~8s).

深度功能测试第三轮 / Deep functional test round three (2026-09-03)

新角度:巡捕游荡触发的城门 reset/make_inventory 路径(log/catch 里成串的 *Bad argument 1 to EFUN call_other() ... Got: int(0))、 留言板 post/read、酒楼 list/buy、真实死亡进入地府。

Bug(AGENTS.md §7.73 新实例):迷你版把装备挪到 npc/obj/

NPC 仍按全局 HEAD_DIR/BLADE_DIR 取值 → 每次城门 reset 都 call_other(0)

xunburandom_move() 懒加载城门房间时,make_inventory 克隆 士兵/卖花姑娘,其 create() 里无防护的 carry_object(...)->wear()/ wield() 对缺失路径返回 0,立刻炸:

| NPC | 坏路径 | 本档案实际位置 | |---|---|---| | liu_yan / run_yu | HEAD_DIR "huang_m" / "yu_jin" 等花 | d/city/yangzhou/npc/obj/*.lpc | | shibing1 / shibing2 / xiaowei | BLADE_DIR + "changdao" | 同上 obj/changdao.lpc |

xo_final/xajh2 在全局 clone/wear/head/clone/weapon/blade/ 里有这些文件,所以同名代码在兄弟档不炸——这是迷你版裁剪后的路径 错位,不是内容彻底丢失。vendor_goods 也指向同样的坏 HEAD_DIR 路径,卖花 list/buy 同样会失败。

修复:花与长刀改为 __DIR__ "obj/...",并对所有 carry_objectwear/wield 链加上 §7.73 标准守卫(先赋值再 if (ob))。现场验证:goto 通泗门/安定门/镇淮门/草河小街/ 禾嘉街,士兵与柳烟均正常出现;list liu yan 列出六种花; buy 干菜包子 from xiao er(酒楼)成交;游荡约 20s 后 log/catch0call_other 错误(仅剩启动时已知的 emoted 损坏存档 restore_object 警告,CATCH 住、与本轮无关)。

本轮其它现场验证(无新 bug)

本轮修改的文件