Legend of the Three Realms

✅ 可玩

三界传说 (San Jie Chuan Shuo)

sjcs

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

▶ 开始游玩 · Play Now

以中国古典神话"三界"(天界/人间/地府)为背景的江湖世界,新角色从长安城"南城客栈"起步,客栈内的告示板汇聚玩家心得、巫师反馈与最新更新公告。注册时天赋分配全程透明:玩家自行决定体格/根骨/悟性/灵性四项点数的分配比例,默认平均分配,也可调整后再确认;拜师体系分明,门派各有不同门槛,可先拜同门中的低阶师父再逐步靠近掌门;法术体系分修行/攻击/防御/其它四大类,涵盖飞行、变化、天眼通、天耳通等经典法术效果,`wimpy` 自动逃命阈值可自行调节比率(新手建议设高一些,50-70,以避免无谓战死),`fight`/`kill` 均支持,特殊技能需先 `enable` 才能在战斗中使用。与本项目中同样带"三界"招牌的 `sanjieshenhua` 只是名字相似,经逐文件比对确认并非同一份代码(`master.lpc`/`securityd.lpc`/`logind.lpc` 均差异显著),两者是各自独立的作品。

English

A jianghu world set against the backdrop of the classical Chinese cosmology of the "Three Realms" — Heaven, the Mortal World, and the Underworld. New characters start at the South-City Inn in Chang'an, whose bulletin board doubles as a running log of player tips, wizard feedback, and update notices. Registration exposes stat allocation directly: players split points across physique/bone-structure/comprehension/spirituality themselves (an even split by default, adjustable before confirming). The master/apprentice system is tiered by sect, letting a newcomer study under a junior disciple before working up to the sect leader, and spells are organized into four schools — cultivation, attack, defense, and miscellaneous — covering classic effects like flight, transformation, and clairvoyant/clairaudient sight. The tunable "wimpy" auto-flee threshold (recommended high, 50-70%, for newcomers) works with both `fight` and `kill`, while special combat skills require an explicit `enable` first. It shares only a name with the similarly titled sanjieshenhua elsewhere in this archive; file-by-file comparison of their master.lpc, securityd.lpc, and logind.lpc confirms the two are unrelated codebases.

README

在线试玩

https://mudlibs.fluffos.info/sjcs/

管理员账号 / Admin account

警告:Mud@2026 是本地游玩用的公开默认密码。若要正式对外开放主机,
请先修改此密码。

本地运行

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

游戏端口:40097

NOTES · 移植与修复记录

三界传说.rar → sjcs

Triage / lineage

grep -rIl inherit finds thousands of hits — genuine LPC mudlib, not a non-LPC engine. Diffed core files (master.lpc, securityd.lpc, logind.lpc) against sibling sanjieshenhua (also assigned to this batch, same "三界" branding) — all three differ substantially in line count and content (495 vs 416 lines for master.lpc, 316 vs 747 for securityd.lpc, etc.) — not a derivative pair despite the shared title prefix (per AGENTS.md §2.1's warning that titles are not a lineage signal). One coincidental match: both libs ship a byte-identical corrupted d/sea/npc/beast1.lpc (see below) — most likely just shared common ancestry several forks back (both plausibly ES-II-mega-family descendants, per AGENTS.md §11), not evidence the two archives are the same codebase. Treated as a fully independent unique game.

State at handoff (this session)

A previous agent session had already: extracted the archive, run the encoding+rename conversion, written config.fluffos (port 40097), applied the loopback-allow patch to band.lpc/securityd.lpc, fixed the privatenomask command_hook bug (3 files), disabled dns_master in preload, and registered+admin-seeded the fluffos account (wizlist entry fluffos (admin) already present, character already existed with Chinese name 浮浮). No NOTES.md/README.md existed yet. This session picked up from there, verified the existing work, and found/fixed two things the interrupted session hadn't reached yet (below).

Fixes applied this session

1. 166 files stuck as literal uppercase .C (not renamed to .lpc) — exactly AGENTS.md §4.2 item 7's known trap (the rename glob and the forced-text-extension conversion check are both case-sensitive). Spread across clone/armor/, clone/bq/, cmds/adm/, d/qujing/..., u/tonggang/... — mostly clonable weapon/armor templates and a few NPCs/commands. Verified no lowercase .c/.lpc sibling existed at the same path (so no "which one is authoritative" ambiguity, unlike AGENTS.md's zitengzhan case) before a blanket .C.lpc rename. Most were already correctly UTF-8 (the conversion pass's file-based text detection caught them fine even with the wrong extension); 6 were still raw GBK and needed an explicit iconv -f GB18030 -t UTF-8 pass after the rename (adm/CL/{SHUSHAN,HELL,MOON,LONGGONG,JJF,QIANG}.lpc). 2. 2 genuinely-corrupted files found by a full tree-wide Python UTF-8-decode scan (AGENTS.md §4.1's "stronger check"), both truncated mid-statement with a garbage binary tail in the RAW archive itself (confirmed via xxd against raw/sjcs/sjcs/world/... — not something the conversion pipeline broke): - d/qujing/start/24/12.lpc — truncated mid-carry_object(...) call; closed the file after the last complete statement with a comment noting the drop, per AGENTS.md §6.6 ("close truncated files with an empty body; don't fabricate content"). - d/obj/quest/shuijingqiu.lpc — truncated mid-call (...locate_quest(this_player(),arg + garbage); completed the obviously-intended );\n} (matching the sibling do_task() function's identical one-statement-else shape) rather than stubbing it out, since the completion was unambiguous. - d/sea/npc/beast1.lpc — trailing 2 garbage bytes (\xff\xba) right after a clean }\n\n ending; simply truncated the 2 bytes. (Same exact corruption, same byte offset, found in sibling sanjieshenhua — see that lib's NOTES.md.)

Verification (native)

Booted cd libs/sjcs && ~/src/fluffos/build-debug/src/driver config.fluffos — clean boot, zero fatal errors in log/debug.log (only the usual #pragma/unused-variable warnings).

Full registration flow (fresh id wenshua, real Chinese name 秦风): gb (encoding) → no (not-a-student gate) → new → English id (3-8 lowercase letters only) → Chinese name → password → confirm → email → gender (m/f) → gift/stat menu (9 to accept defaults, y to confirm) → entered 南城客栈 (starting room). look, score (full 个人档案 stat card), and quit all produced correct output.

Admin: logged in as fluffos/Mud@2026 (already registered by the prior session, character name 浮浮, fluffos (admin) line in adm/etc/wizlist) → update /adm/obj/master.lpc重新编译 /adm/obj/master.lpc:成功! (wizard write ACL confirmed working) → quit clean.

Verification (WASM)

node scripts/wasm_client.js ~/src/fluffos/build-wasm/src libs/sjcs — same full registration flow (fresh id wenshua, name 秦风) reached the same starting room; look/score/quit all correct. Admin login as fluffos + update /adm/obj/master.lpc also succeeded under WASM. This lib is fully playable under WASM, not just "boots" — no IP-format/sockets-absent blockers hit on this lineage's login path.

Known remaining issues (documented, not fixed)

How to run

cd libs/sjcs
~/src/fluffos/build-debug/src/driver config.fluffos
python3 ../../scripts/mudclient.py 127.0.0.1 40097 --timeout 15 \
  --send "gb" --send "no" --send "new" --send "yourid" \
  --send "你的中文名" --send "yourpass" --send "yourpass" \
  --send "[email protected]" --send "m" --send "9" --send "y" \
  --send "look" --send "score" --send "quit"

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

Native driver, port 40097, tested via raw socket (finer control over timing than mudclient.py for this lib's charset→age-check→id/New→ Chinese-name→password×2→email→gender→gift-selection wizard). Test characters: qfthree/秦风三 (password TestPassA) is a clean, fully- completed registration used for the main playthrough; qftester and qftwo are two earlier registrations deliberately left stuck mid-gift- wizard (see bug below) and kept as before/after evidence.

Bug found and fixed, live-reproduced and re-verified: d/wiz/init.lpc's init() schedules call_out("get_start0", 0, me) on every reconnect while the account's gift-selection wizard is still incomplete (no_gift still set), meant to automatically re-show the gift menu so the player isn't left wondering what happened. get_start0() tried to do this via me->command("start") — but the real command() efun (core.spec: int command(string)) takes no object argument, so this is a call_other to a method named command that is not defined anywhere on the player object (confirmed via a lib-wide grep). FluffOS silently no-ops an undefined call_other with no error raised anywhere (not even in debug.log), so this reconnect path produced zero visible output: a player reconnecting mid-wizard saw nothing at all after "重新连线完毕。" — no menu, no error, no hint — and the only way out was to already know to type the undocumented start command themselves (confirmed live: typing start manually DID correctly redisplay the menu, since that add_action registration itself works fine). Root-caused by directly inspecting data/user/q/*.o for no_gift, then confirming live with a raw-socket test that showed identical silence even after a genuine 10-second wait.

Fixed by rewriting get_start0() to replicate get_start1()'s body directly (using tell_object(me, ...) instead of write(), since write() implicitly targets this_player(), which is unset inside a call_out) and calling get_start(me) directly instead of round- tripping through the broken command() call. Also fixed show_gift() the same way (write()tell_object(me, ...)), since it's reached via the same call_out path. Verified live: after the fix, reconnecting to a mid-wizard account (qftwo) auto-displays the full gift menu within seconds with no manual start needed, matching the intended "重新连线完毕" → immediate resume UX. A fresh, uninterrupted registration (id → New → Chinese name → password ×2 → email → gender → gift accept 9+y) was independently confirmed to already work correctly end-to-end (lands cleanly in 南城客栈/South City Inn per the newbie doc), so this bug specifically affects the reconnect-while- mid-wizard path, not first-time registration.

Verified working: full registration flow, look/score/hp all render correctly with rich, properly-escaped ANSI formatting (no orphaned escape sequences), clean quit. debug.log/driver stdout show only pre-existing harmless compile warnings (unused locals, unknown #pragma) throughout — no new runtime errors from any of this session's testing.

Not verified live this pass (time budget went to the reconnect- wizard investigation above): net-dead disconnect/reconnect after actual gameplay has begun, skill learning, sect/faction join, shop purchase, combat. Given the newbie doc's own detailed skill/combat/shop instructions, this lib very likely has full playable content beyond the registration wizard — a future pass should pick up from a qfthree-style completed character and continue the rest of the §10.7 checklist.

Files modified: libs/sjcs/work/d/wiz/init.lpc (the fix above). Test character saves kept as before/after evidence rather than removed.

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

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

#define ROOM "/std/room"include/globals_old.h 也定义了同一 宏值,但该文件未被任何源码 include,是死文件,未处理):删除 479 处多余的、独立成行的 replace_program(ROOM);(保留 inherit ROOM;),475 处脚本自动删除;另有 2 份房间建造工具副本 手动修正——clone/misc/roommaker.lpc 是标准的"两套模板"简单变体 (1 处);obj/roommaker.lpc 是"3 处出现"room_code/str 变体 (一处 room_code += 拼接 + do_saveroom() 里两条分支各一处,共 3 处)。work/data 下未发现额外 .lpc 源文件。修复后全库仅剩 8 处历史遗留的 //-注释掉实例,均确认无害、未改动。已用 build-debug 驱动干净启动验证(0 个新增编译错误,端口 40097 正常 监听,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.

AGENTS.md §7.19 sweep (2026-09-01): enable_player() reentrancy from init()

Same corpus-wide bug class as mhxy/wuhanzhan (AGENTS.md §7.19): this lib's feature/command.lpc enable_player() wrapper (around the raw enable_commands() efun) is reachable from an NPC's init() via a redundant create()-then-init()-calls-setup() (or reset_me() calling setup()) chain -- confirmed live via a static scan of every init() body in this lib: 52 NPC/item files call setup() directly or via reset_me() from init(), after create() already called setup() once (which already made the object living()). Calling enable_commands() a second time on an already-living() object makes the driver re-invoke that object's own init() as a side effect, which re-enters this same chain while the original call is still on the stack -- genuine reentrancy, crashing with "Too deep recursion" (most likely to surface on an NPC's first-ever preload/compile).

feature/damage.lpc's revive() and cmds/std/sleep.lpc's wakeup1()/wakeup2() call enable_player() again while the object is still living(). This confirms a bare if (living(this_object())) return; guard would be the WRONG fix (it would silently break that legitimate re-enable) -- used the same true reentrancy-flag fix as mhxy instead: a nosave private int in_enable_player_now; set for the duration of the wrapper's body, guarding only genuine same-call-stack reentrancy while leaving every legitimate re-enable (revive/wakeup/disguise) unaffected. feature/command.lpc's enable_player() had a single fall-through exit (no early returns), so one guard-at-top + one clear-at-bottom pair was sufficient. Verified via a single-file lpcc --batch compile check (PASS) -- not individually live-boot-tested.