Storm III: Collector's Edition

✅ 可玩

风云典藏版 — fy3dz

fy3dz

🔑 fluffos(无密码) 更新 dc19ce0 2026-09-01 源码 下载 ZIP

▶ 开始游玩 · Play Now

风云 3.8.0,"风云工作室"内部整理的一份"典藏版",在风云 3.7.4 基础上补充了此前未发布或已散佚的原创内容。属于本批次的"风云III"系列,与同系的 `fy330`(风云III 3.0版)、`fy3xd`(星星修订版)逐文件核实约九成域文件逐字节相同——三者其实是同一个"风云III"世界的先后快照,而非各自独立开发的游戏。真正让它称得上"内容最完整"的地方,是另外两版没有的内容:一处"bat"战场区域和一处新疆地图,以及黄山、嵩山两地额外补充的几个专属 NPC。世界设定同样是古龙风格的江湖,从凤求凰客栈起步,选好民族(汉族/苗族/满族/蒙古族)和性别即正式踏入江湖;注册流程比同引擎其他版本更精简——没有密码设置这一步,选完中文名字直接进入性别选择。

English

Storm 3.8.0, a "collector's edition" compiled internally by the "Storm Studio" team, building on Storm 3.7.4 with previously unreleased or otherwise lost original content. It belongs to this collection's Fengyun III lineage together with fy3xd (Xingxing's Revision) and fy330 (Storm III v3.0) — a file-level check found roughly 90% of its domain files byte-identical to each of those two, confirming all three are the same underlying "Storm III" world rather than independently written games. What actually earns it the "most content-complete" label: areas the other two lack, including a "bat" battlefield zone and a Xinjiang region, plus a handful of extra named NPCs layered into Huangshan and Songshan. Set in a Gu Long-style jianghu starting at the Fengqiuhuang Inn, with a streamlined registration that skips the password step entirely — logging into any account, including the admin's, needs only a "y" confirmation, a real security hazard worth fixing before any public deployment.

README

内容亮点

在线试玩

https://mudlibs.fluffos.info/fy3dz/

管理员账号 / Admin account

警告:本版本无密码保护,任何人输入 id 即可登录任意账号(包括管理员)。
公开架站前必须先给登录流程加上密码验证。

本地运行

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

游戏端口:40090

NOTES · 移植与修复记录

fy3dz — 风云典藏版 (Fengyun "Collector's Edition")

Archive: archives/风云III典藏版.rar (archive #98). Byte-identical duplicate archives/风云III典藏版 (1).rar confirmed via md5sum (fb4d9f21939b6a0c4be33aa37f29f581 for both) — only the primary was processed, per AGENTS.md's "Duplicate archives" table. Port: 40090. Status: done (boots clean, full registration flow verified end-to-end four times with real Chinese names, look/score/quit all confirmed).

What this is

The archive's own classic.txt (a readme, GB18030-encoded) identifies this as 风云 3.8.0 ("Fengyun 3.8.0"), an unofficial fan compilation built on top of "风云3.7.4" ("在风云3.7.4版本的基础上添加了新收集的【风云工作室】 原创程序" — "adds newly-collected original Fengyun Workshop code on top of the 3.7.4 base") — i.e. a "collector's edition" bundle of previously unreleased/abandoned 风云工作室 (Fengyun Workshop) content, not an official numbered release. Archive root nested at fy3dcb/<mudlib>/; the mudlib directory itself was stored in the RAR with a raw GBK-encoded directory name (bytes b7 e7 d4 c6 b5 e4 b2 d8 b0 e6, decoding to 风云典藏版 under GB18030) rather than proper UTF-8 — unrar (UTF-8-locale-aware for file *contents*) doesn't transcode filenames themselves, so the directory landed on disk as mojibake. Renamed it to the correctly-decoded 风云典藏版 before running convert_lib.sh (which only transcodes file *contents*, not paths) — confirmed via python3 -c "os.listdir(...).encode(...).decode('gb18030')" that this was the only such filename in the whole archive (no other garbled paths found via a tree-wide scan for surrogate-escaped bytes). config.fy3's own name : field confirms 风云典藏版 as the in-game mud name, matching both the archive's own filename and the directory name — no slug rename needed beyond the ASCII-safe fy3dz. ~3,948 raw files, 3,765 after the .c.lpc rename.

Lineage: confirmed via diff, not assumption, before doing anything else

Per the task brief, checked this archive's core files against every previously-shipped "风云" (Fengyun)-themed lib in this repo (fengyun434 #14, fy2005 #16, fy2 #17, zzfy #30, moniHuafu #57) and against the concurrently-running sibling agent's own raw extraction for archive #97 (fy3xd, "风云III修订版" / Fengyun III Revised Edition) — comparing raw .c files byte-for-byte (CRLF-stripped, since some copies use CRLF and others don't) rather than trusting shared branding/title alone:

| file | vs zzfy (#30) | vs moniHuafu (#57) | vs fy3xd (#97, raw, concurrent) | |---|---|---|---| | adm/obj/master.c | identical (0 diff) | — | identical (0 diff) | | adm/obj/simul_efun.c | identical (0 diff) | 4 lines diff | identical (0 diff) | | adm/daemons/securityd.c | 541 lines diff | 76 lines diff | identical (0 diff) | | adm/daemons/logind.c | 499 lines diff | 854 lines diff | 389 lines diff | | adm/simul_efun/chinese.c | identical (0 diff) | identical (0 diff) | identical (0 diff) |

This confirms two things: 1. This is the same 风云3 engine lineage already processed as zzfy/moniHuafu (archives #30/#57) — master.c/simul_efun.c/ chinese.c are byte-identical or near-identical across all three, the same core-engine-vs-site-skin split already documented in those libs' own NOTES.md (each site customizes logind.c/securityd.c, the rest of the engine is shared). 2. This archive is an unusually close sibling of the concurrently- processing #97 (fy3xd) specifically — master.c, simul_efun.c, securityd.c, AND chinese.c are ALL byte-identical between the two, with only logind.c (site banner/messages) diverging. "典藏版" (Collector's Edition) and "修订版" (Revised Edition) are evidently two different content/documentation packagings of what is functionally the *same* underlying .7.4-based 风云3 codebase, not independent forks. Flagging for the cross-check the task brief requested: since #97 was still mid-processing at the time this lib was done (its work/ didn't exist yet, only raw/), a later diff between libs/fy3xd/work/ and this lib's work/ (once #97 lands) is worth doing — any fix #97's agent found in master.lpc/ simul_efun.lpc/securityd.lpc/chinese.lpc almost certainly applies here verbatim too (and vice versa), given the byte-identical raw starting point for those four files.

Given the confirmed engine match to zzfy/moniHuafu, every fix pattern those two libs' own NOTES.md documented was checked directly against this archive's actual source (not reapplied blindly) before the first boot attempt.

Fixes applied

1. AGENTS.md §15h (GBK byte-range Chinese detection) — same shape as every other lib in this lineage, confirmed present verbatim: - adm/simul_efun/chinese.lpc's is_chinese(): GBK lead-byte range check (strlen(str)>=2 && str[0] > 160 && str[0] < 255) → CJK Unicode codepoint range check (strlen(str)>=1 && str[0] >= 0x4e00 && str[0] <= 0x9fff). - adm/daemons/logind.lpc's check_legal_name(): byte-count bound (< 2 || > 12) halved to character count (< 1 || > 6) — the message ("必须是一到六个中文字", "must be 1 to 6 Chinese characters") already stated the correct character bound; removed the i%2==0 even-byte-offset gate so every character position is actually checked instead of every other one. - Verified via a real interactive registration test: four different real Chinese names accepted across two driver sessions (秦风, 秋月, 令狐冲, 任我行 — 1-, 2-, and 3-character names), each reaching the actual game world.

2. AGENTS.md §15p (DNS/intermud daemon preload exclusion): adm/etc/preload listed /adm/daemons/network/dns_master — removed it (unreachable boot-server handshake in this sandboxed environment).

3. AGENTS.md §15u (dormant phone-home license-check neutralized): adm/daemons/securityd.lpc's checking_status(mapping info) is a circa-2000 anti-piracy check that, if a matching magic string (crypt(content, "jqp5JO9YfN2Dk") == "jqp5JO9YfN2Dk") is ever seen in an inbound payload, deletes the ENTIRE mudlib (rmhirdir("")) and shuts down the driver (shutdown(0)). Confirmed genuinely *reachable* (unlike the moniHuafu instance, which was unreachable) — called from adm/daemons/network/services/gtell.lpc's incoming_request(), itself part of the intermud/DNS subsystem gated behind dns_master (excluded above, fix #2), so unreachable in this sandbox regardless. Neutralized the destructive body as cheap insurance per §15u's standing guidance (function kept, in case anything depends on the call succeeding harmlessly; body replaced with a no-op).

4. A \bstatic\bnosave blanket-sed counterexample (AGENTS.md §3's moniHuafu precedent), found independently in THREE files here: the raw archive had one real log/static/ directory on disk containing CALL_PLAYER, CRASHES, promotion, SUICIDE — but convert_lib.sh's blanket staticnosave sed rewrote the *string literal* path references to these files too, since they contain the bare word "static" as a path segment, not the keyword: - adm/obj/master.lpc: log_file("static/CRASHES", ...) → had become "nosave/CRASHES" (3 call sites). - adm/daemons/securityd.lpc: log_file( "static/promotion", ...) → had become "nosave/promotion". - cmds/std/suicide.lpc: log_file("static/SUICIDE", ...) → had become "nosave/SUICIDE". Confirmed via the raw pre-conversion GBK bytes (grep -a needed, since grep treats the GBK files as binary) that all three originally read "static/...". Reverted all three back to "static/..." to match the real on-disk directory (no /log/nosave/ directory exists or was needed). Cross-checked the whole tree for any other "static (opening quote immediately before the word) occurrence — these three were the only ones.

5. Two genuine pre-existing typos found via the lpcc_check.sh sweep (unrelated to the conversion pipeline, present in the raw archive): - d/fy/npc/gangster2.lpc's init(): used for(i=sizeof(ob)-1; ...) with int i; never declared (only object *ob; was) — added the missing declaration. Checked for the same shape (for(i=sizeof(ob)-1 with no preceding int i in the surrounding lines) elsewhere in the tree; this was the only file affected. - daemon/class/bonze/rainbow-zhi/changhongjingtian.lpc's perform(): a multi-line if(!target || !target->is_character() || !me->is_fighting(target) was missing its closing ) before the return notify_fail(...) — added it. (The adjacent "...\n"NOR string-literal-immediately-followed-by-macro idiom elsewhere in the same statement is NOT a bug — confirmed this driver supports it via several dozen other passing files using the identical "text"NOR/ "text"HIR pattern elsewhere in the lib; the *only* real defect here was the missing paren.)

6. AGENTS.md §15s (message() 4th-argument type rejection), found via the lpcc sweep and confirmed reachable in real gameplay (an NPC horse moving into a room and triggering its init()): adm/simul_efun/ message.lpc's tell_room(mixed ob, string str, object *exclude) unconditionally called message("tell_room", str, ob, exclude) — when called with only 2 args (the overwhelmingly common case, e.g. d/qianfo/tanghuai.lpc's init()), exclude defaults to int 0, which this driver's message() efun rejects at the VM dispatch level ("Bad argument 4 to EFUN message() Expected: object, array, Got: int(0)") even though f_message()'s own C++ body would tolerate it internally (confirmed by reading efuns_main.cc — the rejection happens in interpret.cc's generic per-efun argument-type check, a layer earlier than f_message()'s own lenient switch). Fixed with exclude || ({}). Checked the other functions in the same file (message_vision, shout, write, say) for the same pattern: shout()'s message("shout", str, users(), this_player()) has the same theoretical exposure if this_player() were 0, but its only caller (cmds/std/shout.lpc, a player command) guarantees a live player context, so left as-is (verified, not just assumed).

7. AGENTS.md §8e (tail() is not a real efun): cmds/adm/tail.lpc (an admin-only, non-preloaded command) called bare tail(file). Reimplemented in plain LPC per the catalog's own snippet (read_file+explode+slice-last-N-lines+write). First attempt forward-referenced the new helper from main() before its definition (AGENTS.md §8b) — the lpcc sweep caught it as Undefined function do_tail_lpc; fixed with a forward declaration.

What was confirmed NOT needed (checked directly, not assumed)

Known remaining issues (not fixed, real archive content gaps or

genuinely dead legacy code — not driver-compat bugs)

lpcc_check.sh results

Final sweep: 3750/3765 pass (99.6%). The 15 remaining failures are exactly the "known remaining issues" above (4 missing-room boards + 9 dead network daemons + 1 sweep-only #include-fragment artifact + the /cmds/adm/tail reimplementation is now passing, not counted as a failure — see the fix list above). Started at 18 failures before the gangster2/changhongjingtian/tail.lpc fixes (§ fixes 5 and 7 above), reduced to 15 (all content-gap/dead-code, none driver-compat bugs).

How to run

cd libs/fy3dz
~/src/fluffos/build-debug/src/driver config.fluffos
python3 ../../scripts/mudclient.py 127.0.0.1 40090 --timeout 25 \
  --send "yourid" --send "y" --send "你的中文名" --send "m" --send "0" \
  --send "look" --send "score" --send "quit"

(--send sequence: English id (3-10 lowercase letters) → y to confirm new-character creation → a real Chinese name (1-6 characters) → m/f for gender → 0/1/2/3 to pick 汉/苗/满/蒙古 nationality — no password step exists in this lib's registration flow, confirmed by reading logind.lpc's full input_to callback chain rather than assumed from prompt text, per the task's standing "read the actual callback" guidance.)

Verified across four full registration + look + score + quit sessions this pass, with names 秦风 / 秋月 / 令狐冲 / 任我行 — all reached the correct nationality-specific starting room, all look/score output rendered correctly, all quit cleanly dropped inventory and disconnected. Zero real errors in debug.log across all four sessions (only benign compile warnings: "Illegal to declare nosave function" from nosave functions -- §3's own footnote that this warning is harmless -- and "Unused local variable").

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

WASM-enablement pass (loopback / admin seeding)

深度功能测试 / Deep functional test (AGENTS.md §10.7, round two)

One continuous native session (native driver, scripts/mudclient.py), following the lib's own doc/help/newbie.txt as the intended test path (拜师 via apprentice, learn <skill> from <master> with <potential>, fight for safe sparring, list/buy for shop purchases). Several real Chinese-name test characters registered across the session (沈风/曲阳/ 林风/北斗), landing correctly in nationality-specific start zones (汉族 → 凤求凰客栈; 苗族 → 沉香镇/沉香南宫). look/score/i/hp all correct at every state change.

Bugs found and fixed

1. file_owner() path-depth off-by-one — confirmed live instance of AGENTS.md §7.26, adm/simul_efun/object.lpc. The original sscanf(file, "/u/%s/%s/%s", dir, name, rest) == 3; return name; returned the SECOND segment after /u/ (e.g. "npc" for /u/guanwai/npc/petowner.lpc) instead of the wizard's own directory name — correct only for the rare exactly-2-levels-deep case. Every compile diagnostic (even a harmless "Unused local variable" warning) on nested /u/ content (the normal case — npc/, obj/ subdirs) made master.lpc's log_error() write to a bogus path (/u/n/npc/log), throwing *Wrong permissions for opening file ... for append. "No such file or directory" — caught by the driver so nothing crashed visibly, but spammed debug.log with a real error on ordinary lazy compiles (reproduced live: any command that triggers a fresh compile of /u/guanwai/npc/* or /u/guanwai/obj/* content, e.g. an NPC wandering there, or an admin update). Fixed per §7.26's own established pattern: capture only the first segment after /u/ (sscanf(file, "/u/%s/%s", name, rest) == 2; return name;).

2. NEW bug class: user_path()/user_cwd() assume a letter-sharded wizard-directory layout that this archive's /u/ tree never had, adm/simul_efun/path.lpc. user_cwd(name) returned "/u/" + name[0..0] + "/" + name (e.g. /u/g/guanwai/, the ES II-family letter-sharding convention seen elsewhere in this project), but this archive's actual /u/ tree is flat (/u/guanwai/, /u/palace/, etc.) — confirmed present in the RAW, pre-conversion archive too (raw/fy3dcb/风云典藏版/u/ has the same flat layout), so this is a pre-existing mismatch in the original code, not something the conversion pipeline introduced. Only 3 call sites lib-wide (cmds/adm/cd.lpc, adm/obj/master.lpc's log_error(), path.lpc itself), both wizard/admin-facing: bare cd (no argument) resolved to a directory that never exists for EVERY wizard (没有这个目录。), and — chained with bug #1 above — even after fixing file_owner(), log_error() still failed one level further down (/u/g/guanwai/log instead of /u/guanwai/log) until this was also fixed. Fixed by dropping the letter-shard segment: return ("/u/" + name);. Verified live after a fresh driver restart: update /u/guanwai/npc/petowner now recompiles cleanly with zero debug.log errors, and cd ~guanwai correctly resolves to /u/guanwai/ (bare cd for fluffos itself still reports "没 有这个目录" — expected, since the seeded admin account has no real /u/fluffos/ wizard-content directory of its own, not a bug). Likely affects other ES II-lineage siblings with a flat /u/ archive layout — worth a quick ls u/ + grep user_cwd\( check on fy3xd (confirmed byte-identical master.c/ simul_efun.c/securityd.c/chinese.c to this lib per the lineage table above) and the other 风云3 siblings.

3. cmds/usr/save.lpc's unguarded environment(me)->query(...) — same class as the already-fixed AGENTS.md §7.14 instance in cmds/usr/quit.lpc (same lib, explicit code comment there credits "Same fix as fy2qh/fy2"). The save command's valid_startroom check dereferenced environment(me) without a null guard; quit.lpc's sibling call site already carries the defensive if (environment(me)) guard for the identical post-registration-race class, but save.lpc was missed. Added the same guard (if (environment(me) && environment(me)->query(...))). Not independently reproduced live (the race window is narrow and this lib's enter_world() has no intervening input_to pause that would make it easy to hit), but the fix is cheap, safe, and directly mirrors an already-established, already-fixed pattern in the exact same file tree — applied proactively per AGENTS.md's own "port to every sibling immediately" guidance, scoped here to a sibling call site within the SAME lib rather than a different lib.

Confirmed working (no bug)

Not independently verified this pass (honest gaps)

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

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

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

Deep functional test round three (2026-08-14)

Independently re-verified against current code rather than trusting the round-two writeup above. All 3 prior fixes confirmed still present and live-re-exercised. Found and fixed a fourth bug — the same cmds/wiz/update.lpc-class present(environment(me)) crash found repeatedly this session, but at this lib's own alternate path (cmds/adm/update.lpc), which the original 135-file corpus sweep didn't cover. That discovery led to a small follow-up sweep across the corpus for the same alternate path — see the separate corpus sweep: cmds/adm/update.lpc commit for the other 5 libs found. Plus the two now-standard checklist gaps (file.lpc hardening, one printf leak).

New fix: cmds/adm/update.lpcpresent(file, environment(me)) crash, alternate path

Byte-identical crash shape to the one found on xiakexing2017/ dtslmud/dtxywzxzb earlier this session, just living at cmds/adm/update.lpc instead of the more common cmds/wiz/update.lpc — this lib doesn't have a cmds/wiz/ directory equivalent. Fixed with the same environment(me) && guard. Live-verified: update /u/guanwai/npc/petowner succeeded cleanly.

New fix: adm/simul_efun/file.lpc — same §7.11-class gap as siblings

log_file() missing assure_file(), cat() missing a null-guard. Fixed both (with the forward declaration this driver requires).

New fix: one active printf("%O\n", ob) debug leak in logind.lpc

This lib only has the manual-name-entry branch (get_resp() is forward-declared but never implemented, so there's no separate random- name-accept path to check) — one leak found and removed.

Re-verified live: all 3 round-two fixes still hold

Verification method

Booted native build-debug driver, admin login (fluffos, no password step in this lineage — confirmed flow, not a bug). update /u/guanwai/npc/petowner and cd ~guanwai as the real privileged-action checks that also re-exercise the two path-fix bugs. Two full rapid reconnects, both clean. work/log/debug.log line count checked before/ after (357→363, only harmless compile warnings, zero error-signature matches for either original bug). Driver killed by exact PID after testing; incidental fluffos.o save-timestamp churn reverted before commit.

Files modified this pass

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

#define ROOM "/std/room":删除 662 处多余的、独立成行的 replace_program(ROOM);(保留 inherit ROOM;),全部由脚本自动 删除,无任何历史遗留的 //-注释实例、无异常格式。本库没有任何在 游戏内建造房间的工具(roommaker/rmmaker 等名称均未找到),因 此没有"工厂"侧需要修复。已用 build-debug 驱动干净启动验证(0 个 新增编译错误,端口 40090 正常监听,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.

Round-four (§10.7), shop purchase gap — investigated, NOT resolved (2026-08-21)

Narrowly-scoped follow-up dispatch, targeting only the round-three honest gap "Shop purchase / economy" above. Goal: use the project's sanctioned admin clone+give pattern (documented working on sibling libs, e.g. xjcq2000's NOTES.md: clone /clone/money/silver 60 as the fluffos admin, then buy at a real vendor) to fund a real purchase and verify price deduction + item receipt.

Blocked at the tooling level, not the game-logic level: this specific archive has NO admin object-manipulation command of any kind — no clone, goto, eval, summon, or transfer. Confirmed via:

Per this dispatch's own explicit scope guidance ("if you find yourself building elaborate test scaffolding... STOP and reconsider... report back and let the orchestrator decide"), did not add any new .lpc command file to work around this (would be new scaffolding, out of scope) and did not hand-edit a player save file to inject money (not the sanctioned pattern, and not attempted). The gap remains open; resolving it would require either accepting a save-file-edit workaround or an organic in-game earn path (e.g. beg, gated behind 丐帮/Beggar-sect membership and a skill check — itself a multi-step setup beyond this dispatch's bound) as a future dispatch's explicit scope, not a clone+give shortcut, since that shortcut's prerequisite commands simply don't exist in this archive.

Fast standard-checklist pass (static, no live boot needed — no code changes resulted)

All confirmed already clean/fixed on this lib's current code:

No code was modified this pass; no new debug.log errors to check since no driver boot was performed (the checklist items above were all resolvable via static reads, and the shop-purchase task itself never reached a boot because the blocking discovery was made first).

Round-four (§10.7), combat progression to death/respawn — REACHED (2026-08-21)

Narrowly-scoped follow-up dispatch, targeting only the round-three honest gap "Combat progression to death/respawn — not reached." No admin clone/goto/stat-grant exists on this lib (see the shop-gap entry above), so this pass reached a real lethal fight entirely through organic travel and the real kill command, using a raw Python telnet script (not tmux_mud.sh).

Fast standard-checklist pass

No code was modified this pass (nothing needed fixing — combat, wimpy, unconscious, and death/respawn all worked exactly as coded). Test character beidouxia/北冥霜 was left at DEATH_ROOM (/d/death/gate) with 1 recorded death; its plaintext password is not recorded here per this project's standing convention. Driver killed by exact PID (1093280, confirmed via readlink -f /proc/1093280/cwd == this lib's work/ before killing) after testing.