diff --git a/website/app/docs/page.tsx b/website/app/docs/page.tsx index 8b799a8e..41b5e813 100644 --- a/website/app/docs/page.tsx +++ b/website/app/docs/page.tsx @@ -59,6 +59,8 @@ export default function DocsIndex() { ["docs_quick_restore", "/docs/recovery#restore-missing-output", "rebuild missing files without regenerating"], ["docs_quick_pack", "/docs/artifacts#pack", "build sprite sheets and SpriteFrames for the engine"], ["docs_quick_ci", "/docs/quality#plan-gate", "block stale or unreviewed art in CI"], + ["docs_quick_chain", "/docs/revisions#across-styles", "chain several models in one project"], + ["docs_quick_scenario", "/docs/scenario", "see what Scenario's models cost and where they fit"], ].map(([id, href, label]) => ( {label} ))} diff --git a/website/app/globals.css b/website/app/globals.css index e5f71acb..2f9396d3 100644 --- a/website/app/globals.css +++ b/website/app/globals.css @@ -190,6 +190,7 @@ a { color: inherit; text-decoration: none; } .button-primary:hover { background: var(--ember-light); } .button-secondary { border-color: var(--line-strong); color: var(--cream); } .button-secondary:hover { border-color: var(--cream-muted); } +.hero-install { margin-top: 22px; } .trust-line { display: flex; flex-wrap: wrap; @@ -386,15 +387,16 @@ a { color: inherit; text-decoration: none; } .workflow-section { padding-block: 150px; } .workflow-grid { display: grid; - grid-template-columns: repeat(4, 1fr); + grid-template-columns: repeat(5, 1fr); + grid-template-rows: auto auto auto 1fr auto auto; margin-top: 72px; border-top: 1px solid var(--line-strong); } .workflow-grid article { - min-height: 420px; - display: flex; - flex-direction: column; - padding: 32px; + grid-row: span 6; + display: grid; + grid-template-rows: subgrid; + padding: 28px 24px 34px; border-right: 1px solid var(--line); } .workflow-grid article:first-child { padding-left: 0; } @@ -421,10 +423,14 @@ a { color: inherit; text-decoration: none; } image-rendering: pixelated; } .workflow-grid h3 { margin: 0 0 14px; font-size: 23px; letter-spacing: -0.035em; } -.workflow-grid p { margin: 0 0 26px; color: #a39b8d; font-size: 14px; line-height: 1.68; } +.workflow-grid p { margin: 0 0 18px; color: #a39b8d; font-size: 13px; line-height: 1.66; } +.step-io { display: block; align-self: start; margin: 0 0 22px; padding-top: 14px; border-top: 1px solid var(--line); color: #857e70; font-size: 12px; line-height: 1.55; } +.workflow-deck { max-width: 560px; margin-top: 22px; } .workflow-grid code { - align-self: flex-start; - margin-top: auto; + align-self: end; + justify-self: start; + max-width: 100%; + overflow-x: auto; padding: 8px 10px; border: 1px solid var(--line); background: #100f0c; @@ -448,27 +454,6 @@ a { color: inherit; text-decoration: none; } } .review-copy h2 { max-width: 540px; } .review-copy .section-deck { max-width: 570px; margin-top: 28px; } -.provider-status { - display: grid; - gap: 11px; - margin-top: 30px; - color: #aaa293; - font-family: var(--font-geist-mono), monospace; - font-size: 11px; -} -.provider-status span { display: flex; align-items: center; gap: 10px; } -.provider-status em { font-style: normal; font-size: 10px; color: #7f786b; border: 1px solid #3a352c; padding: 1px 6px; } -.provider-status i { width: 7px; height: 7px; border: 1px solid #6f685d; } -.provider-status i.status-dot { border: 0; } -.provider-note { - max-width: 570px; - margin: 28px 0 0; - padding-top: 26px; - border-top: 1px solid var(--line); - color: #777064; - font-size: 12px; - line-height: 1.7; -} .review-links { display: flex; flex-wrap: wrap; gap: 26px; } .review-visuals { display: grid; gap: 34px; min-width: 0; } .review-visual { @@ -615,7 +600,15 @@ a { color: inherit; text-decoration: none; } .provider-showcase-section { padding-block: 150px; } -.provider-showcase-heading .section-deck { max-width: 520px; } +.provider-showcase-heading .section-deck { max-width: 560px; } +.provider-table-wrap { margin-top: 56px; overflow-x: auto; border: 1px solid var(--line-strong); background: #1b1913; } +.provider-table { width: 100%; min-width: 720px; border-collapse: collapse; text-align: left; } +.provider-table th, .provider-table td { padding: 16px 20px; border-top: 1px solid var(--line); vertical-align: top; font-size: 13px; line-height: 1.65; color: #b2a999; } +.provider-table thead th { border-top: 0; color: #857e70; font-family: var(--font-geist-mono), monospace; font-size: 10px; font-weight: 500; } +.provider-table tbody th { color: var(--cream); font-size: 14px; font-weight: 600; white-space: nowrap; } +.provider-table td:nth-child(2), .provider-table td:nth-child(3) { white-space: nowrap; } +.provider-table .provider-badge { margin: 0; } + .provider-showcase-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); @@ -886,35 +879,6 @@ a { color: inherit; text-decoration: none; } .lock-callout.top { top: 105px; } .lock-callout.bottom { bottom: 52px; } -.capabilities-section { padding-block: 150px; } -.capability-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 1px; - margin-top: 72px; - padding: 1px; - background: var(--line); -} -.capability-card { - min-height: 340px; - padding: 38px; - background: #1b1913; -} -.card-index { color: #8a8273; font-family: var(--font-geist-mono), monospace; font-size: 11px; font-weight: 600; } -.capability-card h3 { max-width: 500px; margin: 70px 0 18px; font-size: 30px; line-height: 1.1; letter-spacing: -0.045em; } -.capability-card p { max-width: 500px; margin: 0; color: #968e7f; font-size: 13px; line-height: 1.7; } -.capability-card.large { min-height: 390px; } -.budget-meter { margin-top: 42px; } -.budget-meter > div:first-child { display: flex; justify-content: space-between; color: #827b6e; font-family: var(--font-geist-mono), monospace; font-size: 11px; } -.budget-meter strong { color: var(--cream); } -.meter-track { height: 7px; margin-top: 12px; background: #373228; } -.meter-track span { display: block; width: 66.66%; height: 100%; background: var(--ember); } -.micro-state { display: inline-flex; align-items: center; gap: 10px; margin-top: 55px; padding: 12px 14px; border: 1px solid var(--line); color: var(--lime); font-family: var(--font-geist-mono), monospace; font-size: 9px; } -.audit-bars { height: 52px; display: flex; align-items: end; gap: 7px; margin-top: 44px; } -.audit-bars span { width: 14px; background: var(--ember); } -.audit-bars span:nth-child(1) { height: 45%; }.audit-bars span:nth-child(2) { height: 75%; }.audit-bars span:nth-child(3) { height: 57%; }.audit-bars span:nth-child(4) { height: 92%; }.audit-bars span:nth-child(5) { height: 69%; } -.format-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 42px; } -.format-list span { padding: 9px 11px; border: 1px solid var(--line-strong); color: #8d8577; font-family: var(--font-geist-mono), monospace; font-size: 8px; } .generator-section { padding-block: 140px; border-block: 1px solid var(--line); background: #201d17; } .generator-table { margin-top: 70px; border-top: 1px solid var(--line-strong); } @@ -980,7 +944,7 @@ a { color: inherit; text-decoration: none; } .site-footer { padding-top: 78px; border-top: 1px solid var(--line); background: #100f0c; } .footer-grid { display: grid; grid-template-columns: 1fr auto; gap: 80px; padding-bottom: 70px; } .footer-grid > div:first-child p { margin: 24px 0 0; color: #777064; font-size: 12px; } -.footer-links { display: grid; grid-template-columns: repeat(2, 150px); gap: 40px; } +.footer-links { display: grid; grid-template-columns: repeat(3, 150px); gap: 40px; } .footer-links > div { display: flex; flex-direction: column; gap: 12px; font-size: 11px; } .footer-links span { margin-bottom: 7px; color: #6f695d; font-family: var(--font-geist-mono), monospace; font-size: 11px; } .footer-links a { color: #a9a091; } @@ -1084,17 +1048,98 @@ a { color: inherit; text-decoration: none; } .markdown-body th { color: var(--cream); text-align: left; } .markdown-body th, .markdown-body td { padding: 11px 12px; border: 1px solid var(--line); vertical-align: top; } .markdown-body img { display: block; max-width: 100%; height: auto; border: 1px solid var(--line); background: #eef3f2; image-rendering: pixelated; } +.gallery-section { + padding-block: 140px; + border-top: 1px solid var(--line); +} +.gallery-deck { max-width: 640px; margin-top: 22px; } +.gallery-hero, .gallery-editor { margin-top: 64px; } +.gallery-hero { box-shadow: 20px 20px 0 rgba(255, 107, 53, .08); } +.gallery-editor { margin-top: 72px; } +.gallery-tiers { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + margin-top: 72px; + border-top: 1px solid var(--line-strong); +} +.gallery-tiers article { + display: grid; + grid-template-rows: subgrid; + grid-row: span 4; + padding: 28px 28px 8px; + border-right: 1px solid var(--line); +} +.gallery-tiers article:first-child { padding-left: 0; } +.gallery-tiers article:last-child { border-right: 0; padding-right: 0; } +.gallery-tiers { grid-template-rows: auto auto auto 1fr; } +.gallery-tiers h3 { margin: 0 0 16px; font-size: 26px; letter-spacing: -0.035em; } +.gallery-tiers code { + justify-self: start; + align-self: start; + margin-bottom: 18px; + max-width: 100%; + overflow-x: auto; + padding: 8px 10px; + border: 1px solid var(--line); + background: #100f0c; + color: #c9bfae; + font-family: var(--font-geist-mono), monospace; + font-size: 11px; + line-height: 1.3; + white-space: nowrap; +} +.gallery-tiers .step-io code { display: inline; padding: 0; border: 0; background: none; color: #a39b8c; font-size: inherit; margin: 0; } +.gallery-tiers ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 14px; align-content: start; } +.gallery-tiers li { + position: relative; + padding-left: 18px; + color: #a39b8d; + font-size: 13px; + line-height: 1.62; +} +.gallery-tiers li::before { + content: ""; + position: absolute; + left: 0; + top: 0.62em; + width: 7px; + height: 1px; + background: var(--ember-light); +} +.gallery-tiers li code { + display: inline; + margin: 0; + padding: 0; + border: 0; + background: none; + color: #c9bfae; + font-size: 12px; +} +.gallery-tiers a { color: var(--ember-light); } +.gallery-links { margin-top: 56px; } + .markdown-body hr { margin: 48px 0; border: 0; border-top: 1px solid var(--line); } +@media (max-width: 1240px) { + .workflow-grid code { white-space: normal; overflow-wrap: anywhere; } +} + @media (max-width: 980px) { .hero { grid-template-columns: 1fr; gap: 44px; } .hero-copy { max-width: 720px; } .hero-visual { width: min(640px, 94%); margin-inline: auto; } .proof-grid { grid-template-columns: repeat(3, 1fr); } .proof-grid p { grid-column: 1 / -1; padding: 25px 0 27px; border-top: 1px solid var(--line); } - .workflow-grid { grid-template-columns: repeat(2, 1fr); } - .workflow-grid article { min-height: 370px; } - .workflow-grid article:nth-child(2) { border-right: 0; } + .workflow-grid { grid-template-columns: repeat(2, 1fr); grid-template-rows: none; } + .workflow-grid article { grid-row: auto; display: flex; flex-direction: column; padding: 28px 24px; } + .workflow-grid code { margin-top: auto; } + .gallery-tiers { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; } + .gallery-tiers article { grid-row: auto; display: block; padding: 32px 0; border-right: 0; border-bottom: 1px solid var(--line); } + .gallery-tiers article:last-child { border-bottom: 0; } + .gallery-tiers code { display: inline-block; margin-bottom: 18px; } + .gallery-tiers .step-io { margin-bottom: 20px; } + .workflow-grid article:nth-child(odd) { padding-left: 0; } + .workflow-grid article:nth-child(even) { border-right: 0; padding-right: 0; } .workflow-grid article:nth-child(n + 3) { border-top: 1px solid var(--line); } .safety-grid { grid-template-columns: 1fr; } .review-grid { grid-template-columns: 1fr; } @@ -1129,13 +1174,17 @@ a { color: inherit; text-decoration: none; } .proof-grid > div { min-height: 92px; padding: 20px 0; border-right: 0; border-bottom: 1px solid var(--line); } .proof-grid p { grid-column: auto; padding: 24px 0 27px; } .split-heading { grid-template-columns: 1fr; gap: 30px; } - .workflow-section, .provider-showcase-section, .scenario-section, .capabilities-section, .install-section { padding-block: 95px; } + .workflow-section, .provider-showcase-section, .scenario-section, .install-section { padding-block: 95px; } .scenario-panel, .scenario-snippet { padding: 22px; } .scenario-strip-four { grid-template-columns: repeat(2, minmax(0, 1fr)); } .scenario-facts div { grid-template-columns: 1fr; gap: 6px; padding: 16px 22px; } .workflow-grid { grid-template-columns: 1fr; margin-top: 48px; } - .workflow-grid article { min-height: 400px; padding: 30px 0; border-right: 0; border-top: 1px solid var(--line); } - .safety-section, .generator-section, .review-section, .cast-section { padding-block: 95px; } + .workflow-grid article { min-height: 0; padding: 30px 0; border-right: 0; border-top: 1px solid var(--line); } + .workflow-grid .step-io { margin-bottom: 22px; } + .workflow-grid code { margin-top: 4px; align-self: flex-start; } + .gallery-hero { box-shadow: 10px 10px 0 rgba(255, 107, 53, .08); margin-top: 44px; } + .gallery-editor { margin-top: 48px; } + .safety-section, .generator-section, .review-section, .gallery-section, .cast-section { padding-block: 95px; } .cast-grid { grid-template-columns: 1fr; gap: 54px; margin-top: 60px; } .cast-manifest { box-shadow: 10px 10px 0 rgba(255, 107, 53, .08); } .cast-manifest .lock-callout { display: none; } @@ -1153,14 +1202,13 @@ a { color: inherit; text-decoration: none; } .provider-workflow { grid-template-columns: 1fr; } .provider-workflow span { grid-column: auto; } .provider-card dl div { grid-template-columns: 105px 1fr; gap: 14px; } - .capability-grid { grid-template-columns: 1fr; } - .capability-card { min-height: 330px; padding: 28px; } .generator-row { grid-template-columns: 0.5fr 1fr; gap: 15px; padding-block: 14px; } .generator-row > span:last-child { grid-column: 1 / -1; } .generator-row.header span:last-child { display: none; } .install-panel { grid-template-columns: 1fr; gap: 48px; padding: 38px 25px; } .install-actions > div { flex-direction: column; } - .footer-grid { grid-template-columns: 1fr; } + .footer-grid { grid-template-columns: minmax(0, 1fr); gap: 48px; } + .footer-links { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; } .footer-base { align-items: flex-start; flex-direction: column; justify-content: center; gap: 5px; } .docs-index { padding-block: 70px 95px; } .docs-featured { padding: 28px; } diff --git a/website/app/lib/analytics.ts b/website/app/lib/analytics.ts index 3a306a41..0fb6f6d1 100644 --- a/website/app/lib/analytics.ts +++ b/website/app/lib/analytics.ts @@ -12,6 +12,7 @@ export type CtaSection = | "hero" | "install" | "review" + | "gallery" | "characters" | "safety" | "generator" diff --git a/website/app/lib/docs.ts b/website/app/lib/docs.ts index 88bb4992..9197899b 100644 --- a/website/app/lib/docs.ts +++ b/website/app/lib/docs.ts @@ -51,7 +51,7 @@ export const docs: DocEntry[] = [ { slug: "scenario", title: "Set up Scenario", - description: "Configure hosted models, two-part credentials, CU preflight, and durable downloads.", + description: "Set up hosted models and two-part credentials, then use reference-image edits, multi-model chains, and the measured findings.", file: "docs/SCENARIO.md", group: "Providers", }, @@ -95,7 +95,7 @@ export const docs: DocEntry[] = [ { slug: "generators", title: "Generator selection", - description: "Choose the right capability and understand measured costs.", + description: "Pick a generator and see what it costs.", file: "docs/GENERATORS.md", group: "Guides", }, @@ -116,7 +116,7 @@ export const docs: DocEntry[] = [ { slug: "revisions", title: "Controlled asset revisions", - description: "Revise current art with hashed parents, masks, approval gates, and side-by-side review, including PixelLab palette cleanup, animation, and interpolation.", + description: "Revise current art with hashed parents, masks, approval gates, and side-by-side review. Covers PixelLab palette cleanup, animation, interpolation, and chaining revisions across styles.", file: "docs/REVISIONS.md", group: "Guides", }, diff --git a/website/app/page.tsx b/website/app/page.tsx index 5a80d518..1cfd32c8 100644 --- a/website/app/page.tsx +++ b/website/app/page.tsx @@ -39,10 +39,11 @@ export default function Home() {
+

- Generated pixel art, without the guesswork + A build pipeline for generated pixel art

Fire once. @@ -52,8 +53,9 @@ export default function Home() { with receipts.

- Declare the art you need, see the price before generation, choose - candidates yourself, and keep a hash for every file you ship. + Declare the sprites you need in one manifest. PixelKiln prices the + run offline, lets you choose among candidates, and records a SHA-256 + hash for every file you ship.

-
+
+ +
+
Offline planning Hard budgets Exact provenance @@ -162,45 +167,59 @@ export default function Home() { LLM calls in the loop

- The judgment stays human. + You choose every image.
- The mechanics stay deterministic. + PixelKiln does the polling, hashing, and file placement the same way every time.

-

Four steps from one committed manifest

-

Declare it. Price it.
Review it. Ship it.

+

Declare it. Price it. Generate it.
Review it. Ship it.

+

+ One committed manifest drives every step. Each step says what it reads and what it writes. +

01

Declare

-

Put asset names, prompts, provider settings, and an optional final-art quality profile in one file.

+

List each asset, its prompt, its provider, and an optional final-art quality profile in one file.

+ You write the manifest. pixelkiln.manifest.json
02

Plan

-

Compare the manifest with the lockfile and disk. See what costs money and what can be restored for free.

+

Compare the manifest with the lockfile and the files on disk. The plan shows what costs money and what you can restore for free, and it makes no provider calls.

+ Reads the manifest, lockfile, and disk. Spends nothing. pixelkiln plan
03 +
+

Generate

+

Pass a budget and PixelKiln submits, polls, and downloads. It saves each remote id before polling, so a failed download is recoverable work and not a second charge.

+ Writes the lockfile and the downloaded files. + pixelkiln gen --budget 120 +
+
+ 04

Review

Choose from a local candidate sheet, touch a sprite up in the gallery's editor, then approve the exact pixels you ship.

+ Writes your choice and approval to the lockfile. pixelkiln pick
- 04 + 05

Ship

-

Build repeatable atlases, Aseprite sheet JSON, Godot SpriteFrames, and tilesets for Tiled and Godot. A style with a palette rule never ships a colour outside it. Quality-profile styles stay blocked until approval is current.

+

Build atlases, Aseprite sheet JSON, Godot SpriteFrames, and tilesets for Tiled and Godot. A style with a palette rule never ships a color outside it. Quality-profile styles stay blocked until approval is current.

+ Writes sheets and exports with provenance. pixelkiln pack
@@ -209,84 +228,27 @@ export default function Home() {
-

Review and edits stay local

-

Choose the image.
Fix the pixel.
Keep the receipts.

-

- PixelLab, Retro Diffusion, ComfyUI, and Scenario use the same review, - lockfile, and recovery flow. PixelKiln records every candidate, - then leaves the visual decision to you. The page preserves native - aspect ratios and stays readable on ultrawide displays. Afterwards,{" "} - pixelkiln gallery opens any generation with its - prompt, cost, hashes, lineage, and approval. It compares two - records side by side. With --edit it changes prompts - and style fields and adds assets. With --budget it - generates again, under a ceiling you set. -

-

- Regenerating keeps the version it replaces. Each record lists its - previous generations, up to a count you choose, and one click - brings any of them back. Nothing is spent, and the swap can be - undone from the same list. -

+

Pick the image.
Approve the pixels.

- Providers are asked for your palette; enforcePalette{" "} - makes it a guarantee. Every downloaded sprite is snapped to the - nearest palette colour as it is written, the provider's - bytes stay in the cache, and turning the rule on or off later - re-applies it to art you already paid for. + pixelkiln pick opens a local page with every + candidate. It preserves native aspect ratios and stays readable on + ultrawide displays, and a frame set counts as one choice. + PixelKiln records every candidate and leaves the decision to you.

- Hand edits stay beside the art, never over the record. Open a - sprite in your own editor with pixelkiln edit, or in - the gallery's built-in{" "} - Pixelorama, - a pinned build fetched once and verified by hash, and save it - back with its layers kept. Frame sets and tile sets open as one - project with a frame per member, and every member is written back - under its role. Art edited in PixelLab's own editor returns - with fetch --refresh. -

-
- PixelLab production - Retro Diffusion experimental - ComfyUI experimental - Scenario experimental - FakeProvider tests -
-

- PixelLab has live coverage for generation and account recovery. - Retro Diffusion has live-tested single-candidate stills. ComfyUI - has passed local generation, candidate review, cache recovery, - and grid refinement. Atomic frame sets have automated coverage, - and accepted frame prompts are saved before the next one is queued. - They still need a live pose recipe and benchmark. The tested SDXL - graph needs manual cleanup and art review. Scenario has passed paid - single- and two-output generation, human review, and durable - recovery, and has run ten more models, six tool models, - reference-image edits, and multi-model chains once each. + PixelKiln asks providers for your palette, and enforcePalette{" "} + makes it a rule: every downloaded sprite is snapped to the nearest + palette color as it is written, while the provider's bytes stay + in the cache. Turning the rule on or off later re-applies it to art + you already paid for.

- - Compare providers - - - See the environment benchmark - - - Browse the gallery command + + Read about pick Touch art up by hand - - PixelLab MCP ↗ -
@@ -304,34 +266,139 @@ export default function Home() { />
The local review page with generated brand sprites. No model chooses for you.
-
-
- localhost pixelkiln gallery - provenance -
- PixelKiln's local gallery showing 24 generated environments from three providers, with one record open -
The local gallery on the environment benchmark, three providers in one view, every record a click away.
-
-
-
- localhost pixelkiln gallery --edit - hand edit -
- PixelKiln's gallery with a benchmark fortress sprite open in the built-in Pixelorama editor, ready to save back to the project -
The in-browser editor, a pinned and hash-verified Pixelorama. It saves beside the generated file, never over it.
-
+
+
+
+ + + +
+
+
+

Paid work needs a paper trail.

+

+ Every provider object, prompt identity, output role, path, and + byte hash survives in project state. A failed download remains + recoverable work, not a reason to pay twice. +

+
    +
  • ✓ Remote identity saved before polling
  • +
  • ✓ Content-addressed local recovery cache
  • +
  • ✓ Hand edits kept beside the generated file
  • +
  • ✓ Replaced generations kept, restorable at no cost
  • +
  • ✓ Manual-edit and overwrite protection
  • +
  • ✓ Transactional atlas and export writes
  • +
+ + Explore recovery guarantees + +
+
+
pixelkiln.lock.json
+
{`{
+  "base/anvil": {
+    "status": "downloaded",
+    "provider": "pixellab",
+    "specHash": "61c9…a071",
+    "cost": { "value": 1,
+              "unit": "generations" },
+    "outputs": [{
+      "path": "art/base/anvil.png",
+      "sha256": "98f1…c42a"
+    }]
+  }
+}`}
+
◇ paid-work identity
+
◇ exact output bytes
@@ -346,7 +413,6 @@ export default function Home() {
-

Characters are a family, not a file

Draw the base once.
Everything else follows it.

A character style holds a base drawn facing 4 or 8 @@ -422,25 +488,57 @@ export default function Home() {

-

Real runs.
Different pixels.

+

Four providers, one review flow.

- These are outputs from committed benchmark projects. The - ComfyUI card separates its model canvas from the recovered native - pixel grid, because a large raster can still contain fake pixels. - Its samples are diagnostics, not finished asset recommendations. - Scenario shows its first paid integration smoke, not a comparable - environment benchmark; its measured findings are in their own - section below. A manifest style.quality profile - can apply the same offline palette and approval gate after any - supported single-image provider or an atomic ComfyUI frame set. - ComfyUI and PixelLab both back controlled revisions, and - PixelLab adds palette cleanup, animation, and interpolation of an - existing asset. PixelKiln hashes the parent and mask bytes before - any revision runs. + PixelLab, Retro Diffusion, ComfyUI, and Scenario share the same + review, lockfile, and recovery flow. The cards below show outputs from + committed benchmark projects, one sample each. The ComfyUI card + separates its model canvas from the recovered native pixel grid, + because a large raster can still contain fake pixels. Its samples are + diagnostics, not asset recommendations. A style.quality{" "} + profile applies the same palette and approval gate after any + single-image provider or an atomic ComfyUI frame set. ComfyUI and + PixelLab both back controlled revisions, and PixelLab adds palette + cleanup, animation, and interpolation of an existing asset. + PixelKiln hashes the parent and mask bytes before a revision runs.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ProviderStatusBilled inWhat has run
PixelLabProductionGenerationsGeneration and account recovery against a live account.
Retro DiffusionExperimentalUSDSingle-candidate stills, live. Its other paths need paid runs.
ComfyUIExperimentalNothing (self-hosted)Local generation, candidate review, cache recovery, and grid refinement. Atomic frame sets have automated coverage, and PixelKiln saves each accepted frame prompt before it queues the next one. They still need a live pose recipe and benchmark. The tested SDXL graph needs manual cleanup and art review.
ScenarioExperimentalCompute unitsPaid single- and two-output generation, human review, and recovery. Ten more models, six tool models, reference-image edits, and multi-model chains ran once each.
+
+
@@ -655,6 +753,9 @@ export default function Home() {
+ + PixelLab MCP ↗ + Use several providers in one project @@ -670,8 +771,7 @@ export default function Home() {
-

Scenario, measured

-

Cheap models.
A real pipeline.
Honest limits.

+

Scenario, measured: ten models, one chain, and where it fails.

We ran Scenario's catalogue through PixelKiln: ten text-to-image @@ -722,7 +822,7 @@ export default function Home() {

1 CU render
- The knight pixelated onto a 32-colour palette + The knight pixelated onto a 32-color palette
5 CU Pixelate
@@ -748,7 +848,7 @@ export default function Home() {

What a real game taught us

  • Large art works. A 240 px landmark chain returned the existing sprite's exact size at high confidence, with far more detail, for 8 CU on the cheap model or 18 CU on the strongest.
  • -
  • A reference keeps the design. Sending the current sprite as a reference raised silhouette overlap from 0.39 to 0.66 to 0.93 to 1.00, at the same pixel scale. Some models shift colours.
  • +
  • A reference keeps the design. Sending the current sprite as a reference raised silhouette overlap from 0.39 to 0.66 to 0.93 to 1.00, at the same pixel scale. Some models shift colors.
  • Small sprites and tiles do not. 32 px props came back as different objects with holes after the cutout; terrain tiles and characters need tools built for them.
  • Backdrops need the prompt to say flat. An isometric prompt lay on a diagonal plane; asking for a front-facing horizontal strip gave the exact grid. A mist fade needs a better cutout route.
  • The pixelate grid is not always literal. On a 960 px render, asking for 240 made 2 px blocks and asking for 120 made the 240 cells wanted. Check one image first.
  • @@ -794,94 +894,13 @@ export default function Home() {
-
-
-
-

Paid work needs a paper trail.

-

- Every provider object, prompt identity, output role, path, and - byte hash survives in project state. A failed download remains - recoverable work, not a reason to pay twice. -

-
    -
  • ✓ Remote identity saved before polling
  • -
  • ✓ Content-addressed local recovery cache
  • -
  • ✓ Hand edits kept beside the generated file
  • -
  • ✓ Replaced generations kept, restorable at no cost
  • -
  • ✓ Manual-edit and overwrite protection
  • -
  • ✓ Transactional atlas and export writes
  • -
- - Explore recovery guarantees - -
-
-
pixelkiln.lock.json
-
{`{
-  "base/anvil": {
-    "status": "downloaded",
-    "provider": "pixellab",
-    "specHash": "61c9…a071",
-    "cost": { "value": 1,
-              "unit": "generations" },
-    "outputs": [{
-      "path": "art/base/anvil.png",
-      "sha256": "98f1…c42a"
-    }]
-  }
-}`}
-
◇ paid-work identity
-
◇ exact output bytes
-
-
-
- -
-
-
-

The prompt is only the start.

-
-

PixelKiln handles the work between a prompt and the files your game loads.

-
-
-
- Plan -

Know the bill before the fire starts.

-

Offline diffs distinguish new spend from zero-cost recovery. Copy the estimate into a hard budget ceiling.

-
-
Selected work80 / 120
-
-
-
-
- Recover -

Restore before you regenerate.

-

Rebuild missing output from trusted cache bytes or a provider URL without new generation cost. A regeneration keeps the version it replaced, so the old one is one command away.

-
recoverable, 0 generations
-
-
- Audit -

Turn accepted pixels into a release gate.

-

Declare the final palette and grid threshold, record human approval, and block stale or unreviewed art in CI.

- -
-
- Package -

Build the files your engine expects.

-

Pack sheets, mount stable cells, and export lossless generic, Tiled, or Godot terrain metadata with provenance.

-
PNGJSONTILEDGODOT 4
-
-
-
-
-

Different routes, different bills

-

Use the capability you need.
Pay only for that.

+

The same sprite can cost 1 generation or 40.

-

Measured PixelLab costs vary by up to 40×. Retro Diffusion uses USD pricing. Self-hosted ComfyUI has no provider charge. PixelKiln keeps those units separate.

+

Measured PixelLab costs vary by up to 40×. Retro Diffusion bills in USD, Scenario in compute units, and self-hosted ComfyUI has no provider charge. PixelKiln keeps those units separate.

GeneratorBest forMeasured cost
@@ -891,7 +910,7 @@ export default function Home() {
1dirReferences and candidate variety 20–40 gen
tilesGround and structural sets 20–40 gen
terrainTwo-terrain elevation tilesets 20–40 gen (unmeasured)
-
isometricTileA single elevation tile — a mesa, a cliff block 1 gen
+
isometricTileA single elevation tile, such as a mesa or a cliff block 1 gen
characterA base in 8 directions, its poses, its loops 1–40 gen per base by engine, 1–4 per template loop, mirrors free
objectProA skeleton-free prop's base, poses, and loops about 6 gen per base at 64px, 1 per loop (unmeasured)
imageProFlashStyled stills on the Pro Flash model, 16–256px 5–9 gen (quoted)
@@ -914,8 +933,8 @@ export default function Home() {
-

Teach your agent the PixelKiln workflow.

-

The skill tells compatible agents when to plan, ask for a budget, restore existing work, stop for human review, and verify output.

+

Give your agent the PixelKiln workflow.

+

The skill tells compatible agents when to plan, when to ask for a budget, when to restore existing work, when to stop for human review, and how to verify output.

@@ -940,6 +959,7 @@ export default function Home() {
+
diff --git a/website/app/ui/site-chrome.tsx b/website/app/ui/site-chrome.tsx index 2259c427..4777e781 100644 --- a/website/app/ui/site-chrome.tsx +++ b/website/app/ui/site-chrome.tsx @@ -23,7 +23,8 @@ export function SiteHeader({ compact = false }: { compact?: boolean }) { pixelkiln