Journey to the West: New Era

✅ 可玩

西游记 2000 — xyj2000f

xyj2000f

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

▶ 开始游玩 · Play Now

西游记之新纪元(xiyouji.org,自 1998 年前后运行至今的经典老牌 MUD)取材吴承恩原著神话世界观,新角色从长安城南城客栈出发,此后游历天庭、地府、花果山等经典场景;字节级比对显示,这并非本合集里 `xyj2000` 的普通姊妹档案,而实际是同一份档案分两次分别归档:约 8700 个文件里超过 99% 逐字节相同,剩余差异大多只是行末空格或这份拷贝独有的后期 bugfix 注释;注册前有一道真实的年龄声明("您是否是中小学学生或年龄更小?"),回答是会被系统直接请出游戏,是与 `xyj2000` 共有的原始设计,不是 bug。

English

Journey to the West: New Era (xiyouji.org), a classic old-school MUD running since ~1998, set in Wu Cheng'en's mythological world -- new characters start at a South City Inn in Chang'an before roaming the Heavenly Court, the underworld, and Flower-Fruit Mountain. A file-level check this pass found this is not merely a sibling of this collection's xyj2000 but effectively the exact same archive packaged and onboarded separately: over 99% of its roughly 8,700 files are byte-identical, and nearly all remaining differences are either a single stray space or later bugfix-stage comments this copy happens to carry that the other doesn't. Shares the same real age-declaration registration gate (rejects players who say they're primary/secondary-school students) as xyj2000.

README

内容亮点

在线试玩

https://mudlibs.fluffos.info/xyj2000f/

管理员账号 / Admin account

警告:公开架站前请务必修改此默认密码。

本地运行

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

游戏端口:40012

NOTES · 移植与修复记录

fluffos(西游记2000).tar.gz → xyj2000f

Status: DONE — boots clean, playable over telnet

Full flow confirmed: ASCII banner, GB/BIG5 prompt (send "gb"), site credits, age-appropriateness question (a real, intentional gameplay/ content gate, not a bug). Note the BIG5 hint line in the encoding-select banner itself displays as mojibake (﹁村癘舧眤...) — likely a genuine BIG5-encoded substring embedded in an otherwise-GBK file (same shape as ds386's Latin-1-in-GBK-file issue) — cosmetic only, not fixed.

What was fixed

1. Encoding: routine GB18030→UTF-8 pass, 766 .c" refs auto-fixed, 72 angle-bracket .c>.lpc> refs, and 89 local angle-bracket #include <x.lpc>"x.lpc" conversions handled automatically by convert_lib.sh's newly-generalized fix (first real large-scale test of that generalization from lib #13's manual fix — worked cleanly, no manual follow-up needed for this pattern at all this time). .c.lpc: 5637 files. staticnosave: 47 files. 2. adm/daemons/convertd.lpc (a charset-conversion daemon, containing a large Greek-alphabet lookup table as string literals) had 5 lines shaped like "α\", — a stray trailing backslash right before the closing quote, which escapes it instead of closing the string, turning the rest of the file into one runaway unterminated string literal (Illegal character/syntax error cascade). Pre-existing data typo, not something our pipeline introduced. Fixed with a targeted sed -E 's/\\"(,)?$/"\1/' on the whole file (removes a trailing \"", or \",",, at end of line only, so it can't touch a legitimately-escaped quote appearing mid-string elsewhere).

Known remaining issues (documented, not fixed)

How to run

cd libs/xyj2000f
~/src/fluffos/build-debug/src/driver config.fluffos
python3 ../../scripts/mudclient.py 127.0.0.1 40012 --timeout 10 --send "gb" --send "" --send "quit"

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

Re-verification pass: driver rebuild + LPC formatter + WASM build

WASM-enablement pass (loopback / admin seeding)

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

第一次完整游玩测试(原生驱动 build,ASAN/UBSAN debug 构建)。测试角 色 id xyjtestb,中文名 沙悟净。本轮 WASM 未重新验证:emsdk 工具链 下载硬编码指向 storage.googleapis.com,本次会话的出口代理策略性拒 绝该域名(403,已用 curl $HTTPS_PROXY/__agentproxy/status 确认是策 略拒绝而非临时故障),本地无法构建 WASM 驱动。

发现并修复:maximum evaluation cost 过低,每一次新角色注册都会在 make_body() 里静默中止(AGENTS.md §7.90 新的、更严重的实例)

发现并修复:注册流程里遗留的 printf("%O", ob) 调试输出(AGENTS.md §7.34 已知模式的又一实例)

测试内容与结果

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

西游记 2000 的一份快照。

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

§7.100 sweep (2026-08-19)

Fixed the corpus-wide inherit ROOM; ... replace_program(ROOM); redundant-replace bug (AGENTS.md §7.100). 142 live occurrences deleted: 141 via scripted sweep (fix_710_room.py), plus 1 hand-fixed roommaker-tool template (obj/roommaker.lpc, simple string-builder variant, same lineage as sibling xyj2000). 1 already-commented-out instance left untouched. No real .lpc source found under work/data/. Verified via build-debug driver boot: clean compile, zero new "cannot replace"/"cannot bind" debug.log lines; confirmed serving via raw-socket connect on port 40012.

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

Round-four gap closure: sect apprenticeship + shop/economy (2026-08-24)

Closes the two items the 2026-08-06 §10.7 pass left explicitly untested (see that section above).

Sect apprenticeship

No stationary, map-placed sect-master NPC exists in this archive's current room layout — d/nanhai/npc/master.lpc (玄智和尚, a bonze master of 山烟寺, create_family("山烟寺", 26, "住持")) is a fully functional recruiter NPC (attempt_apprentice/do_recruit/ recruit_apprentice), but a corpus-wide grep found zero room files anywhere under d/ that load it — same "written but never placed" shape as d/obj/misc/muren.lpc noted in the original pass. Used the admin account's clone wizard command to place it in 南城客栈 (the same technique implicitly endorsed by this round's task framing) as the practical way to reach it.

Found and fixed a real instance of AGENTS.md §7.117 (bai.lpc/ apprentice.lpc's "did you betray your old sect" check missing an existence guard for first-time applicants): cmds/std/apprentice.lpc line 59 had the exact dominant vulnerable form, if ((string)me->query("family/family_name") != (string)ob->query("family/family_name")), with no guard on whether the applicant (me) already has a family. Its sibling cmds/std/recruit.lpc already carries the fix on its own matching branch (line 64, if ((ob->query("family")) && ...), with the tell-tale // follow modified by elon 09-10-95 to fix a bug in 1st time recruit comment) — this lib was not part of the large corpus-wide §7.117 sweep (not matched by that session's grep), so it's a new, previously-uncaught instance of the same one-file-of-the-pair-missed gap already seen on sjshv150. Fixed identically to the documented remedy: if (me->query("family") && (string)me->query("family/family_name") != (string)ob->query("family/family_name")).

Shop / economy

Found a real, placed vendor NPC: d/city/bookstore.lpc loads d/city/npc/bookseller.lpc (孔方兄, inherit F_VENDOR_SALE), selling several books via vendor_goods. Tested with the admin account (cloned the vendor and some /obj/money/silver into the same room, set_amount() via call to fund the purchase):

No programming bugs found in the shop/vendor path itself (feature/vendor.lpc/vendor_sale.lpc/cmds/std/buy.lpc) — the type-mismatch-looking mixed buy_object(object who, object item) override in bookseller.lpc (declared parameter type object but always actually passed a string item id from cmds/std/buy.lpc) is functionally harmless in this driver (no runtime type enforcement on dynamically-dispatched call args), so not treated as a bug per the scope rule (no crash, no error signature).

Cleanup

Removed the two round-four test character saves (xyjtc/xyjte, untracked .o files under work/data/{login,user}/x/) and destroyed all admin-side clones (the two placed-for-testing NPCs, leftover money/book clones) before stopping the driver. xyjtestb (from the original 2026-08-06 pass, already tracked in git) was left untouched.

AGENTS.md §7.19: enable_player() reentrancy guard (2026-09-01)

Same corpus-wide bug class as mhxy/wuhanzhan: feature/command.lpc's enable_player() wraps enable_commands() and is unconditionally reachable from an NPC's init() via setup()/reset_me() (confirmed on this lib's own d/*/npc/zhangmen*.lpc-family NPCs, matching mhxy's originally-documented d/xueshan/npc/zhangmen.lpc pattern). Calling enable_commands() on an object that's already living() makes the driver re-invoke that object's init() as a side effect; since init() calls back into enable_player(), that is genuine same-call-stack reentrancy that repeats until "Too deep recursion" aborts a room's first-ever visit.

Fixed with a true reentrancy flag (nosave private int in_enable_player_now;), NOT a bare if (living(this_object())) return; guard — this lib's feature/damage.lpc revive() and cmds/std/sleep.lpc wakeup()/wakeup2() all legitimately re-invoke enable_player() while the object is still living() (that's how a fainted/asleep character gets commands back), so a living()-gated guard would silently break every one of those real re-enables. enable_player()'s single body has no early return statements, so the flag is set at entry and cleared once, before the function's fall-through end. Verified with a single-file lpcc compile check (exit 0, no errors) against feature/command.lpc.