dsh-maid-atelier-tod
给 DeepSeek Harness 皮肤 「深海女仆工坊 / Abyssal Maid Atelier」 加的两件事:
- 窗景随本机时间走过六个时段 —— 破晓 · 黎明 · 早中 · 傍晚 · 晚上 · 深夜,窗外的天色、室内烛光、星点、暗角连续插值变化,不是白天/夜里两档切换。
- 立绘自己动 —— 呼吸、重心移动、缓慢浮动、轻微转身,每隔几秒眨一次眼(偶尔连眨两下);「明显」档再叠一层极低频位移场,让裙摆和长发飘起来。不跟随鼠标,也不对画面做任何抠图。
A post-build patch for the DSH skin
@smalltailqwq/dsh-client-ui-skin-maid-atelier: a six-band time-of-day lighting rig for the window backdrop, plus self-driven figure motion (breathing, weight shift, sway, blinks, and an optional low-frequency cloth displacement). Nothing inside the artwork is cut out.
| 破晓 | 黎明 | 早中 |
|---|---|---|
![]() |
![]() |
![]() |
| 傍晚 | 晚上 | 深夜 |
![]() |
![]() |
![]() |
一键复刻(含素材)
不想打补丁的话,直接下载发布包:Releases → v0.2.0 里的
smalltailqwq-dsh-client-ui-skin-maid-atelier-0.1.9-tod.tgz(6.7 MB,已包含全部立绘与背景素材):
mkdir -p ~/.dsh/profiles/<profile>/node_modules/@smalltailqwq/dsh-client-ui-skin-maid-atelier
tar -xzf smalltailqwq-dsh-client-ui-skin-maid-atelier-0.1.9-tod.tgz \
-C ~/.dsh/profiles/<profile>/node_modules/@smalltailqwq/dsh-client-ui-skin-maid-atelier
# 确认该 profile 的 package.json → dsh.profile.bundles 含这个包名,然后重启 dsh
发布包由 node tools/build-release.mjs 从"已打补丁的本机安装"直接打包,所以解包即得同样的效果,不需要再跑 patch.mjs。
安装
前提:皮肤已经装进某个 DSH profile(~/.dsh/profiles/<profile>/node_modules/@smalltailqwq/dsh-client-ui-skin-maid-atelier)。
node patch.mjs # 自动找到所有 profile 里的皮肤并打补丁
node patch.mjs --check # 只报告状态
node patch.mjs --revert # 回滚(从 client.js.orig 恢复)
node patch.mjs --profile desktop # 只处理某个 profile
node patch.mjs --bundle path/to/lib/client.js # 手动指定
第一次应用会在 bundle 旁边写 lib/client.js.orig 作为备份。
打完补丁后:皮肤的 client bundle 被 DSH 的 client HMR 监听(artifact 的 mtime/size 变化即重新广播),前端通常会热替换;没反应就刷新一下页面。
设置
皮肤设置页里多了两项:
| 设置 | 取值 | 说明 |
|---|---|---|
| 窗景与室内光线 | 跟随本机时间 / 破晓 / 黎明 / 早中 / 傍晚 / 晚上 / 深夜 / 关闭 | 关闭 时退回皮肤原本的浅色/深色主题两档逻辑 |
| 立绘动效 | 关闭 / 轻微(默认) / 明显 | 轻微 只动变换矩阵,像素完全不动;明显 才启用位移场让裙摆发丝飘动。眨眼在两档里都有 |
眨眼是用两层极薄的「眼皮」盖在眼睛上做出来的:每 3–7 秒一次,透明度包络 110–190ms,28% 的概率连眨两下。贴片不是纯色块——它由 canvas 在运行时生成:从脸颊取中位色当眼皮底色、按睫毛色描一条下眼睑曲线、再羽化成椭圆,所以颜色来自这张画本身。除这几帧之外贴片透明,脸部像素始终是原图。

局部肢体
整张位图不能单独旋转一只手,但位移场能让一块区域动、邻居不动。每张立绘一张低分辨率位移贴图(72×128),运行时把 5.2 秒的循环预烘焙成 26 帧,逐帧只换 feImage 的 href:
| 立绘 | 会动的部位 |
|---|---|
| 左(挥手那位) | 举起的左手上下摆、左侧长发飘、鲸鱼尾上下摆 |
| 右(拿本子那位) | 拿本子的手上下摆、左右耳、辫子、鲸鱼尾 |
每个部位是一个高斯软斑,幅度按 amp / 最大amp 归一化后写进 G 通道(R 通道带 1/4 的横向分量,避免看起来像整体平移)。贴图避开了眼睛区域,所以眨眼贴片不会和位移打架。

光照模型
时段不是手调的关键帧表,而是从太阳高度角推出来的(无网络、无定位权限):
- 日序定赤纬、本机钟点定时角,默认纬度 30°(
maidAtelierTod.setLatitude(deg)可改); - 窗户进光量
windowLight = cos(入射角)·直射 + 漫射天光,垂直玻璃按朗伯体算; - 夜色底图按民用晨昏线淡入(高度角 −8°→+4°),所以夏天和冬天同一个钟点亮度不同;
- 烛光是"窗外不够亮才点"的补偿:
lamp = 1 − smoothstep(windowLight),而不是按钟点拍脑袋; - 星点按太阳沉入地平线的深度出现(−5° 起,−14° 饱和),月光按"满月与太阳反相"近似;
- 太阳位置与色温给出
--maid-tod-sun-x/--maid-tod-sun-color(1000K–5300K 黑体拟合),晨昏那层暖光因此会跟着太阳在窗面上移动,颜色也从橙红到粉紫地变。
实测一张 24 小时表(10 月末,北纬 30°):
| 时间 | 高度角 | 进光 | 夜色 | 烛光 | 时段 |
|---|---|---|---|---|---|
| 00:00 | −75° | 0.00 | 1.00 | 1.00 | 深夜 |
| 05:30 | −14° | 0.00 | 1.00 | 1.00 | 破晓 |
| 06:30 | −1° | 0.05 | 0.40 | 1.00 | 黎明 |
| 12:00 | +45° | 0.88 | 0.00 | 0.04 | 早中 |
| 17:00 | +5° | 0.13 | 0.00 | 0.79 | 傍晚 |
| 18:00 | −8° | 0.00 | 0.99 | 1.00 | 晚上 |
人物动效:当前状态
肢体位移默认关闭。 所有旋转场代码都还在(MAID_TOD_LIMB_GROUPS + maidTodBakeGroupMap),但由一个开关控制:
const MAID_TOD_LIMBS_ENABLED = false; // src/maid-atelier-tod.js
关掉之后人物只剩整体动作——呼吸、重心移动、缓慢浮动、轻微转身,以及每 3–7 秒一次的眨眼。这是逐像素不动的那一档,也是最稳的一档。
为什么默认关:手、头发、尾巴要单独摆动,就必须对位图做位移场;而对一张已经画好的图做区域变形,在关节和道具(笔记本/笔/裙摆蕾丝)上总会留下痕迹。几轮调参后结论是——要么整体动,要么重画分层,中间态在动态里始终会被看出来。
想再试的话,把上面那行改成 true 然后重跑 node patch.mjs:位移是按骨头做的旋转场(尾巴以胯为轴、长发以耳侧为轴、抬手以肩为轴),道具(笔记本+握笔的手)有挖空禁区保持刚体,速度是 2.2s/3.8s/4.4s 一拍并带跟随延迟。
性能
- 逐帧路径只剩 2 个元素写
transform(值没变就不写)和眨眼包的透明度; - 位移动画在浏览器合成器里跑,标签页隐藏时 rAF 直接返回、SMIL 暂停;
- 有一个帧预算看门狗:连续 120 帧平均超过 22ms 就自动关掉位移滤镜(控制台会打印一行原因),退化到只剩整体呼吸/摇摆;
- 眼睑贴片只在挂载时烘焙一次,之后每次眨眼只是改透明度。
调试
控制台:
maidAtelierTod.preview("dusk") // 立刻切到某个时段:firstlight/dawn/day/dusk/evening/midnight
maidAtelierTod.preview("auto") // 回到跟随本机时间
document.body.dataset.maidTodLabel // 当前时段中文名
离线预览(不需要改动运行中的应用):
node tools/gen-harness.mjs # 生成 preview/*.html
node tools/gen-harness.mjs --shot # 再用无头 Chrome 渲染 PNG
tools/gen-harness.mjs 里的 CSS 是直接从 src/maid-atelier-tod.js 里抽出来的,所以预览看到的就是补丁注入的效果。
目录
patch.mjs 补丁器(幂等、带备份、可回滚)
src/maid-atelier-tod.js 注入到皮肤 client bundle 的模块源码
tools/gen-harness.mjs 离线预览生成器
tools/make-docs.py 把预览 PNG 压成 docs/ 里的 JPG
docs/ 截图
许可
- 代码(
patch.mjs、src/、tools/):MIT,见 LICENSE。 docs/里的截图包含第三方插画:CC BY-NC-SA 4.0,署名链与使用限制见 NOTICE。不要商用,转载需保留完整署名链。
致谢
皮肤、立绘与原始窗景由 Small-tailqwq 制作(dsh-deep-whale / maid-atelier);鲸鱼娘角色形象的一创、二创作者见 NOTICE。
本项目只做运行时增强,不包含、也不再分发上述美术资源。






No comments yet. Be the first to write one.