info.html · 介绍 · play.html · 游玩 · llms.txt · 下载与本地运行 · ZIP · GitHub
和 `sjplgfjxb`(书剑飘零官方教学版)同属飞白工作室的《书剑飘零》ES II 引擎家族,这份档案用的是 `adm/daemons/securityd.lpc`(没有 `sjplgfjxb` 那种 `securd`/`securityd` 双档案混淆的问题),而且与同一批档案里的 `sjpl2`(书剑飘零II)其实是同一次发布的两份快照——两者约 13,073/13,080 个档案路径相同,其中 98.2% 逐字节一致,应理解为一份发布分别打包成 zip、rar 两种形式的结果,而非各自独立开发的游戏。出生时可选四种"家境"(书香门第/商贾之家/贫寒农家/武力世家),各自带来不同的初始技能与出身技能(商贾之家带交易术、贫寒农家带乞讨术),实际出生地点也随之落在山东泰安或沿海福州的对应民居,而非固定的单一新手村(巫师权限账号仍会被固定送到长安城"大慈恩寺",是刻意的巫师起始点设计,与出生状况选择无关)。拜师用的 `apprentice` 指令身兼二职:第一次拜师加入门派,此后再敲同一指令则变成向师父磕头请安,能提升自己在门派中的地位。门派之外还有一套"江湖营生"玩法:山东粮店/马场可以打工赚钱,福州街头看卖艺人表演能长拆招技能,沿海船坞能造船出海捕鱼、练徒手搏击,这些都能换取潜能或江湖阅历。地图规模明显大于 `sjplgfjxb`:除了共享的长安"大慈恩寺"新手区,还有一整套皇宫场景(大殿、丹凤门、白虎/青龙门等)以及杭州、苏州、宁波、扬州、襄阳、成都、武汉等多座城市。
English
A Feibai Studio "Stray Book and Sword II" title on the ES II engine, sibling to sjplgfjxb (the Official Tutorial Edition, a trimmed subset of this same base). Like sjplgfjxb, a character's "birth circumstance" (scholarly/merchant/poor-farmer/martial family) sets both starting skills and actual starting location (a home in Tai'an, Shandong, or Fuzhou) rather than a single fixed newbie village; Chang'an's Great Compassion Temple is only a fallback for a failed saved-room load, though wizard-level accounts are always routed there regardless of birth circumstance, by design. The `apprentice` command does double duty — first use joins a sect, later uses become a respect-paying gesture that raises standing within it. Beyond sect life there's a whole "jianghu livelihoods" layer: day-labor at a grain store or horse ranch in Shandong, watching street performers in Fuzhou to pick up dodge/counter techniques, and building boats at a coastal shipyard to fish or practice unarmed combat, all convertible into potential or worldly experience. Its map is noticeably larger than sjplgfjxb's, adding a full imperial palace complex (main hall, Vermilion Bird Gate, White Tiger/Azure Dragon gates) plus the cities of Hangzhou, Suzhou, Ningbo, Yangzhou, Xiangyang, Chengdu, and Wuhan. Sibling sjpl2 elsewhere in this archive carries the exact same Chinese title (书剑飘零II) and turns out to be far more than a same-family engine relative: 13,073 of ~13,080 files share a path between the two archives, and 98.2% of those are byte-identical, indicating they are two snapshots of the same Feibai-Studio release (one .zip, one .rar) rather than independent games.
README
本次修复的 bug
WASM 启动/注册流程本身确实一次性顺利通过(sjplgfjxb 的
report_error()/CHANNEL_D 编译期递归崩溃、未定义的 REMOTE_DIR
这两个 bug在这个快照里确实不存在),但后续 §10.7 深度功能测试发现:
sjplgfjxb 的另外三个 bug——d/fuzhou/npc/chess_player.lpc 编译期
error(自由函数误用 feature/name.lpc 的 name(int raw))、
adm/daemons/logind.lpc 的两处 printf 路径泄漏、obj/board/
wizard_j.lpc 的 /std/jboard 版 §7.86 留言板崩溃——在 sjplii
里其实同样存在,均已修复并在原生驱动上逐条验证(细节见
NOTES.md "深度功能测试"一节)。此外还独立发现并修复了 sjplgfjxb
没有的第四个问题:adm/daemons/emoted.lpc 的存档 data/emoted.o
里有一段从未转换成 UTF-8 的遗留 GBK 字节,导致 preload 时
restore() 抛出未捕获异常(§7.41 类);已给 restore() 包一层
catch() 并补上空 mapping 兜底。
管理员账号通过标准方式写入 /adm/etc/wizlist——需要注意的是这份档
案下还散落着好几个同名的 securityd.lpc/wizlist
(adm/、adm/tmp/、adm/daemons/bak/),已经用
include/globals.h/login.h 里的宏定义确认真正生效的是
adm/daemons/securityd.lpc + adm/etc/wizlist 这一对。
管理员账号 / Admin account
- ID:
fluffos - 密码 / Password:
Mud@2026 - 权限 / Level:
(admin),通过/adm/etc/wizlist授予。
警告:对外公开架设前请务必修改此密码。
本地运行
cd libs/sjplii
~/src/fluffos/build-debug/src/driver config.fluffos游戏端口:40153。
NOTES · 移植与修复记录
WASM 修复摘要(迁移自 meta.json 的 group_note)
sjplgfjxb 的手足档案(同一个飞白工作室《书剑飘零》ES II 代码库家族,这次用的是 adm/daemons/securityd.lpc——没有 securd/securityd 分裂,没有双档案混淆)。和 sjplgfjxb 不同,这份快照启动和注册都干净,完全不需要任何修复——sjplgfjxb 的那些 bug(report_error/CHANNEL_D、未定义的 REMOTE_DIR、损坏的 emote 存档)在这里都不存在。管理员账号播种:fluffos (admin) 加入 adm/etc/wizlist(已通过 include/globals.h 和 login.h 确认 SECURITY_D/WIZLIST 具体解析到的是 adm/daemons/securityd.lpc 和 adm/etc/wizlist——这份档案还带着好几个其它名叫 securityd.lpc/wizlist 的档案,分别在 adm/、adm/tmp/、adm/daemons/bak/ 下,都不是真正被使用的那些,符合既定的 §7.56 提醒)。已验证:完整注册(id→确认→名字→密码→确认→电子邮件→性别→出生地选择)→look/score/quit 全部干净,权限正确显示 (admin),update 成功。LPC 格式化工具对全部 12421 个档案运行;还原了 2 个其实是纯文本 Windows dir 指令输出、被粘贴成 .lpc 扩展名的档案(不是真正的代码,格式化工具试图把它们当 LPC 重新排版导致损坏),另外还有 3 个确认有真正 CJK 重新加空格损坏的档案,都是通过"去空格后比对旧档案"扫描(覆盖 68 个格式化工具触碰过的档案)找到的;另外直接逐一比对了全部 3 个 map.lpc 档案——全部干净,只是排版调整。格式化后重新验证过,干净。
§7.86 跨库扫描修复(留言板 post 崩溃)
BULLETIN_BOARDinherit+ 多余replace_program()致命形状(AGENTS.md §7.86,post命令崩溃):全档案 44 处命中,已删除多余的replace_program(...)调用(保留inherit),逐文件保留原有行尾格式(CRLF/LF 按文件原样)。本次为跨库 §7.86 扫描修复(触发原因:该 bug 已在 6+ 个互不相关的血统家族独立确认,属于近乎普遍的拷贝粘贴模式),仅做编译检查(驱动干净启动、端口正常监听),未做完整 §10.7 深度游玩测试。
深度功能测试(§10.7,2026-08-08)
README.md/上面的 WASM 摘要曾写"sjplgfjxb 的那些 bug 在这里都不存
在"——本次逐条独立核实后需要部分更正:chess_player.lpc 编译错误、
logind.lpc 的 printf 泄漏、/std/jboard 的 §7.86 变体这三个 sjplgfjxb
发现的 bug,在 sjplii 里同样存在(同一个飞白工作室代码库家族,同源
程度比先前认识到的更高);只有 report_error()/CHANNEL_D 崩溃、未定义
的 REMOTE_DIR、emoted.lpc 存档损坏这三个 sjplgfjxb 独有的 bug 真的不
在 sjplii 里——不过 sjplii 自己另外还有一个不同位置的 §7.41 类损坏存
档(见下)。都已在原生驱动上逐条改前/改后验证。
本次修复的 bug
1. 一处真正的编译期 error(AGENTS.md §7.35 类,object-vs-string
参数类型不匹配,裸调用触发硬编译错误):d/fuzhou/npc/chess_player.lpc
(棋摊老板"韦守儒")第 39-40 行 play_chess() 里
printf("%s", name(this_player())); 和
command("give chess to " + name(this_player())); 把继承自
feature/name.lpc 的本地方法 varargs string name(int raw)(取*自
己*的名字,参数是"要不要去头衔"的整数开关)当成"取对方名字"的自由
函数误用,传了一个 object 给一个只接受 int 的参数。驱动的静态类
型检查在裸调用上直接拒绝:Bad type for argument 1 of name ( int vs
object ),导致这个 NPC 档案全程无法编译,福州"茶馆"填充它时会级联
*No program in object 报错。修复:删掉那行调试用 printf(§7.34
同款,无意义调试输出),command(...) 改为
this_player()->name()。改前:update /d/fuzhou/npc/chess_player
报上述两行 error;改后:成功!(只剩 /std/char/npc.lpc 两行无
关的 Unused local variable warning)。全档案 grep
name(this_player() 及类似形状未发现第二处。
2. 两处 §7.34 类调试遗留:adm/daemons/logind.lpc 的 get_resp()
(第 293 行)和 get_name()(第 328 行)各有一行
printf("%O\n", ob);,紧跟在中文名字确认之后、密码提示之前,把登
录物件的内部路径(/obj/login#N)原样打印给玩家。已各删一行。改
前后用全新注册的 fluffos(中文名"云中鹤")验证:改前会在"您的中
文名字:云中鹤"后多印一行 /obj/login#0;改后中文名字确认后直接
跳到"请设定您的密码:",无路径泄漏。
3. §7.86 类第三个变体:obj/board/wizard_j.lpc(巫师"工作进度报
告"板,/d/wiz/jobroom)inherit "/std/jboard"; 之后 create()
尾巴又多余调用了 replace_program("/std/jboard");——与已扫描修复的
44 处 BULLETIN_BOARD 实例是同一致命形状,只是基类叫
/std/jboard.lpc,命令动词也不是 post 而是 project/report
(do_project()/do_report() 同样用
this_player()->edit((: lfun, ... :)) 建闭包)。已删除多余的
replace_program()。改前:全档案 §7.86 扫描时只做过编译检查,未做
过实机验证;改后:以 fluffos 管理员账号在 /d/wiz/jobroom
执行 project 深度测试计划 → 输入正文 → . 结束,新工作计画提
出。,无崩溃;update /obj/board/wizard_j 单独重新编译也确认无报
错(只有一条无关的 Unused local variable 'myid' warning)。全档
案已确认再无第二处 board 相关的 inherit X + replace_program(X)
同名组合(用 BULLETIN_BOARD/BBS_BOARD//std/jboard/
/std/bboard 分别 grep 过 45 个继承过任一板类的档案,逐一反查其
replace_program)。
4. 一处新的 §7.41 类损坏存档(sjplgfjxb 没有这一个,是 sjplii
自己独有的):adm/daemons/emoted.lpc 的 create() 对自己的存档
data/emoted.o 做未加保护的 restore(),preload 时抛出未捕获异
常(*restore_object(): Invalid utf8 string while restoring
emote.,冒泡到 master.lpc 的 preload() catch,说明 create()
没跑完,emote 变量停在未初始化状态)。用 Python 检查
data/emoted.o 二进制内容,第 58 字节起有一段确认是遗留的 GBK 字
节(\xbf\xb4\xbf\xb4$n\xcd\xb7... 等),从未在原始编码转换阶段
被转成 UTF-8——这是货真价实的损坏存档,不是驱动或 harness 的问题。
修复(与 sjplgfjxb 完全一致的写法):create() 里把
if (!restore() && !mapp(emote)) emote = ([]); 改成
catch(restore()); if (!mapp(emote)) emote = ([]);。改前:驱动启
动日志里这行异常会冒泡到 master.lpc 自己的 CATCH()(错误讯息
被拦截);改后:异常被 emoted.lpc 自己的 CATCH() 拦下(调用链
多了一层 emoted.lpc 的 CATCH() 第 43 行),create() 正常跑完,
emote 兜底成空 mapping,驱动其余启动流程无变化。
排查过程中确认"不是 bug"的现象
- 出生地机制与 sjplgfjxb 不完全相同,取决于账号权限:
sjplii的enter_world()(adm/daemons/logind.lpc第 545-547 行)里有一行if (wiz_level(user) > wiz_level("(apprentice)")) user->set("startroom", "/d/city/ciensi.lpc");——任何权限高于学徒 的账号(含刚播种的fluffos管理员)在enter_world()里会被强 制把出生房间覆盖成长安城"大慈恩寺",无论角色创建时选的是哪种"出生 状况"。这不是 sjplgfjxb 那种"仅在load_object(startroom)失败时才 退回大慈恩寺"的兜底逻辑(那段兜底逻辑在sjplii里也存在, 第 585-592 行,两者并存、互不冲突),而是刻意为巫师账号设计的固定 出生点。实机验证:fluffos((admin) 权限,选"武力世家")落地在/d/city/ciensi;同一次会话另外注册的非管理员一次性测试角色sjplcheck(中文名"赵日天",同样选"武力世家")落地在/d/fuzhou/minzhai4(start_loc[3],与出生状况选择完全对应)。结 论:普通玩家的出生地机制与 sjplgfjxb 一致(按出生状况落在山东/福州 对应民居,长安城只是load_object失败时的兜底),但巫师账号有一 条独立的、非 bug 的固定出生点覆盖规则,测试或验收时不要用巫师账号 的落地房间去判断出生地机制是否正常。 - "游客"NPC 一度像是
kill/present()失效:在白虎大街kill youke反复报"这里没有这个人。"——追查后发现单纯是这个 NPC 恰好在指 令送达的同一瞬间被自己的chat_msg/random_move()带离了房间(游 客走的方向和我确认剩余在场角色的时机凑巧撞上),不是id()/present()出问题;换一个更强、更常驻的目标(d/fuzhou/npc/ bing.lpc系或城门"小兵")后战斗流程完全正常。 std/jboard.lpc的post指令实际上不存在:这份板子的动词是project(开新计画)/report(对已有计画提交进度)/read/terminate,不是post——房间里同时摆着一个普通BULLETIN_BOARD(短 id"board")和这个jboard(短 id 同样含"board"),裸打post <标题>会命中前者而非 jboard,一开始容易误判 jboard 修复没生 效;确认要用project <标题>才能真正触雷 jboard 自己的do_project()闭包路径。
已验证正常工作(原生驱动,fluffos/Mud@2026 管理员账号 + 一个
一次性非管理员测试角色"赵日天"/sjplcheck)
- 完整注册流程(英文 id → 确认 → 中文名字 → 密码 → 确认 → 邮箱 → 性 别 → 出生状况)→
look/score→ 二次连线(get_passwd重新连线路 径,非首次注册路径,显示"重新连线完毕")全部干净;整场会话debug.log未被写入任何新内容(仍是转换时期留下的旧文件),log/log里除已知的Unused local variablewarning 外无任何错误 或崩溃痕迹。 - 移动:长安城内多个房间(大慈恩寺→白虎大街→启夏门→曲江池等)、福 州街区(民居→街道→十字路口)均正常,房间描述、出口、NPC 列表显示 正确。
- 留言板:
大慈恩寺的普通板post/look board正常;/d/wiz/ jobroom的job board(jboard 类)project正常(见上方修复第 3 条)。 maximum evaluation cost : 700000全程未触发cost limit reached,不需要按 §7.90 上调。- 战斗与死亡/复活全流程:
fluffos管理员角色用kill bing(启夏门城 门"小兵",combat_exp30000)触发正常攻防交换与wimpy驱动的自动 逃跑("看来该找机会逃跑了...");再用管理员call指令把自己的eff_kee强制设成负数确认了die()→鬼门关→白无常的死亡流程本 身能正确触发,但d/death/npc/wgargoyle.lpc的init()与 sjplgfjxb 一样带wizardp(previous_object())早退(第 58 行),巫师 幽灵永远不会被排定death_stage(),只会看到白无常的闲聊chat_msg——之后用管理员be_ghost(0)+ 手动恢复三维属性 +move()把fluffos救回人间。**随后另注册的非管理员一次性角色"赵日天" (sjplcheck)用wimpy 0关闭自动逃跑,攻击福州街头一个明显更强 的游走 NPC"彩衣双剑"费慎(npc/newnpc/feishen.lpc,combat_exp随机 10-80 万),完整打满五阶段死亡对话("喂!新来 的,你叫什麽名字?"……"罢了罢了,你走吧。"),reincarnate()后因 角色combat_exp未超过一万走了ob->move("/d/fuzhou/duchang")分 支,正确复活在福州"赌场",score确认状态完全恢复、无【鬼魂】残 留、无任何崩溃或debug.log报错——本次是这次深度测试系列里少数几 个真正走完完整死亡/复活循环(非管理员、真实战斗触发,非管理员强改 属性)的例子之一。death_stage()本身仍带着 AGENTS.md §7.68 已撤回 的裸 guard 形状(if (!ob || !present(ob)) return;),但本次全程未 中断触发过这个分支(复活是一次不受打扰的完整顺跑),没有新证据支持 或反对 §7.68 的旧修补,按撤回结论不做任何改动。 - 食物/饮水初始化:
adm/daemons/logind.lpc的init_new_player()里 直接、无条件地user->set("food", user->max_food_capacity())/set("water", ...),不经过任何age判断,不是 §8.9 那种"检查错误 对象 age"的形状,两个测试角色食物/饮水均正确初始化为满值。
管理员账号播种
adm/etc/wizlist 里此前已有 fluffos (admin) 一行,但账号本身
(data/{login,user}/f/fluffos/)此前从未被真正注册/提交过——已确认
不存在。本次走标准注册流程创建(id fluffos,中文名"云中鹤",密码
Mud@2026),登录后 目前权限:(admin) 立即正确显示(无需额外的
WIZ 密码之类的二级门槛,securityd.lpc 是这份档案里唯一、真正生效的
安全精灵),update /d/fuzhou/npc/chess_player、update
/obj/board/wizard_j 两次写权限验证都成功。测试用的一次性非管理员账
号 sjplcheck(中文名"赵日天")及测试留言板存档(大慈恩寺板、
wizard_j 板各一条测试留言/计画)已在提交前删除,只保留
fluffos 的账号存档。
§7.100 房间基类 replace_program() 扫尾修复(2026-08-19)
ROOM 宏(/std/room)在本档案 2,290 处房间文件的 create() 里
紧跟 inherit ROOM; 之后又多余调用了一次 replace_program(ROOM);
——和姊妹档案 sjpl2(同一份 书剑飘零 血统,房间生成工具家族逐字
节相同)完全一样的 AGENTS.md §7.100 休眠 bug。用 fix_710_room.py
扫过 work/,删除 2,280 处标准形状;另有 9 处不规则形状手工修复,
和 sjpl2 的处理逐一对应:obj/roommaker.lpc 字符串拼接变体、
4 份房间生成工具副本 + 2 份内嵌同一段代码的 NPC 档案
(u/lark/xiaoyao/npc/{rich,tumu}.lpc、u/jakey/npc/rich.lpc)里
"仅当房间没有 item_desc 时才拼接" 的条件变体(u/losey/roommaker.lpc
u/set/obj/roommaker.lpc、u/gdjk/roomm.lpc、
u/gdjk/hongnong/maker.lpc),以及 u/lark/yangmingzhai/ss.lpc
一处真实房间文件(replace_program 紧跟在已注释掉的
/* setup() */ 后面同一行)。u/lark/luoyang/dongmen.lpc 剩下 1
处留着未修:整份文件从 inherit ROOM(无分号)起就缺失几乎全部语
句分号,确认是转档之前就已经损坏、与本次改动无关,和 sjpl2 同一
份损坏文件的表现一致。git diff --stat 显示 2284 个文件净删 2289
行,与 sjpl2 完全对称吻合;另有 150 处转档之前已注释掉的 // 行
原样保留。work/data/ 下没有真实 .lpc 源码命中。
驱动干净启动(零新增编译错误、端口正常监听、debug.log 无任何
"cannot replace"/"cannot bind"行),巫师账号
fluffos/Mud@2026 确认"目前权限:(admin)"后 look/goto 走读
了 y/city/baozipu.lpc(曾经命中过这个 bug 的房间)正常,quit
干净退出。走读时另外撞见 y/city/baihu-n1.lpc 一处转档之前就存在
的 NPC_DIR "people/man" 宏拼接语法错误(git diff 确认本次改动
只碰了 replace_program 那一行),与本次 sweep 无关,不在修复范
围内。登录存档的增量已用 git checkout HEAD -- 撤销,未落入提交。
§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: 45 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).
same as sjpl2 (shared lineage): feature/damage.lpc's revive() calls this_object()->enable_player() 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.
深度功能测试(2026-09-03,第三轮)
新角度:2026-08-08 第一轮已经走完注册、战斗、完整死亡/复活和留言板。
本轮补商店,并尝试红旗镖局拜师。手足 sjplgfjxb 同一轮刚修过缺失
dishes/ 键把整张货表拖垮的 bug;这份完整档带着
d/city/obj/food/dishes/dish*.lpc,预期不会踩那个洞。
- 商店(通过,菜谱是齐的):管理员落地在鬼门关(上一轮死亡测试把
fluffos的 startroom 留在/d/death/gate,不是新 bug)。goto /d/city/kezhan,list列出烤鸡腿 / 包子 / 牛皮酒袋 / 油辣猪 排,以及十道真正的dishes/菜(油炝大虾、红烧素鹅、京酱肉丝等)。clone /obj/money/gold后buy fried chicken leg from waiter成功 (「你向店小二买下一根烤鸡腿」),找零七十文 + 九十九两银子。feature/vendor.lpc没有缺档崩溃。不需要把sjplgfjxb的file_size守卫搬过来——这边货物档案都在。 - 拜师(续完,不是
input_to/command()的 bug):上一小段 停在「你想要拜庄容为师。」、score仍是普通百姓。本段冷启动复 核:庄容living()为真(apprentice的弄醒检查能过)、query_path()是({ "/cmds/std/" })、find_command("recruit")能解析到/cmds/std/recruit、command_hook也挂在 NPC 的 sentence 上。巫师call zhuang->command("say …")返回 0 是假阴 性——call走call_other,找不到 LPC 函数command,碰不到 efun;call -Root zhuang->force_me("say 探测命令")成功(「庄容 说道:探测命令」)。force_me("recruit fluffos")在 pending 已 经设好时仍返回 0,且没有任何「禁止玩家收徒」提示。 根因是测试号还是鬼魂:call me->is_ghost()= 1(2026-08-08 死亡测试留下的ghost标志;enter_world()见鬼魂就强送/d/death/gate,所以看起来像 startroom 被留在鬼门关)。feature/name.lpc的id()先问this_player()->visible(),std/char.lpc的visible()对非鬼魂观察者隐藏鬼魂,于是庄容的present("fluffos")找不到人,recruit.lpc走notify_fail(失败句写在 NPC 身上,玩家看不见)。input_to确认步本身没问 题:be_ghost(0)之后原样apprentice zhuang→ 再输入zhuang→「庄容决定收你为弟子」「恭喜您成为红旗镖局的第四代弟子」。score为「红旗镖局趟子手」「你的师父是庄容」。save后同进程 重连、以及杀掉驱动冷启动再登,都还在;冷启动落地大慈恩寺(巫师wiz_level > apprentice的 startroom 覆盖),不再进鬼门关。 未改apprentice.lpc(中途试过拿掉input_to/call_out推迟, 都已还原)。 save:拜师后save回「档案储存完毕。」- 日志:live
debug.log为libs/sjplii/log/debug.log。本轮无error:/Too deep recursion/couldn't find object。work/log/log只有编译警告。 - 结论:燕云客栈
list/buy通过(完整菜谱)。红旗镖局拜师在 清掉鬼魂标志后通过,并跨冷启动保持。不是编程 bug。未改代码。