msw-painter

msw-painter

當 msw-search 找不到合適的精靈 RUID 時,直接用 SVG / HTML5 Canvas / HTML 程式碼繪製像素風精靈,渲染成 PNG,並透過 msw-mcp 素材上傳工具上傳以取得精靈 RUID(若未連接上傳工具,則引導使用者透過 Maker 註冊)。支援兩種風格模式:chunky pixel(復古/圖示/地磚感)與 maple cartoon(楓之谷風格角色/NPC 感)。觸發詞:直接繪製精靈、建立精靈、圖片生成、自訂圖形、像素藝術、卡通精靈、楓之谷風格、Q版角色、畫家、畫一個精靈、製作圖示、直接建立 NPC 圖片、畫一個史萊姆、自訂精靈。

32星標
2分支
更新於 2026/7/29
SKILL.md
readonlyread-only
name
msw-painter
description

當 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。請勿呼叫畫家。
無搜尋結果,或所有結果都不合適 呼叫畫家 → 直接建立
使用者明確說「我需要一個手繪風格的角色/圖示」 直接呼叫畫家

工作流程

  1. 選擇媒介 — SVG / Canvas / HTML 其中之一。請見「選擇媒介」章節。
  2. 選擇風格chunkymaple。請見「選擇風格」章節。
  3. 決定尺寸 — 請見 references/size-guide.md。預設為 128×128。
  4. 撰寫程式碼 — 依照所選風格的規則:
  5. 渲染成 PNG — 執行 scripts/render.cjs
  6. 上傳資源 — 使用 msw-mcp 素材上傳工具,兩步驟 presigned 模式(§5)。若連接的 MCP 沒有上傳工具,請要求使用者透過 Maker 註冊 PNG。
  7. 註冊精靈屬性 — 上傳後立即執行 asset_update_resource_storage_infofilter_mode / wrap_mode / pivot,以及 UI 框架精靈的 9-slice 邊框。請見「步驟 4」下方。
  8. 回報結果 — 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×64maple 風格沒有足夠的像素來容納 selout + AA + 面部特徵——請將輸出尺寸提高到 64 以上,或改回 chunky


4. PNG 渲染 — render.cjs

一次性相依套件安裝

cd scripts && npm ci

這會從已提交的 package-lock.json 安裝 puppeteer(約 200MB,包含無頭 Chromium)。它與其他基礎技能相依套件分開,因此只在第一次使用畫家時執行此指令。

🔒 使用 npm ci不要使用 npm installnpm ci 會精確安裝 package-lock.json 中鎖定的版本,如果 lockfile 與 package.json 不一致則會失敗——這是 W012 的供應鏈完整性保證。切勿手動編輯 package-lock.json;如果需要升級 puppeteer,請在本機執行 npm install puppeteer@<version> 並提交重新產生的 lockfile。

沙箱與網路隔離

render.cjs 預設以啟用作業系統沙箱的方式執行無頭 Chromium,並封鎖渲染頁面的所有網路請求。頁面也透過 data: URL 提供,並帶有嚴格的 Content-Security-Policydefault-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

選項:

  • --typesvg / 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-SignatureX-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=Clamppivot_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_resourcesasset_list_account_resources 檢查現有精靈的子類別分佈,並與之相符。如果不確定,請使用通用值如 object / etc


6. 回報格式

當畫家任務完成時,僅向使用者提供以下內容:

RUID:<收到的 RUID>
風格:<chunky | maple>
<1–2 句描述:你畫了什麼、尺寸為何、以及註冊為何種精靈>

實體建立/移動/生成、腳本編寫和 UI 編輯不在畫家範圍內。請在其他技能或後續步驟中處理這些。


常見陷阱

  • render.cjs 之前未執行 npm ciCannot find module 'puppeteer'。僅第一次需要。使用 npm ci(不是 npm install),以便安裝 lockfile 鎖定的 puppeteer 版本。
  • 省略 --width / --height → 會回退到 128×128,如果使用者想要不同尺寸則必須重畫。務必指定。
  • SVG/Canvas 內容僅繪製在 PNG 左上角 → 繪圖程式碼宣告了自己的尺寸(例如 SVG width="128" height="128" 或 Canvas scale = 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