Storm III (Xingxing's Revision)

✅ 可玩

风云三(星星修订版)— fy3xd

fy3xd

🔑 fluffos / Mud@2026 更新 d3d53d0 2026-09-04 源码 下载 ZIP

▶ 开始游玩 · Play Now

压缩包内附带的说明文档称之为"星星修订的风云III"——社区爱好者"星星" 整理修订的一个版本。逐文件核实发现"修订版"/"独立内容包"的说法有些夸大:其域文件与 `fy330`(风云III 3.0版)高达 96% 逐字节相同,基本就是同一个版本;与 `fy3dz`(风云典藏版)也有 91% 相同——`fy3dz` 是在同一套底座上进一步加工,新增了一处"bat"战场区域和一处新疆地图,并去掉了 `fy330`、`fy3xd` 仍保留的一些旧调试/管理后门残留。三者其实都是同一个"风云III"世界的先后快照,而非各自独立创作的游戏。游戏本身:古龙风格的江湖世界,从凤求凰客栈起步,选择民族与性别后即可闯荡江湖;根据其自带文档说明,这一快照相比同引擎最早的版本任务内容更丰富,游戏内帮助文档也更详细。

English

The readme bundled with the original archive calls this "Storm III, revised by Xingxing" — a version compiled and revised by a community enthusiast going by "Xingxing." A file-level check found the "revised"/"different content package" framing overstated: fy3xd's domain tree is 96% byte-identical to fy330 (Storm III v3.0) — essentially the same build — and 91% identical to fy3dz (Storm III Collector's Edition), which reworked the same base further by adding a "bat" battlefield zone and a Xinjiang region while dropping some old debug/admin leftovers fy330 and fy3xd both still carry. All three are snapshots of one "Storm III" world rather than separately authored games. Set in a Gu Long-style jianghu starting at the Fengqiuhuang Inn, choosing ethnicity and gender before heading out; per its own bundled documentation this snapshot carries somewhat richer quest content and more detailed in-game help text than the earliest cut of the same engine.

README

内容亮点

在线试玩

https://mudlibs.fluffos.info/fy3xd/

管理员账号 / Admin account

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

本地运行

cd libs/fy3xd
mkdir -p log   # 如尚未创建
~/src/fluffos/build-debug/src/driver config.fluffos

游戏端口:40089

NOTES · 移植与修复记录

fy3xd — 风云Ⅲ (星星修订版) / "Fengyun III, Xingxing's revised edition"

Archive: 风云III修订版 .rar (archive #97; byte-identical duplicate 风云III修订版 (1).rar skipped per AGENTS.md's duplicate table). Port: 40089. Status: done (boots clean, full registration + post-login look/score verified end-to-end with a real Chinese name, across two independent connections).

What this is

Archive unpacks to a nested fy3fixed[1]/fy3fixed/ root (config at fy3fixed/config.fy3, master at fy3fixed/adm/obj/master.c) plus a top-level 小熊泥苑.txt site-branding text file (same "小熊泥苑" snapshot branding already seen on archives #33/#34, sjtx2/ sjpl2). readme.txt (converted): "这是星星修订的风云3,非常 稳定,任务丰富,内有详细的help文档,推荐!" — "This is Xingxing's revised Fengyun 3, very stable, rich in quests, has a detailed help doc set, recommended!", signed "titny". config.fy3's own name field (converted): 风云三(本地) ("Fengyun 3 (local)"). ~3919 raw files, 3714 renamed .lpc/.c source files (medium-sized lib, comparable to moniHuafu's 945 or zzfy's ~10k).

Lineage confirmation (evidence, not assumption)

Per the task's standing instruction, compared this archive's core files directly against every already-done "风云"(Fengyun)-themed lib (fengyun434 #14, fy2005 #16, fy2 #17, zzfy #30, moniHuafu #57) via md5sum/diff BEFORE any fix work:

Conclusion: this is the same 风云3 (Fengyun 3) engine core as zzfy/moniHuafu/fengyun434/fy2/fy2005 — specifically closer to zzfy's snapshot than moniHuafu's (near-identical master.c), with its own distinct site content/branding/quest-layer on top (matching the readme's "revised by 星星" framing — a themed community fork, same pattern as moniHuafu being a school-themed skin). Every fix below was ported directly from the already-verified zzfy/moniHuafu write-ups, then individually re-confirmed against this archive's actual source before applying (not assumed).

Fixes applied

AGENTS.md §15h (GBK byte-range Chinese detection) — identical shape to zzfy/moniHuafu, confirmed via the byte-identical chinese.c/similar logind.c:

AGENTS.md §15p (DNS/intermud daemon preload exclusion): adm/etc/ preload listed /adm/daemons/network/dns_master — removed proactively before first boot.

AGENTS.md §15u (dormant phone-home self-destruct): adm/daemons/ securityd.lpc has the exact same checking_status(mapping info) function already found and neutralized in moniHuafu — checks info["MSG"] against a hardcoded crypt() hash, and on match calls rmhirdir("") (recursively deletes the entire mudlib root) then shutdown(0). Unlike moniHuafu, this one IS referenced in-tree — adm/daemons/network/services/ gtell.c's intermud-tell relay calls SECURITY_D->checking_status(info) — but that relay is itself unreachable in this sandboxed environment (no inbound intermud gtell traffic, dns_master excluded per above, gtell.c not on preload and not called from anywhere else in the lib). Neutralized the destructive body anyway as cheap insurance (replaced with a log_file()-only stub), matching moniHuafu's fix exactly.

AGENTS.md §14 (valid_override 3-arg upgrade): master.lpc's valid_override(file, name) was 2-arg; adm/simul_efun/object.lpc (an #included fragment inside simul_efun.lpc) has an efun::destruct(ob) override, the exact shape §14 warns about. Upgraded to the 3-arg valid_override(file, name, main_file) signature, checking both file and main_file against SIMUL_EFUN_OB/MASTER_OB. Confirmed (via the lpcc sweep, see below) this only ever surfaces as a sweep-only artifact when object.lpc is compiled standalone — the real boot's composed simul_efun.lpc never hits it, same conclusion as every other lib that's checked this.

New collateral-damage instance of the known §3/moniHuafu staticnosave string-literal collision: the blanket \bstatic\bnosave sed rewrote 8 log_file("static/...") calls (in master.lpc, securityd.lpc, cmds/std/suicide.lpc, cmds/arch/call.lpc, cmds/arch/purge.lpc) to "nosave/...", even though work/log/static/ is a real pre-existing seed directory shipped with the archive (contains CRASHES, CALL_PLAYER, promotion, SUICIDE — genuine historical log entries). Confirmed via the same cross-check moniHuafu's write-up recommends (grep -rn '"nosave/' + find work/log -maxdepth 1 -type d showing a same-named static/ directory with real data in it) and reverted all 8 occurrences back to "static/..." with a scoped sed.

Two genuine pre-existing content bugs, found via the lpcc sweep and fixed (both confirmed present in the RAW pre-conversion archive too, not introduced by this pipeline): 1. d/fy/npc/gangster2.lpc's init(): used for(i=sizeof(ob)-1; ...) with i never declared (only object *ob; was declared) — a hard compile error (Undefined variable 'i', Illegal lvalue) that broke this NPC's aggro-on-room-entry logic entirely. Fixed by adding int i; alongside the existing object *ob; declaration. 2. AGENTS.md §15s (tell_room()/message() 2-arg exclude-argument bug): adm/simul_efun/message.lpc's varargs void tell_room(mixed ob, string str, object *exclude) passes a defaulted exclude (int 0 when called 2-arg, the dominant call form — 15 of 21 call sites in this lib) straight through to the real message() efun's 4th argument, which this driver rejects (Bad argument 4 to EFUN message(), Expected: object, array, Got: int(0)). This crashed /d/qianfo/tanghuai's reset()/make_inventory() (a mounted-horse NPC's init() calling tell_room() 2-arg) during the lpcc sweep. Fixed once at the shared wrapper (exclude || ({})) rather than touching any of the 21 call sites, per §15s's own guidance.

Both fixes re-verified with a standalone lpcc re-compile (both now compile with zero errors, only the usual harmless warnings) AND with a fresh full driver restart + registration re-test (see below) — the debug.log grep for the exact Bad argument 4 to.*message error string came up empty across two independent post-fix sessions.

What was checked and confirmed NOT needed

Interactive registration + post-login-command test — full transcript outcome

Read logind.lpc's actual logon()/get_id/confirm_id/get_name/ new_password/confirm_password/get_email/get_gender/get_nresp callback chain in full before scripting the test — no hidden BIG5/ client-version pre-id gate here (the first real prompt is the ordinary English-id prompt); check_legal_id requires 3-10 lowercase letters only (no digits — an early test attempt with a digit in the id, and a second attempt exceeding the 10-char cap, were both correctly rejected by the id-length/charset validator, not a bug).

Ran the complete flow in ONE continuous mudclient.py connection (twice, across a driver restart that picked up the gangster2/tell_room fixes, using different ids each time to avoid double-registering):

1. Connect → ASCII-art banner + poem + uptime/visitor-count banner → 您的英文名字: prompt. 2. qfengx → passes check_legal_id使用 qfengx 这个名字将会创造一个 新的人物,您确定吗(y/n)? 3. y → registration flavor-text banner → 您的中文名字: 4. Real Chinese name 秦风 → accepted immediately, NO rejection message (direct proof the §15h fix works — this exact 2-character Chinese name would previously have failed is_chinese()'s always-false GBK byte-range check) → 请设定您的密码: 5. Aa123456 (password) → 请再输入一次您的密码,以确认您没记错: 6. Aa123456 (confirm) → matches → 您的电子邮件地址: 7. [email protected]您要扮演男性(m)的角色或女性(f)的角色? 8. m → ethnicity menu (汉族/苗族/满族/蒙古族) → 请选择你在风云Ⅲ中的民族 (0,1,2,3): 9. 0 (汉族) → character created, enter_world() called → actual game room: "凤求凰客栈" (Fengqiuhuang Inn), full room description, one exit (west), an NPC (店小二/Waiter) greeting the new arrival with a random flavor line. 10. look: room re-displayed as part of the entry sequence (this lib's enter_world triggers an implicit look on arrival — confirmed the exact same room text appears, i.e. the look command dispatch genuinely executes, not just silently no-op'd). 11. score: produced the full character stat sheet — 普通百姓 秦风 (Qfengx), "你是一位汉族十岁的男性人类,...", all 12 attribute pairs (才智/体质/灵性/魅力/勇气/力量/耐力/韧性/速度/气量/运气/定力), combat stats (攻击力/防御力/杀伤力/保护力), 参数点 — unambiguous proof both look and score genuinely dispatch through add_action post-login (directly ruling out §15ae/§15ar, both of which were also confirmed absent by direct source inspection above). 12. quit → correctly dropped starting inventory (一件布衣/a set of cloth), printed "欢迎下次再来!" ("welcome back next time").

Confirmed both test characters (qinfeng+qinfengtwo from the first pre-fix session, qfengx from the post-fix session) saved correctly to data/user/<initial>/<id>/<id>.o and data/login/<initial>/<id>/<id>.o.

log/debug.log reviewed in full across both sessions (pre- and post-fix): zero fatal errors, zero Undefined function, zero Read access denied, zero Too deep recursion, zero Bad argument 4 to.*message (confirming the tell_room/message fix). The only non-clean-looking output is this lib's own log_error() mislabeling ordinary compile *warnings* (e.g. "Unused local variable", "Illegal to declare nosave function", "Unknown #pragma") as "编译时段错误:" (compile-time error) when broadcasting them to a connected wizard-status player — a pre-existing cosmetic quirk of this mudlib's error handler (same shape already documented for moniHuafu/wuhanzhan §15w), not something introduced by this port, and not a genuine error.

lpcc sweep

3714 files, 3698 pass / 16 fail initially (99.6%) — after fixing the 2 genuine bugs found (gangster2's missing int i;, the tell_room() message() exclude-argument bug), both re-verified clean via standalone lpcc re-compiles, leaving 14 confirmed-harmless failures:

Memory stayed healthy throughout (~9.4GB free / 18GB available on this 23GB host at sweep time, despite a concurrent sibling agent's driver + lpcc sweep also running on fy3dz — no OOM risk at this file count).

How to run

cd libs/fy3xd
mkdir -p log   # if not already present
~/src/fluffos/build-debug/src/driver config.fluffos
python3 ../../scripts/mudclient.py 127.0.0.1 40089 --timeout 25 --idle 0.8 \
  --send "" --send "<3-10 lowercase letters>" --send "y" \
  --send "<Chinese name>" --send "<password>" --send "<password>" \
  --send "<email>" --send "m" --send "0" \
  --send "look" --send "score" --send "quit"

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

Process hygiene note

While this archive was being processed, a sibling agent was concurrently processing archive #98 (风云III典藏版.rarfy3dz, a DIFFERENT archive despite the similar title — confirmed via ls archives/ and TODO.md's table, not a duplicate). Both drivers ran simultaneously on different ports (40089 here, the sibling's own assigned port there) with no interference. Per standing policy, this lib's driver was only ever killed by its own exact tracked PID, never via a broad pkill -f pattern that could have hit the sibling's identically-named process.

WASM-enablement pass (loopback / admin seeding)

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

此前被错误标记为某个不存在于本项目任何档案的原始压缩包文件名的 duplicate_of;这里的内容其实是完全独立、可游玩的游戏(有自己的 -N 变体编号、自己的端口、自己的 README)——duplicate_of 已清除。

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

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

第一次完整游玩测试(原生驱动)。测试角色 id fyxdtest,中文名 云梦仙, 苗族/女性,后拜入金钱帮第三代弟子门下(师父荆无命)。本轮 WASM 未重新 验证:emsdk 工具链下载硬编码指向 storage.googleapis.com,本次会话的 出口代理策略性拒绝该域名(403,已用 curl $HTTPS_PROXY/__agentproxy/status 确认是策略拒绝而非临时故障),本地无法构建 WASM 驱动。

与同引擎家族的 fy3dz(风云3典藏版)核心代码高度一致(README 及此前 的血统分析已确认),本轮开局前先按 fy3dz 自己深潜时记录的、明确标注 "很可能同样影响 fy3xd" 的两处已知 bug 做了主动排查,两处均确认存在并 按已验证过的同一手法修复;另外独立发现并修复了一处新的、注册流程里 的 §7.34 已知模式实例。

主动排查并修复:file_owner() 路径深度差一错误(AGENTS.md §7.26 已确认实例,fy3dz 记录中明确标注"值得检查 fy3xd")

``lpc if (sscanf(file, "/u/%s/%s/%s", dir, name, rest) == 3) { return name; } ` 只在路径恰好是 /u/<wizard>/<file>/<更多> 三段式时才生效,对这份档 案实际使用的 /u/<wizard>/npc/xxx.lpc(两段式:wizard 目录本身就 直接放 npc//obj/ 子目录)永远匹配不到 3 段,返回 0——任何在这 类嵌套内容上的编译诊断(哪怕只是一条"Unused local variable"警告) 都会让 master.lpclog_error() 把日志写到一个错误路径,抛出 *Wrong permissions for opening file ... for append. "No such file or directory"`(被驱动接住不会崩溃,但会把 debug.log 灌满无关噪音)。

``lpc if (sscanf(file, "/u/%s/%s", name, rest) == 2) { return name; } ``

主动排查并修复:user_cwd()/user_path() 假设了这份档案从未使用过的按首字母分片的巫师目录布局

``lpc string user_cwd(string name) { return ("/u/" + name[0..0] + "/" + name); } ` (比如 guanwai 会解析成 /u/g/guanwai)。实测 work/u/ 目录列表 确认是扁平布局chuenyu/ghost/guanwai/palace/ quicksand/resort/taoguan/wudang 直接平铺在 /u/ 下,没有任 何按首字母分片的中间层),与 fy3dz` 记录的情形完全一致。

``lpc string user_cwd(string name) { return ("/u/" + name); } ` 这个函数只有 3 处调用点(cmds/adm/cd.lpcmaster.lpclog_error()path.lpc` 自身),均为巫师/管理指令,不影响普通玩 家游玩。

主动排查并加固:save.lpc 缺少与 quit.lpc 同款的 environment(me) 空指针防护

新发现并修复:注册流程中文名确认环节的 printf("%O", ob) 调试输出泄漏(AGENTS.md §7.34 已知模式的又一实例)

主动排查并提高:maximum evaluation cost 沿用了这份档案自己偏低的默认值

config.fluffos 原为 300000(低于本项目常见的 700000 模板默认值, 更远低于 fy3dz/zzfy 两个姊妹档案已经验证过安全的 5000000)。按 AGENTS.md §7.90 的既定判断标准("数值接近或低于 700000 时上手就查") 主动提高到 5000000,与两个姊妹档案对齐,避免潜在的首次房间/NPC 编 译触发 eval-cost 中止。本轮全程游玩未观察到任何 eval-cost 相关错误。

测试内容与结果

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

#define ROOM "/std/room":删除 663 处多余的、独立成行的 replace_program(ROOM);(保留 inherit ROOM;),全部由脚本自动 删除。本库没有任何在游戏内建造房间的工具(roommaker/rmmaker 等名称均未找到),因此没有"工厂"侧需要修复。修复后全库仅剩 2 处 历史遗留的 //-注释掉实例,均确认无害、未改动。已用 build-debug 驱动干净启动验证(0 个新增编译错误,端口 40089 正常监听, debug.log 无新增 "cannot replace"/"cannot bind" 行);未做完整 §10.7 深度游玩测试。

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

深度功能测试(2026-09-03,第三轮)

新角度:2026-08-07 第一轮已经走完金钱帮拜师(荆无命)和 quit+reconnect, 没有测商店。本轮只补商店,并顺带发现 save 指令被影子文件挡住。