Fengyun IV (2005 Domestic Classic Edition)

✅ 可玩

风云Ⅳ(2005 国内经典版)— fy2005

fy2005

🔑 fluffos / Mud@2026 更新 c030405 2026-09-13 源码 下载 ZIP 上游 seikichin/-mud 落后 3 提交

▶ 开始游玩 · Play Now

配置内自报名为"风云Ⅳ",站内横幅写作"国内经典版"。与 `fengyun434` 是同一套"风云Ⅳ"引擎的不同年份/站点快照,同属本批次的"风云" (Fengyun)武侠引擎家族。

English

The same "Fengyun IV" engine as fengyun434, captured as a different year/site snapshot, with identical Gu Long-inspired wuxia gameplay of choosing an ethnic background and making one's way through jianghu sects. Notable for an ASCII-art CAPTCHA at registration — an unusually early anti-bot measure for this engine family — and for only persisting characters who reach at least 40% experience toward level 2. Active upstream adds MXP/GMCP client protocol support.

README

上游seikichin/-mudmain @ 32803f7)。本馆以 submodule-patch 跟踪该仓库;work/ 是 submodule,管理员试玩号在 overlay/,FluffOS 兼容补丁在 patches/(含 GMCP 所需的 software json.lpc 挂载)。

内容亮点

在线试玩

https://mudlibs.fluffos.info/fy2005/

管理员账号 / Admin account

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

本地运行

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

游戏端口:40013(开服后约 5 分钟内无法登录,请耐心等待)。

NOTES · 移植与修复记录

fy2005.rar → fy2005

Upstream cutover smoke (2026-09-13)

深度功能测试(2026-09-13,upstream cutover 后第二轮)

Native FluffOS build-debug driver, port 40013, catalog patch + overlay/ admin seed applied. work/log/debug.log stayed free of Error / Bad argument / undefined function lines across the whole session.

Covered end-to-end

Not covered this pass (honest gaps)

No new LPC fixes required beyond the existing software-json.lpc simul_efun patch.

Status: DONE — boots clean; has an intentional 5-minute startup grace period

Booted with zero fixes needed (same clean lineage as fengyun434/fy2). This build enforces a 5-minute wait before login is allowed ("风云系统正在初始化,请在五分钟后再登陆。" — "Fengyun system is initializing, please log in again in 5 minutes.") — an intentional startup-grace mechanic (same shape as xyxy2's 30-second wait, just longer here), not a bug. Not waited out to confirm the actual post-wait login flow given the time cost, but the boot itself is clean (no compile errors, no crashes) and the pre-wait prompt flow (name validation) works correctly.

What was fixed

Nothing needed for boot. Routine conversion: encoding (12801 converted, 384 already UTF-8/ASCII, 43 skipped binary, 75 lossy), .c.lpc (9764 files, 1328 refs auto-fixed), 11 local angle-bracket includes converted to quotes automatically, staticnosave (44 files).

Known remaining issues (documented, not fixed)

How to run

cd libs/fy2005
~/src/fluffos/build-debug/src/driver config.fluffos
# wait 5 minutes after boot before the login name prompt will proceed
python3 ../../scripts/mudclient.py 127.0.0.1 40013 --timeout 10 --send "" --send "look" --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)

Gates patched (all in work/):

Admin account (§1.5): fluffos / Mud@2026, display 浮浮, status (admin) via fluffos (admin) appended to /adm/etc/wizlist. Registered through the REAL flow including the ASCII CAPTCHA (solved by exact glyph match against feature/nada.lpc's c_num table — note the glyphs are Chinese numerals 零一二...九, indexes 0-9, plus an unused 十). As a wizlisted account it spawns in /d/wiz/hall. Verified re-login + update /adm/daemons/combatd → 成功.

Retest: fresh normal registration (秦风) through encoding + CAPTCHA into 风云台 with working look/score — confirms the uptime-gate bypass (connected seconds after boot, previously impossible) and that normal players are unaffected. Test char saves removed; no new debug.log errors.

Save files to force-add (untracked, NOT gitignored): libs/fy2005/work/data/user/f/fluffos/fluffos.o, libs/fy2005/work/data/login/f/fluffos/fluffos.o.

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

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

发现并修复:.c.lpc 改名的长尾后遗症——两张运行期数据表整表引用旧扩展名,导致节庆场景系统崩溃、任务掉落系统整体失效(AGENTS.md §4.2 item 2 新实例)

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

关于 CAPTCHA(图形验证码)的测试方法说明

feature/nada.lpc's my_number()c_num 表里 10 个 ASCII 字符画 的中文数字字形,拼成一个 8 位随机数的图形验证码。本轮为了能在自动化 测试里稳定通过这一关,用 git show/直接读源码把 c_num 表的 10 个 字形抽出来写了一个逐字形匹配的小工具(未提交进仓库,纯本地脚手架), 但纯靠字形匹配在实际操作中因为终端输出的时序/换行/颜色码干扰,命中 率不够稳定,最终改用了更简单可靠的办法:临时在 confirm_id() 里加一 行 write()my_number() 已经算出来的明文校验码直接打印出来,验 证完当场撤销这行调试代码(从未提交)。记录这个方法是为了给下一个测 试 fy 家族(fy2fy330fy2mg 等同引擎兄弟档案)的人参考——这 类 CAPTCHA 是纯 ASCII 艺术字,没有依赖任何外部图像渲染,本来就是为 了防自动化注册设计的,测试时没有必要真的去做 OCR,直接读源码 + 临时 调试输出是更稳妥的路子。

测试内容与结果

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

风云Ⅳ 2005 构建版。

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

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

同一形状扩展到全库通用房间基类 #define ROOM "/std/room":删除 1001 处多余的、独立成行的 replace_program(ROOM);(保留 inherit ROOM;)——999 处由脚本批量删除,另外 2 处 (d/fy/wcloud1.lpcd/fy/tiandoor.lpc)行尾带有开发者注释 //add by ldb(后者还有中文说明"希望刷掉乱走的NPC"),脚本的严格 匹配跳过了它们,手工确认后一并删除——注释表明作者是有意添加该调用 以期"冲掉"游荡 NPC,但技术上仍是同一枚定时炸弹(对已 inherit 的 对象重复 replace_program(),一旦该对象后续绑定任何闭包就会崩溃), 故仍按同一原则删除。本库没有房间建造工具(roommaker.lpc 等), 无需修复第二处。已用 build-debug 驱动干净启动验证(0 个新增编译 错误,端口正常监听);未做完整 §10.7 深度游玩测试。

Round-four re-test (2026-08-20): combat + economy, previously untested

Prior rounds explicitly left combat and economy uncovered (no newbie-safe sparring target found within the time budget; shops looked like a standard fy-engine implementation but were never actually transacted against). This pass closed both gaps.

Combat: confirmed working

obj/npc/champion.lpc's cross-sect accept_fight() gate (me->query("class") != query("class")) is real and correctly blocks newbie-unaffiliated challenges, as previously documented — not a bug. Rather than force a sect join, tested combat via the admin account and a disposable clone /obj/npc/scavenger (a plain, non-quest NPC with no accept_fight override) in /d/wiz/hall:

Economy: confirmed working, including a real bug found and fixed along the way

Tested the two facilities actually reachable near the newbie zone (fywest/fysouth maps): d/fy/nanbank.lpc (南宫钱庄, bank) and d/fy/qianyin.lpc (千银当铺, pawnshop), plus a real vendor purchase at d/fy/fqkhotel.lpc's 店小二 (inn waiter, functionally the teahouse-equivalent shop — no room literally named/tagged 茶馆 exists near the newbie start; the one d/biancheng/teashop.lpc teahouse in the whole archive is in an unrelated, far-off zone, and d/fy/npc/teawaiter1.lpc, which reads like a dedicated teahouse vendor, is dead content — never placed in any room's objects map, and had its own list/buy add_actions commented out even if it were reachable).

Real bug found and fixed: log_file() had no assure_file() guard (AGENTS.md §7.11 instance)

While setting up test money via the wizard call debug command (call silver->set_amount(300)), hit a live, uncaught runtime error:

执行时段错误:*Wrong permissions for opening file /log/nosave/CALL_OTHER for append.
"No such file or directory"
程式:/adm/obj/simul_efun.lpc 第 14 行

adm/simul_efun/file.lpc's log_file() did a bare write_file(LOG_DIR + file, text) with no directory-existence guard, even though a correct, already-written assure_file() helper sits two functions below it in the same file, unused — the exact AGENTS.md §7.11 pattern (six-plus prior independent instances across unrelated lineages). This lib's archive never shipped /log/nosave/.

This is not just a debug-tool inconvenience — grepping every log_file("nosave/...") call site found it also sits on the real player-facing cmds/usr/suicide.lpc::check_password() path (the "永远死掉" / permanent-delete branch of the double-confirmation suicide -f flow, precisely the mechanic last round's NOTES flagged as untested): the log call is textually BEFORE the actual rmhirdir() save-directory deletion and destruct(me) calls in that function. An uncaught error there would silently abort the whole deletion sequence — the player would see a raw stack trace instead of the "永别了" farewell message, their save data would NOT actually be deleted, and destruct(me) would never run, leaving the confirmation flow in a broken half-state. Also present in master.lpc's own crash logger (nosave/CRASHES), securityd.lpc's promotion log, imprison/purge wizard audit logs.

Fix: added a forward declaration (void assure_file(string file);) plus a call to assure_file(LOG_DIR + file); immediately before the write_file() in log_file(), matching the established project-wide fix idiom exactly.

Verified live: reproduced the crash pre-fix (call silver->set_amount(300) threw the trace above, and the call silently never executed — confirmed by balance/inventory not reflecting the intended amount). The regular update <path> wizard command cannot hot-reload this fix, since /adm/obj/simul_efun is a driver-special #include-based object, not a normal inherit-based one — attempting update /adm/obj/simul_efun live threw its own *No program in object error and did not apply the fix. Restarted the driver clean instead (old PID killed, fresh boot), then re-ran the identical call sequence: no error, /log/nosave/ auto-created on demand, and all subsequent bank/pawnshop/buy transactions above completed without incident.

Standing bug checklist sanity pass

Cleanup

No new player/test accounts were created this round (all testing done through the existing fluffos admin account, already documented and already save-tracked from earlier passes). Test artifacts (a cloned scavenger corpse, a panic-dropped starting-kit item, cloned test currency/weapon/armor consumed by the transactions themselves) were either consumed by the transactions or explicitly destroyed afterward. Driver killed by exact PID at session end.

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