A World Without Snow

✅ 可玩

天下无雪

tianxiawuxue

🔑 fluffos / Mud@2026 更新 85d6a35 2026-09-02 源码 下载 ZIP

▶ 开始游玩 · Play Now

自称 天下无雪("A World Without Snow"),作者署名"Dream",鸣谢名单包括 Poor、Sinb、Lonely、Zjb 等多位巫师,是一个运营较久、拥有独立世界观的中文武侠 MUD。地图其实和"天涯"家族同源——`d/city/sj.lpc`("世界之巅"跳崖场景)与 `xysylmhb`/`xyzxiiylzymh`/`yzxiiizylfy` 等同样打着 "夕阳再现"或其它品牌、实际却是"天涯"血统的档案逐字节相同(本档案新角色随机落在的"北疆小镇""铁枪庙"等起点也和那几份档案完全对应),此前没有任何一份档案互相记录过这层关系;鸣谢名单里的"Lonely"正是 NT/nitan 系的作者,说明这个更大的生态圈之间本来就存在人员/代码交流。

English

Self-titled "A World Without Snow," credited to an author known as "Dream" with an acknowledgments list naming several fellow wizards (Poor, Sinb, Lonely, Zjb, among others) — a long-running Chinese wuxia MUD with its own distinct setting. Its map, however, turns out to share deep roots with this archive's "Tianya" (Horizon) lineage: several scenes, including its "Peak of the World" cliff-jump location, are byte-for-byte identical to areas in other differently-branded games in that lineage — a connection no prior entry in this archive had documented before. One of its credited wizards, "Lonely," is also the author of the Nitan series, hinting at genuine code and personnel exchange across this wider MUD community.

README

内容亮点

在线试玩

https://mudlibs.fluffos.info/tianxiawuxue/

管理员账号 / Admin account

警告:对外公开架设前请务必修改此密码。

本地运行

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

游戏端口:40045

NOTES · 移植与修复记录

tianxiawuxue — 天下无雪

Archive: 天下无雪.rar (#51). Port: 40045. Status: done (boots clean, full registration flow verified end-to-end including a real Chinese name entering the game world).

What this is

"天下无雪" ("A World Without Snow"), credit line "by Dream" (see the in-game news banner and 2006.6.24 yc credit), thanks a wizard-team roster (Poor/Sinb/Lonely/Zjb/Xxxqi/Yuchang/Lywin/Kool/Weal/Han) in its welcome/news text. adm/obj/{master,simul_efun} layout (not adm/single/), inherits per-object storage via feature/dbase.c (inherit F_DBASE; in logind.c and elsewhere) rather than the nitan-family shared-simul_efun dbase pattern — no AGENTS.md §15 architecture fix needed here (confirmed via source reading before boot, same as rzrmud). ~15,737 raw files, 12,168 .lpc files after rename — one of the larger libs in this batch.

Observation on lineage: this lib's adm/simul_efun/chinese.c is byte-identical to xyzx3's (archive #48), processed in parallel by another agent in this same project run — same standard single-first-character is_chinese shape (strlen>=2 && str[0]>160 && str[0]<255). Worth noting as a possible shared "夕阳再现"/风云-family upstream common ancestor, though this lib's own master.c/securityd.c/logind.c were read and fixed independently rather than assumed identical beyond that one file.

Fixes applied

1. AGENTS.md §15h, standard shape, in adm/simul_efun/chinese.lpc: is_chinese()'s GBK lead-byte check (strlen(str)>=2 && str[0]>160 && str[0]<255) rewritten to a CJK Unicode codepoint check (strlen(str)>=1 && str[0]>=0x4e00 && str[0]<=0x9fff). 2. AGENTS.md §15h, check_legal_name() in adm/daemons/logind.lpc: 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. The message text ("必须是 1 到 5 个中文字") already stated the correct intended character count, confirming the halved bound is right, not a guess. The file has CRCRLF line endings throughout (confirmed via cat -A) — used line-numbered sed rather than a text-match Edit, since the literal \r\r bytes don't match a plain-text search string. The second loop (strsrch(name, banned_name[i]) substring check) was left untouched per the task brief — strsrch works fine on UTF-8 strings as-is, no fix needed there. 3. AGENTS.md §15p: /adm/daemons/network/dns_master was in adm/etc/preload — removed proactively before the first boot attempt. Confirmed via source read that its create() really does call startup_udp() synchronously (not deferred via call_out()), which calls socket_create()/socket_bind() directly at load time — exactly the hang-risk pattern §15p warns about. Checked every other preload entry (dynamicd, channeld, monitord, storyd, toptend, fingerd, aliasd, commandd, autosaved, rankd, virtuald) for socket_create/socket_bind/socket_listen — none of them use any socket efuns, so no other exclusions needed. 4. AGENTS.md §14 (free, low-risk, applied on sight): master.lpc's valid_override(file, name) was 2-arg only — added the 3rd main_file parameter and OR'd it into the SIMUL_EFUN_OB/MASTER_OB allow-check, matching the documented 3-arg apply signature for #included simul_efun fragments. 5. Confirmed NOT needed, via source reading, before the first boot attempt: - §4 (lazy security-daemon load_object recursion) — master.c's valid_write/valid_read already gate via find_object(SECURITY_D) only. valid_read has an unusual extra early branch (if (!undefinedp(user)) if (!objectp(user=previous_object())) return 1;) — left as-is per the task brief, not touched. - §7 (missing get_root_uid/get_bb_uid) — both already present in master.c, returning ROOT_UID/BACKBONE_UID. - §15l (destruct-SIMUL_EFUN_OB-in-create() driver crash) — master.c has no create() logic beyond a write() banner line; no destruct call at all. - §8c (this_player()-override footgun in a custom securityd) — adm/daemons/securityd.c's valid_read is an unconditional return 1; (no ACL at all), and valid_write never overrides user with this_player(). No §15n/§15o custom-ACL gap either, for the same reason — there's effectively no read-side ACL to misfire against driver-internal compiles. - Deep named.lpc fix — no named.c/named.lpc file exists anywhere in this lib (only a stale data/named.o save file). - No hidden pre-id prompt (no BIG5/GB font question, no student age-gate) — logon() goes straight from the welcome banner to the English-id prompt.

Interactive test result — full registration flow

Read logind.lpc's actual get_id/confirm_id/get_name chain before testing (not assumed from another lib). Shape: welcome banner → English id (get_id) → y/n confirm_id → Chinese name (get_name, accepted directly on a valid name, no extra y/n confirmation step) → password (new_password/confirm_password) → gift/attribute selection (select_gift/get_gift) → email (get_email) → gender (get_gender) → enter_world.

banned_name contains the mud's own name ("天下无雪"/"天下有雪"), pronouns, and a few political figures (毛泽东/邓小平/江泽民) — no Jin Yong novel-character names in the list, so no swap was needed from the default test name.

Verified the complete registration path in one continuous mudclient.py connection: id qinfeng → confirm yreal Chinese name 秦风 → accepted (no rejection) → password test1234 (set + confirmed) → gift selection 0 (random) → confirm gift y → email [email protected] → gender m → character created, entered the game world at 铁枪庙 (Iron Spear Temple), the news system announced "又有一个新玩 家:秦风[qinfeng]" and "听说又来了一位叫做秦风的少年侠士", look rendered the room correctly, quit produced the game's own ASCII-art farewell banner. debug.log for the whole session has zero error/denied/Undefined function/Bad argument/recursion/segfault lines — only benign "Unknown #pragma, ignored" and "Unused local variable" compiler warnings (both non-fatal, both extremely common across this whole codebase family).

Re-verification pass (2026-07-23) — found and fixed a §15w bug; noted a rare, non-reproducible void-room anomaly

The original pass tested look but not score. Re-testing surfaced two things:

1. AGENTS.md §15w, fixed: adm/obj/master.lpc's log_error() unconditionally broadcast every compile *warning* to the connected player as 编译时段错误:...warning:... — this lib's boot log shows plenty of ordinary "Unknown #pragma" warnings, so any lazily-compiled file would have spammed this. Fixed with the same strsrch(message, "warning:") == -1 guard already applied to tianxia/shiji/ shujian2008 this pass. Still always logged to file. 2. A rare, one-off "new character lands with no environment" anomaly — observed once, NOT reproduced despite 13 further attempts, not fixed: on the very first registration test after the §15w fix (id qftxwx, real Chinese name 秦风茜, female), look immediately after entering the world printed the void-room fallback text (你的四周灰蒙蒙地一片,什么也没有。, from cmds/look.lpc's !env branch) instead of a real room — enter_world()'s user->move(startroom) (picking randomly among 4 known-good, existing start rooms via random(4)) apparently silently failed to place the character anywhere. score still worked (showed a normal, correctly- populated character sheet), and debug.log for that session shows zero errors of any kind. Re-ran 13 more full registrations afterward (across a driver restart, both genders, deliberately targeting a fresh "first connection of the session" scenario a second time to test for a boot-order race) and every single one landed correctly in one of the 4 real start rooms (北疆小镇/铁枪庙/武庙/客店) — the anomaly did not recur. Given it's not reproducible, produces no error signal to chase, and 13/14 real registrations this pass (plus the original pass's own successful run) landed correctly, this is documented as an observed rarity rather than fixed blind — flagging here in case a future pass sees it recur and can capture a live repro/debug.log snapshot at the moment it happens.

lpcc sweep

Right after the driver was killed post-registration-test, free -h showed only ~1.7GB free with 2.4GB already swapped — two *other* libs being processed concurrently by other agents on this same host (xyzxfy2's lpcc --batch alone at ~6.1GB RSS, dtsl2's at ~1.1GB RSS and rising) had consumed most of the 23GB host's headroom. Waited rather than starting a third concurrent sweep on top of an already-below-threshold state; memory recovered to ~8.7GB free a couple minutes later once those other sweeps finished, at which point the sweep here ran cleanly (peaked at ~2.1GB RSS on the lpcc process, host stayed at 6.7-8.7GB free throughout — no pressure requiring an early kill).

Result: 12,167 files, 11,873 pass / 294 fail (97.6%). Found and fixed one genuine, reasonably-cheap bug via the sweep:

The remaining ~293 failures were triaged by category, not fixed individually (consistent with AGENTS.md §6b/§13 — long-tail zone/ skill content, not registration-blocking):

Rebuilt-driver / formatter / WASM re-verification pass (2026-07-23)

1. LPC formatter applied across all 12,168 .lpc files in work/: {"total":12168,"written":12007,"wouldChange":0,"unchanged":28, "errors":133}. Checked for the ::fn()-after-( formatter bug found elsewhere this pass (see tianxia/NOTES.md) — zero hits of the (: : corruption signature anywhere in this lib. Verified adm/obj/master.lpc's §14 3-arg valid_override and §15w strsrch(message, "warning:") == -1 guard both survived reformatting intact. 2. Native re-test against the rebuilt build-debug/src/driver: booted clean (zero fatal/error in error handler/denied lines). Full registration verified end-to-end via mudclient.py: id txwxfmta → confirm → real Chinese name 秦风庚 → password ×2 → gift/attribute selection (0/random, confirm y) → email [email protected] → gender m → entered the game world at 武庙 (one of the 4 known-good start rooms from the original pass), look/score/ quit all producing correct real output. debug.log for the verified session: zero denied/undefined function/bad argument/error in error handler lines. (One transient, non-reproduced observation, noted in the same spirit as this lib's own already-documented void-room anomaly above: an early boot-time check briefly showed a Bad argument 4 to EFUN message() runtime error attributed to adm/daemons/dynamicd.lpc's regenerate_map()tell_room(), a call_out-scheduled map-regen daemon unrelated to registration; it was not present in the debug.log by the time the full session above ran clean, and repeated checks afterward found no trace of it — logged here per this lib's own convention of flagging non-reproducible oddities rather than silently dropping them, not chased further since it never affected any interactive test.) No new fixes needed. 3. WASM test: boots cleanly through Initializations complete. Login blocked by the documented query_ip_number() limitation, in its most direct form yet seen this pass: adm/daemons/band.lpc's is_banned(site) explicitly does if (!site) return 1; and if (sscanf(site, "%s.%s.%s.%s", ...) != 4) return 1; — i.e. treats any string that fails to parse as a 4-part dotted-quad as banned BY DEFAULT (fail-closed), and logind.lpc's get_id() calls BAN_D->is_banned(query_ip_number(ob)) before accepting any ID. Since query_ip_number() doesn't return a well-formed address under wasm, every connection is rejected with "你的地址在本 MUD 不受欢迎。" (your address is not welcome on this MUD) regardless of the id typed. Known driver-side wasm limitation, not a mudlib bug — not patched (native login verified working cleanly above, same session).

WASM-enablement pass (2026-07-24)

Standard four-change pass (AGENTS.md §1.3b/§1.3e/§1.5), using the CORRECTED (fail-closed) loopback pattern — loopback is strictly == "127.0.0.1", == "::1", or a leading "127." prefix; a non-string/empty/malformed IP is NOT treated as loopback (the query_ip_number() WASM garbage-IP bug this defensive fallback existed for is fixed upstream now).

1. Loopback-allow: adm/daemons/band.lpc is_banned(site) — this was the documented WASM login blocker (if (!site) return 1; / if (sscanf(site, "%s.%s.%s.%s", ...) != 4) return 1;, i.e. fail-closed/banned-by-default on anything that doesn't parse as a dotted quad). Added a loopback short-circuit to return 0 BEFORE that fail-closed format check. 2. Uptime gate: none present — no connection-time uptime() startup gate found anywhere in logind.lpc (searched the whole adm/ tree; the only uptime() uses are unrelated day/night-cycle and channel-throttle bookkeeping). 3. Anti-flood throttles exempt loopback: - adm/daemons/logind.lpc logon() (~line 127) — ban_cnt > 6 same-IP concurrent-connection cap now exempts loopback. - adm/daemons/logind.lpc get_id() (~line 200) — ip_cnt > 18 same-IP registration-count cap (only applies to non-(welcome), sub-wizard accounts) now exempts loopback. - Left alone (in-game content, not hosting protection, per AGENTS.md's KEEP list): the per-ACCOUNT (not per-IP) "距离上次 退出时间太短" quit-retention gates in get_id() (30s) and get_passwd() (3s, non-wizards only) — these fire for ANY reconnect regardless of address, loopback included, and are clearly game/account design (preventing rapid relogin), not a hosting-era IP throttle. Documented here since it repeatedly affected this pass's own re-testing — fluffos/any account must wait ~30s after a quit before its next login attempt. - vaild_allow_address() in band.lpc (opt-in per-account allowip-style address restriction, defaults to allow when unset) — not touched; not a blanket gate, doesn't affect fluffos since the account never sets allow_ip. 4. Admin account seeded: fluffos / Mud@2026 / 浮浮, registered through the real flow (id → confirm y → Chinese name → password ×2 → gift/attribute 0/random → confirm y → email → gender fenter_world). Granted (admin) (top rank) via /adm/etc/wizlist (securityd.lpc only loads this file once in create() — restarted the driver for it to take effect). Save files: data/login/f/fluffos.o, data/user/f/fluffos.o — neither gitignored (a plain git add picks them up, no force-add needed). Verified: update /cmds/usr/score.lpc → 重新编译 /cmds/usr/score.lpc :成功! with (admin) shown at login banner. 5. Real bug found and fixed: maximum evaluation cost : 400000 in config.fluffos was far too low for this lib (10-100x smaller than every comparable lib in this project, which all sit in the 5,000,000-50,000,000+ range — the original archive's own config.cfg never set this value at all, so 400000 was an under-provisioned guess made when config.fluffos was first written). Symptom: *Too long evaluation. Execution aborted. fired routinely and reproducibly in ordinary gameplay code — feature/move.lpc move(), feature/command.lpc command_hook(), adm/daemons/natured.lpc's day/night cycle, cmds/std/look.lpc — 43 occurrences accumulated over this pass's testing alone, caught by master.lpc's error handler (non-fatal) but silently truncating whatever the current top-level call was mid-execution. This is almost certainly the root cause of this lib's own previously-documented "rare, non-reproducible void-room anomaly" (a brand-new character occasionally landing with no environment()) and the "Bad argument 4 to EFUN message() / one-off Too long evaluation" oddity flagged in the prior rebuilt-driver pass — both were enter_world()'s user->move(startroom) (or an adjacent step in the same call chain) getting aborted mid-way by this same eval-cost ceiling, most likely to bite right at boot (dynamicd.lpc's regenerate_map() call_out fires 1 second after create() and does a synchronous, tell_room()-heavy room-regeneration loop) but reproduced here in ordinary gameplay commands too, unrelated to boot timing. Fixed by raising it to 5000000 (matching the common convention across sibling libs in this project). Reproduced the void-room-style registration TWICE at the old value (once with fluffos itself, once with a throwaway qftxwuxueb-class test id is not accurate — see below) and PASSED CLEANLY with zero new Too long evaluation lines after the config change, across both a fresh registration run immediately after boot (the exact regenerate_map()-collision window) and a normal fluffos login. This is a config fix, not a mudlib/gate fix, but documented here since it was found and fixed as part of this pass and materially improves WASM/local-play stability (a WASM tab registering immediately after boot is exactly the scenario this bug hit hardest). 6. Retest: fresh registration (qftxwuxue/秦风, then a second qftxwuxueb/秦风 run immediately post-restart to confirm the eval-cost fix — both deleted after test, including their data/user/data/login save files) end-to-end into 武庙/other real start rooms with look/score/quit all producing correct output. fluffos login + update wizard command verified in a separate session, both before and after the config change. debug.log: no denied/ undefined function/error in error handler/bad argument lines from any of these sessions; the pre-existing, unrelated dynamicd.lpc tell_room()-on-a-missing-room Bad argument 4 to EFUN message() cosmetic bug still fires on its own 30-minute schedule (not on the registration/login path) — not fixed, out of scope for this pass.

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

First real *playthrough* pass on this lib per AGENTS.md §10.7. Read doc/help/newbie{,1,2,3,4} and doc/help/combat in full first — note that this content is recycled from a DIFFERENT, unrelated upstream game (it repeatedly names itself "晚霞"/"红尘", uses "hc" as its own abbreviation, and describes a Yangzhou-centric map with a gc central square and sects/mechanics that don't match this installation at all) and does not reflect this lib's actual starting rooms or geography — harmless (nothing crashes because of it) but a documentation-quality observation, not fixed, out of scope. README.md's own description (four random start rooms, sect/拜师/江湖历练) is accurate and was used instead. Native driver (build-debug), one continuous character (shenmubai/沈慕白) across many scripts/mudclient.py sessions, each session's own close (no quit) itself exercising an unclean/net-dead disconnect.

Task directive: check for the tianxia-sibling changed_match_path bug first. This lib does NOT share it. tianxia's bug was a never-defined changed_match_path(mapping, string) simul_efun restored as a bare passthrough to the real match_path() efun. tianxiawuxue has no such function anywhere (confirmed via grep -rn changed_match_path — zero hits) and uses a completely different, architecturally-correct storage mechanism: feature/dbase.lpc (inherit F_TREEMAP;, not a simul_efun-based property store) delegates multi-segment "a/b"-style property paths to feature/treemap.lpc's own _query()/_set()/_delete() — genuine hand-written recursive nested-mapping descent (explode(prop, "/"), walk one segment per level), never touching the real match_path() efun at all (confirmed grep -rn '\bmatch_path\b' outside doc/ has zero hits in work/). Traced feature/command.lpc's bare-directional-movement fast path (environment()->query("exits/" + verb)) by hand against treemap.lpc's _query() and confirmed it correctly returns the nested exits["west"] value. Live-verified this explicitly, per the task's own instruction to test BOTH forms: registered 沈慕白, and both bare west/east/north/south/northwest/out etc. AND go <direction> correctly moved the character through 20+ distinct rooms across several zones (长安/北京城2/华山派练武场/丐帮地下暗道) with no asymmetry between the two forms. No fix needed here — noted for the record since the task specifically asked.

Test character (kept, not cleaned up, as playthrough evidence): id shenmubai, Chinese name 沈慕白 (male), password TxTest2026#. Random gift roll: 膂力23/悟性20/根骨22/身法15. Final state: at a valid_startroom (location re-randomizes on every fresh login — see bug/observation below, so "current" location is not meaningful state); no sect/skill acquired (see below); inventory Cloth/Trans site (魔法传送帖); credits/deaths reset to 0 after an unavoidable mid-session driver restart (§10.5-consistent — only save/quit persist state, an in-memory-only death from before a restart does not survive it, which is expected, not a bug). Saves: work/data/user/s/shenmubai.o, work/data/login/s/shenmubai.o.

Bug found and fixed (NEW class): safe-sparring training dummies (mu-ren/muren, 9 files) never set can_speak, so fight/hit route every spar attempt through the REAL lethal kill_ob() path instead of the dummy's own carefully-written safe accept_fight() — live-reproduced player death on the very first hit

Files: d/city/npc/mu-ren.lpc, d/shaolin/npc/mu-ren.lpc, d/shaolin/obj/mu-ren.lpc, d/shaolin/npc/obj/mu-ren.lpc, d/quanzhen/npc/muren.lpc, d/mingjiao/obj/mu-ren.lpc, d/mingjiao/npc/obj/mu-ren.lpc, d/shushan/obj/muren.lpc, d/working/obj/mu-ren.lpc.

Bug found and fixed: kungfu/class/gaibang/hong.lpc's attempt_apprentice() wraps two rejection conditions in mapp(), which is always false for a boolean/int comparison result, permanently bypassing both intended sect-entry gates

File:line: kungfu/class/gaibang/hong.lpc:75 and :79.

``lpc if (mapp(ob->query("shen") < 100000)) { command("say " + RANK_D->query_respect(ob) + "的侠义不够啊,怎么能成为我老叫花的徒弟呢"); return; } if (mapp(ob->query_skill("huntian-qigong") < 600)) { command("say " + RANK_D->query_respect(ob) + "的本派内功不够啊,怎么能成为我老叫花的徒弟呢"); return; } ` ob->query("shen") < 100000 and ob->query_skill(...) < 600 are both relational-comparison expressions that evaluate to plain int 0/1mapp() is the driver's mapping-type predicate and returns 0 (false) for ANY non-mapping argument, including these ints. So mapp(<anything> < <anything>) is unconditionally 0, the if body (the rejection) can NEVER execute, and both gates are dead code: every character, regardless of actual shen/skill level, sails past these two checks. This sits directly between a correctly-formed guard two lines above it (if ((int)ob->query_str() < 30 || (int) ob->query_con() < 25) { ...; return; }, no mapp()) and another correctly-formed guard four lines below it (if (mapp(ob->query ("family")) && ...), where mapp() is used CORRECTLY because ob->query("family") really is expected to be a mapping) — the mapp() wrapper on the two broken lines is an obvious copy/paste artifact from the third guard's *correct* usage of mapp()`, applied to the wrong kind of expression on the two lines above it.

``lpc // BEFORE: if (mapp(ob->query("shen") < 100000)) { ...; return; } if (mapp(ob->query_skill("huntian-qigong") < 600)) { ...; return; } // AFTER: if (ob->query("shen") < 100000) { ...; return; } if (ob->query_skill("huntian-qigong") < 600) { ...; return; } ``

Observation (NOT fixed — genuinely ambiguous, documented per the task's own instruction rather than guessed): fresh characters' spawn location is re-randomized on literally EVERY future login, not just the first, because enter_world()'s success branch never persists "startroom"

File: adm/daemons/logind.lpc, enter_world(), contrast the success branch (~line 690) against the fallback branch (~line 693-695).

if (file_size(startroom + ".lpc") > 0 && !catch(load_object(startroom)))
  user->move(startroom);          // <-- no user->set("startroom", ...) here
else {
  user->move(start_room[i]);
  startroom = start_room[i];
  user->set("startroom", start_room[i]);   // <-- only the fallback persists it
}

Sixth independent occurrence of the known driver-fatal crash class (AGENTS.md §10.8) — corroborating, not a new mudlib bug

During this pass's net-dead soak window (character disconnected uncleanly, driver left running idle ~12 minutes with no player commands), the driver process itself aborted:

md: debugmalloc: attempted to free non-malloc'd pointer <addr>
Aborted (Signal sent by tkill() <pid> 1000)

with a full C++ backtrace through reclaim_objects()gc_mapping()check_svalue()free_svalue()dealloc_object()debugfree()MDfree()'s own internal consistency check aborting — i.e., triggered by the driver's own periodic ~5-minute remove_destructed_objects()/reclaim_objects() GC sweep, the exact same trigger path §10.8 already documents for shenzhou. This is corroborating evidence for the existing §10.8 entry (now six independent occurrences across six unrelated libs/lineages), not a new finding — flagged here per §10.8's own "treat 'the process was still alive at the end' as worth checking" guidance, not silently omitted. One small refinement to the existing note: unlike every prior occurrence (which left debug.log completely untouched), THIS occurrence's debugmalloc warning line was captured in debug.log (one line, no further detail) — apparently that specific abort path routes through debug_message() before abort(), unlike the plain ref-count-consistency-check crashes in the other five occurrences. Not mudlib-fixable; not root-caused further here, consistent with the existing entry's own conclusion.

What was tested and confirmed working

What was NOT verified live, and why

深度功能测试(2026-08-14,round three,新驱动重测)

针对驱动升级(quest_times/win_times %-operator 修复 + Warning/warning 大小写回退兼容)做的重测,逐项独立核对了本轮新确立的检查项(不只 是信任 NOTES.md 已有记录):log_error() 确认已经有严重度判断; 安全陪练木人 can_speak 修复仍然生效——现场用 fluffos 管理员对 d/city2/wuchang 的木人打了完整一轮 fight mu ren(受伤但非致 命,score 确认"你共死亡:0 次"),修复稳定持续生效; feature/dbase.lpc 未发现密码写保护;win_times%-operator 也已用 to_int(query("win_times")) % 5。§10.8 已归 档的驱动级致命崩溃类问题不属于本轮 mudlib 检查范围。

本轮新发现并修复的 PROGRAMMING bug

1. §8.9 食物/饮水初始化判断的对象错了adm/daemons/ logind.lpcenter_world()ob->query("age") == 14(应为 user)。已改成 user->query("age") == 14。 2. get_resp()/get_name()adm/daemons/logind.lpc)各有一处 调试残留 printf("%O\n", ob)(AGENTS.md §7.34-class):紧跟 在中文名字确认之后,把连线桩物件的原始引用直接回显给正在注册 的新玩家。已删除两处。 3. log_file()adm/simul_efun/file.lpc)本身缺少 assure_file() 保护:已加上前向声明 + assure_file(LOG_DIR + file);。 4. cat()(同一文件)对不存在文件的空指针式崩溃,主动加固: 未在本档案现场触发,属主动加固,改成 write(read_file(file) || "");

实测过程

管理员 fluffos/Mud@2026(此前已确认可用)真实重连两次(先用 update /adm/simul_efun/file 触发了这个档案已知的 §include 型 simul_efun 限制——/adm/simul_efun/file.lpc#includeadm/obj/simul_efun.lpc,不是独立编译单元,update 直接指向它会 报"No program in object",改用一个真正独立的物件 /adm/daemons/logind 验证写权限:"重新编译 /adm/daemons/logind.lpc:成功!")。第二次单独验证密码重连本身。 均成功登录,存档数据一致。全程 debug.log 无运行时错误(除了我自 己误触发的 §include 限制产生的编译期错误,与 mudlib 本身无关)。 驱动按精确 PID 结束;测试期间产生的帮会背景数据/存档时间戳增量已 git checkout -- 还原。

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

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

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

AGENTS.md §7.100 修复(2026-08-19,批次五)

ROOM 基类冗余 replace_program(ROOM); 自崩溃地雷(详见 AGENTS.md §7.100):3004 个房间文件的 create() 里紧跟 inherit ROOM; 之后 都有这一行多余调用,永久设下"待替换"标记,第一次对该房间对象绑 定闭包就会崩溃。自带建房工具有 8 份拷贝(clone/misc/roommaker.lpc 及 7 个巫师目录下的副本),其中 u/lonely/obj/roommaker.lpc/ roommk.lpc 各自有 3 处独立的字符串拼接地雷(缩进/后缀写法略有不 同),全部逐一手动摘除。

修复:脚本化删除所有房间文件里独立成行的 replace_program(ROOM);, 加上 8 处模板手动摘除字符串拼接片段。git diff --stat:3004 files changed,与预期精确吻合(0 处遗留匹配,全部干净)。

验证:build-debug 驱动真实冷启动,端口 40045 正常监听, debug.log 全程干净。既有管理员账号 fluffos/Mud@2026 登录正常 (落地武庙,look/quit),全程无新增 "cannot replace"/"cannot bind" 日志行。

Round-four §10.7 deep test: closing the 2 flagged gaps (2026-08-20)

Targeted the exact 2 items the prior round-two pass explicitly left unverified (shop purchase, real combat to death/respawn), plus a fast checklist sanity pass. Native build-debug driver, two concurrent live telnet sessions (custom incrementally-flushing Python client, since the standard mudclient.py buffers its whole transcript until the connection closes and can't be watched mid-session or interleaved with a second connection) — one as the existing admin fluffos, one as a brand-new throwaway test character qindtest/秦斗 (per this session's "separate throwaway character, not a 'clean' representative one" precedent), used together so the admin could teleport the throwaway character via eval + users()/file_name() (goto only repositions the admin's own body, not another player's).

Gap 1 — real shop purchase: COMPLETED, works correctly, no bug

Read feature/dealer.lpc's do_list()/do_buy() (as the prior pass already had) and completed a live purchase this pass. Cloned /clone/money/coin onto fluffos via eval (had to split into two eval calls — new(...)->move(this_player()) then a second present("coin", this_player())->set_amount(500), since set_amount() is void and chaining it directly after new() in one expression made the following ->move() call on eval's own return value fail with *Bad argument 1 to EFUN call_other(); this is a limitation of eval's single-expression wrapper, not a mudlib bug), then goto /d/city2/xidan (one of the two rooms carrying the xiaofan vendor identified last pass) and buy bingtang hulu. Result: exactly correct. Before: 500 coin. Item price per list: 五十文钱 (50 coin). After purchase: 50 coin + 4 silver (= 450 coin equivalent, 500-50=450 ✓) in inventory, plus the purchased 糖葫芦(Bingtang hulu) item physically present. debug.log for the whole sequence: zero error/denied/undefined-function/bad-argument lines (only the pre-existing benign compiler warnings already documented above).

Gap 2 — real combat to death/respawn: COMPLETED, real death_stage() reincarnation chain exercised end-to-end, no bug

Read feature/damage.lpc's die()/unconcious()/reincarnate() and cmds/std/kill.lpc before attempting anything (per this session's established "the real kill command has no safety gate for NPC targets" precedent — confirmed true here too: kill.lpc's main() has no no_die/attitude check at all before me->kill_ob(obj); obj->kill_ob(me);). Registered a fresh throwaway character (qindtest/秦斗, password TxTest2026#, unequipped, no skills, default rolled stats), then used the concurrent fluffos admin session's eval filter(users(), (: $1->query("id")=="qindtest" :))[0]->move(load_object("/d/city2/aobai6")) to teleport it directly into 鳌拜's (Aobai, a "满洲第一勇士" boss NPC, attitude: aggressive, combat_exp: 4280000 — deliberately picked as a massive stat mismatch against a level-0 character to guarantee a real, fast death rather than an uncertain multi-round fight) bedroom, then sent kill ao bai from the qindtest session.

Real lethal combat, real death, and real reincarnation all ran correctly, unmodified, start to finish: 1. kill ao bai → immediately hit "这里不准战斗" (no_fight in the room briefly) then real combat resolved — one exchange (鳌拜's「天目昭辉」strike), "你受伤过重,已经有如风中残烛..." → "你口中喷出几口鲜血,倒在地上,死了!" — a real death via feature/damage.lpc's die(). 2. die()'s userp branch correctly fired: ghost=1, this_object()->move(DEATH_ROOM), DEATH_ROOM->start_death(this_object()) — landed at 鬼门关 (Ghost Gate), the death-room, next to 白无常 (d/death/npc/wgargoyle.lpc — one of the exact 3 files checked clean for the §7.112 death_stage_active reentrancy guard in this pass's checklist section below, now exercised LIVE, not just statically). 3. The full 5-stage death_stage() narration chain played out correctly over ~25s real time (5s per call_out), each stage's dialogue line printing once per tick, no duplication, no stall. 4. Final stage correctly called ob->reincarnate() (clearing ghost, restoring eff_jing/eff_qi to max) and ob->move(REVIVE_ROOM) — landed at 武庙, one of the lib's own 4 known-good start rooms. 5. score immediately after: "你共死亡:1 次" (death counter correctly incremented from 0→1), <精>/<气> bars showing partial (not full/not zero — correctly reduced post-revival, not a stale/broken value), character fully interactive afterward (look rendered the real 武庙 room correctly).

debug.log across the entire kill → death → 5-stage narration → reincarnate → score sequence: zero new error/denied/undefined-function/bad-argument/recursion/segfault lines — only the same pre-existing benign compiler warnings already logged in this file. No bug found or fixed — the death/reincarnation pipeline works correctly end-to-end on real, unmodified game logic.

Cleanup: both sessions quit cleanly (server-side ASCII farewell banner, clean disconnect). fluffos's incidental inventory/location drift from this pass's eval/goto use reverted via git checkout --; the throwaway qindtest character's save files (data/{login,user}/q/qindtest.o) deleted (never meant to be kept); the eval command's scratch tmp/ directory (recreated for this pass, same pre-existing gap the round-two pass already flagged as out-of-scope) removed again afterward. git status for this lib confirmed clean (no unintended save-file drift) before finishing.

Standard checklist sanity pass (confirm-only, no fixes needed)

All 7 checklist items: already fixed / already clean, zero new fixes needed this pass.

§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.