Legend of the Chivalrous Hero III

✅ 可玩

侠客英雄传 III

xkyx3b

🔑 fluffos / Mud@2026 更新 7efe930 2026-09-01 源码 下载 ZIP

▶ 开始游玩 · Play Now

一款早期国产 MudOS 自研引擎打造的小型武侠 MUD(`adm/obj` 目录结构),约 3800 个文件,独立开发,不与本项目其他任何 lib 共享代码血统。游戏登录界面自称"以金庸小说、西欧中世纪传说及漫画为背景"的混搭世界,玩家可以在同一个江湖里遇到武侠门派、西欧风格的骑士传说与漫画式的种族设定;新角色创建时要在人类、矮人、精灵、妖精、龙人、兽人六个种族中选择,这在同类武侠 MUD 里并不常见。归档里甚至带着一份《罗德斯岛战记》(Record of Lodoss War)风味的世界观文档,收在 `d/lodoss/` 目录下,描述一个多国并立的奇幻背景故事,不过那个区域的房间文件目前只是未完工的占位符,还没有做成可玩区域。官方新手教程做得比较完整:六个连续场景手把手教移动、观察/拾取、饮食购物、求助,还安排了一场和"野狗"的练习战斗,走完教程才正式进入"中央广场"开始闯荡江湖,是这批档案里教程设计较用心的一个。

English

A small (~3,800 files), independently built wuxia MUD running on an early home-grown domestic MudOS engine (classic adm/obj directory layout), with an unusual crossover premise stated right in its own login banner: a world set against Jin Yong novels, Western European medieval legend, and manga. New characters pick a race from six options -- human, dwarf, elf, fairy, dragonkin, or orc -- a mechanic rare among this corpus's wuxia archives. The archive even bundles a Record of Lodoss War-flavored lore document (a multi-kingdom fantasy backstory) under d/lodoss/, though that zone's room files are only unbuilt placeholder stubs, not a completed area. The tutorial is unusually polished for this corpus: six connected starter rooms walk a new player through movement, looking/picking up items, eating and shopping, asking for help, and a scripted practice fight against a wild dog, before dropping them into the Central Square to start the real adventure. It doesn't share a codebase lineage with any other lib in this collection.

README

内容亮点

深度功能测试新发现的 bug(详见 NOTES.md)

logind.lpc 里两条并行取名流程(接受系统随机中文名 / 自己手动输 入)都各自残留了一行调试用的 printf("%O\n", ob),紧挨在"请设定 您的密码:"提示之前,每一个新玩家注册时都会看到(AGENTS.md §7.34)。已删除。(另外确认了此前"已知但未修复"里提到的 private nomask command_hook 问题其实已经在本项目更早一次系统性 排查中修好,本轮重测全程未再触发。)

在线试玩

https://mudlibs.fluffos.info/xkyx3b/

管理员账号 / Admin account

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

本地运行

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

游戏端口:40036

NOTES · 移植与修复记录

xkyx3b — 侠客英雄传 III

Archive: 侠客英雄传III 可用.zip. Port: 40036. Status: done (boots clean and quick, full registration flow verified end-to-end including a real Chinese name).

What this is

"侠客英雄传" — its own connection banner describes the setting as "以 金庸小说、西欧中世纪传说及漫画为背景的世界" (a world set against a backdrop of Jin Yong novels, Western European medieval legend, and manga — an unusual crossover premise). adm/obj/{master,simul_efun} layout. Small lib, ~3,839 raw files.

Fixes applied

1. AGENTS.md §15h, with a pre-existing (non-UTF8) typo along for the ride: adm/daemons/chinesed.c's is_chinese() had a for loop that always checked str[0] instead of str[i] — a genuine authoring bug predating this pass, not introduced by conversion. It was harmless in practice because the only caller, logind.lpc's check_legal_name(), always invokes it with a fresh per-character slice (CHINESE_D->is_chinese(name[i..<0])) — so "always check index 0 of whatever was passed" is equivalent to "check character i of the original name." Fixed to the standard single-character CJK codepoint check, which preserves this same effective (harmless) behavior while correcting the actual GBK byte-range logic (dropped the now- meaningless even-byte-length check and the loop, since only the first character of the argument ever mattered anyway). 2. check_legal_name()'s bound strlen(name) < 2 || > 12< 1 || > 6 (halved to character count), removed the i % 2==0 even-byte-offset gate. 3. AGENTS.md §15p: /adm/daemons/network/dns_master was in adm/etc/preload — removed proactively before the first boot attempt. Booted clean in well under 10 seconds, zero compile errors, no hang.

Interactive test result — full registration flow

No hidden pre-id prompts here (banner → stats → straight to the English id prompt). Verified the complete registration path in one continuous connection: id xkyxbtest → confirm yreal Chinese name 秦风 (avoiding "张三丰"/Zhang Sanfeng — a real historical/wuxia figure found in this lib's banned_name list, alongside game-specific terms) → accepted, proceeds straight to "请设定您的密码:".

lpcc sweep

3,178 files, 3,116 pass / 62 fail (98.0%). Failure tail is the usual shape (missing globals, a handful of syntax typos) — not triaged individually per AGENTS.md §6b/§13. Memory stayed healthy throughout (~13GB free).

Re-verification pass (2026-07-23)

Boot + registration re-tested end-to-end (real Chinese name 秦岭, English id + race selection this time, since the original pass only verified up to the password prompt). Found and fixed one new regression, same bug class as AGENTS.md §15ah:

Driver rebuild / formatter / WASM pass (2026-07-23)

WASM-enablement pass (2026-07-23)

Standard four-change pass (AGENTS.md §1.3b/§1.3e/§1.5). Gates patched:

1. Loopback always allowedadm/daemons/logind.lpc logon() (around line 78-95): added an _local predicate computed from query_ip_number(ob) (true for 127.0.0.1, a leading 127. prefix, an empty/non-string IP, or any IP that fails a 4-part sscanf — i.e. WASM garbage). Guarded both connection-rejection gates with it: - the BAN_D->is_banned(query_ip_name(ob)) destruct gate (line ~89), - the per-IP multi-login cap if (IPCount > 10) destruct(ob) (line ~113). adm/daemons/band.lpc's is_banned() takes a *site name* string (not a raw connection) and is only reached via the guarded logind gate, so no separate patch there. 2. Uptime startup gate — none in the login path (no uptime()<N connection gate exists in logind); nothing to bypass. 3. Anti-flood throttle — the only per-IP throttle is the IPCount>10 multi-login cap, now loopback-exempt via the same _local guard. 4. Admin account seeded — id fluffos, pw Mud@2026, name 浮浮, registered through the normal flow; granted (admin) by adding fluffos (admin) to adm/etc/wizlist. Verified update works. Save file: work/data/user/f/fluffos/{user.o,login.o} (NOT gitignored; shows as untracked — orchestrator must git add it).

Retest: fresh registration (秦风, race human, male) reaches world, score renders; fluffos login + update works; zero new runtime errors in debug.log. Test char freshtest removed; fluffos kept.

Fail-closed loopback retrofit (2026-07-24)

Security correction, applied retroactively. The original loopback predicate above (item 1) treated an empty/non-string/malformed IP as "local" (fail-open) — a defensive stopgap for a since-fixed WASM driver bug (query_ip_number() used to return garbage like "(" on WASM connections). That bug is now fixed upstream, so this lib's _local check was tightened to fail-closed: adm/daemons/logind.lpc's logon(), _local is now stringp(_ip) && (_ip == "127.0.0.1" || _ip == "::1" || (strlen(_ip) >= 4 && _ip[0..3] == "127.")) — an unparseable/empty IP is now treated as remote/untrusted (subject to the normal ban/multi-login gates), not as loopback. Retested: fresh registration (id gatetesteronegatetestone, name 秦岭客, race human, male) still reaches the world via loopback with look/score/quit all correct; fluffos login + update /adm/daemons/logind still succeeds. Zero new runtime errors from this change (the pre-existing apply() with insufficient permission ... command_hook ... needs: private, has: hidden lines seen in debug.log are the known §8.3a private nomask command_hook class in feature/command.lpc — NOT introduced by this pass, and did not block look/score/update/quit in any observed session here; flagging for a future pass rather than fixing now since it's outside this pass's four-item scope).

深度功能测试(第二轮,2026-08-03)

之前的会话只做过注册流程 + 管理员权限验证,本轮做了完整的 §10.7 深度功能测试。proactive 检查 AGENTS.md 已归档的四类常见坏味道:

完整流程验证:连续注册多个全新角色,走完整个官方新手教程(游 戏本身把教程做成了六个连续房间:start1如何移动→start2如何看/ 捡→start3如何吃喝购买→start4如何求助→start5关于战斗→down 进入正式世界),教程房间之间的出口方向并不是简单的连续东进( start2出口是south,start3出口是west,start4出口是north), 按各房间实际定义的方向走通;start5教程明确指引"wear cloth"/ "wield sword"装备防具武器后"fight dog"和野狗打一场——照做,完整 交手十余回合,伤害叙述随野狗伤势分级变化(从"可能受了点轻伤"一路 到"受了相当重的伤,只怕会有生命危险"再到力竭倒地),战斗系统工作 正常;score/hp面板渲染正确(食物/饮水槽创建时即为满值,没有 §8.9 症状);一路到达"中央广场"(登录留言板显示15张留言), quit干净退出("欢迎下次再来!")。全程 debug.log 没有任何一条 执行时段错误——是这次会话覆盖的几个 lib 里少见的、从注册到教程 到战斗到 quit 全程零报错的一次。

未覆盖范围:留言板内容、拜师、商店购买、种族差异(矮人/精灵/ 妖精/龙人/兽人五个非人类种族本轮未测)因时间原因未实测。

Round-four gap-closing pass: board/apprentice/shop/race (2026-08-24)

Closed all four gaps flagged above. scripts/tmux_mud.sh hit its known telnet-escape-character artifact partway through the board test (a Chinese UTF-8 byte sequence tripped the *local* telnet client's ^] command mode, not a mudlib bug) — switched to scripts/mudclient.py (raw socket, no local telnet interpretation) for the rest of the session, which had no such issue.

Bug found and fixed (real crash, confirmed live in debug.log, not content): wandering NPCs (巡捕/捕快, xun-bu) periodically drift into rooms that haven't been visited yet, triggering that room's first reset()make_inventory() for its "objects" mapping. A handful of rooms/NPCs reference files that don't exist in this archive:

Root cause in the shared code: std/room.lpc's make_inventory() did ob = new(file); ob->move(this_object()); with no check that new() succeeded — for an ordinary missing file this is Bad argument 1 to EFUN call_other() ... Got: int(0), and for a file that exists but has a bad inherit (the ling case) new() itself throws (Inherited file '.../ling' does not exist!) rather than quietly returning 0. Fixed by wrapping the new() in catch() and returning 0 on failure; reset()'s case 1 branch (single-instance "objects" entries) also lacked the same "skip if the object didn't load" guard that the default: (multi-instance) branch already had via its continue, so added a matching if (!objectp(...)) break; there too. Also fixed the two carry_object(...)->wield() unguarded chains in shizhe.lpc/shenxian-shizhe.lpc directly (assign-then-check instead of chaining).

Also fixed a hard compile error discovered via the same lpcc_check.sh pass, unrelated to the missing-/u pattern: d/beijing2/zhang/npc/wife3.lpc's create() called return_home("/beijing2/zhang/room7.lpc") — a bare string — but return_home(object home) (this file even carries its own byte-for-byte copy of the parent std/char/npc.lpc implementation, doing nothing custom) requires an object. This is dead/erroneous leftover code (the NPC already manages its own coming-and-going via goout()/do_return() with hardcoded move() paths); the call has no effect on anything else in the file and its bad-type argument was a hard compile failure that took the whole NPC object (and by extension its room's "objects" entry) down. Removed the line.

Verification: scripts/lpcc_check.sh pass count went from 3116→3142/3178 (fail 62→36) purely from these fixes (no other changes) — the room-load crash was cascading into several other objects' compile counts. Live-boot spot check: fresh driver restart, visited /d/center/furen, /d/center/zhu, and /d/wizard/guest_room (where shenxian-shizhe really lives) directly — all load cleanly, shenxian-shizhe's missing sword silently and correctly skipped (just wears the cloth, no crash). Zero new 执行时段错误 in debug.log from normal play afterward. (One artifact-only error was seen mid-session from goto <bare npc file> directly instantiating shizhe.lpc outside any room, so its greeting()command("say ...") hit a null environment() — not reachable in normal play since shizhe.lpc isn't placed in any room's "objects" mapping at all, and shenxian-shizhe.lpc (which is) works fine when visited the normal way.) Remaining lpcc failures are pre-existing, individually-untriaged content gaps (missing globals, syntax typos, plus the still-irreducible /obj/weapon/ling compile failure since its /std/weapon/ling base class was simply never included in this archive and authoring a new weapon-type class is out of this pass's scope).

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

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

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

信件系统整体死亡(与 xkyxciii 完全同源的 bug)

adm/daemons/logind.lpcenter_world() 在创建/挂载玩家的邮箱物件 之后紧跟一行多余的 destruct(mail_box)——这销毁了那个在 init() 里注册全部六个信件指令(send/mail/forward/check/from/ read/discard)的物件,导致每一次登录、每一位玩家的信件系统 完全失效,报"什么?"(未知指令),且没有任何玩家可见的错误提示。 这个 bug 是 xkyxciii 那一轮 round-three 深度测试发现并修复后, 用同一行代码做全库 grep 时命中的姐妹档案(libs/xkyxciii 的 NOTES.md round-three 章节里已经记录了这条线索)。修复:删除多余的 destruct(mail_box) 调用。已用干净重启的驱动实测验证: fluffos/Mud@2026 登录后,send/check/from/read 全部给出 正常的交互式提示(标题/内容/是否留底 y-n 询问、"没有这个编号的 信件"等),不再是未知指令;debug.log 全程干净。

§7.100 sweep (2026-08-19): redundant replace_program(ROOM); landmine

Same corpus-wide bug as documented at AGENTS.md §7.100: rooms inheriting ROOM (/std/room) had a redundant, harmful replace_program(ROOM); call right after inherit ROOM; in create(), setting a permanent "pending replace" flag that crashes the object the first time anything binds a closure to it. This lib had 1,452 live occurrences (survey-ranked #90 of 166 candidates >=100, tied with sibling lib xkyxciii, both 侠客英雄传III but distinct archives/ snapshots). Fixed with the sweep's binary-mode script (fix_710_room.py); git diff --numstat totals (0 insertions, 1452 deletions) match the survey's live-occurrence count exactly. Like xkyxciii, this lib has no in-game room-building tool, so no factory-bug variant to fix. No work/data/ room-source false-negative found. Verified via a clean build-debug boot (zero "cannot replace"/"cannot bind" debug.log lines, port 40036 listening) plus a live spot-check: no admin fluffos save currently exists in data/login/, so a fresh test account was registered through the full flow (id → confirm → Chinese name → password → email → gender → race) and landed at the new-player training room; look/quit both worked, debug.log stayed clean throughout. Test account's save directory deleted before committing.

§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): 3 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.