msw-painter

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

MSW Painter

MSW Painter

A workflow for registering a hand-drawn pixel art sprite as a sprite resource. Call
msw-search
first, and only invoke this skill when no suitable RUID is found.
This skill is dedicated to the sprite category. It does not handle animation / audio / avatar / atlas.
The painter supports two pixel art styles: chunky pixel (retro, icon/tile feel) and maple cartoon (MapleStory-inspired, character/NPC feel). Pick one before writing code — see step 2 below.

这是一个将手绘像素画精灵注册为精灵资源的工作流。请先调用
msw-search
,仅在未找到合适RUID时再调用此技能。
本技能专门处理精灵类资源,不涉及动画/音频/头像/图集。
绘图工具支持两种像素画风格chunky像素风(复古、图标/ tile质感)和Maple卡通风(灵感来自MapleStory,角色/NPC质感)。编写代码前请选择一种风格——详见下方步骤2。

When to invoke

调用时机

SituationAction
User wants a specific spriteFirst use
msw-search
(Resource search section, sprite category)
msw-search
returns an RUID that matches the intent
Use that RUID directly. Do not invoke painter.
No search results, or all results are unsuitableInvoke painter → create directly
User explicitly says "I need a hand-drawn looking character/icon"Invoke painter directly

场景操作
用户需要特定精灵先使用
msw-search
(资源搜索板块,精灵分类)
msw-search
返回符合需求的RUID
直接使用该RUID。请勿调用绘图工具。
无搜索结果,或所有结果均不符合需求调用绘图工具→直接创建
用户明确表示“我需要手绘风格的角色/图标”直接调用绘图工具

Workflow

工作流

  1. Choose the medium — One of SVG / Canvas / HTML. See "Choosing the medium" below.
  2. Choose the style
    chunky
    or
    maple
    . See "Choosing the style" below.
  3. Decide the size — See references/size-guide.md. Default is 128×128.
  4. Write the code — Follow the rules for the chosen style:
    • chunky
      references/style-chunky-pixel.md
    • maple
      references/style-maple-cartoon.md
  5. Render to PNG — Run
    scripts/render.cjs
    .
  6. Upload the resource
    mcp__msw-mcp__asset_create_resource_storage_item
    two-step pattern.
  7. Report the result — RUID + a 1–2 sentence description (include which style was used). Entity placement / script application is outside the painter's scope.

  1. 选择媒介——SVG / Canvas / HTML三者之一。详见下方“选择媒介”。
  2. 选择风格——
    chunky
    maple
    。详见下方“选择风格”。
  3. 确定尺寸——参考references/size-guide.md。默认尺寸为128×128。
  4. 编写代码——遵循所选风格的规则:
    • chunky
      references/style-chunky-pixel.md
    • maple
      references/style-maple-cartoon.md
  5. 渲染为PNG——运行
    scripts/render.cjs
  6. 上传资源——采用
    mcp__msw-mcp__asset_create_resource_storage_item
    两步式流程。
  7. 汇报结果——提供RUID + 1-2句描述(说明使用的风格)。实体放置/脚本应用不属于绘图工具的处理范围。

1. Choosing the medium

1. 选择媒介

MediumRecommended useStrengths
SVGIcons, logos, simple characters, shape-based pixel artIntuitive code, easy to drop 1px
<rect>
dots
CanvasProcedural patterns, iterative logic (loop-drawn textures / noise)Generate complex patterns via JS programming logic
HTMLComposite layouts that can be styled quickly with CSSRarely used — SVG/Canvas is usually a better fit for pixel art
媒介推荐用途优势
SVG图标、logo、简单角色、基于形状的像素画代码直观,可轻松添加1px的
<rect>
像素点
Canvas程序化图案、迭代逻辑(循环绘制纹理/噪点)通过JS编程逻辑生成复杂图案
HTML可通过CSS快速样式化的复合布局极少使用——SVG/Canvas通常更适合像素画

Minimal SVG template

极简SVG模板

xml
<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"/>
  <!-- Place dots one by one with 1px rects -->
</svg>
⚠️ Use
width="100%" height="100%"
(NOT a fixed pixel count). The SVG element draws at its own declared size inside the render.cjs viewport — if you hard-code 128 but render at
--width 1024
, the SVG fills only the top-left 128px and the rest of the PNG is transparent.
100%
makes the SVG fill whatever canvas
--width
/
--height
specifies.
xml
<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
指定的任意画布尺寸。

Minimal Canvas template

极简Canvas模板

javascript
// `c` (canvas element) and `ctx` (2D context) are auto-exposed by render.cjs.
// ctx.imageSmoothingEnabled = false is applied automatically as well.
// IMPORTANT: derive scale from c.width, not a hard-coded constant — otherwise
// a different --width leaves the bottom-right of the canvas blank.
const GRID = 16;
const scale = c.width / GRID;  // 16×16 logical grid → canvas-sized output
ctx.fillStyle = '#4A90D9';
ctx.fillRect(6 * scale, 2 * scale, scale, scale);
javascript
// `c`(画布元素)和`ctx`(2D上下文)由render.cjs自动暴露。
// ctx.imageSmoothingEnabled = false已自动设置。
// 重要:从c.width推导缩放比例,不要使用硬编码常量——否则
// 不同的--width会导致画布右下角留白。
const GRID = 16;
const scale = c.width / GRID;  // 16×16逻辑网格→画布尺寸输出
ctx.fillStyle = '#4A90D9';
ctx.fillRect(6 * scale, 2 * scale, scale, scale);

Minimal HTML template

极简HTML模板

html
<!doctype html>
<html><body style="margin:0; image-rendering: pixelated;">
  <!-- Anything you like -->
</body></html>

html
<!doctype html>
<html><body style="margin:0; image-rendering: pixelated;">
  <!-- 自定义内容 -->
</body></html>

2. Choosing the style

2. 选择风格

StyleRecommended useLook & feelLogical gridOutlineShading
chunky
Icons, buttons, tiles, blocks, simple propsRetro / 8-bit / NES-SNESSmall (16×16, 32×32)Black or white, 1px2–4 stepped levels, NO AA
maple
Characters, NPCs, monsters, cute mascotsMapleStory / storybook / cartoonLarger (32×32 ~ 128×128)Selout (darker version of fill color)4–6 stepped levels + selective AA on silhouette + optional 2×2 dithering
风格推荐用途视觉感受逻辑网格轮廓着色
chunky
图标、按钮、 tiles、方块、简单道具复古/8位机/NES-SNES风格小尺寸(16×16、32×32)黑色或白色,1px2-4阶分层,无抗锯齿
maple
角色、NPC、怪物、可爱吉祥物MapleStory/故事书/卡通风格大尺寸(32×32 ~ 128×128)Selout(填充色的深色版本)4-6阶分层 + 轮廓处选择性抗锯齿 + 可选2×2抖动

Defaults when in doubt

不确定时的默认选择

  • Icon / button / tile / block →
    chunky
  • Character / NPC / monster / mascot / "cute" requests / "draw a slime" →
    maple
  • User says "retro" / "8-bit" / "NES" / "minimal" →
    chunky
  • User says "MapleStory" / "cute" / "cartoon" / "chibi" / "illustrated" →
    maple
Full per-style rules:
  • references/style-chunky-pixel.md
  • references/style-maple-cartoon.md
Both styles share the same forbidden APIs (no curve APIs, no gradient APIs, no fractional coordinates, no
filter: blur
/
drop-shadow
). They differ in palette richness, outline color, AA, and working grid.

  • 图标/按钮/tile/方块 →
    chunky
  • 角色/NPC/怪物/吉祥物/“可爱”需求/“绘制史莱姆” →
    maple
  • 用户提到“复古”/“8-bit”/“NES”/“极简” →
    chunky
  • 用户提到“MapleStory”/“可爱”/“卡通”/“Q版”/“插画风格” →
    maple
各风格完整规则:
  • references/style-chunky-pixel.md
  • references/style-maple-cartoon.md
两种风格均禁用部分API(无曲线API、无渐变API、无分数坐标、无
filter: blur
/
drop-shadow
)。它们在调色板丰富度、轮廓颜色、抗锯齿和工作网格上有所区别。

3. Size guide (summary)

3. 尺寸指南(摘要)

UseRecommended size
Icon / button48×48 ~ 64×64
Character / item / NPC / monster96×96 ~ 128×128
Tile / floor / block64×64 ~ 128×128
Background / large object256×256 or larger (only on explicit request)
The default is 128×128. For style-specific working-grid tables (chunky uses a small logical grid like 16×16; maple uses a larger one like 64×64) and SD character proportions, see references/size-guide.md.
If the requested output is below 64×64, the
maple
style does not have enough pixels for selout + AA + facial features — either bump the output size to 64+ or fall back to
chunky
.

用途推荐尺寸
图标/按钮48×48 ~ 64×64
角色/物品/NPC/怪物96×96 ~ 128×128
Tile/地板/方块64×64 ~ 128×128
背景/大型物体256×256或更大(仅在明确请求时使用)
默认尺寸为128×128。风格专属工作网格表(chunky使用16×16等小逻辑网格;maple使用64×64等大逻辑网格)和SD角色比例,请参考references/size-guide.md
如果请求的输出尺寸小于64×64
maple
风格没有足够像素来实现selout + 抗锯齿 + 面部特征——要么将输出尺寸提升至64+,要么切换为
chunky
风格。

4. PNG render —
render.cjs

4. PNG渲染 ——
render.cjs

One-time dependency install

一次性依赖安装

bash
cd scripts && npm ci
This installs
puppeteer
(~200MB including headless Chromium) from the committed
package-lock.json
. It is separate from other base skill dependencies, so run this only the first time you use painter.
🔒 Use
npm ci
, not
npm install
.
npm ci
installs exactly the versions pinned in
package-lock.json
and fails if the lockfile and
package.json
disagree — this is the supply-chain integrity guarantee for W012. Never edit
package-lock.json
by hand; if you need to bump puppeteer, run
npm install puppeteer@<version>
locally and commit the regenerated lockfile.
bash
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。

Sandboxing & network isolation

沙箱与网络隔离

render.cjs
runs the headless Chromium with the OS sandbox enabled by default and blocks all network requests from the rendered page. The page is also served via a
data:
URL with a strict
Content-Security-Policy
(
default-src 'none'
), and the SVG / HTML input is sanitized to strip
<script>
,
<foreignObject>
, inline
on*
handlers, and non-
data:
URLs. You do not need to do anything to opt in — these protections are always on.
If you are in a constrained environment where Chromium cannot start its sandbox (some CI containers, certain WSL setups), set
PAINTER_DISABLE_SANDBOX=1
before invoking
render.cjs
. Do not set this on a developer workstation.
render.cjs
默认启用操作系统沙箱运行无头Chromium,并阻止渲染页面的所有网络请求。页面还通过带有严格
Content-Security-Policy
default-src 'none'
)的
data:
URL提供服务,SVG/HTML输入会被清理以移除
<script>
<foreignObject>
、内联
on*
处理器和非
data:
URL。无需手动开启这些保护——它们始终处于启用状态。
如果处于Chromium无法启动沙箱的受限环境(部分CI容器、特定WSL设置),请在调用
render.cjs
前设置
PAINTER_DISABLE_SANDBOX=1
请勿在开发者工作站上设置此变量。

Invocation

调用方式

bash
node scripts/render.cjs --type <svg|canvas|html> --in <code-file> --out <out.png> --width <W> --height <H>
Or pass the code via stdin:
bash
echo "<svg ...>" | node scripts/render.cjs --type svg --out out.png --width 128 --height 128
Options:
  • --type
    : One of
    svg
    /
    canvas
    /
    html
    . Required.
  • --in
    : Path to the code file. Omit or use
    -
    for stdin.
  • --out
    : Output PNG path. Required.
  • --width
    /
    --height
    : Output pixel size. Default 128.
On success, the absolute path of the output PNG is printed to stdout on a single line and exit code is 0. On failure, the error is printed to stderr and exit code is 1.
The PNG defaults to a transparent background. If you need a background color, draw it explicitly inside the SVG/Canvas/HTML.

bash
node scripts/render.cjs --type <svg|canvas|html> --in <代码文件路径> --out <输出.png> --width <宽度> --height <高度>
或通过标准输入传递代码:
bash
echo "<svg ...>" | node scripts/render.cjs --type svg --out out.png --width 128 --height 128
选项说明:
  • --type
    :
    svg
    /
    canvas
    /
    html
    三者之一。必填
  • --in
    : 代码文件路径。省略或使用
    -
    表示从标准输入读取。
  • --out
    : 输出PNG路径。必填
  • --width
    /
    --height
    : 输出像素尺寸。默认128。
成功时,输出PNG的绝对路径会单行打印到标准输出,退出码为0。失败时,错误信息会打印到标准错误输出,退出码为1。
PNG默认背景为透明。若需要背景色,请在SVG/Canvas/HTML内明确绘制。

5. Resource upload — two-step pattern

5. 资源上传 —— 两步式流程

mcp__msw-mcp__asset_create_resource_storage_item
is called twice.
🔒 Security — handling the presigned URL (W007). The
presignedUrl
returned in step 1 is a short-lived signed credential (anyone holding it can PUT to that storage slot until it expires). Treat it as a secret:
  • Never echo, quote, paraphrase, or include the URL or any of its query parameters (
    X-Amz-Signature
    ,
    X-Amz-Credential
    , etc.) in the assistant's user-facing response, in commit messages, in logs, or in any subsequent prompt — including when reporting "what you did".
  • When invoking the shell, pass the URL via the
    PAINTER_PRESIGNED_URL
    environment variable as shown below, not as a command-line argument. Command-line arguments are visible to other processes via
    /proc/*/cmdline
    (Linux/macOS) and
    Get-Process
    (Windows), and they are recorded in shell history.
  • When invoking step 3, pass the URL directly as the
    fileUrl
    tool argument — do not copy it into a code block or markdown for the user to see first.
  • If the PUT step fails (typically
    401
    /
    403
    → URL expired), discard the URL and restart from step 1. Do not reuse it elsewhere.
需调用两次
mcp__msw-mcp__asset_create_resource_storage_item
🔒 安全注意事项 —— 处理预签名URL(W007)。步骤1返回的
presignedUrl
是短期签名凭证(任何人持有该URL均可向对应存储槽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重新开始。不要在其他地方复用。

Step 1 — request a presigned URL

步骤1 —— 请求预签名URL

mcp__msw-mcp__asset_create_resource_storage_item({
  category: "sprite",
  subcategory: "<appropriate subcategory>",   // e.g. "monster", "npc", "object", "icon"
  name: "<resource name>",
  description: "<1–2 sentence description>",
  makerOwnerType: 0,                          // 0 = Account
  makerOwnerId: "<account id>",               // look up in advance with mcp__msw-mcp__account_get_my_user_id
  // omit fileUrl in this step
})
The response contains a
presignedUrl
. Keep it inside the agent's reasoning context only — do not surface it in chat output.
mcp__msw-mcp__asset_create_resource_storage_item({
  category: "sprite",
  subcategory: "<合适的子分类>",   // 例如:"monster", "npc", "object", "icon"
  name: "<资源名称>",
  description: "<1-2句描述>",
  makerOwnerType: 0,                          // 0 = 账户
  makerOwnerId: "<账户ID>",               // 提前通过mcp__msw-mcp__account_get_my_user_id查询
  // 此步骤省略fileUrl
})
响应包含
presignedUrl
。仅在代理的推理上下文中保留该URL——不要在聊天输出中展示。

Step 2 — PUT the PNG binary (URL passed via env var)

步骤2 —— PUT PNG二进制文件(通过环境变量传递URL)

PowerShell:
powershell
$env:PAINTER_PRESIGNED_URL = "<presignedUrl from step 1>"
try {
  Invoke-WebRequest -Method PUT -InFile out.png -Uri $env:PAINTER_PRESIGNED_URL -ContentType "image/png"
} finally {
  Remove-Item Env:\PAINTER_PRESIGNED_URL -ErrorAction SilentlyContinue
}
bash (Git for Windows / WSL):
bash
PAINTER_PRESIGNED_URL="<presignedUrl from step 1>" \
  curl -X PUT -T out.png "$PAINTER_PRESIGNED_URL" && \
  unset PAINTER_PRESIGNED_URL
The PUT itself is a plain binary upload — no auth headers are needed (the signature is embedded in the presigned URL). The env-var pattern keeps the URL out of
Get-Process
/
ps
-visible argument lists and out of shell history.
PowerShell:
powershell
$env:PAINTER_PRESIGNED_URL = "<步骤1返回的presignedUrl>"
try {
  Invoke-WebRequest -Method PUT -InFile out.png -Uri $env:PAINTER_PRESIGNED_URL -ContentType "image/png"
} finally {
  Remove-Item Env:\PAINTER_PRESIGNED_URL -ErrorAction SilentlyContinue
}
bash(Git for Windows / WSL):
bash
PAINTER_PRESIGNED_URL="<步骤1返回的presignedUrl>" \
  curl -X PUT -T out.png "$PAINTER_PRESIGNED_URL" && \
  unset PAINTER_PRESIGNED_URL
PUT本身是普通二进制上传——无需认证头(签名已嵌入预签名URL)。环境变量模式可避免URL出现在
Get-Process
/
ps
可见的参数列表和shell历史中。

Step 3 — report upload completion

步骤3 —— 汇报上传完成

mcp__msw-mcp__asset_create_resource_storage_item({
  ...same arguments,
  fileUrl: "<presignedUrl from step 1>"   // pass directly as tool arg, do not echo
})
The response contains the sprite RUID. That is the final deliverable. After this call returns, treat the URL as fully consumed — do not retain it.
mcp__msw-mcp__asset_create_resource_storage_item({
  ...相同参数,
  fileUrl: "<步骤1返回的presignedUrl>"   // 直接作为工具参数传递,不要回显
})
响应包含精灵RUID。这是最终交付物。此调用返回后,该URL视为已完全使用——请勿保留。

Choosing a subcategory

选择子分类

First inspect the subcategory distribution of existing sprites with
asset_search_resources
or
asset_list_account_resources
and match it. When in doubt, fall back to a generic value such as
object
/
etc
.

先通过
asset_search_resources
asset_list_account_resources
查看现有精灵的子分类分布并匹配。不确定时,使用通用值如
object
/
etc

6. Report format

6. 汇报格式

When the painter task is done, hand the user only this:
RUID: <received RUID>
Style: <chunky | maple>
<1–2 sentence description: what you drew, at what size, and what sprite it was registered as>
Entity creation/movement/spawn, script authoring, and UI editing are outside the painter's scope. Handle those in another skill or a follow-up step.

绘图工具任务完成后,仅向用户提供以下内容:
RUID: <获取到的RUID>
Style: <chunky | maple>
<1-2句描述:绘制的内容、尺寸、注册的精灵类型>
实体创建/移动/生成、脚本编写和UI编辑不属于绘图工具的处理范围。请在其他技能或后续步骤中处理。

Common pitfalls

常见陷阱

  • Not running
    npm ci
    before
    render.cjs
    Cannot find module 'puppeteer'
    . Only needed the first time. Use
    npm ci
    (not
    npm install
    ) so the lockfile-pinned puppeteer version is installed.
  • Omitting
    --width
    /
    --height
    → It falls back to 128×128, and if the user wanted a different size you have to redraw. Always specify it.
  • SVG/Canvas content drawn only in the top-left corner of the PNG → The drawing code declared its own dimensions (e.g. SVG
    width="128" height="128"
    or Canvas
    scale = 8
    ) but render.cjs was invoked with a larger
    --width
    /
    --height
    . The content fills only its declared size and the rest of the PNG stays transparent. Fix: SVG uses
    width="100%" height="100%"
    ; Canvas derives scale from
    c.width
    . The Minimal templates above already follow this.
  • Always Read the output PNG before uploading → A misconfigured SVG/Canvas can silently produce a blank or off-canvas PNG. One
    Read
    on the output catches the size-mismatch and blank-canvas bugs in seconds; uploading first means re-doing the 2-step upload.
  • Background comes out black → You drew a background inside the SVG/Canvas/HTML. To keep it transparent, remove the background shape itself.
  • Curves look smooth → If using
    chunky
    , this is a rule violation; remove
    arc()
    /
    bezierCurveTo()
    /gradients and redraw with dots. If using
    maple
    , smoothness should come from selective AA pixels at the silhouette, NOT from gradient/curve APIs — the API ban still applies.
  • Maple sprite looks like chunky with extra colors → You probably forgot the selout (1-pixel darker-color outline around each surface) and/or the selective AA at silhouette edges. Re-check
    style-maple-cartoon.md
    Selout and Selective AA sections.
  • Chunky sprite looks mushy / blurry → You added intermediate-color pixels on edges. Chunky forbids ALL anti-aliasing — remove transition pixels and keep edges sharp. If a softer look is desired, switch to
    maple
    instead.
  • Maple sprite at small size (32×32 output) looks bad → Maple style needs ≥ 64×64 output to fit selout + AA + features. Either increase size or switch to
    chunky
    .
  • PUT step fails with 401/403 → The presigned URL expired or is wrong. Restart from step 1.
  • Changing other metadata in the step-2 completion call → Pass the exact same
    category
    /
    subcategory
    /
    name
    /
    description
    /
    makerOwnerType
    /
    makerOwnerId
    as in step 1. Only add
    fileUrl
    .
  • 运行
    render.cjs
    前未执行
    npm ci
    Cannot find module 'puppeteer'
    。仅首次使用时需要。请使用
    npm ci
    (不要用
    npm install
    )以安装lockfile固定版本的puppeteer。
  • 省略
    --width
    /
    --height
    → 会 fallback到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
    推导缩放比例。上述极简模板已遵循此规则。
  • 上传前务必查看输出PNG → 配置错误的SVG/Canvas可能会静默生成空白或偏移画布的PNG。查看输出可在几秒内发现尺寸不匹配和空白画布问题;若先上传则需重新执行两步式上传流程。
  • 背景显示为黑色 → 你在SVG/Canvas/HTML内绘制了背景。若要保持透明,请移除背景形状。
  • 曲线看起来平滑 → 如果使用
    chunky
    风格,这违反规则;请移除
    arc()
    /
    bezierCurveTo()
    /渐变并重新用像素点绘制。如果使用
    maple
    风格,平滑效果应来自轮廓处的选择性抗锯齿像素,而非渐变/曲线API——API禁用规则仍然适用。
  • Maple风格精灵看起来像添加了额外颜色的chunky风格 → 你可能忘记了**selout(每个表面周围1px深色轮廓)**和/或轮廓处的选择性抗锯齿。请重新查看
    style-maple-cartoon.md
    中的Selout和选择性抗锯齿部分。
  • Chunky风格精灵看起来模糊/柔和 → 你在边缘添加了中间色像素。Chunky风格禁止所有抗锯齿——请移除过渡像素并保持边缘锐利。若需要更柔和的效果,请切换为
    maple
    风格。
  • 小尺寸(32×32输出)的Maple风格精灵效果不佳 → Maple风格需要≥64×64的输出尺寸才能容纳selout + 抗锯齿 + 特征。要么增大尺寸,要么切换为
    chunky
    风格。
  • PUT步骤返回401/403失败 → 预签名URL已过期或错误。请从步骤1重新开始。
  • 在步骤2完成调用中修改其他元数据 → 传递与步骤1完全相同的
    category
    /
    subcategory
    /
    name
    /
    description
    /
    makerOwnerType
    /
    makerOwnerId
    。仅添加
    fileUrl