{
  "slug": "pixelfx",
  "skill": "pixelfx",
  "upstream": "patch-gg/pixelfx@a84159688af3ca37a4be05a0d422b94451b2e24e",
  "upstreamSha": "a84159688af3ca37a4be05a0d422b94451b2e24e",
  "patches": {
    "count": 1,
    "sha256": "33fc39fcbcdccf663a13dc3da83aed8847397eaf94ed0155ffd8d17644703616"
  },
  "date": "2026-11-03",
  "engine": "pixelfx tools on Node 22 + Godot 4.7.2 (SpriteFrames import)",
  "env": [
    "Node v22.23.4",
    "pixelfx library and tools from upstream-support/ (no npm install)",
    "Godot 4.7.2-stable headless for the sprite-sheet import"
  ],
  "trigger": "static",
  "passed": 43,
  "total": 43,
  "commands": [
    "(cd examples && env GODOT={godot} node tests/run_tests.mjs)",
    "(cd examples && node tests/screenshot.mjs ../screenshot.png)"
  ],
  "checks": [
    {
      "criterion": "trigger",
      "name": "SKILL.md description says when to use it",
      "pass": true,
      "detail": "Make pixel art effects and sprite animations in code with the pixelfx library, which has 244 ready-made ones, acted out "
    },
    {
      "criterion": "trigger",
      "name": "triggers on: \"Make a pixel art frost nova effect sprite sheet for my mage in Godot\"",
      "pass": true,
      "detail": "rank 1/121, overlap 9"
    },
    {
      "criterion": "trigger",
      "name": "triggers on: \"I need pixel art VFX: a coin pickup sparkle and a fire torch loop for my Phaser game\"",
      "pass": true,
      "detail": "rank 1/121, overlap 9"
    },
    {
      "criterion": "trigger",
      "name": "triggers on: \"Export pixel effects as sprite sheets with an Aseprite JSON for Unity\"",
      "pass": true,
      "detail": "rank 1/121, overlap 6"
    },
    {
      "criterion": "trigger",
      "name": "does not trigger on: \"Write a save system for my RPG\"",
      "pass": true,
      "detail": "rank 27/121, overlap 0"
    },
    {
      "criterion": "trigger",
      "name": "does not trigger on: \"Set up a multiplayer lobby in Godot\"",
      "pass": true,
      "detail": "rank 7/121, overlap 1"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: our effect sits in a scratch copy of the shipped library",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: tools/check.mjs passes gameskill/lantern-sway",
      "pass": true,
      "detail": "ok    gameskill/lantern-sway"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: tools/check.mjs passes weather/rain",
      "pass": true,
      "detail": "ok    weather/rain"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: tools/check.mjs passes fire/brazier",
      "pass": true,
      "detail": "ok    fire/brazier"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: tools/list.mjs finds the new effect by a word",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: tools/render.mjs --sheet exports gameskill/lantern-sway",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: gameskill/lantern-sway sheet meta",
      "pass": true,
      "detail": "loop, 120 frames at 30 fps"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: tools/render.mjs --sheet exports fire/brazier",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: fire/brazier sheet meta",
      "pass": true,
      "detail": "loop, 90 frames at 30 fps"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: same time, same frame (seeded, no Math.random)",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: the 24 s loop wraps like any other step",
      "pass": true,
      "detail": "seam 31.83% vs step 38.55% of pixels changed"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: the scene is alive (frames differ over time)",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: the lantern glows warm in the scene",
      "pass": true,
      "detail": "196 warm pixels"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot fire/brazier",
      "pass": true,
      "detail": "Godot parses the sheet JSON"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot fire/brazier",
      "pass": true,
      "detail": "Godot loads the sheet PNG at its size: 1232x1332"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot fire/brazier",
      "pass": true,
      "detail": "SpriteFrames has every frame: 90"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot fire/brazier",
      "pass": true,
      "detail": "animation plays at the JSON fps: 30.0"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot fire/brazier",
      "pass": true,
      "detail": "loop flag follows the JSON"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot fire/brazier",
      "pass": true,
      "detail": "frame size matches frameSize: (112.0, 148.0)"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot fire/brazier",
      "pass": true,
      "detail": "AnimatedSprite2D plays with the pivot offset"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot fire/brazier",
      "pass": true,
      "detail": "no empty frame in the loop: 0 empty"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot 4.7 headless run exits 0 for fire/brazier",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot gameskill/lantern-sway",
      "pass": true,
      "detail": "Godot parses the sheet JSON"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot gameskill/lantern-sway",
      "pass": true,
      "detail": "Godot loads the sheet PNG at its size: 1248x1200"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot gameskill/lantern-sway",
      "pass": true,
      "detail": "SpriteFrames has every frame: 120"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot gameskill/lantern-sway",
      "pass": true,
      "detail": "animation plays at the JSON fps: 30.0"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot gameskill/lantern-sway",
      "pass": true,
      "detail": "loop flag follows the JSON"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot gameskill/lantern-sway",
      "pass": true,
      "detail": "frame size matches frameSize: (96.0, 120.0)"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot gameskill/lantern-sway",
      "pass": true,
      "detail": "AnimatedSprite2D plays with the pivot offset"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot gameskill/lantern-sway",
      "pass": true,
      "detail": "no empty frame in the loop: 0 empty"
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: Godot 4.7 headless run exits 0 for gameskill/lantern-sway",
      "pass": true
    },
    {
      "criterion": "runs",
      "name": "our lantern effect, the courtyard loop and Godot SpriteFrames: exits 0 with no script errors",
      "pass": true,
      "detail": "exit 0"
    },
    {
      "criterion": "output",
      "name": "screenshot screenshot.png rendered",
      "pass": true
    },
    {
      "criterion": "output",
      "name": "self-check list has at least 3 items",
      "pass": true,
      "detail": "6 items"
    },
    {
      "criterion": "single",
      "name": "one job per skill (reviewed)",
      "pass": true,
      "detail": "One job: pixel-art effects as code (reuse, author, check and export them as sprite sheets). Character sprites, high-resolution VFX and game feel tuning are left to codixel, rng-vfx and game-feel."
    },
    {
      "criterion": "bilingual",
      "name": "English SKILL.md from upstream",
      "pass": true
    },
    {
      "criterion": "bilingual",
      "name": "Chinese guide written",
      "pass": true,
      "detail": "1249 chars"
    }
  ]
}
