
msw-painter
當 msw-search 找不到合適的精靈 RUID 時,直接用 SVG / HTML5 Canvas / HTML 程式碼繪製像素風精靈,渲染成 PNG,並透過 msw-mcp 素材上傳工具上傳以取得精靈 RUID(若未連接上傳工具,則引導使用者透過 Maker 註冊)。支援兩種風格模式:chunky pixel(復古/圖示/地磚感)與 maple cartoon(楓之谷風格角色/NPC 感)。觸發詞:直接繪製精靈、建立精靈、圖片生成、自訂圖形、像素藝術、卡通精靈、楓之谷風格、Q版角色、畫家、畫一個精靈、製作圖示、直接建立 NPC 圖片、畫一個史萊姆、自訂精靈。
當 msw-search 找不到合適的精靈 RUID 時,直接用 SVG / HTML5 Canvas / HTML 程式碼繪製像素風精靈,渲染成 PNG,並透過 msw-mcp 素材上傳工具上傳以取得精靈 RUID(若未連接上傳工具,則引導使用者透過 Maker 註冊)。支援兩種風格模式:chunky pixel(復古/圖示/地磚感)與 maple cartoon(楓之谷風格角色/NPC 感)。觸發詞:直接繪製精靈、建立精靈、圖片生成、自訂圖形、像素藝術、卡通精靈、楓之谷風格、Q版角色、畫家、畫一個精靈、製作圖示、直接建立 NPC 圖片、畫一個史萊姆、自訂精靈。
MSW Painter
一個將手繪像素風精靈註冊為精靈資源的工作流程。請先呼叫 msw-search,只有在找不到合適的 RUID 時才使用此技能。
此技能專門處理精靈類別。不處理動畫、音訊、頭像、圖集。
畫家支援兩種像素藝術風格:chunky pixel(復古、圖示/地磚感)與 maple cartoon(楓之谷風格、角色/NPC 感)。在撰寫程式碼前請先選擇一種風格——請見下方步驟 2。
何時呼叫
| 情況 | 動作 |
|---|---|
| 使用者想要特定精靈 | 先使用 msw-search(資源搜尋區段,精靈類別) |
msw-search 回傳符合意圖的 RUID |
直接使用該 RUID。請勿呼叫畫家。 |
| 無搜尋結果,或所有結果都不合適 | 呼叫畫家 → 直接建立 |
| 使用者明確說「我需要一個手繪風格的角色/圖示」 | 直接呼叫畫家 |
工作流程
- 選擇媒介 — SVG / Canvas / HTML 其中之一。請見「選擇媒介」章節。
- 選擇風格 —
chunky或maple。請見「選擇風格」章節。 - 決定尺寸 — 請見 references/size-guide.md。預設為 128×128。
- 撰寫程式碼 — 依照所選風格的規則:
chunky→ references/style-chunky-pixel.mdmaple→ references/style-maple-cartoon.md
- 渲染成 PNG — 執行
scripts/render.cjs。 - 上傳資源 — 使用 msw-mcp 素材上傳工具,兩步驟 presigned 模式(§5)。若連接的 MCP 沒有上傳工具,請要求使用者透過 Maker 註冊 PNG。
- 註冊精靈屬性 — 上傳後立即執行
asset_update_resource_storage_info:filter_mode/wrap_mode/ pivot,以及 UI 框架精靈的 9-slice 邊框。請見「步驟 4」下方。 - 回報結果 — RUID + 1–2 句描述(包含使用的風格)。實體放置/腳本應用不在畫家範圍內。
1. 選擇媒介
| 媒介 | 建議用途 | 優點 |
|---|---|---|
| SVG | 圖示、標誌、簡單角色、形狀為主的像素藝術 | 直觀的程式碼,容易放置 1px <rect> 點 |
| Canvas | 程序化圖案、迭代邏輯(迴圈繪製的紋理/雜訊) | 透過 JS 程式邏輯產生複雜圖案 |
| HTML | 可用 CSS 快速設定樣式的複合佈局 | 較少使用——SVG/Canvas 通常更適合像素藝術 |
最小 SVG 模板
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
width="100%" height="100%" preserveAspectRatio="xMidYMid meet"
style="image-rendering: pixelated;">
<rect x="6" y="2" width="1" height="1" fill="#4A90D9"/>
<!-- 用 1px 矩形逐個放置點 -->
</svg>
⚠️ 使用
width="100%" height="100%"(不要使用固定像素數)。SVG 元素在 render.cjs 的視口中以其自身宣告的大小繪製——如果你寫死 128 但以--width 1024渲染,SVG 只會填滿左上角 128px,PNG 其餘部分為透明。100%讓 SVG 填滿--width/--height指定的畫布。
最小 Canvas 模板
// `c`(canvas 元素)和 `ctx`(2D 上下文)由 render.cjs 自動暴露。
// ctx.imageSmoothingEnabled = false 也會自動套用。
// 重要:從 c.width 推導 scale,不要寫死常數——否則不同的 --width 會導致畫布右下角空白。
const GRID = 16;
const scale = c.width / GRID; // 16×16 邏輯網格 → 畫布大小的輸出
ctx.fillStyle = '#4A90D9';
ctx.fillRect(6 * scale, 2 * scale, scale, scale);
最小 HTML 模板
<!doctype html>
<html><body style="margin:0; image-rendering: pixelated;">
<!-- 任何你喜歡的內容 -->
</body></html>
2. 選擇風格
| 風格 | 建議用途 | 外觀感受 | 邏輯網格 | 輪廓線 | 陰影 |
|---|---|---|---|---|---|
chunky |
圖示、按鈕、地磚、方塊、簡單道具 | 復古 / 8-bit / NES-SNES | 小(16×16、32×32) | 黑色或白色,1px | 2–4 階層,無 AA |
maple |
角色、NPC、怪物、可愛吉祥物 | 楓之谷 / 故事書 / 卡通 | 較大(32×32 ~ 128×128) | Selout(比填充色更深的顏色) | 4–6 階層 + 輪廓選擇性 AA + 可選 2×2 遞色 |
不確定時的預設值
- 圖示 / 按鈕 / 地磚 / 方塊 →
chunky - 角色 / NPC / 怪物 / 吉祥物 / 「可愛」要求 / 「畫一個史萊姆」 →
maple - 使用者說「復古」/「8-bit」/「NES」/「極簡」 →
chunky - 使用者說「楓之谷」/「可愛」/「卡通」/「Q版」/「插畫風」 →
maple
完整風格規則:
兩種風格共用相同的禁用 API(無曲線 API、無漸層 API、無分數座標、無 filter: blur/drop-shadow)。它們在調色盤豐富度、輪廓線顏色、AA 和工作網格上有所不同。
3. 尺寸指南(摘要)
| 用途 | 建議尺寸 |
|---|---|
| 圖示 / 按鈕 | 48×48 ~ 64×64 |
| 角色 / 物品 / NPC / 怪物 | 96×96 ~ 128×128 |
| 地磚 / 地板 / 方塊 | 64×64 ~ 128×128 |
| 背景 / 大型物件 | 256×256 或更大(僅在明確要求時) |
預設為 128×128。關於風格特定的工作網格表格(chunky 使用小邏輯網格如 16×16;maple 使用較大網格如 64×64)和 SD 角色比例,請見 references/size-guide.md。
如果要求的輸出低於 64×64,
maple風格沒有足夠的像素來容納 selout + AA + 面部特徵——請將輸出尺寸提高到 64 以上,或改回chunky。
4. PNG 渲染 — render.cjs
一次性相依套件安裝
cd scripts && npm ci
這會從已提交的 package-lock.json 安裝 puppeteer(約 200MB,包含無頭 Chromium)。它與其他基礎技能相依套件分開,因此只在第一次使用畫家時執行此指令。
🔒 使用
npm ci,不要使用npm install。npm ci會精確安裝package-lock.json中鎖定的版本,如果 lockfile 與package.json不一致則會失敗——這是 W012 的供應鏈完整性保證。切勿手動編輯package-lock.json;如果需要升級 puppeteer,請在本機執行npm install puppeteer@<version>並提交重新產生的 lockfile。
沙箱與網路隔離
render.cjs 預設以啟用作業系統沙箱的方式執行無頭 Chromium,並封鎖渲染頁面的所有網路請求。頁面也透過 data: URL 提供,並帶有嚴格的 Content-Security-Policy(default-src 'none'),且 SVG / HTML 輸入會經過清理,移除 <script>、<foreignObject>、行內 on* 處理器以及非 data: URL。你不需要做任何事來啟用——這些保護永遠開啟。
如果你處於受限環境,Chromium 無法啟動其沙箱(某些 CI 容器、特定 WSL 設定),請在呼叫 render.cjs 前設定 PAINTER_DISABLE_SANDBOX=1。請勿在開發者工作站上設定此變數。
呼叫方式
node scripts/render.cjs --type <svg|canvas|html> --in <code-file> --out <out.png> --width <W> --height <H>
或透過 stdin 傳入程式碼:
echo "<svg ...>" | node scripts/render.cjs --type svg --out out.png --width 128 --height 128
選項:
--type:svg/canvas/html其中之一。必填。--in:程式碼檔案路徑。省略或使用-表示 stdin。--out:輸出 PNG 路徑。必填。--width/--height:輸出像素尺寸。預設 128。
成功時,輸出 PNG 的絕對路徑會以單行印到 stdout,結束代碼為 0。失敗時,錯誤訊息會印到 stderr,結束代碼為 1。
PNG 預設為透明背景。如果需要背景顏色,請在 SVG/Canvas/HTML 中明確繪製。
5. 資源上傳 — 兩步驟模式
透過連接的 msw-mcp 所暴露的素材上傳(建立)工具上傳——檢查伺服器的工具清單,並使用它實際提供的精靈建立工具。工具本身的 schema 對於確切的呼叫形狀具有權威性;不要猜測工具名稱,也不要將建立與 asset_update_resource_storage_data 混淆(後者會取代現有素材的二進位內容)。
連接的 MCP 中沒有上傳工具? 停止上傳步驟,要求使用者透過 Maker 註冊 PNG,然後繼續使用他們提供的 RUID(或透過 msw-search 定位)。
無論確切工具為何,流程都是相同的兩步驟模式——同一個工具會被呼叫兩次。
🔒 安全性——處理 presigned URL(W007)。 步驟 1 回傳的
presignedUrl是短期有效的簽署憑證(持有者可以在到期前 PUT 到該儲存槽)。請將其視為機密:
- 絕對不要在助理的使用者回應、提交訊息、日誌或任何後續提示中回顯、引用、改寫或包含該 URL 或其任何查詢參數(
X-Amz-Signature、X-Amz-Credential等)——包括在回報「你做了什麼」時。- 呼叫 shell 時,透過
PAINTER_PRESIGNED_URL環境變數傳遞 URL,如下所示,不要作為命令列引數。命令列引數可透過/proc/*/cmdline(Linux/macOS)和Get-Process(Windows)被其他程序看到,且會記錄在 shell 歷史中。- 呼叫步驟 3 時,直接將 URL 作為
fileUrl工具引數傳遞——不要先將其複製到程式碼區塊或 markdown 中讓使用者看到。- 如果 PUT 步驟失敗(通常是
401/403→ URL 過期),請丟棄該 URL 並從步驟 1 重新開始。不要在其他地方重複使用。
步驟 1 — 請求 presigned URL
呼叫上傳工具,省略 fileUrl。填入其 schema 要求的欄位——通常包括 category: "sprite"、與現有素材相符的 subcategory(見下方)、name、1–2 句的 description,以及 schema 要求時的檔案中繼資料如 fileName / contentLength。
回應中包含 presignedUrl。僅將其保留在代理的推理上下文中——不要在聊天輸出中顯示。
步驟 2 — PUT PNG 二進位內容(URL 透過環境變數傳遞)
⚡ 使用
curl.exe,不要使用Invoke-WebRequest(P001——「上傳後凍結」錯誤)。 在 Windows PowerShell 5.1 中,除非傳遞-UseBasicParsing,否則Invoke-WebRequest會透過 Internet Explorer 引擎解析 HTTP 回應。IE 在 Windows 11 上已被移除/停用,因此呼叫會阻塞在 IE「首次啟動設定」上,且在位元組已上傳後似乎會凍結很長時間(MCP 工具本身約 45 ms 回傳——停頓完全來自此步驟)。curl.exe(Windows 10 1803+ 及所有 Windows 11 的System32中都有)沒有 IE 相依性,且在 PowerShell 和 Git Bash 中行為一致,因此在兩種 shell 中都優先使用它。
PowerShell(優先——curl.exe):
$env:PAINTER_PRESIGNED_URL = "<步驟 1 的 presignedUrl>"
try {
# 透過 stdin 設定檔 (-K -) 將 url/request/upload-file 餵給 curl,
# 這樣 URL 就不會出現在 argv(可透過 Get-Process 看到)或 shell 歷史中。
"url = `"$env:PAINTER_PRESIGNED_URL`"`nrequest = `"PUT`"`nupload-file = `"out.png`"" | curl.exe -K -
} finally {
Remove-Item Env:\PAINTER_PRESIGNED_URL -ErrorAction SilentlyContinue
}
bash(Git for Windows / WSL——curl):
# 1) 在**自己的**陳述句中指派(export),不要作為行內前綴。
# `VAR=… curl … "$VAR"` 無法運作:shell 在指派生效前就展開了同一命令列上的 "$VAR",
# 因此 curl 收到空 URL 並失敗。
export PAINTER_PRESIGNED_URL="<步驟 1 的 presignedUrl>"
# 2) 透過從 stdin 讀取的設定檔 (-K -) 將 URL 餵給 curl。
# 如果作為一般引數傳遞(curl … "$PAINTER_PRESIGNED_URL"),URL 會直接展開到 argv 中,
# 可透過 `ps` / /proc/<pid>/cmdline 看到——-K - 使其完全脫離引數清單。
printf 'url = "%s"\nrequest = "PUT"\nupload-file = "out.png"\n' "$PAINTER_PRESIGNED_URL" | curl -K -
unset PAINTER_PRESIGNED_URL
PUT 本身是純二進位上傳——不需要驗證標頭(簽章已嵌入 presigned URL)。-K -(stdin 設定)形式在兩種 shell 中都能讓 URL 遠離 ps / Get-Process 引數清單和 shell 歷史。
僅限備用——Invoke-WebRequest。 如果 curl.exe 真的不可用,你必須加上 -UseBasicParsing(跳過 IE 引擎 → 不會凍結)並關閉進度條(另一個 PS 5.1 錯誤,會使傳輸速度慢 10–50 倍):
$env:PAINTER_PRESIGNED_URL = "<步驟 1 的 presignedUrl>"
$ProgressPreference = 'SilentlyContinue'
try {
Invoke-WebRequest -Method PUT -InFile out.png -Uri $env:PAINTER_PRESIGNED_URL `
-ContentType "image/png" -UseBasicParsing
} finally {
Remove-Item Env:\PAINTER_PRESIGNED_URL -ErrorAction SilentlyContinue
}
步驟 3 — 回報上傳完成
再次呼叫同一個工具,使用相同的引數,並加上 fileUrl 設定為步驟 1 的 presigned URL(直接作為工具引數傳遞——不要將其回顯到聊天或程式碼區塊中)。
回應中包含精靈 RUID。這是最終交付物。此呼叫回傳後,將 URL 視為已完全消耗——不要保留它。
步驟 4 — 註冊精靈屬性
建立工具不接受 properties——在步驟 3 回傳 RUID 後,立即使用素材的 guid 呼叫 mcp__msw-mcp__asset_update_resource_storage_info。屬性條目為小寫的 { "key": "...", "value": "..." },值為字串(資源回應顯示 Properties: [{ "Key", "Value" }]——不要在輸入中模仿該大小寫)。
| 鍵 | 值 | 意義 |
|---|---|---|
pivot_x / pivot_y |
數字字串 | 精靈樞紐 |
border_left / border_right / border_top / border_bottom |
數字字串 | 9-slice 邊框(像素) |
filter_mode |
Point / Bilinear / Trilinear |
紋理濾波 |
wrap_mode |
Repeat / Clamp / Mirror / MirrorOnce |
紋理環繞 |
畫家預設值:filter_mode=Point(Bilinear 會模糊 chunky/maple 像素邊緣)、wrap_mode=Clamp、pivot_x=0.5;圖示/UI 面板使用 pivot_y=0.5,角色和站立在地面上的道具使用 pivot_y=0.0(僅在視覺驗證顯示腳部偏移時調整)。僅在精靈是 9-slice UI 框架(按鈕/面板/進度條)時設定非零的 border_*——.ui 端還需要 SpriteGUIRendererComponent.Type = Sliced(1)(請見 component-api.md §「SpriteGUIRenderer — ImageType Selection」)。切勿發明此表格之外的屬性鍵或列舉值。如果連接的 MCP 工具清單中沒有 asset_update_resource_storage_info,請將預期的屬性值報告給使用者,而不是呼叫不同的工具。
選擇子類別
首先使用 asset_search_resources 或 asset_list_account_resources 檢查現有精靈的子類別分佈,並與之相符。如果不確定,請使用通用值如 object / etc。
6. 回報格式
當畫家任務完成時,僅向使用者提供以下內容:
RUID:<收到的 RUID>
風格:<chunky | maple>
<1–2 句描述:你畫了什麼、尺寸為何、以及註冊為何種精靈>
實體建立/移動/生成、腳本編寫和 UI 編輯不在畫家範圍內。請在其他技能或後續步驟中處理這些。
常見陷阱
- 在
render.cjs之前未執行npm ci→Cannot find module 'puppeteer'。僅第一次需要。使用npm ci(不是npm install),以便安裝 lockfile 鎖定的 puppeteer 版本。 - 省略
--width/--height→ 會回退到 128×128,如果使用者想要不同尺寸則必須重畫。務必指定。 - SVG/Canvas 內容僅繪製在 PNG 左上角 → 繪圖程式碼宣告了自己的尺寸(例如 SVG
width="128" height="128"或 Canvasscale = 8),但 render.cjs 以更大的--width/--height呼叫。內容僅填滿其宣告的尺寸,PNG 其餘部分保持透明。修正:SVG 使用width="100%" height="100%";Canvas 從c.width推導 scale。上方的最小模板已遵循此規則。 - 務必先讀取輸出 PNG 再上傳 → 設定錯誤的 SVG/Canvas 可能靜默產生空白或畫布外的 PNG。對輸出執行一次
Read可在幾秒內發現尺寸不匹配和空白畫布錯誤;先上傳意味著要重做兩步驟上傳。 - 背景變成黑色 → 你在 SVG/Canvas/HTML 中繪製了背景。要保持透明,請移除背景形狀本身。
- 曲線看起來平滑 → 如果使用
chunky,這是違反規則;移除arc()/bezierCurveTo()/漸層並用點重新繪製。如果使用maple,平滑度應來自輪廓處的選擇性 AA 像素,而不是漸層/曲線 API——API 禁令仍然適用。 - Maple 精靈看起來像多了顏色的 chunky → 你可能忘記了 selout(每個表面周圍 1 像素的深色輪廓線)和/或輪廓邊緣的選擇性 AA。重新檢查
style-maple-cartoon.md的 Selout 和選擇性 AA 章節。 - Chunky 精靈看起來模糊 / 糊掉 → 你在邊緣添加了中間色像素。Chunky 禁止所有抗鋸齒——移除過渡像素並保持邊緣銳利。如果需要較柔和的外觀,請改用
maple。 - Maple 精靈在小尺寸(32×32 輸出)下看起來很糟 → Maple 風格需要 ≥ 64×64 的輸出才能容納 selout + AA + 特徵。請增大尺寸或改用
chunky。 - PUT 步驟失敗,出現 401/403 → Presigned URL 已過期或不正確。從步驟 1 重新開始。
- 在完成呼叫中更改其他引數 → 傳遞與步驟 1 完全相同的引數。僅添加
fileUrl。





