幸运方块 (dsh-lucky-block)
一个 dsh 插件,同时工作在 dsh web 与 dsh desktop。两件事:
- 幸运方块选项 —— AI 向你提选择题时,每个问题的选项末尾会自动多出一个「幸运方块」。
选它,就随机替你挑一个选项、或把几个选项揉成一个新方案,全随机。
不满意?说一句「回滚」(或打
/rollback),立刻回到上一版本。 - 幸运方块按钮 —— 屏幕角落一个可拖动、可锁定的我的世界幸运方块(16×16 原版方块面贴图)。 闲着没事就戳它一下:左键单点零成本,抽弹窗表演 / 假蓝屏 / 今日运气 / 冷知识 / 冷笑话; 长按 1.4 秒挖穿它,伴随裂纹、碎裂粒子和原版 Minecraft 挖石头声,接着它会在你的 默认工作区自动开一个新会话,全程不需要你做任何事地随机写篇论文 / 扒几条新闻 / 发明个东西。 松手时方块若离屏幕边缘够近(48px 以内)会自动吸附贴边。
它会说话。所有随机事件都套着一层固定的说话腔调:短句、机器口吻、偶尔损你一句。
这套腔调是纯文本的,参数在 lib/persona.js 的 DEFAULT_PERSONA 里,
可以用配置里的 persona 整段换成你自己写的性格。
它从不往会话里写东西,所以绝不会污染你的对话历史。
两个池:单击零成本,长按才花钱
脚本现在分成两个互相独立的池,触发方式不同,抽的东西也不同:
| 触发 | 代价 | 池 |
|---|---|---|
| 左键单点 | 零 token、零延迟、不建会话 | 弹窗 / 蓝屏 / 抽签 / 冷知识 / 冷笑话 / 音乐 |
| 长按挖满(1.4 秒) | 开新会话、调模型 | 论文 / 新闻 / 待办整理 |
单点是手滑也会发生的动作,所以它不该有成本;长按是明确意图,才值得花 token。 分成两个池而不是一个池加过滤,是为了让两边的权重能独立调节 —— 否则往单击池 里加十条音频,会把长按事件的命中率一起稀释掉。
单击池(10 个事件,权重合计 20)
| 概率 | 事件 | 类型 | 会做什么 |
|---|---|---|---|
| 10.0% | 无害弹窗表演 | 视觉 | 连弹 24 个无意义提示框(三种皮轮转:老式错误框 / Win11 通知卡 / 朴素框),再按创建顺序倒序全部关掉 |
| 10.0% | 蓝屏屏保(60 秒) | 视觉 | 全屏显示仿 Windows 蓝屏,三张脸随机一张,60 秒后自动恢复 |
| 15.0% | 抽今日运气 | 本地 | 抽一档签文:鸿运齐天 / 大吉 / 中吉 / 小吉 / 顺 / 平 / 凶,每档五条文案。不调 AI,附「无科学依据,仅供参考」 |
| 20.0% | 随机冷知识闲聊 | 本地 | 从 818 条本地冷知识库里抽 1 条 |
| 15.0% | 冷笑话专场 | 本地 | 从 353 条本地笑话库里抽 1~2 条 |
| 10.0% | Never Gonna Give You Up | 本地 | 放 42 秒副歌(唯一不是完整版的一首) |
| 5.0% | Who's Ready for Tomorrow | 本地 | 放完整版 112 秒 |
| 5.0% | I Really Want to Stay at Your House | 本地 | 放完整版 241 秒 |
| 5.0% | My Shot | 本地 | 放完整版 328 秒 |
| 5.0% | Satisfied | 本地 | 放完整版 330 秒 |
长按池(3 个事件,权重合计 8)
| 概率 | 事件 | 类型 | 会做什么 |
|---|---|---|---|
| 37.5% | 随机选题写论文 | AI | 随机词条拼出题目(如「边缘计算 × 古籍数字化 × 的鲁棒性研究」),写 4 节正文并落盘到 lucky-block-papers/<hash>.md |
| 37.5% | 时事新闻速览 | AI | 联网检索 3 条最近真实新闻,每条一句事实 + 一句点评 + 来源链接;查不到就直说,绝不编 |
| 25.0% | 随机发明一个东西 | AI | 发明一样不存在的东西:起名 + 解决什么问题 + 怎么工作 + 最明显的副作用,像正经产品说明 |
单击池十个全部零 token、不建会话、零延迟 —— 点下去立刻有反应。
全部单击事件都能按 ESC 提前结束
单击池的十种表演,回车同效:按一下 ESC,屏幕上正在放的东西立刻收干净 —— 弹窗不再继续弹、蓝屏直接恢复、音乐立刻停、居中长文立刻消失。 单击池里最长的表演是 330 秒的歌,没有这个出口的话,点错一次就得等五分半。
实现上是一张登记表(registerEscape),不是「当前表演」单槽:
一次单击可能同时起好几样(蓝屏 + 方块台词、音乐 + 标题、长文 + 气泡),
单槽会让后起的挤掉先起的,先起的那样就再也关不掉了。
没有表演在放的时候,ESC 完全不拦截 —— 直接放行给 dsh 自己用。 方块头顶那行小气泡故意不登记(它只占一角、6 秒自己消失, 为了它吞掉 ESC 会让用户 6 秒内关不掉 dsh 的任何东西)。
「抽今日运气」一天只抽一次:当天再点,返回的还是那一签,并在末尾注明
「今天已经抽过了,明天再来吧。」。状态记在
$DSH_HOME/plugins/dsh-lucky-block/fortune-state.json,删掉这个文件就等于当天重抽。
「抽今日运气」的签文权重是刻意偏吉的:吉类合计 87%(鸿运齐天 5% / 大吉 26% / 中吉 33% / 小吉 23%),顺 8%,平 4.9%,凶只有 0.1%; 而且**「凶」的正文是反着写的**(「从某种角度来说,你运气还挺好 —— 今天该踩的坑都提前踩完了」), 抽到下签也能笑一下。这个插件是用来打发时间的,不是用来给人添堵的 —— 所以「凶」的五条也不预告任何具体的坏事,也不写「要是有什么没办成」这种假设句。 最狠的一条干脆不给「凶」找理由,改为报概率:「这一签的概率是 0.1%,是本系统里最稀有的一种。 稀有款都这样:不一定好看,但一定难抽(差评!)」—— 不解释也不取消后果, 只是让抽到这个结果本身变成一件值得说的事。
从好到差是 鸿运齐天 > 大吉 > 中吉 > 小吉 > 顺 > 平 > 凶。 每一档有五条签文,抽到哪一档之后再在那一档里等概率挑一条 —— 所以同一档连抽两天也不会撞到同一句话。
档位权重和文案条数是完全解耦的:drawFortune() 先按权重定档,
再调 withText() 在档内挑文案。把文案摊平成一个个独立条目是很自然的写法,
但那样一来「给凶多写两条」就等于把凶从 0.1% 悄悄提到 0.3% —— 加文案不该改变概率。
「顺」是后加的第五档,插在「小吉」和「平」之间:小吉是有件小事让你高兴, 平是什么都没有,顺是没有好事、但也没有坎。 它比平多一分安心,比小吉少一件好事,所以平从 9.9% 让位到 4.9%。
音频事件
一首歌一条事件,所以每首能单独关掉。事件 id 由文件名派生:
never-give-you-up.ogg → audio-never-give-you-up。想永久关掉某一首,
在面板里取消勾选,或在 config.json 的 events 里写 "audio-never-give-you-up": { "enabled": false }。
用文件名而不是曲名当 id,是因为 id 要进 config 覆盖层、还要过
/^[a-z][a-z0-9-]*$/ 的白名单(曲名里有中文和空格过不了);
这样即使以后改了 title,覆盖配置也不会悄悄失效。
每首歌的权重默认是 1,不写 3:曲目数会随加歌增长,写死 3 的话加满十首
就会把冷知识/冷笑话的命中率稀释掉一半。想单独调某一首,在
lib/audio-tracks.json 那条里写 "weight": 2(包里 never-give-you-up 就是 2)。
lib/audio-tracks.json 里是曲库,往这个 json 填
{ "file": "xxx.ogg", "title": "显示名", "weight": 2 }、
把文件丢进 lib/audio/,事件就自动开始参与抽取 —— 不用改代码。
文件名只接受 [A-Za-z0-9_-] + .ogg|.mp3,防目录穿越。
曲库有两份查找位置,用户目录优先:先看
$DSH_HOME/plugins/dsh-lucky-block/audio-tracks.json,没有再退回随包的
lib/audio-tracks.json。第三方想扩展曲库时不用改插件包本体(插件升级会覆盖回去)。
包里带了五首,除了 Never Gonna Give You Up 是副歌,其余四首都是完整版:
| 曲目 | 时长 | 说明 |
|---|---|---|
| Never Gonna Give You Up | 42 秒 | 副歌(唯一一首切过的) |
| Who's Ready for Tomorrow | 112 秒 | 完整版,去掉结尾 4 秒静音 |
| I Really Want to Stay at Your House | 241 秒 | 完整版,去掉结尾 6 秒静音 |
| My Shot | 328 秒 | 完整版 |
| Satisfied | 330 秒 | 完整版,去掉开头 26 秒黑胶底噪 |
这五首都能按 ESC 立刻停(见上一节),所以完整版不会变成「点一下就得等五分半」。
切法写在 lib/audio/README.md。
骰子会话里你只会看到一行字
开新会话的那 3 个事件,用户消息只有一行(🎲 随机事件:时事新闻速览),
人格设定和任务正文走的是系统提示,不会糊在你眼前。
这样做纯粹是为了观感 —— 之前用户消息里塞着几百字的指令墙,点进会话第一眼就是它。
需要说明的是,宿主没有「发一条不显示的消息」这种能力(PromptContentPart 只有
text / image / file 三种,没有任何可见性字段),所以这里不是把消息藏起来,
而是根本不把它发成消息。
清单可用 node tools/list-events.mjs 随时重新生成 —— 它直接从 lib/index.js
的 buildEvents() 里解析并按池分组,不会和代码漂移。
设置面板(右键方块 → 设置…)
| 开关 | 作用 |
|---|---|
| 长按挖掘音效 | 循环挖掘声 + 碎裂声。关掉就完全静音 |
面板分三块:
方块外观 —— 大小(24~128 像素)、图案(幸运方块 / 命令方块 / TNT / 南瓜 /
自定义图片)、圆角、描边宽度与颜色、投影、背景。改动立即生效并落盘,
不用点保存。图片只接受 data:image/ 或 http(s):// 开头的地址——
blob: 在这个缓存域里用不了、file: 会被 CSP 拦下来,两种都会让图片裂开。
「恢复默认」走的和手动改是同一套校验,所以恢复回来的一定是能用的值。
随机事件 —— 每条事件一个复选框加一个权重输入框。关掉一条事件时权重会同时写 0, 两个字段说同一件事,不会出现「权重还在但事件没了」的假象。权重上限 25 (「每条事件最多占四分之一」的量级,再大就没有意义了)。
扩展接口 —— 只读显示 persona 与 prompts 这两段配置的当前值。
刻意不做成编辑器:JSON 精度要求高,直接粘贴整段更稳;
而且这里显示的是宿主回传的当前值,上一段写坏了重新打开看到的还是那段坏内容,
不会被悄悄换成默认值。
改事件权重/开关需要重启 dsh 才生效:事件池在插件加载时就建好了。 刻意不做热重载 —— 每个事件都带着自己的 prompt 与 prepare 逻辑, 热替换等于在运行期换掉一整套行为定义。
自定义事件(扩展点)
往 $DSH_HOME/plugins/dsh-lucky-block/custom-events.json 写一个数组,
就能加自己的事件。形状和内置事件一致:
[
{ "id": "my-quote", "title": "随机一句书摘", "weight": 2,
"trigger": "click", "kind": "local",
"lines": ["第一句", "第二句"] },
{ "id": "my-summary", "title": "让 AI 总结点什么", "weight": 3,
"trigger": "hold", "kind": "agent",
"prompt": "随便挑一个话题,写三百字。" }
]
kind: 'local' + lines 从里面随机挑一行当正文(零 token);
kind: 'agent' + prompt 把 prompt 当任务发进新会话(走 AI)。
任何一条不合格就整份忽略,原因显示在设置面板底部 —— 半份生效会让「我加的事件怎么没动静」变成一个只能靠读日志排查的问题。 没有这个文件是完全正常的状态(面板会写「0 条」)。
自定义事件的 id 不能和内置事件重名:重名时内置赢, 第三方文件无法覆盖内置行为。原因是内置事件的 prompt 与 prepare 都在代码里写死, 一个只带 id/weight 的 JSON 造不出真的行为。
面板里还列着事件清单,每条事件标着它属于单击还是长按 —— 照着这张表就知道点一下会发生什么、要不要花 token。
冷知识和冷笑话现在固定走本地库,不再有「调不调 AI」的开关: 它们本来就在单击池里,单击不该有成本,给一个勾选框只会让人以为这里能省钱。
| 本地库 | 条数 | 位置 |
|---|---|---|
| 冷笑话 + 点评 | 353 条 + 30 条 | lib/jokes-data.json |
| 冷知识 | 818 条(人体 133 / 动物 139 / 科学 121 / 日常 111 / 历史 111 / 地理 103 / 语言 100) | lib/trivia-data.json |
| 曲库 | 5 首(42 / 112 / 241 / 329 / 330 秒) | lib/audio-tracks.json + lib/audio/ |
冷知识库里分主题存的 topic 只用于统计,永远不显示给用户 —— 显示主题等于
把「这是一条从哪抽的」直接摊开。笑话的 form 字段同理。
两个库的完整内容可以在 lib/语料库总览.md 里逐条翻阅;
那份文件由 node tools/build-corpus-overview.mjs 从运行库生成,改动语料后重跑即可
(--check 用于回归时校验它没过期)。
写进配置也会被忽略并记一条警告。
配置里 events 字段是事件的权重/开关覆盖层(读-改-写,不整份覆盖 ——
model / persona 也在同一个文件里):
{
"sound": true,
"events": {
"trivia": { "weight": 8 },
"paper": { "enabled": false },
"joke": { "weight": 0 }
}
}
只认两个字段,都是可选的:写哪个改哪个,没写的保持原样。
weight 会夹到 [0, 25],0 等价于关掉。
用户侧配置里的事件 id 只接受小写字母/数字/横杠(挡 __proto__ 之类的怪东西),
大写、下划线、点号一律忽略。
设置写在 %DSH_HOME%\plugins\dsh-lucky-block\config.json,是手写与界面共用的同一个文件
(界面保存走读-改-写,不会抹掉你手写的 model / persona):
{
"sound": true,
"model": { "provider": "workbuddy", "model": "deepseek-v4.1-flash", "reasoningEffort": "low" }
}
localOnly 已经没有了 —— 冷知识/冷笑话现在无条件走本地库,见上面「设置面板」一节。
老配置里留着这个字段不会报错,只是被忽略。
安装(本地开发)
# 方式一:直接指向本目录(plugin-manager 支持本地 spec)
# 在插件市场里「安装」填本目录的绝对路径
# 方式二:npm 打包后按包装
npm pack
装完后不需要动 ~/.dsh/profiles/desktop/cordis.patch.yml:宿主侧条目由本包
package.json 的 dsh.bundle.patch 自动插入,profile 的 patch 里再加一条同 id 的
- insert: 反而会造成组装冲突、让插件加载不上(实测踩过)。
只要确认 ~/.dsh/profiles/desktop/package.json 的 dsh.profile.bundles 里有
"dsh-lucky-block"(插件市场安装会自动加;手动装则加这一行)。
"patchReload": "live"(profile 自带)让 cordis.patch.yml 热生效;但改动
bundles 列表必须重启 dsh才生效。
⚠️ 改
lib/下的任何 JS 都必须重启 dsh。 宿主侧插件代码没有热重载 —— 正在跑的进程内存里持有旧模块,代码改了行为不会变。这个坑骗过一整轮排查: 源码里已经搜不到某段字符串,会话里却还在出现它,最后才发现是进程跑的是旧代码。 客户端那半(lib/client.js)刷新页面即可,但桌面端要重启宿主才会重新收集注入行。
可选配置:给骰子会话单独指定模型
默认不启用,骰子会话直接沿用你的默认模型。想让随机事件跑便宜/快的模型时,
在 %DSH_HOME%\plugins\dsh-lucky-block\config.json 写(这个字段只能手写,设置面板里没有):
{
"model": {
"provider": "workbuddy",
"model": "deepseek-v4.1-flash",
"reasoningEffort": "low"
}
}
reasoningEffort 可省略。provider / model 必须精确匹配可用目录里的名字
(目录拿不到时会跳过切换、不影响掷骰子),不确定就先用 /dice 命令观察日志。
⚠️ 为什么默认关着:宿主只提供会话级
sessionController.selectModel,而它 成功后会把这次选择异步写成 profile 的全局默认模型。也就是说开启本配置后, 第一次掷骰子会顺带把你的默认模型也改成这里写的那个。想恢复就把文件删掉, 再在界面里手动把默认模型选回来。
用法
| 想干什么 | 怎么做 |
|---|---|
| 让 AI 给选择题加幸运方块 | 正常提问,选项末尾自动多一项 |
| 抽一次零成本的(弹窗/蓝屏/签/冷知识/笑话/音乐) | 左键单点方块 / 打 /dice |
| 抽一次要花 token 的(论文/新闻/待办) | 长按方块挖到碎裂 / 打 /dice |
| 不满意,回去 | 说「回滚」或打 /rollback |
| 方块按钮固定住不挡路 | 右键方块 → 锁定(或双击);锁定后仍可单点/长按触发 |
| 让方块贴边 | 把它拖到离屏幕边缘 48px 以内松手,自动吸附 |
| 改设置 | 右键方块 → 设置… |
单点零成本、长按才花钱**:单点只在单击池里抽(十个事件全是本地/视觉, 不建会话、不调模型);长按只在长按池里抽(三个事件都会开新会话调模型)。 单点是手滑也会发生的动作,所以它不该有成本。
长按阈值 1.4 秒(lib/client.js 的 BREAK_MS)。按住时手指挪动超过 5 像素即判为
「在拖动按钮」并取消挖掘——所以拖位置和挖方块不会打架。松开或移开都会取消挖掘,
纹路和挖掘声立刻一起停。
音效从宿主的 /dsh-lucky-block/sound/*.ogg 按需取(16 个原版音节,共 142 KB),
不内联进客户端 bundle —— lib/client.js 是每次页面启动都要下载的入口,
为只在长按瞬间才用到的音效把它撑大 4 倍不划算。挖掘声每 210ms 一个、4 个变体随机轮播
(只听一个会明显「卡带」),挖穿那一刻再叠一声碎裂音;同时最多 6 个 Audio 元素,
页面切到后台自动静音。
松手吸附(SNAP_THRESHOLD = 48)只在真的拖动过时生效:鼠标只是滑出方块边缘
(会触发 pointerleave)不会吸附,按下就松手也不会。锁定状态下完全不吸附 —— 锁定
就是不建拖动状态,自然短路。吸附有 160ms 的 left/top 过渡,视觉上是滑过去而不是瞬移。
方块按钮位置、外观、锁定状态存在浏览器 localStorage(键 dshLuckyBlock.block),换机器不跟。
出错了怎么看
方块头顶的气泡只在报错时出现(正常触发的进度、成功、会话 ID 都不写了 —— 有视觉表演的事件自己会演,没表演的由新会话内容承担反馈)。报错时气泡里是宿主 翻译过的人话,点一下可以关掉,例如:
| 情况 | 气泡说什么 |
|---|---|
插件本体没激活(改动 lib/ 后没重启) |
插件没有注册这个接口,通常是插件本体未激活:重启 dsh 后再试 |
| 登录态过期 | 宿主拒绝了请求(未登录或登录已过期),刷新页面后重试 |
| 默认工作区被删/移走 | 默认工作区目录不存在或已被移动。请在 dsh 里重新确认默认工作区路径后再试 |
| 工作区不可写 | 没有权限写入工作区(被系统或沙箱拦下了) |
config.json 里的模型不在目录里 |
模型不可用:config.json 里指定的 provider/model 不在可用目录中 |
| 都不是 | 意外错误:<宿主的原始信息> |
想看完整堆栈就翻宿主日志(dsh 标准输出)——那边始终打的是原始错误。
音效不会报错。拿不到音效文件、浏览器拦截自动播放、没有可用音频设备 —— 这些一律静默忽略。音效是锦上添花,为它弹一个红色报错气泡是本末倒置。
目录
lib/index.js—— 宿主侧(Node):选项注入、答案识别、回滚、幸运方块事件(分单击/长按两个池)、默认工作区会话创建、可选模型切换、人格层与状态机、本地语料库、音频清单、设置读写、音效文件投放、错误翻译。lib/client.js—— 客户端(浏览器):可拖拽幸运方块按钮(含边缘吸附、锁定)+ 单击/长按分流 + 长按挖掘裂纹 / 碎裂粒子 / 音效 + 音频播放 + 弹窗表演 + 蓝屏屏保 + 设置面板 + 台词气泡。lib/persona.js—— 随机事件的人格层(纯函数,可单测):默认人格、覆盖合并、人格段拼装、任务正文保护、收尾点评请求。lib/jokes.js—— 本地笑话库加载器(读jokes-data.json,带 BOM 剥离与只读一次缓存)。lib/jokes-data.json/lib/trivia-data.json—— 本地语料库。lib/audio-tracks.json—— 音频事件清单(用户目录下的同名文件优先)。lib/audio/—— 音频文件目录,由宿主/dsh-lucky-block/audio/<file>投放。 已内含《Never Gonna Give You Up》副歌 42 秒。lib/sounds/—— 16 个原版 Minecraft 音效(.ogg,共 142 KB),由宿主按需投放。cordis.patch.yml—— 把宿主侧插件插进插件树(客户端那半由package.json的dsh.client自动加载)。
素材出处
方块面与裂纹是原版 Minecraft 像素素材,以 base64 data URI 内联在 lib/client.js 里
(静态 bundle 的 require() 只认包 id、不认相对路径,所以不做成独立模块):
| 素材 | 尺寸 | 来源 |
|---|---|---|
| 方块面 | 16×16 | alexsocha/luckyblock mod 的 lucky_block.png |
| 挖掘裂纹 10 帧 | 16×16 ×10 | 原版资源包 PixiGeko/Minecraft-default-assets 的 assets/minecraft/textures/block/destroy_stage_0..9.png |
裂纹用 image-rendering: pixelated 保持硬边,长按时按进度切到下一帧,最后一帧之后碎裂。
之所以找原素材而不是手绘:手绘的裂纹再怎么调都像程序生成的线条,和那张像素方块贴图
放在一起会突兀;换成原版的黑褐裂纹 + 白色反光碎屑,才是游戏里挖方块的样子。
音效是 Minecraft 1.20.1 原版 assets(dig/stone1..4.ogg、random/break.ogg),
经 tools/build-sounds.mjs 从 mcasset.cloud 镜像取到 lib/sounds/。版权归 Mojang Studios;
本插件只作本地开发期素材镜像,运行时不依赖网络。
试水那首《Never Gonna Give You Up》来自 B 站官方 MV(BV1GJ411x7h7),
只取了 100~142 秒的副歌段转成 Vorbis(44100 Hz / 立体声 / 632 KB)。
抓取脚本 tools/.fetch-bv.mjs 与找高潮的 tools/.loudest.mjs 都留在 tools/ 里
(点前缀 = 不进 npm 包),加歌时按 lib/audio/README.md 走一遍即可。
版权归原权利人;运行时不依赖网络,音频随插件包发布。
默认性格是机器客服口吻 + 音量梗 + 人体数据冷知识,靠语气和句式传达。
实现里刻意不提任何作品名、角色名或制造商,也不靠名字塑造性格 ——
persona-check.mjs 有多条断言盯着这一点。
开发期工具(tools/,安装运行不依赖):
host-smoke.mjs 跑宿主侧回归(含音效路由与白名单)、
persona-check.mjs 人格层单测(真 import)、
snap-check.mjs 吸附纯函数(从 client.js 抽源码跑,不会与实现漂移)、
escape-check.mjs ESC 收尾登记表(同样抽源码跑)、
config-check.mjs 配置读取(含 BOM 坑)、
local-check.mjs 本地语料库与分流、
events-check.mjs 事件覆盖层与第三方事件校验(从 index.js 抽取源码跑)、
verify-sounds.mjs 音效文件 ↔ 客户端清单 ↔ 宿主白名单三方一致性、
list-events.mjs 打印事件清单与概率、
merge-trivia.mjs / merge-jokes.mjs 语料合并器(--check 只体检不写盘)、
build-corpus-overview.mjs 重新生成 lib/语料库总览.md(--check 校验是否过期)、
build-sounds.mjs 把原版音效取到 lib/sounds/。
端到端探针(需要先起克隆 profile,流程见 docs/探针流程.md):
probe-sound.mjs、probe-audio.mjs、probe-settings.mjs、probe-visual-ids.mjs、
probe-persona.mjs、probe-local-path.mjs、probe-fortune.mjs、
probe-dice-prompt.mjs。
调研笔记与语料候选文件归档在 docs/research-notes/(考据报告、语料来源、
合并器的候选 JSON)。
已知边界
- 回滚是「fork 到上一版本」:历史会话保留,新分支继续,不会删任何东西。
- 幸运方块开出来的会话不回滚(随机剧本被回滚会变得没意义)。
- 蓝屏屏保只盖 dsh 自己的窗口,不碰系统、不碰其他插件,60 秒或按 ESC 结束。
- 方块按钮用 pointer 事件区分两个动作:按下即开始计时(
pointerdown记起点与时间), 挖满 1.4 秒是长按(hold池),中途松手算单击(click池)。 鼠标左键/触摸都行;键盘 Tab 聚焦后 Enter/Space 直接走单击。 单击不含挖掘动画,也不会播放碎裂声。 - 挖掘裂纹用原版
destroy_stage10 帧贴图(透明底),方块碎裂是纯 DOM 的一次白光闪 + 26 个像素碎片;都不受用户主题影响。 - 事件权重/开关的改动要重启 dsh 才生效,方块外观改动立即生效。
No comments yet. Be the first to write one.