Msw Painter
When msw-search cannot find a suitable sprite RUID, draw a pixel art sprite directly with SVG / HTML5 Canvas / HTML code, render it to PNG, and upload it via the msw-mcp asset upload tool to obtain a sprite RUID (if no upload tool is connected, guide the user to register it through Maker). Two style modes are supported: chunky pixel (retro / icon / tile feel) and maple cartoon (MapleStory-inspired character / NPC feel). Triggers: draw sprite directly, create sprite, image generation, custom graphic, pixel art, cartoon sprite, maple style, chibi character, painter, draw a sprite, make an icon, create NPC image directly, draw a slime, custom sprite.
- Skill ID
- msw-git/msw-ai-coding-plugins-official/msw-painter
- Publisher
- msw-git
- Repository
- msw-ai-coding-plugins-official
- Installs
- 0
- Files
- 6
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
msw-git/msw-ai-coding-plugins-official/msw-painterInstalls these files- SKILL.md
- references/size-guide.md
- references/style-chunky-pixel.md
- references/style-maple-cartoon.md
- scripts/package.json
- scripts/render.cjs
What this skill tells the agent
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.
When to invoke
| Situation | Action |
|---|---|
| User wants a specific sprite | First 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 unsuitable | Invoke painter → create directly |
| User explicitly says "I need a hand-drawn looking character/icon" | Invoke painter directly |
Workflow
- Choose the medium — One of SVG / Canvas / HTML. See "Choosing the medium" below.
- Choose the style —
chunkyormaple. See "Choosing the style" below. - Decide the size — See references/size-guide.md. Default is 128×128.
- Write the code — Follow the rules for the chosen style:
chunky→ references/style-chunky-pixel.mdmaple→ references/style-maple-cartoon.md
- Render to PNG — Run
scripts/render.cjs. - Upload the resource — the msw-mcp asset upload tool, two-step presigned pattern (§5). If the connected MCP has no upload tool, ask the user to register the PNG through Maker.
- Register sprite properties —
asset_update_resource_storage_inforight after upload:filter_mode/wrap_mode/ pivot, plus 9-slice borders for UI frame sprites. See "Step 4" below. - 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. Choosing the medium
| Medium | Recommended use | Strengths |
|---|---|---|
| SVG | Icons, logos, simple characters, shape-based pixel art | Intuitive code, easy to drop 1px <rect> dots |
| Canvas | Procedural patterns, iterative logic (loop-drawn textures / noise) | Generate complex patterns via JS programming logic |
| HTML | Composite layouts that can be styled quickly with CSS | Rarely used — SVG/Canvas is usually a better fit for pixel art |
Minimal SVG template
<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>⚠️ Usewidth="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/--heightspecifies.
Minimal Canvas template
// `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);Minimal HTML template
<!doctype html>
<html><body style="margin:0; image-rendering: pixelated;">
<!-- Anything you like -->
</body></html>2. Choosing the style
| Style | Recommended use | Look & feel | Logical grid | Outline | Shading |
|---|---|---|---|---|---|
| `chunky` | Icons, buttons, tiles, blocks, simple props | Retro / 8-bit / NES-SNES | Small (16×16, 32×32) | Black or white, 1px | 2–4 stepped levels, NO AA |
| `maple` | Characters, NPCs, monsters, cute mascots | MapleStory / storybook / cartoon | Larger (32×32 ~ 128×128) | Selout (darker version of fill color) | 4–6 stepped levels + selective AA on silhouette + optional 2×2 dithering |
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.
3. Size guide (summary)
| Use | Recommended size |
|---|---|
| Icon / button | 48×48 ~ 64×64 |
| Character / item / NPC / monster | 96×96 ~ 128×128 |
| Tile / floor / block | 64×64 ~ 128×128 |
| Background / large object | 256×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, themaplestyle does not have enough pixels for selout + AA + facial features — either bump the output size to 64+ or fall back tochunky.
4. PNG render — render.cjs
One-time dependency install
cd scripts && npm ciThis 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.
🔒 Usenpm ci, notnpm install.npm ciinstalls exactly the versions pinned inpackage-lock.jsonand fails if the lockfile andpackage.jsondisagree — this is the supply-chain integrity guarantee for W012. Never editpackage-lock.jsonby hand; if you need to bump puppeteer, runnpm install puppeteer@<version>locally and commit the regenerated 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.
Invocation
node scripts/render.cjs --type <svg|canvas|html> --in <code-file> --out <out.png> --width <W> --height <H>Or pass the code via stdin:
echo "<svg ...>" | node scripts/render.cjs --type svg --out out.png --width 128 --height 128Options:
--type: One ofsvg/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.
More from msw-git
Use this skill in a project
Open any RiverX project, search the Skills panel for msw-git/msw-ai-coding-plugins-official/msw-painter, and install it in one click.
