diff --git a/README.md b/README.md
index fc5ed54..3c3b585 100644
--- a/README.md
+++ b/README.md
@@ -1,50 +1,243 @@
# piskel-cli
-一个面向脚本与自动化场景的像素画命令行工具。
+> **Headless pixel art engine for scripts, pipelines, and AI agents.**
+> Create, edit, and export `.piskel` files entirely from the terminal — no browser, no GUI, no clicks.
-本工具围绕 **Piskel** 的 `.piskel` 工程格式与常见的图层 / 帧 / 像素编辑工作流建模,便于在终端里创建、修改和导出像素图。实现为独立的 **Node.js** 程序:不依赖在浏览器中打开官方 Piskel 编辑器即可执行读写与导出。
+[](https://www.npmjs.com/package/@ne9roni/piskel-cli)
+[](LICENSE)
+[](https://nodejs.org)
-## 当前能力
+---
-支持工程管理、图层与帧、像素绘制与读取、多种图像导出,以及通过计划文件批量执行步骤。具体子命令与参数见 `docs/commands.md`。
+## Why piskel-cli?
-## Get started
+[Piskel](https://www.piskelapp.com/) is a beloved browser-based pixel art editor. **piskel-cli** brings its `.piskel` format to the command line, making pixel art a first-class citizen in any automated workflow:
+
+- **AI agents** can generate sprites and animations with a single prompt — no image model required
+- **Build pipelines** can produce and export assets without human interaction
+- **Scripts** can batch-edit hundreds of frames in seconds
+- **CI/CD** can validate and regenerate pixel art assets automatically
+
+Every operation is scriptable, composable, and returns structured JSON — trivially easy to chain with other tools.
+
+---
+
+## AI Agent Integration
+
+**You don't need an image generation model to create pixel art with AI.** Any LLM that can write JSON can generate production-ready sprites and animations by describing them as a plan file.
+
+### Install the AI skill
```bash
-npm install
-npm run build
-node dist/src/cli.js --help
+npx skills add Ne9roni/piskel-cli
+```
+
+This installs a structured prompt ([`skills/using-piskel-cli/SKILL.md`](skills/using-piskel-cli/SKILL.md)) into your AI agent that teaches it the full piskel-cli workflow — including a mandatory alignment step before making any changes, so the AI never generates something you didn't ask for.
+
+### How it works
+
+Tell your AI agent (Claude, GPT, Cursor, etc.) what you want in plain language:
+
+> *"Draw a 16×16 red mushroom sprite with white spots and export it as PNG"*
+
+The agent writes a `plan.json` and runs:
+
+```bash
+piskel-cli run mushroom-plan.json --json
+```
+
+That's it. No image model. No diffusion. Pure geometry.
+
+---
+
+## AI-Generated Demo
+
+Everything below was generated entirely by an AI agent using piskel-cli — from a one-line description to exported files. No image model was involved.
+
+### Sprites (PNG)
+
+
+
+### Animations (GIF)
+
+
+
+Each example is a self-contained JSON plan file in [`examples/`](examples/). Run any of them yourself:
+
+```bash
+piskel-cli run examples/fire-plan.json --json
```
-也可以直接运行 `node dist/src/cli.js` 查看完整命令用法。
+---
-如果通过 npm 安装已发布版本,可使用:
+## Install
```bash
+# Install globally (recommended)
npm install -g @ne9roni/piskel-cli
+
+# Verify
piskel-cli --help
```
-## 文档与技能
+Or use locally from source:
+
+```bash
+git clone https://github.com/Ne9roni/piskel-cli.git
+cd piskel-cli
+npm install && npm run build
+node dist/src/cli.js --help
+```
+
+---
+
+## Quick Start
+
+### 1. Create a project
+
+```bash
+piskel-cli project create --width 16 --height 16 --name my-sprite --json
+```
+
+### 2. Draw pixels
+
+```bash
+piskel-cli draw rect output/my-sprite.piskel --x1 2 --y1 2 --x2 13 --y2 13 --color "#ff0000" --filled --json
+piskel-cli draw pixel output/my-sprite.piskel --x 8 --y 8 --color "#ffffff" --json
+```
+
+### 3. Export
+
+```bash
+piskel-cli export png output/my-sprite.piskel --json
+piskel-cli export gif output/my-sprite.piskel --json
+piskel-cli export frames output/my-sprite.piskel --json
+```
+
+### Or do it all at once with a plan file
+
+```json
+{
+ "steps": [
+ { "command": "project.create", "args": { "width": 16, "height": 16, "name": "hero" } },
+ { "command": "draw.rect", "args": { "project": "output/output.piskel", "x1": 3, "y1": 0, "x2": 12, "y2": 15, "color": "#4fc3f7", "filled": true } },
+ { "command": "export.gif", "args": { "project": "output/output.piskel" } }
+ ]
+}
+```
+
+```bash
+piskel-cli run my-plan.json --json
+```
+
+---
+
+## All Commands
+
+| Group | Commands |
+|-------|----------|
+| **Project** | `project create`, `project info` |
+| **Layer** | `layer list`, `layer add`, `layer remove`, `layer rename`, `layer set-opacity`, `layer move` |
+| **Frame** | `frame list`, `frame add`, `frame remove`, `frame duplicate`, `frame move` |
+| **Draw** | `draw pixel`, `draw pixels`, `draw line`, `draw rect`, `draw circle` |
+| **Fill / Erase** | `fill area`, `erase pixel`, `clear frame` |
+| **Read** | `read pixel`, `read frame`, `read project`, `read palette`, `read bounds` |
+| **Export** | `export png`, `export gif`, `export spritesheet`, `export frames` |
+| **Run** | `run ` — execute multi-step plan files |
+
+Full reference: [`docs/commands.md`](docs/commands.md)
+
+---
+
+## JSON Protocol
+
+Every command supports `--json` for machine-readable output:
+
+```json
+// Success
+{ "ok": true, "data": { ... } }
+
+// Failure
+{ "ok": false, "error": { "code": "FRAME_INDEX_OUT_OF_RANGE", "message": "..." } }
+```
+
+Consistent error codes across all commands make error handling simple in any language.
-- 命令用法与说明:`docs/commands.md`
-- 安装 Agent 技能([Skills CLI](https://www.npmjs.com/package/skills)):`npx skills add Ne9roni/piskel-cli`
-- 技能说明:`skills/using-piskel-cli/SKILL.md`
+---
-## 示例
+## Plan Files
+
+The `run` command executes a JSON plan file as an atomic sequence of steps — ideal for AI agents, build scripts, or complex multi-frame animations:
+
+```bash
+piskel-cli run examples/twinkle-star-plan.json --json
+```
-计划文件样例位于 `examples/heart-plan.json` 与 `examples/twinkle-star-plan.json`。
+See [`examples/`](examples/) for full working examples and [`skills/using-piskel-cli/reference/reference-plan-format.md`](skills/using-piskel-cli/reference/reference-plan-format.md) for the complete plan format spec.
-对应的实际生成产物位于 `examples-output/`:
-- `examples-output/heart/`:包含 heart 示例生成的 `.piskel`、`.png`、`.gif` 与逐帧 PNG
-- `examples-output/twinkle-star/`:包含 twinkle-star 示例生成的 `.piskel` 与 `.gif`
+---
-通用计划格式与 JSON 协议摘要见 `skills/using-piskel-cli/reference/reference-plan-format.md`。
+## Architecture
+
+piskel-cli is implemented as a pure **Node.js / TypeScript** library with zero runtime browser dependencies. It operates directly on the `.piskel` JSON format:
+
+- **`src/probe/`** — headless read/write engine for `.piskel` files
+- **`src/cli/`** — command parser and JSON protocol layer
+- **`tests/`** — Vitest test suite covering `.piskel` I/O, CLI behavior, export correctness, and plan execution
+
+---
+
+## Development
+
+```bash
+npm install
+npm run build # Compile TypeScript
+npm test # Run full test suite (Vitest)
+npm run test:watch # Watch mode
+```
-## 测试
+Tests live in [`tests/`](tests/) and cover `.piskel` read/write, CLI behavior, default output paths, and plan execution end-to-end.
-开发与验证使用 package.json 中的 `test` 脚本(Vitest)。用例位于 `tests/`,覆盖 `.piskel` 读写、CLI 行为、默认输出与计划执行等。
+---
## License
-本项目采用 `Apache-2.0` 许可证,完整条款见根目录 `LICENSE`。
+[Apache-2.0](LICENSE)
diff --git a/examples-output/coin-spin/coin-spin.gif b/examples-output/coin-spin/coin-spin.gif
new file mode 100644
index 0000000..4ff8e2f
Binary files /dev/null and b/examples-output/coin-spin/coin-spin.gif differ
diff --git a/examples-output/coin-spin/coin-spin.piskel b/examples-output/coin-spin/coin-spin.piskel
new file mode 100644
index 0000000..fda7949
--- /dev/null
+++ b/examples-output/coin-spin/coin-spin.piskel
@@ -0,0 +1 @@
+{"modelVersion":2,"piskel":{"name":"coin-spin","description":"","fps":8,"width":16,"height":16,"hiddenFrames":[],"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":4,\"chunks\":[{\"layout\":[[0],[1],[2],[3]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAQCAYAAACm53kpAAABqUlEQVR4Ae3BsUrzUBiA4fekNssHOikEihCX3kDdHb2JLmdzcRQXEXERRxe3s/RG3O0NdMpSCOik8C0p5fwGkp/DIQ0dLfZ52PvjDBF14ukhVg091Imnh1g19FAnnh5i1dBDnXgay8WK2mg8pCVWDQFDQJ14tiBWDR1eLg49P67uT+jy+vBB7frt29Dh9vzI03h8PiZ0d/NJ6+n9y9BBnXgay8WK0Gg8pCVWDY2EhjrxBNI8I80z0jwjzTNC6sQTUSeeLakTT0SdeLakTjwRdeIJnF2e0jq7PCWkTjyNhA5pnlEbTGYMJjNqaZ6xK9I8I5bmGV0SImmeEVrPp7TSPOO3S/OMTdI8I5awwWAyY5cNJjO2ccAG6/mUXbaeT9lGwh+XEKmKkk2qouS3q4qSTaqiJJbQoSpKYlVRsiuqoiRWFSVdDAF14tmCWDV0eLk49Py4uj+hy+vDB7Xrt29Dh9vzI0/j8fmY0N3NJ62n9y9DB3XiaSwXK0Kj8ZCWWDU0DBF14ukhVg091Imnh1g19FAnnh5i1dBDnXgay8WK2mg8pCVWDXt7//0DQmSQ6bxcA8oAAAAASUVORK5CYII=\"}]}"]}}
\ No newline at end of file
diff --git a/examples-output/fire/fire.gif b/examples-output/fire/fire.gif
new file mode 100644
index 0000000..7cea03a
Binary files /dev/null and b/examples-output/fire/fire.gif differ
diff --git a/examples-output/fire/fire.piskel b/examples-output/fire/fire.piskel
new file mode 100644
index 0000000..c781f05
--- /dev/null
+++ b/examples-output/fire/fire.piskel
@@ -0,0 +1 @@
+{"modelVersion":2,"piskel":{"name":"fire","description":"","fps":6,"width":16,"height":16,"hiddenFrames":[],"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":3,\"chunks\":[{\"layout\":[[0],[1],[2]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAQCAYAAABQrvyxAAABqElEQVR4Ae3BMWrjQBQG4H9mF1xELOvGmGnSiHeIXGCbPYAa1zqA64ANbn0A38N9SjVmDjBM40IQ1ASNsMAY6y0GCYyQZEkpskW+D9/+Z0UWMT6hyCIusogxUpFFXGQRo4NEh+thgcubzxjpeljgeljg8uYzRrgeFrgeFujyEx2KvcNnFHuHm8k2ERih2Ds88gMtzssZo/T68rTaRKc1BjgvZ5zGOc7ZBZs/v1eb6LTGAOfljFF6fXlabaLTGg0kWky2iUBpsk0EBkrjHJU0zjFUGueopHGONhItksBjlJLAYwzktELFaYUhksBj1CSBx2gg0SAJPEZNEniMnpLAY9QkgcfoyWmFaThHGudI4xw3Tis0keiQxjnk318Y43lXwGkFpxXG+Ni9ozIN52gj0cBphcrH7h03Tiv05bTCMZSoPO8KOK0whNMKTis4rXAMJdpI1FgiRmkaznHPEjEesESMmmMocWOJGA9YIkYLS8SoEbhjiRg9+MYINLBEjB58YwQaWCJGD74xAiWBGkvE6OAbI9DBEjE6+MYIdLBEjA6+MQJ3JL59rX93FboU7M8j3QAAAABJRU5ErkJggg==\"}]}"]}}
\ No newline at end of file
diff --git a/examples-output/gem/gem.piskel b/examples-output/gem/gem.piskel
new file mode 100644
index 0000000..cc21d09
--- /dev/null
+++ b/examples-output/gem/gem.piskel
@@ -0,0 +1 @@
+{"modelVersion":2,"piskel":{"name":"gem","description":"","fps":12,"width":16,"height":16,"hiddenFrames":[],"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxklEQVR4AdXBsW2DQBiA0e8cKNiAms5NkDxCNkhxEnUGucKDUJ90BRswwknQ0LlmgysQ+mOkWMInsC1FKfIe/59ig9VB2FC5TBFRrFgdJC9Txm6icplixeogeZkydhOVyxQ/EiJjN7GwOgiRsZuIKSJWB+GBymWKlYRIXqYsjp9vLIZm5o7jzoEHhmbmmQM7hmbmpq172rpnS8ILPr7e2ZMQaeuem/PlpLgyhRd2KHaYwgsr58tJ8SpTeOHKFF74LVN44S99A2uePhTGlKjbAAAAAElFTkSuQmCC\"}]}"]}}
\ No newline at end of file
diff --git a/examples-output/gem/gem.png b/examples-output/gem/gem.png
new file mode 100644
index 0000000..6d4bd1f
Binary files /dev/null and b/examples-output/gem/gem.png differ
diff --git a/examples-output/ghost/ghost.gif b/examples-output/ghost/ghost.gif
new file mode 100644
index 0000000..d217409
Binary files /dev/null and b/examples-output/ghost/ghost.gif differ
diff --git a/examples-output/ghost/ghost.piskel b/examples-output/ghost/ghost.piskel
new file mode 100644
index 0000000..1547338
--- /dev/null
+++ b/examples-output/ghost/ghost.piskel
@@ -0,0 +1 @@
+{"modelVersion":2,"piskel":{"name":"ghost","description":"","fps":4,"width":16,"height":16,"hiddenFrames":[],"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":4,\"chunks\":[{\"layout\":[[0],[1],[2],[3]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAQCAYAAACm53kpAAABt0lEQVR4Ae3BvW3rMBQG0I+GB2DJinOwYMOCFQFukTIDeIIMkDJbCFClQo0KzXGrW94N7pMLIYRhyT95cBHkHPz587sQixKL4gKxKLEoLhxxgVgUC++sQYNYFAvvrMEOYlEsvLMGDWJRLLyzBjuIRbHwzho0iEWx8M4a3IFYFHc4YgOxKH6AWBQ/QCyKFzjgF4qpIKaCVUwFMRVcc8AVMRXEVLCKqSCmgleJqSCmglVMBTEV3EIsihuIRdE4oEEsihuIRbGBWBSLmApiKljFVBBTwRmxKDYQi+IGYlH8R0f8QtPYozWNPbYcccU09mhNY49XmsYerWns8YxumHFWc8CWI3Z0w4yzmgMeMY09WtPY4xlv7yecfX1+4FHdMGPVDTNqDrjmgA3dMGPVDTOe0Q0zumHGM97eT1i9vZ/wqJoDag6oOaDmgC1HbKg54Ce6YcaqG2bUHPCIr88PvMIBF7yzBg3vrEHDO2twh5oDag6oOaDmgHt5Zw0a3lmDhnfWYId31qDhnTVoeGcN9hCLokEsigaxKHYQi6JBLIoGsSh2EIuiQSyKBrEodhCLokEsigaxKP58+wfRg8jKS7oDbQAAAABJRU5ErkJggg==\"}]}"]}}
\ No newline at end of file
diff --git a/examples-output/mushroom/mushroom.piskel b/examples-output/mushroom/mushroom.piskel
new file mode 100644
index 0000000..e351485
--- /dev/null
+++ b/examples-output/mushroom/mushroom.piskel
@@ -0,0 +1 @@
+{"modelVersion":2,"piskel":{"name":"mushroom","description":"","fps":12,"width":16,"height":16,"hiddenFrames":[],"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAoUlEQVR4AcXBsQ3CMBBA0X8WHVucK9fxCFBmFmbJLJRkBKem8q1iQALJsmIIouA9/k5oJNXCG9FMqDhWDDkz5MwWjkpSLTwt3vMy5MyQMw9JtVBxrFi8p7Z4T4/wlFQLX4hmwp2jEs2ED6KZUBEaSbWEeWLN9XAimgkVRyPMEz1hnmjt6LheztTCcWSNo7HXUejY6yg0dnSE48gWjh85/u0GcLIppgJriNcAAAAASUVORK5CYII=\"}]}"]}}
\ No newline at end of file
diff --git a/examples-output/mushroom/mushroom.png b/examples-output/mushroom/mushroom.png
new file mode 100644
index 0000000..822ee49
Binary files /dev/null and b/examples-output/mushroom/mushroom.png differ
diff --git a/examples-output/sword/sword.piskel b/examples-output/sword/sword.piskel
new file mode 100644
index 0000000..9cec828
--- /dev/null
+++ b/examples-output/sword/sword.piskel
@@ -0,0 +1 @@
+{"modelVersion":2,"piskel":{"name":"sword","description":"","fps":12,"width":16,"height":16,"hiddenFrames":[],"layers":["{\"name\":\"Layer 1\",\"opacity\":1,\"frameCount\":1,\"chunks\":[{\"layout\":[[0]],\"base64PNG\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAvElEQVR4AdXBIW4CQRQG4H/3ACBrinsHWUcvUFk3CSEhqLnFuM0Y9Fxi3atfvQfYFgEOsE/8DMnKNtkJNf0+/D9fpwsfMKlRoB9Grl6W+D5fUawfRiLrh5EoYSo0FSLrh5EoYSqMqSOymDriBzV+YSo8HCN2H29VTB03rzvMZip0PhBZTB1NhZjLVGgqROZ8oKkQJZwPROZ8oKkQJdbvWyJzPtBUiBkqTNpmQUz2n7cKM9V4Uo2/1DYLotAdwk9b1fw/5DIAAAAASUVORK5CYII=\"}]}"]}}
\ No newline at end of file
diff --git a/examples-output/sword/sword.png b/examples-output/sword/sword.png
new file mode 100644
index 0000000..29917e2
Binary files /dev/null and b/examples-output/sword/sword.png differ
diff --git a/examples/coin-spin-plan.json b/examples/coin-spin-plan.json
new file mode 100644
index 0000000..38f9352
--- /dev/null
+++ b/examples/coin-spin-plan.json
@@ -0,0 +1,48 @@
+{
+ "steps": [
+ {
+ "command": "project.create",
+ "args": {
+ "width": 16,
+ "height": 16,
+ "fps": 8,
+ "output": "examples-output/coin-spin/coin-spin.piskel",
+ "name": "coin-spin"
+ }
+ },
+ { "command": "draw.circle", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 0, "x1": 2, "y1": 2, "x2": 13, "y2": 13, "color": "#f59e0b" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 0, "x1": 3, "y1": 3, "x2": 12, "y2": 12, "color": "#fbbf24", "filled": true } },
+ { "command": "draw.circle", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 0, "x1": 2, "y1": 2, "x2": 13, "y2": 13, "color": "#f59e0b" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 0, "x": 7, "y": 5, "color": "#fef3c7" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 0, "x": 8, "y": 5, "color": "#fef3c7" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 0, "x": 7, "y": 6, "color": "#fef3c7" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 0, "x": 6, "y": 7, "color": "#fef3c7" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 0, "x": 7, "y": 7, "color": "#fef3c7" } },
+ { "command": "frame.duplicate", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 0 } },
+ { "command": "frame.duplicate", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 0 } },
+ { "command": "frame.duplicate", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 0 } },
+ { "command": "draw.rect", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 1, "x1": 5, "y1": 3, "x2": 10, "y2": 12, "color": "#fbbf24", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 1, "x1": 3, "y1": 3, "x2": 4, "y2": 12, "color": "#92400e", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 1, "x1": 11, "y1": 3, "x2": 12, "y2": 12, "color": "#92400e", "filled": true } },
+ { "command": "draw.line", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 1, "x1": 5, "y1": 2, "x2": 10, "y2": 2, "color": "#f59e0b" } },
+ { "command": "draw.line", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 1, "x1": 5, "y1": 13, "x2": 10, "y2": 13, "color": "#f59e0b" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 2, "x1": 6, "y1": 3, "x2": 9, "y2": 12, "color": "#fbbf24", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 2, "x1": 3, "y1": 3, "x2": 5, "y2": 12, "color": "#78350f", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 2, "x1": 10, "y1": 3, "x2": 12, "y2": 12, "color": "#78350f", "filled": true } },
+ { "command": "draw.line", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 2, "x1": 6, "y1": 2, "x2": 9, "y2": 2, "color": "#f59e0b" } },
+ { "command": "draw.line", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 2, "x1": 6, "y1": 13, "x2": 9, "y2": 13, "color": "#f59e0b" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 3, "x1": 7, "y1": 2, "x2": 8, "y2": 13, "color": "#d97706", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 3, "x": 6, "y": 3, "color": "#d97706" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 3, "x": 9, "y": 3, "color": "#d97706" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 3, "x": 6, "y": 12, "color": "#d97706" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/coin-spin/coin-spin.piskel", "frame": 3, "x": 9, "y": 12, "color": "#d97706" } },
+ {
+ "command": "export.gif",
+ "args": {
+ "project": "examples-output/coin-spin/coin-spin.piskel",
+ "output": "examples-output/coin-spin/coin-spin.gif",
+ "delay-ms": 120
+ }
+ }
+ ]
+}
diff --git a/examples/fire-plan.json b/examples/fire-plan.json
new file mode 100644
index 0000000..345270c
--- /dev/null
+++ b/examples/fire-plan.json
@@ -0,0 +1,69 @@
+{
+ "steps": [
+ {
+ "command": "project.create",
+ "args": {
+ "width": 16,
+ "height": 16,
+ "fps": 6,
+ "output": "examples-output/fire/fire.piskel",
+ "name": "fire"
+ }
+ },
+ { "command": "draw.rect", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x1": 5, "y1": 10, "x2": 10, "y2": 14, "color": "#dc2626", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x1": 4, "y1": 11, "x2": 11, "y2": 14, "color": "#dc2626", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x": 3, "y": 12, "color": "#dc2626" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x": 12, "y": 12, "color": "#dc2626" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x1": 6, "y1": 7, "x2": 9, "y2": 11, "color": "#ea580c", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x": 5, "y": 8, "color": "#ea580c" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x": 10, "y": 8, "color": "#ea580c" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x": 5, "y": 9, "color": "#ea580c" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x": 10, "y": 9, "color": "#ea580c" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x1": 7, "y1": 4, "x2": 8, "y2": 8, "color": "#f97316", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x": 6, "y": 5, "color": "#f97316" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x": 9, "y": 5, "color": "#f97316" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x": 7, "y": 3, "color": "#fbbf24" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x": 8, "y": 3, "color": "#fbbf24" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x": 7, "y": 2, "color": "#fef3c7" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x": 8, "y": 9, "color": "#fbbf24" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0, "x": 7, "y": 11, "color": "#fbbf24" } },
+
+ { "command": "frame.duplicate", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0 } },
+ { "command": "frame.duplicate", "args": { "project": "examples-output/fire/fire.piskel", "frame": 0 } },
+
+ { "command": "draw.rect", "args": { "project": "examples-output/fire/fire.piskel", "frame": 1, "x1": 6, "y1": 7, "x2": 9, "y2": 11, "color": "#dc2626", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/fire/fire.piskel", "frame": 1, "x1": 7, "y1": 5, "x2": 8, "y2": 8, "color": "#ea580c", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 1, "x": 6, "y": 6, "color": "#ea580c" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 1, "x": 9, "y": 6, "color": "#ea580c" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 1, "x": 10, "y": 8, "color": "#ea580c" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 1, "x": 5, "y": 9, "color": "#ea580c" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 1, "x": 7, "y": 4, "color": "#f97316" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 1, "x": 8, "y": 4, "color": "#f97316" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 1, "x": 9, "y": 3, "color": "#fbbf24" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 1, "x": 8, "y": 2, "color": "#fef3c7" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 1, "x": 6, "y": 9, "color": "#fbbf24" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 1, "x": 9, "y": 10, "color": "#fbbf24" } },
+
+ { "command": "draw.rect", "args": { "project": "examples-output/fire/fire.piskel", "frame": 2, "x1": 5, "y1": 8, "x2": 10, "y2": 11, "color": "#dc2626", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/fire/fire.piskel", "frame": 2, "x1": 6, "y1": 6, "x2": 9, "y2": 9, "color": "#ea580c", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 2, "x": 5, "y": 7, "color": "#ea580c" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 2, "x": 10, "y": 7, "color": "#ea580c" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/fire/fire.piskel", "frame": 2, "x1": 7, "y1": 4, "x2": 8, "y2": 7, "color": "#f97316", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 2, "x": 6, "y": 5, "color": "#f97316" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 2, "x": 9, "y": 5, "color": "#f97316" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 2, "x": 7, "y": 3, "color": "#fbbf24" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 2, "x": 8, "y": 3, "color": "#fbbf24" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 2, "x": 8, "y": 2, "color": "#fef3c7" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 2, "x": 6, "y": 8, "color": "#fbbf24" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/fire/fire.piskel", "frame": 2, "x": 9, "y": 9, "color": "#fbbf24" } },
+
+ {
+ "command": "export.gif",
+ "args": {
+ "project": "examples-output/fire/fire.piskel",
+ "output": "examples-output/fire/fire.gif",
+ "delay-ms": 160
+ }
+ }
+ ]
+}
diff --git a/examples/gem-plan.json b/examples/gem-plan.json
new file mode 100644
index 0000000..f065c11
--- /dev/null
+++ b/examples/gem-plan.json
@@ -0,0 +1,39 @@
+{
+ "steps": [
+ {
+ "command": "project.create",
+ "args": {
+ "width": 16,
+ "height": 16,
+ "output": "examples-output/gem/gem.piskel",
+ "name": "gem"
+ }
+ },
+ { "command": "draw.line", "args": { "project": "examples-output/gem/gem.piskel", "x1": 5, "y1": 3, "x2": 10, "y2": 3, "color": "#a855f7" } },
+ { "command": "draw.line", "args": { "project": "examples-output/gem/gem.piskel", "x1": 3, "y1": 5, "x2": 12, "y2": 5, "color": "#a855f7" } },
+ { "command": "draw.line", "args": { "project": "examples-output/gem/gem.piskel", "x1": 3, "y1": 4, "x2": 5, "y2": 4, "color": "#a855f7" } },
+ { "command": "draw.line", "args": { "project": "examples-output/gem/gem.piskel", "x1": 10, "y1": 4, "x2": 12, "y2": 4, "color": "#a855f7" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/gem/gem.piskel", "x": 4, "y": 4, "color": "#c084fc" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/gem/gem.piskel", "x": 11, "y": 4, "color": "#c084fc" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/gem/gem.piskel", "x1": 4, "y1": 6, "x2": 11, "y2": 10, "color": "#c084fc", "filled": true } },
+ { "command": "draw.line", "args": { "project": "examples-output/gem/gem.piskel", "x1": 4, "y1": 6, "x2": 11, "y2": 6, "color": "#a855f7" } },
+ { "command": "draw.line", "args": { "project": "examples-output/gem/gem.piskel", "x1": 4, "y1": 11, "x2": 6, "y2": 11, "color": "#7e22ce" } },
+ { "command": "draw.line", "args": { "project": "examples-output/gem/gem.piskel", "x1": 9, "y1": 11, "x2": 11, "y2": 11, "color": "#7e22ce" } },
+ { "command": "draw.line", "args": { "project": "examples-output/gem/gem.piskel", "x1": 6, "y1": 12, "x2": 9, "y2": 12, "color": "#7e22ce" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/gem/gem.piskel", "x": 5, "y": 13, "color": "#7e22ce" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/gem/gem.piskel", "x": 7, "y": 13, "color": "#7e22ce" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/gem/gem.piskel", "x": 8, "y": 14, "color": "#7e22ce" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/gem/gem.piskel", "x": 6, "y": 7, "color": "#e9d5ff" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/gem/gem.piskel", "x": 7, "y": 7, "color": "#e9d5ff" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/gem/gem.piskel", "x": 6, "y": 8, "color": "#e9d5ff" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/gem/gem.piskel", "x": 9, "y": 9, "color": "#7e22ce" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/gem/gem.piskel", "x": 10, "y": 9, "color": "#7e22ce" } },
+ {
+ "command": "export.png",
+ "args": {
+ "project": "examples-output/gem/gem.piskel",
+ "output": "examples-output/gem/gem.png"
+ }
+ }
+ ]
+}
diff --git a/examples/ghost-plan.json b/examples/ghost-plan.json
new file mode 100644
index 0000000..c79d877
--- /dev/null
+++ b/examples/ghost-plan.json
@@ -0,0 +1,79 @@
+{
+ "steps": [
+ {
+ "command": "project.create",
+ "args": {
+ "width": 16,
+ "height": 16,
+ "fps": 4,
+ "output": "examples-output/ghost/ghost.piskel",
+ "name": "ghost"
+ }
+ },
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x1": 4, "y1": 4, "x2": 11, "y2": 12, "color": "#e2e8f0", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x1": 3, "y1": 7, "x2": 12, "y2": 12, "color": "#e2e8f0", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x": 4, "y": 3, "color": "#e2e8f0" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x": 5, "y": 3, "color": "#e2e8f0" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x": 10, "y": 3, "color": "#e2e8f0" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x": 11, "y": 3, "color": "#e2e8f0" } },
+ { "command": "draw.line", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x1": 3, "y1": 13, "x2": 4, "y2": 14, "color": "#e2e8f0" } },
+ { "command": "draw.line", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x1": 5, "y1": 13, "x2": 7, "y2": 13, "color": "#e2e8f0" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x": 8, "y": 14, "color": "#e2e8f0" } },
+ { "command": "draw.line", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x1": 9, "y1": 13, "x2": 11, "y2": 13, "color": "#e2e8f0" } },
+ { "command": "draw.line", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x1": 11, "y1": 13, "x2": 12, "y2": 14, "color": "#e2e8f0" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x1": 5, "y1": 6, "x2": 6, "y2": 8, "color": "#1e293b", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x1": 9, "y1": 6, "x2": 10, "y2": 8, "color": "#1e293b", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x": 7, "y": 10, "color": "#94a3b8" } },
+ { "command": "draw.line", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x1": 6, "y1": 11, "x2": 9, "y2": 11, "color": "#94a3b8" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0, "x": 8, "y": 10, "color": "#94a3b8" } },
+
+ { "command": "frame.duplicate", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0 } },
+ { "command": "frame.duplicate", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0 } },
+ { "command": "frame.duplicate", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 0 } },
+
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 1, "x1": 4, "y1": 5, "x2": 11, "y2": 13, "color": "#e2e8f0", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 1, "x1": 3, "y1": 8, "x2": 12, "y2": 13, "color": "#e2e8f0", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 1, "x": 4, "y": 4, "color": "#e2e8f0" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 1, "x": 5, "y": 4, "color": "#e2e8f0" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 1, "x": 10, "y": 4, "color": "#e2e8f0" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 1, "x": 11, "y": 4, "color": "#e2e8f0" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 1, "x1": 5, "y1": 7, "x2": 6, "y2": 9, "color": "#1e293b", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 1, "x1": 9, "y1": 7, "x2": 10, "y2": 9, "color": "#1e293b", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 1, "x": 7, "y": 11, "color": "#94a3b8" } },
+ { "command": "draw.line", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 1, "x1": 6, "y1": 12, "x2": 9, "y2": 12, "color": "#94a3b8" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 1, "x": 8, "y": 11, "color": "#94a3b8" } },
+
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 2, "x1": 4, "y1": 4, "x2": 11, "y2": 12, "color": "#e2e8f0", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 2, "x1": 3, "y1": 7, "x2": 12, "y2": 12, "color": "#e2e8f0", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 2, "x": 4, "y": 3, "color": "#e2e8f0" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 2, "x": 5, "y": 3, "color": "#e2e8f0" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 2, "x": 10, "y": 3, "color": "#e2e8f0" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 2, "x": 11, "y": 3, "color": "#e2e8f0" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 2, "x1": 5, "y1": 6, "x2": 6, "y2": 8, "color": "#1e293b", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 2, "x1": 9, "y1": 6, "x2": 10, "y2": 8, "color": "#1e293b", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 2, "x": 7, "y": 10, "color": "#475569" } },
+ { "command": "draw.line", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 2, "x1": 6, "y1": 11, "x2": 9, "y2": 11, "color": "#475569" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 2, "x": 8, "y": 10, "color": "#475569" } },
+
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 3, "x1": 4, "y1": 3, "x2": 11, "y2": 11, "color": "#e2e8f0", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 3, "x1": 3, "y1": 6, "x2": 12, "y2": 11, "color": "#e2e8f0", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 3, "x": 4, "y": 2, "color": "#e2e8f0" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 3, "x": 5, "y": 2, "color": "#e2e8f0" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 3, "x": 10, "y": 2, "color": "#e2e8f0" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 3, "x": 11, "y": 2, "color": "#e2e8f0" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 3, "x1": 5, "y1": 5, "x2": 6, "y2": 7, "color": "#1e293b", "filled": true } },
+ { "command": "draw.rect", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 3, "x1": 9, "y1": 5, "x2": 10, "y2": 7, "color": "#1e293b", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 3, "x": 7, "y": 9, "color": "#94a3b8" } },
+ { "command": "draw.line", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 3, "x1": 6, "y1": 10, "x2": 9, "y2": 10, "color": "#94a3b8" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/ghost/ghost.piskel", "frame": 3, "x": 8, "y": 9, "color": "#94a3b8" } },
+
+ {
+ "command": "export.gif",
+ "args": {
+ "project": "examples-output/ghost/ghost.piskel",
+ "output": "examples-output/ghost/ghost.gif",
+ "delay-ms": 250
+ }
+ }
+ ]
+}
diff --git a/examples/mushroom-plan.json b/examples/mushroom-plan.json
new file mode 100644
index 0000000..e706c7e
--- /dev/null
+++ b/examples/mushroom-plan.json
@@ -0,0 +1,43 @@
+{
+ "steps": [
+ {
+ "command": "project.create",
+ "args": {
+ "width": 16,
+ "height": 16,
+ "output": "examples-output/mushroom/mushroom.piskel",
+ "name": "mushroom"
+ }
+ },
+ { "command": "draw.rect", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x1": 4, "y1": 2, "x2": 11, "y2": 8, "color": "#cc2222", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 3, "y": 4, "color": "#cc2222" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 3, "y": 5, "color": "#cc2222" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 3, "y": 6, "color": "#cc2222" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 12, "y": 4, "color": "#cc2222" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 12, "y": 5, "color": "#cc2222" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 12, "y": 6, "color": "#cc2222" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 2, "y": 6, "color": "#cc2222" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 2, "y": 7, "color": "#cc2222" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 13, "y": 6, "color": "#cc2222" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 13, "y": 7, "color": "#cc2222" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 5, "y": 3, "color": "#ffffff" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 6, "y": 3, "color": "#ffffff" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 5, "y": 4, "color": "#ffffff" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 9, "y": 4, "color": "#ffffff" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 10, "y": 4, "color": "#ffffff" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 10, "y": 5, "color": "#ffffff" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x1": 5, "y1": 8, "x2": 10, "y2": 14, "color": "#f5deb3", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 4, "y": 9, "color": "#f5deb3" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 4, "y": 10, "color": "#f5deb3" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 11, "y": 9, "color": "#f5deb3" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x": 11, "y": 10, "color": "#f5deb3" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/mushroom/mushroom.piskel", "x1": 6, "y1": 10, "x2": 9, "y2": 11, "color": "#cc9966", "filled": true } },
+ {
+ "command": "export.png",
+ "args": {
+ "project": "examples-output/mushroom/mushroom.piskel",
+ "output": "examples-output/mushroom/mushroom.png"
+ }
+ }
+ ]
+}
diff --git a/examples/sword-plan.json b/examples/sword-plan.json
new file mode 100644
index 0000000..fa3d16c
--- /dev/null
+++ b/examples/sword-plan.json
@@ -0,0 +1,38 @@
+{
+ "steps": [
+ {
+ "command": "project.create",
+ "args": {
+ "width": 16,
+ "height": 16,
+ "output": "examples-output/sword/sword.piskel",
+ "name": "sword"
+ }
+ },
+ { "command": "draw.line", "args": { "project": "examples-output/sword/sword.piskel", "x1": 12, "y1": 2, "x2": 13, "y2": 3, "color": "#e2e8f0" } },
+ { "command": "draw.line", "args": { "project": "examples-output/sword/sword.piskel", "x1": 11, "y1": 3, "x2": 12, "y2": 4, "color": "#cbd5e1" } },
+ { "command": "draw.line", "args": { "project": "examples-output/sword/sword.piskel", "x1": 10, "y1": 4, "x2": 11, "y2": 5, "color": "#cbd5e1" } },
+ { "command": "draw.line", "args": { "project": "examples-output/sword/sword.piskel", "x1": 9, "y1": 5, "x2": 10, "y2": 6, "color": "#94a3b8" } },
+ { "command": "draw.line", "args": { "project": "examples-output/sword/sword.piskel", "x1": 8, "y1": 6, "x2": 9, "y2": 7, "color": "#94a3b8" } },
+ { "command": "draw.line", "args": { "project": "examples-output/sword/sword.piskel", "x1": 7, "y1": 7, "x2": 8, "y2": 8, "color": "#94a3b8" } },
+ { "command": "draw.line", "args": { "project": "examples-output/sword/sword.piskel", "x1": 6, "y1": 8, "x2": 7, "y2": 9, "color": "#64748b" } },
+ { "command": "draw.line", "args": { "project": "examples-output/sword/sword.piskel", "x1": 5, "y1": 9, "x2": 6, "y2": 10, "color": "#64748b" } },
+ { "command": "draw.line", "args": { "project": "examples-output/sword/sword.piskel", "x1": 4, "y1": 10, "x2": 5, "y2": 11, "color": "#64748b" } },
+ { "command": "draw.line", "args": { "project": "examples-output/sword/sword.piskel", "x1": 3, "y1": 11, "x2": 4, "y2": 12, "color": "#475569" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/sword/sword.piskel", "x": 5, "y": 9, "color": "#fbbf24" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/sword/sword.piskel", "x": 9, "y": 5, "color": "#fbbf24" } },
+ { "command": "draw.line", "args": { "project": "examples-output/sword/sword.piskel", "x1": 4, "y1": 9, "x2": 8, "y2": 5, "color": "#fbbf24" } },
+ { "command": "draw.line", "args": { "project": "examples-output/sword/sword.piskel", "x1": 6, "y1": 11, "x2": 10, "y2": 7, "color": "#fbbf24" } },
+ { "command": "draw.rect", "args": { "project": "examples-output/sword/sword.piskel", "x1": 2, "y1": 12, "x2": 4, "y2": 14, "color": "#92400e", "filled": true } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/sword/sword.piskel", "x": 3, "y": 15, "color": "#92400e" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/sword/sword.piskel", "x": 13, "y": 2, "color": "#ffffff" } },
+ { "command": "draw.pixel", "args": { "project": "examples-output/sword/sword.piskel", "x": 12, "y": 3, "color": "#ffffff" } },
+ {
+ "command": "export.png",
+ "args": {
+ "project": "examples-output/sword/sword.piskel",
+ "output": "examples-output/sword/sword.png"
+ }
+ }
+ ]
+}