<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Merl Merl</title>
    <description>The latest articles on DEV Community by Merl Merl (@merl985).</description>
    <link>https://dev.to/merl985</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4028925%2F309a350a-b9f4-41fb-b074-88d8a67eb019.png</url>
      <title>DEV Community: Merl Merl</title>
      <link>https://dev.to/merl985</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/merl985"/>
    <language>en</language>
    <item>
      <title>Treating an AI Anime Character Generator Like a Function With Default Arguments</title>
      <dc:creator>Merl Merl</dc:creator>
      <pubDate>Mon, 21 Sep 2026 12:48:40 +0000</pubDate>
      <link>https://dev.to/merl985/treating-an-ai-anime-character-generator-like-a-function-with-default-arguments-jag</link>
      <guid>https://dev.to/merl985/treating-an-ai-anime-character-generator-like-a-function-with-default-arguments-jag</guid>
      <description>&lt;p&gt;&lt;a href="https://eap.pixai.art/go/balazs2" rel="noopener noreferrer"&gt;Tsubaki.3&lt;/a&gt;, the newest anime model on PixAI, is now officially released, and I used the release week for a small controlled test. I took one original character from a three-sentence spec to a design I would keep developing, changing one layer at a time and logging what each step changed. If you think in code, the process maps neatly onto a function call with default arguments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subject:&lt;/strong&gt; Kazane is a broom-racing witch I created for this test.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model:&lt;/strong&gt; Every run used Tsubaki.3, with batches of four for the text-only runs and single images for the reference runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preprocessing:&lt;/strong&gt; Prompt Helper was on in every run. It rewrites the prompt before generation, and each image's detail page shows the rewritten version next to the original.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Out of scope:&lt;/strong&gt; I skipped LoRAs. PixAI's &lt;a href="https://blog.pixai.art/en/model-vs-lora-pixai-foundations/" rel="noopener noreferrer"&gt;model vs LoRA explainer&lt;/a&gt; covers when one is worth adding; my questions were about individual clothing pieces.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Run 1: most arguments unset
&lt;/h2&gt;

&lt;p&gt;In the first prompt, I passed three values and left everything else open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;generate_character&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;loud, competitive witch who races brooms between floating islands&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;hook&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;flies bareheaded, anything on her head would slow her down&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;style_note&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dressed for speed rather than for a storybook&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;# hair, eyes, outfit and footwear were never passed
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Batch 1&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Recognizable anime witch on a broom&lt;/td&gt;
&lt;td&gt;4/4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bareheaded, as specified&lt;/td&gt;
&lt;td&gt;1/4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anything resembling racing gear&lt;/td&gt;
&lt;td&gt;0/4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Looks like an adult in her twenties&lt;/td&gt;
&lt;td&gt;0/4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distinct hair colors&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The unset arguments resolved to the most familiar version of "witch": pointed hats, dark robes, school uniforms and red ribbons. In three images, that default replaced a value I had passed explicitly. The spec described a bareheaded racer, and three of the four images showed the stock witch instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run 2: pass the values explicitly
&lt;/h2&gt;

&lt;p&gt;I treated the batch as a diff to review. I kept the bareheaded image, the shouting expression and the trailing fabric. I rejected the hat, ribbon, robe and skirt, and I replaced the reddish hair and the teenage look. Then I appended each decision to the unchanged original three sentences:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;generate_character&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;...,&lt;/span&gt;  &lt;span class="c1"&gt;# the original three sentences, verbatim
&lt;/span&gt;    &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;top of her head and full hairstyle visible&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;hair&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;deep plum, single high ponytail&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;eyes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;golden yellow&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fitted midnight-navy racing top with a zip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;capelet&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;short, teal, right shoulder only&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;legs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;black trousers tucked into white knee boots&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;broom&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;exactly three teal bands&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;head&lt;/code&gt; argument describes what must be visible instead of passing a negative flag like "no hat". Batch 2 changed many values at once, so I cannot credit the bare head to this line alone. The head stayed bare in 4/4 images, and hair, eyes, top, trousers, boots and broom bands matched in every image.&lt;/p&gt;

&lt;p&gt;Two values still varied because I had left them loose or unset. The trailing fabric came out navy three times and teal once, and the broom handle's end changed shape. The pose also repeated across all eight images: she hovers over a rock ledge instead of riding the banked turn I asked for.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0qzoetfqfucvccwdn4uk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0qzoetfqfucvccwdn4uk.jpg" alt=" " width="800" height="595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Run 3: images as arguments, and the scope bug
&lt;/h2&gt;

&lt;p&gt;Tsubaki.3 accepts two reference images in the prompt box, addressed as &lt;code&gt;@image1&lt;/code&gt; and &lt;code&gt;@image2&lt;/code&gt;. I passed the refined character as &lt;code&gt;@image1&lt;/code&gt; and a photo of a monarch butterfly as &lt;code&gt;@image2&lt;/code&gt;, then compared two scopes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# wide scope
&lt;/span&gt;&lt;span class="nf"&gt;redesign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;outfit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;image2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# narrow scope
&lt;/span&gt;&lt;span class="nf"&gt;redesign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;capelet and its trailing fabric&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;image2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;navy top&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;black trousers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;white knee boots&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Run&lt;/th&gt;
&lt;th&gt;Pattern source&lt;/th&gt;
&lt;th&gt;Scope&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;butterfly&lt;/td&gt;
&lt;td&gt;whole outfit&lt;/td&gt;
&lt;td&gt;pattern on the entire suit; top, capelet, trousers and boots lost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;soap bubble&lt;/td&gt;
&lt;td&gt;whole outfit&lt;/td&gt;
&lt;td&gt;swirl pattern on the entire suit; white boots kept&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;butterfly&lt;/td&gt;
&lt;td&gt;capelet only&lt;/td&gt;
&lt;td&gt;pattern on the capelet; top, trousers and boots kept, one sleeve turned orange&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Reading the Rewritten Prompt for run A explained the result. My wide wording became "a fully covering racing suit patterned after the butterfly", so the rewrite kept my wide scope and stated it even more broadly. In the narrow-scope version, the rewrite kept every named item almost word for word. The practical rule: when you pass an image, pass the scope with it.&lt;/p&gt;

&lt;p&gt;One more edge case: an earlier attempt that described the capelet's "streaming tail" produced a furry tail beside the fabric. Tokens like tail, wing and horn can resolve to anatomy, so I now describe those pieces as fabric.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb8hilcbt4xdu3342biq7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb8hilcbt4xdu3342biq7.jpg" alt=" " width="800" height="1123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Run 4: a style layer as a regression test
&lt;/h2&gt;

&lt;p&gt;Recipes are reusable prompt add-ons in the Tsubaki.3 generator panel, and PixAI Official publishes style Recipes among them. I reran the narrow-scope setup with the Holographic Recipe switched on. Face, hair, eyes and broom bands passed. The outfit scope, the background and the camera distance all changed.&lt;/p&gt;

&lt;p&gt;I read that like a failing regression test. The traits that passed are stable enough to build on, and the ones that failed need locking before I explore looks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flhayj4ujn9jzj4b5tniy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flhayj4ujn9jzj4b5tniy.jpg" alt=" " width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would tell another developer
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Unset arguments get defaults from the role word, and those defaults can override values you did pass.&lt;/li&gt;
&lt;li&gt;Describe what should be present instead of passing negations.&lt;/li&gt;
&lt;li&gt;Keep the original spec verbatim and append decisions, so each batch is a clean diff.&lt;/li&gt;
&lt;li&gt;Pass scope explicitly with every reference image, and read the Rewritten Prompt when a result surprises you.&lt;/li&gt;
&lt;li&gt;Check ambiguous tokens like tail, wing or horn before a run.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to run the same experiment on your own character, start with a three-sentence spec and a batch of four on &lt;a href="https://eap.pixai.art/go/balazs" rel="noopener noreferrer"&gt;PixAI&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>design</category>
    </item>
    <item>
      <title>I Ran a Five-Step Image Pipeline Entirely on a Phone</title>
      <dc:creator>Merl Merl</dc:creator>
      <pubDate>Wed, 16 Sep 2026 08:41:26 +0000</pubDate>
      <link>https://dev.to/merl985/i-ran-a-five-step-image-pipeline-entirely-on-a-phone-3ahi</link>
      <guid>https://dev.to/merl985/i-ran-a-five-step-image-pipeline-entirely-on-a-phone-3ahi</guid>
      <description>&lt;p&gt;Most write-ups about mobile AI image apps stop at the first generation. That is the easy case. The interesting question is whether a full pipeline runs on a phone: generate, swap the model, condition on a reference, edit a region, then retrieve the artifact later.&lt;/p&gt;

&lt;p&gt;I ran that pipeline end to end in the PixAI mobile app, on an iPhone, with the laptop closed. Below is the setup, the controls, and what each step produced.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fixture
&lt;/h2&gt;

&lt;p&gt;The prompt runs to about a hundred and twenty words and describes a character and a scene: subject, clothing, pose, environment, light direction, camera position. Five visual identifiers in the description that are easy to check in an output:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Identifier&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hair&lt;/td&gt;
&lt;td&gt;copper-red, cropped&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jacket&lt;/td&gt;
&lt;td&gt;dark green band jacket with a wide cream diagonal sash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Undershirt&lt;/td&gt;
&lt;td&gt;black, high collar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trousers&lt;/td&gt;
&lt;td&gt;cream with a single green side stripe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prop&lt;/td&gt;
&lt;td&gt;brass tuba&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Everything else varied one axis at a time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: baseline generation
&lt;/h2&gt;

&lt;p&gt;The generate screen puts LoRA, model, style, mode, output size, and quantity into one horizontally scrolling row under the prompt card. One run returned four images at the quantity setting shown.&lt;/p&gt;

&lt;p&gt;The bottleneck is text entry, not compute. With the keyboard open, the prompt field is a few lines tall, so proofreading a long description means scrolling inside a small window. If you build prompts programmatically or keep them in a notes file, paste them in rather than typing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj8dgup1zj227n1m5jfoe.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj8dgup1zj227n1m5jfoe.jpg" alt=" " width="800" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: model swap, seed held constant
&lt;/h2&gt;

&lt;p&gt;The second run used the same prompt string and the same seed on a different base model. A seed fixes the random starting point, so holding it constant removes one variable.&lt;/p&gt;

&lt;p&gt;The model picker has three tabs: Preset for official models, Collection for saved ones, and Market for community uploads. Every card is labeled with its architecture family, so DiT.2, DiT.1, or XL, which is the practical signal for what kind of prompt the model prefers. The swap took three taps, and the session continued without a restart.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Assertion&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Written identifiers reappear on model B&lt;/td&gt;
&lt;td&gt;Pass, all five&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Face and proportions match model A&lt;/td&gt;
&lt;td&gt;Fail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rendering style matches model A&lt;/td&gt;
&lt;td&gt;Fail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same seed reproduces the composition&lt;/td&gt;
&lt;td&gt;Fail&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The last row is the one that changes how you store a character definition. A seed indexes noise inside one model. Across two models, the same integer produced no resemblance at all. Prompt text is the portable part of a character definition, and the seed is not.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnf69i6n7ibifp64wnpin.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnf69i6n7ibifp64wnpin.jpg" alt=" " width="799" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: reference conditioning
&lt;/h2&gt;

&lt;p&gt;The reference workflow is exposed as a preset in the model list rather than as a separate mode, which means selecting it replaces your base model selection. Worth knowing before you plan a session around it.&lt;/p&gt;

&lt;p&gt;The panel enforces an order: the image loads first, and the prompt field stays inactive until it does. I had a paragraph ready and could not enter a character of it until the reference was in place.&lt;/p&gt;

&lt;p&gt;The input came from the camera roll, where the previous step had already saved it. That is the structural argument for doing this work on a phone. The source artifact and the output destination are the same device, so the file transfer step disappears.&lt;/p&gt;

&lt;p&gt;Conditioning on the earlier output plus a short new-scene description returned the same character in a different location. Hair, sash, collar, and instrument came back intact, with nothing about the character repeated in the prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: masked edit
&lt;/h2&gt;

&lt;p&gt;Edit opens a canvas with Inpaint and Outpaint as separate tabs, and mask size, brush, eraser, mask shape, and feather along the bottom. A small box in the corner previews where the masked region falls on the image.&lt;/p&gt;

&lt;p&gt;I masked one element and requested a change there. Measured against the source file, the marked band came back about a third wider at mid-chest, while the buttons, the hand, the mouthpiece, and the collar were unchanged. Whatever else you think of the result, containment held: the diff concentrates inside the mask by a wide margin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: retrieval
&lt;/h2&gt;

&lt;p&gt;Library opens on a menu of collections, published work and likes, with Recent Tasks below it. Each run is a card titled with the opening words of its own prompt, stamped with a date and time, and the list has a search box above it.&lt;/p&gt;

&lt;p&gt;Open a single result, and the next actions are on one screen: Download, Publish, Animate, Edit, Import to Generate, and Re-roll. Import to Generate pulls that run's prompt and model back into the generate screen, which is the resume-session path.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzt7rx6dwcvepl8pwcotf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzt7rx6dwcvepl8pwcotf.jpg" alt=" " width="800" height="805"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What a phone is bad at
&lt;/h2&gt;

&lt;p&gt;Long prompt editing, because the visible field is small. Comparing several outputs at once, because a run returns thumbnails, and judging them at full size means opening one at a time. Detail review, because a small display hides errors: one of my outputs has a clearly elongated forearm that I only noticed on a laptop. And finding a rarely used control, since there is less room off the main path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verdict
&lt;/h2&gt;

&lt;p&gt;The pipeline ran five steps on one device with no restarts, end-to-end on a phone, and the constraints are input and review rather than capability. If you want to run the same test, four checks matter: the model picker has to expose metadata, the reference input has to accept a local file, the editor has to respect a mask, and the history has to be searchable.&lt;/p&gt;

&lt;p&gt;For where each control is in the interface, the PixAI app guide covers it screen by screen: &lt;a href="https://blog.pixai.art/en/pixai-app-guide/" rel="noopener noreferrer"&gt;https://blog.pixai.art/en/pixai-app-guide/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://eap.pixai.art/go/balazs" rel="noopener noreferrer"&gt;Try the same pipeline on PixAI&lt;/a&gt; and see how far your phone takes you.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>design</category>
    </item>
    <item>
      <title>Free tier, real workflow: what I learned testing an anime image generator on one character</title>
      <dc:creator>Merl Merl</dc:creator>
      <pubDate>Sun, 13 Sep 2026 09:12:58 +0000</pubDate>
      <link>https://dev.to/merl985/free-tier-real-workflow-what-i-learned-testing-an-anime-image-generator-on-one-character-13l1</link>
      <guid>https://dev.to/merl985/free-tier-real-workflow-what-i-learned-testing-an-anime-image-generator-on-one-character-13l1</guid>
      <description>&lt;p&gt;Most write-ups about free image generation stop at the credit count. That number tells you almost nothing, because what decides whether a free tier is usable is how much of the pipeline it exposes and where it hard-stops.&lt;/p&gt;

&lt;p&gt;I ran a session on PixAI to find out, using one original character as a fixed test subject and staying on features a never-paid account can reach. Three findings are worth passing on, and all three are the kind of thing you only hit by actually running the thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;The subject was a surfer with a deliberately over-specified design: turquoise streak on the left of the hair, green eyes, short asymmetric wetsuit with the right arm bare, orange leash on the left ankle, beaded bracelet on the right wrist, shell earring on the right ear, board with three stripes. That gives seven checkable attributes, several of them side-specific and one of them countable.&lt;/p&gt;

&lt;p&gt;That is a test harness, not a character sheet. Side-specific and countable attributes fail visibly, which means you can grade an output instead of squinting at it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgv3c0ht5c7aqx5rf1qak.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgv3c0ht5c7aqx5rf1qak.jpg" alt="The baseline generation. Seven specified attributes, a scene, a light direction, and a camera angle, produced from a single prompt with no editing after." width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding one: prompt syntax belongs to the model family, not the platform
&lt;/h2&gt;

&lt;p&gt;The platform hosts two architecture families. The DiT models parse natural-language sentences. The SDXL-derived models respond to tag-style input. Running the same character through one model from each meant rewriting the prompt, not swapping a dropdown.&lt;/p&gt;

&lt;p&gt;The rewrite is where things broke. Hair color, the streak, and the eye color carried over. Everything else drifted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;orange ankle leash on left ankle&lt;/code&gt; rendered as orange boots on both feet&lt;/li&gt;
&lt;li&gt;the three board stripes vanished entirely&lt;/li&gt;
&lt;li&gt;the shell earring became a turquoise stud&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;right shoulder and arm bare&lt;/code&gt; collapsed into a bare shoulder with both sleeves intact&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6h5ivjh3t1zl78nkx8ge.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6h5ivjh3t1zl78nkx8ge.jpg" alt="Same subject, two model families. The crops underneath are cut from the same two files at full resolution, since the failing attributes measure about ten pixels across at feed scale." width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some of that is the model, and some is my tag translation, and I cannot cleanly separate the two from one test. The transferable point stands either way: switching model families is a prompt rewrite, and every attribute you care about needs re-anchoring in the new syntax. Treat your prompt as source coupled to a target, not as portable input.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding two: LoRAs are architecture-bound dependencies
&lt;/h2&gt;

&lt;p&gt;LoRAs are small adapter files that steer a base model toward a specific style, outfit, character, or concept. Free accounts can load them into normal generation, which is the part that makes a free tier interesting rather than decorative.&lt;/p&gt;

&lt;p&gt;The dependency behavior is the useful bit. Each LoRA is trained against a specific base model and loads only onto matching ones. The browser has no architecture filter, so the ecosystem solved it socially: creators write the architecture into the LoRA name. Searching &lt;code&gt;dit.2&lt;/code&gt; returns results literally named &lt;code&gt;Yuu_style DiT.2&lt;/code&gt;, &lt;code&gt;BotanInk(DiT.2)&lt;/code&gt;, &lt;code&gt;ColorSnapVibe(DiT.2)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq31q2drfg4qnyqzzf9cu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq31q2drfg4qnyqzzf9cu.jpg" alt="The adapter loaded at strength 0.7, with  raw `dit.2` endraw  in the search box. Every result carries the architecture in its name, which is the ecosystem routing around a missing filter." width="656" height="1240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every LoRA card carries a base model field, and loading the LoRA sets that base model for you. The consequence is worth stating plainly: your adapter choice determines your base model, so on a free account part of your control decision resolves before you generate anything.&lt;/p&gt;

&lt;p&gt;One more practical note. The first adapter I picked had a trigger word list running to nine separate instructions, all of them about eyelashes and under-eye detail. The model obliged by building an extra eye onto the character's cheek. Read the trigger list before loading, the same way you would read a package's peer dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding three: a seed does not survive a mode change
&lt;/h2&gt;

&lt;p&gt;The platform offers two generation modes, both open to free accounts, differing in cost and compute. I assumed the cheaper mode would give me the same image at lower fidelity, so I ran one prompt through both with the seed pinned.&lt;/p&gt;

&lt;p&gt;It gave me sibling images, not the same image at two quality settings. Measured on a coarse layout comparison, the pair sat inside the same similarity range as two other outputs from the same batch. The prompt explains the resemblance; the seed contributed nothing measurable across the boundary.&lt;/p&gt;

&lt;p&gt;That has a workflow implication. If you explore cheaply and find a composition you like, you cannot promote it to the expensive mode by reusing the seed. The modes are separate generations, so explore in whichever mode you intend to finish in.&lt;/p&gt;

&lt;p&gt;Where the two modes did differ was background detail. The water carried noticeably less fine texture in the cheaper mode while the face barely changed. One pair is thin evidence for a rule, so run the check on your own subject before committing a day's budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the free tier actually gates
&lt;/h2&gt;

&lt;p&gt;Two categories get conflated constantly, and separating them is most of the analysis:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unavailable without paying.&lt;/strong&gt; The fastest generation queue, the video tools, the reference-based consistency tools, and a monthly adapter training allowance. The &lt;a href="https://blog.pixai.art/en/membership-payment-faq-web/" rel="noopener noreferrer"&gt;membership and payment information&lt;/a&gt; page carries the specifics, and it is worth reading rather than trusting my summary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Available, and metered.&lt;/strong&gt; Everything else. That covers both generation modes, the public model library, community adapters and the standard image sizes. Lean on any of them and the daily allowance drains faster, which is a budget constraint rather than a wall. The &lt;a href="https://blog.pixai.art/en/pixai-free-credits-guide/" rel="noopener noreferrer"&gt;free credits guide&lt;/a&gt; covers the refill mechanics.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I did not expect
&lt;/h2&gt;

&lt;p&gt;I assumed the first generation would be the best one and everything after would be cleanup. The opposite happened. My character's description never fully landed until the fourth stage, after the model and the adapter were settled and the scene had changed completely. The final image carried every specified attribute at once, including the countable one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn9k6dc2aq6jpnkp40jzh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn9k6dc2aq6jpnkp40jzh.jpg" alt="Stage one on the left, stage four on the right. Same model, same adapter, same character block, everything else replaced." width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For anyone benchmarking a free tier, that is the measurement worth taking. A tier that produces one good image and locks the door behind it is a demo. A tier that lets you converge across four generations is a tool, and the convergence is the thing to test.&lt;/p&gt;

&lt;p&gt;The whole session ran to roughly a dozen generation jobs across four configurations, entirely on the free side. If you want to reproduce the method, &lt;a href="https://eap.pixai.art/go/balazs" rel="noopener noreferrer"&gt;the platform is here&lt;/a&gt;. Pick a subject with side-specific and countable attributes, and grade the outputs instead of admiring them.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>tooling</category>
      <category>productivity</category>
    </item>
    <item>
      <title>An Anime Image Model Is a Flaky Dependency, So I Asserted on Every Property Twice</title>
      <dc:creator>Merl Merl</dc:creator>
      <pubDate>Thu, 10 Sep 2026 16:11:10 +0000</pubDate>
      <link>https://dev.to/merl985/an-anime-image-model-is-a-flaky-dependency-so-i-asserted-on-every-property-twice-4g21</link>
      <guid>https://dev.to/merl985/an-anime-image-model-is-a-flaky-dependency-so-i-asserted-on-every-property-twice-4g21</guid>
      <description>&lt;p&gt;Image models are nondeterministic functions. Same input, different output, and the variance is controlled by a seed you can pin. Anyone who has written tests against a flaky service already knows what that implies: a single call proves nothing. You need a second call with one variable changed, or you are reading noise as behavior.&lt;/p&gt;

&lt;p&gt;The comparisons I read mostly skip this. One image per product, results side by side, call it a benchmark. So I ran a proper version on one anime image platform, with a control run for every claim.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fixture
&lt;/h2&gt;

&lt;p&gt;I built one test character with assertable properties, the way you would design a fixture rather than a mood board:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dark brown bob cut straight at the jawline&lt;/li&gt;
&lt;li&gt;pale grey green eyes&lt;/li&gt;
&lt;li&gt;a mustard base layer whose &lt;strong&gt;left&lt;/strong&gt; sleeve turns charcoal below the elbow&lt;/li&gt;
&lt;li&gt;exactly &lt;strong&gt;four&lt;/strong&gt; tool loops on the &lt;strong&gt;right&lt;/strong&gt; thigh&lt;/li&gt;
&lt;li&gt;a charcoal patch on the &lt;strong&gt;left&lt;/strong&gt; knee&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two of those are side-specific, one is countable, two are pure color. Side and count are the ones worth including, because a symmetrical character with no countable elements passes every test by accident.&lt;/p&gt;

&lt;p&gt;All runs used the same model, mode and settings, with only the stated variable changed between a run and its control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check 1, prompt following with a batch instead of a single call
&lt;/h2&gt;

&lt;p&gt;Ten checkable instructions in one prompt, generated four times with nothing changed but the seed.&lt;/p&gt;

&lt;p&gt;Six instructions appeared in all four outputs: the camera framing, which hand held which object, the two-color sleeve on the correct arms, the loops on the correct thigh, the patch on the correct knee, and the eye color. Those are model behavior and you can build on them.&lt;/p&gt;

&lt;p&gt;One failed in all four: the requested low camera angle never arrived. The count landed once, as four straps on a tool roll the model invented, and came back as six, seven and six in the others.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbskdfff7cwe582y6orul.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbskdfff7cwe582y6orul.jpg" alt=" " width="800" height="1129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I later ran the same prompt four more times with a single color word changed. Across those eight generations, the correct count of four appeared twice. A single sample would have supported either conclusion, which is the argument for control runs in one number.&lt;/p&gt;

&lt;p&gt;One more thing surfaced only because there were four outputs. The prompt asked for the object at chest height and for the character to look up. Exactly one output satisfied the first, and it is the same output that failed the second. The model coupled two instructions I had written as independent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check 2, state across calls
&lt;/h2&gt;

&lt;p&gt;Same character, two new scenes, fresh prompts.&lt;/p&gt;

&lt;p&gt;High-level identity held everywhere. Hair, eyes and the main colors survived without effort. The fine-grained state did not. In both new scenes the camera sat behind the character, and the entire left and right assignment flipped: the mustard sleeve and the loops moved to the opposite side of the body. They stayed on the side nearest the camera, which is where they had been in the original.&lt;/p&gt;

&lt;p&gt;If you are generating a comic or a character sheet where handedness matters, that is a real constraint, and you will never see it with a symmetrical design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check 3, reference input versus full description
&lt;/h2&gt;

&lt;p&gt;Same scene, same seed, two runs. First with the full written description. Second with the description deleted and the earlier image attached as a reference at default strength.&lt;/p&gt;

&lt;p&gt;The reference carried hair, eyes and the main colors with zero description, which is a genuine reduction in prompt length. It dropped the color break at the elbow, so both sleeves came back plain. The loops multiplied.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj3z0a5preuoboasxom3t.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj3z0a5preuoboasxom3t.jpg" alt=" " width="800" height="859"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Large flat regions transfer. Small structural information does not. That split repeated in every check where the character moved between generations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check 4, edit versus regenerate
&lt;/h2&gt;

&lt;p&gt;One instruction: change the mustard layer to deep teal, keep everything else, with the preserved elements listed by name including the charcoal sleeve.&lt;/p&gt;

&lt;p&gt;The edit held the composition almost exactly and then turned both sleeves teal, erasing the element I had named in the preservation clause, and repainted the knee patch. The output also came back at a smaller resolution than the source.&lt;/p&gt;

&lt;p&gt;The control, the original prompt with one word changed and generated fresh, kept every property correct across all four runs and produced a completely different composition.&lt;/p&gt;

&lt;p&gt;Regenerating behaved as the method predicts. The edit is the interesting half, because it decides whether you can fix an artifact you already like without losing the parts that made it worth keeping.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means if you are evaluating a platform
&lt;/h2&gt;

&lt;p&gt;Treat the evaluation like testing an unreliable dependency. Assert on properties, not on vibes. Run every assertion twice. Pin the seed when you want to isolate a variable and release it when you want to sample the distribution. Count things instead of eyeballing them, and pick a fixture where counting is possible.&lt;/p&gt;

&lt;p&gt;I ran all of this on &lt;a href="https://eap.pixai.art/go/balazs2" rel="noopener noreferrer"&gt;Tsubaki.3&lt;/a&gt; on PixAI, which is anime focused and exposes models, LoRAs, reference input and instruction editing in one panel. The platform's &lt;a href="https://blog.pixai.art/en/sdxl-anime-models-pixai-guide/" rel="noopener noreferrer"&gt;SDXL model guide&lt;/a&gt; covers why the older model family behaves differently on prompt syntax, which matters if you plan to mix families.&lt;/p&gt;

&lt;p&gt;The numbers above are that platform's numbers. The method is portable, and it takes an afternoon.&lt;/p&gt;

&lt;p&gt;If you want to run it, &lt;a href="https://eap.pixai.art/go/balazs" rel="noopener noreferrer"&gt;start here&lt;/a&gt; and design your fixture with one asymmetric property. That single detail will tell you more than any gallery of cherry-picked samples.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>design</category>
    </item>
    <item>
      <title>Chaining Image Generations Is a Pipeline Bug: Measuring Drift Across Four Rendering Stages</title>
      <dc:creator>Merl Merl</dc:creator>
      <pubDate>Wed, 09 Sep 2026 12:07:16 +0000</pubDate>
      <link>https://dev.to/merl985/chaining-image-generations-is-a-pipeline-bug-measuring-drift-across-four-rendering-stages-4ioj</link>
      <guid>https://dev.to/merl985/chaining-image-generations-is-a-pipeline-bug-measuring-drift-across-four-rendering-stages-4ioj</guid>
      <description>&lt;p&gt;If you have ever built a data pipeline where each step consumes the previous step's output, you already know the failure mode: an error introduced at step two arrives at step five looking exactly like a legitimate value. Downstream, both look like ordinary values of the same type.&lt;/p&gt;

&lt;p&gt;Image generation pipelines behave the same way, and I measured it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;The subject is one drawing of an ice sculptor beside a block of ice with a thermos frozen inside it. Four rendering stages, run on Tsubaki.3 in PixAI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;line art -&amp;gt; grayscale -&amp;gt; flat colors -&amp;gt; final render
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every run held these constant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;same seed&lt;/li&gt;
&lt;li&gt;same model, no style preset, Pro mode&lt;/li&gt;
&lt;li&gt;one image in the Base Image slot&lt;/li&gt;
&lt;li&gt;Single generation, no batch, so the measurement reflects instruction following rather than best of four&lt;/li&gt;
&lt;li&gt;same instruction shape: one sentence naming the stage, one clause listing what stays fixed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Six identifying details were declared up front, chosen to be asymmetric or countable so that survival is checkable rather than arguable: a braid behind the left ear, a badge on the left collar, four tools on the belt, one glove on the left hand, one sleeve rolled and one down, and the thermos inside the ice.&lt;/p&gt;

&lt;p&gt;Loading a base image changes the output size without changing the setting. Runs without a base image came back at 960 by 1280, and the identical setting with a base image loaded came back at 896 by 1184. Trust the size on the finished file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxi0delknzmwmkap0wkmp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxi0delknzmwmkap0wkmp.png" alt=" " width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What held
&lt;/h2&gt;

&lt;p&gt;Composition held almost exactly. Aligning edge maps against the line art, the largest displacement across every base-image run was six pixels on a frame 1,184 pixels tall. All six declared details and the camera angle came through every stage.&lt;/p&gt;

&lt;p&gt;Run the same finishing instruction directly from the line art, and edge overlap against the original scores 0.168. Run it from the flat color stage instead, and it scores 0.147. Drop the base image entirely and generate from the text alone, and it scores 0.083, with the composition sitting 31 pixels across and 28 down from where the line art put it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flgn7io95w08vjogu91ze.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flgn7io95w08vjogu91ze.png" alt=" " width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What broke
&lt;/h2&gt;

&lt;p&gt;The chained final render preserved everything and advanced almost nothing.&lt;/p&gt;

&lt;p&gt;Measured on the ice surface, the share of pixels sitting on a hard edge went from 15.8 percent at the flat color stage to 24.7 percent after the render instruction. A finishing pass should be moving in the other direction. The same instruction run directly from the line art brought that share to 3.7 percent, and the ice came back translucent.&lt;/p&gt;

&lt;p&gt;In an empty patch of white background, the tonal range ran zero in the line art, two in the grayscale, two in the flat colors, then 52 after the chained render step, filled with a blocky mosaic. That pattern was already present at stage two, sitting at an amplitude too low to see. Four passes later it was the most visible thing in the frame. The direct render, from the same prompt text, left the same patch at a range of one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the topology matters
&lt;/h2&gt;

&lt;p&gt;At stage three the model gave the thermos a pale wood handle. My prompt says nothing about a handle color. At stage four that handle arrived unchanged, in the same shape and the same tone, because by then it was pixels in the input image exactly like everything I had specified.&lt;/p&gt;

&lt;p&gt;Each pass behaves as though its input image is the whole story. Chaining therefore promotes every intermediate guess to a fact, and on this evidence the later passes had nothing to separate an instruction from an earlier guess.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3mtejsxftbcqkyuotrmg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3mtejsxftbcqkyuotrmg.png" alt=" " width="800" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Across three renders started from the line art rather than the chain, that handle came out dark red once and grey metal twice. Pale wood appeared in none of them. The two chained stages matched each other exactly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The refactor
&lt;/h2&gt;

&lt;p&gt;Hold the structural base fixed and generate every treatment from it directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 +-&amp;gt; final render
line art (base) -+-&amp;gt; warm sunset
                 +-&amp;gt; cool moonlight
                 +-&amp;gt; strong backlight
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drift stops compounding, because every step reads the same fixed input. The cost is real: a direct render has no access to the intermediate information, so it reinvents anything the middle stages had settled. In my runs the direct version produced the better finish and dropped details the chain had locked in. From one instruction you get one of the two.&lt;/p&gt;

&lt;p&gt;That is the configuration behind the four finishes here, one per lighting condition, with only the light changed between them. Composition held in all four, shadows followed the named source, and the stated local colors kept their hue under colored light in three of the four. Under moonlight the warm bias on the stone wall fell from 23 points of red over blue to under one, which is the one case where the light repainted the surface instead of lighting it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Treat the earliest artifact that carries the structure as the source of truth, and read from it every time.&lt;/li&gt;
&lt;li&gt;Chaining generations is convenient and lossy. Every pass rewrites the entire image, so anything that survives does so by being redrawn the same way.&lt;/li&gt;
&lt;li&gt;Lock the seed and change one input at a time, or you cannot attribute any difference you observe.&lt;/li&gt;
&lt;li&gt;Declare your checkable details before the run. Asymmetric and countable beats descriptive.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of the above comes from single generations rather than repeated trials, so treat the direction as the finding and the exact numbers as one sample.&lt;/p&gt;

&lt;p&gt;If you want to run the same experiment on a drawing of your own, the model I used is on &lt;a href="https://eap.pixai.art/go/balazs" rel="noopener noreferrer"&gt;PixAI&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>design</category>
    </item>
    <item>
      <title>29 Words on One Locked Seed, and What They Cost the Picture Underneath</title>
      <dc:creator>Merl Merl</dc:creator>
      <pubDate>Tue, 08 Sep 2026 08:16:56 +0000</pubDate>
      <link>https://dev.to/merl985/29-words-on-one-locked-seed-and-what-they-cost-the-picture-underneath-2l5a</link>
      <guid>https://dev.to/merl985/29-words-on-one-locked-seed-and-what-they-cost-the-picture-underneath-2l5a</guid>
      <description>&lt;p&gt;Every guide on getting text into AI-generated images says the same thing: keep it short, keep it big, and hope. That is folk wisdom, and folk wisdom is what you get when nobody isolates the variables.&lt;/p&gt;

&lt;p&gt;So I isolated them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Think of a text-to-image call as a function with a lot of arguments, most of which nobody holds constant when they benchmark it. Model, seed, aspect ratio, subject description, style, and the actual text instruction all move at once in a typical comparison, and then somebody publishes a conclusion about text rendering.&lt;/p&gt;

&lt;p&gt;My setup pinned everything except one argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;generate(
  model:    "Tsubaki.3",          // fixed
  seed:      &amp;lt;locked&amp;gt;,            // fixed, identical on every run
  ratio:    "3:4",                // fixed
  subject:   &amp;lt;one paragraph&amp;gt;,     // fixed, reused verbatim
  style:     none,                // no preset, no LoRA
  batch:     1,                   // single generation, never best-of-four
  text:      &amp;lt;THE ONLY VARIABLE&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last constraint matters more than it looks. Generating four and picking the nicest one measures your fourth attempt, not the model's instruction following. Every result below is a first and only run.&lt;/p&gt;

&lt;p&gt;I also ran a control with the &lt;code&gt;text&lt;/code&gt; argument empty, which turned out to be the most informative run of the whole set.&lt;/p&gt;

&lt;p&gt;The subject was a woman in her fifties repairing box kites on a coastal dune, carrying four checkable details: short grey hair, goggles on her forehead, a brown patch on the right hip of her apron, and a spool of orange cord on her left forearm. Countable features give you a diff target.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test 1: two text elements
&lt;/h2&gt;

&lt;p&gt;A title and a subtitle, requested in large capitals in the empty sky at the top.&lt;/p&gt;

&lt;p&gt;Both correct. Title cap height 163 pixels, subtitle 31, clean gap between them, nothing overlapping the character.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test 2: five text elements
&lt;/h2&gt;

&lt;p&gt;Title, tagline, date, a two-line information block, and a corner badge, in one call. I chose the strings so no word repeated anywhere on the poster, which gives you traceability: every rendered string maps to exactly one instruction.&lt;/p&gt;

&lt;p&gt;All five elements appeared in the requested positions. Four were correct. The fifth was a small corner block where &lt;code&gt;NINE&lt;/code&gt; rendered as &lt;code&gt;NIVE&lt;/code&gt;, while &lt;code&gt;NORTH DUNE&lt;/code&gt; on the line beneath it came out right.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feihany0s63a4b7tchcgx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feihany0s63a4b7tchcgx.jpg" alt=" " width="799" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The hierarchy is the interesting part, because it is measurable rather than a matter of taste. Cap heights, top to bottom:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Element&lt;/th&gt;
&lt;th&gt;Cap height&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Title&lt;/td&gt;
&lt;td&gt;164 px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tagline&lt;/td&gt;
&lt;td&gt;31 px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Date&lt;/td&gt;
&lt;td&gt;22 px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Badge&lt;/td&gt;
&lt;td&gt;~18 px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Info line 2&lt;/td&gt;
&lt;td&gt;17 px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Info line 1&lt;/td&gt;
&lt;td&gt;15 px&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That ordering matches the importance I assigned each element in the prompt. I never specified a single size. The model inferred the ranking from the semantic role of each string, which is useful behavior if you are generating a lot of layouts.&lt;/p&gt;

&lt;p&gt;Note where the error landed: the 15 pixel line, the smallest thing on the poster. Two pixels separate it from the correct line directly below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test 3: swap the script, hold everything else
&lt;/h2&gt;

&lt;p&gt;Same seed, same position, same instruction shape, comparable title length. Only the writing system changed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Latin: correct&lt;/li&gt;
&lt;li&gt;Japanese (3 characters, kanji plus hiragana): correct&lt;/li&gt;
&lt;li&gt;Korean (4 Hangul blocks): 1 of 4 blocks correct&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxeb6mi561qrpsl5uubqv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxeb6mi561qrpsl5uubqv.jpg" alt=" " width="800" height="665"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Korean failure mode is the one to internalize. All four blocks are valid, well formed Hangul syllables. Spacing is even. Stroke weight is consistent. The output looks completely correct and says the wrong thing.&lt;/p&gt;

&lt;p&gt;This is the difference between a crash and silent data corruption, and it has the same implication: you cannot validate this by looking at it, only by having someone read it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test 4: relational layout instructions
&lt;/h2&gt;

&lt;p&gt;Three simultaneous position constraints in one prompt, expressed relative to the subject rather than to the canvas: title above her head, date in the lower left, badge in the upper right, all text clear of her face and the kite.&lt;/p&gt;

&lt;p&gt;Then the same prompt with one addition: reserve the top third as empty sky.&lt;/p&gt;

&lt;p&gt;Run A honored all three positions and put a lowercase &lt;code&gt;i&lt;/code&gt; in the middle of an all-capital title, plus a small non-letter mark after the final D.&lt;/p&gt;

&lt;p&gt;Run B produced every word correctly and solved the reservation by building something I never asked for: a solid header strip across the top 23.7 percent of the frame with the title set inside it. Her head starts at 34.8 percent, the kite at 36.2, both below the band as requested. The badge left its assigned corner and attached itself to the end of the title.&lt;/p&gt;

&lt;p&gt;Across both runs: 15 element position requests, 14 honored.&lt;/p&gt;

&lt;h2&gt;
  
  
  The finding nobody benchmarks
&lt;/h2&gt;

&lt;p&gt;Here is why the empty control run mattered. I measured the vertical position of the top of the character's head as a fraction of frame height:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Run&lt;/th&gt;
&lt;th&gt;Head position&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Control, no text&lt;/td&gt;
&lt;td&gt;25.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Layout run A&lt;/td&gt;
&lt;td&gt;28.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Japanese&lt;/td&gt;
&lt;td&gt;33.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Five elements&lt;/td&gt;
&lt;td&gt;34.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Korean&lt;/td&gt;
&lt;td&gt;34.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Layout run B&lt;/td&gt;
&lt;td&gt;34.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Two elements&lt;/td&gt;
&lt;td&gt;35.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Same seed on every row. Every run carrying text pushed the subject lower and made it smaller, by 2.5 to 9.3 percentage points.&lt;/p&gt;

&lt;p&gt;The text is not composited over a finished illustration. It is drawn in the same pass, out of the same frame budget, and the artwork is what gets compressed to make room. In run B a quarter of the output stopped being a picture entirely.&lt;/p&gt;

&lt;p&gt;If you are generating assets programmatically, this is a real constraint on your pipeline: you cannot add a text argument and expect the visual to stay put, and you cannot fix a bad string with a retry without rebuilding the composition around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aggregate results
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;29 Latin words requested, 27 rendered exactly&lt;/li&gt;
&lt;li&gt;2 failures: one wrong letter, one case defect&lt;/li&gt;
&lt;li&gt;Large display type: correct in 100% of runs&lt;/li&gt;
&lt;li&gt;Both failures at small size or under heavy layout constraints&lt;/li&gt;
&lt;li&gt;Japanese correct, Korean 1 of 4 blocks&lt;/li&gt;
&lt;li&gt;15 position requests, 14 honored&lt;/li&gt;
&lt;li&gt;Hierarchy correctly ranked in every layout, unprompted&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I would ship
&lt;/h2&gt;

&lt;p&gt;Generate the composition and the headline together, since that is where the model is strong and where it does work you would otherwise do by hand. Treat every returned string as untrusted input and read it character by character. Set fine print, dates, prices, and anything legally fixed in an editor afterward. And never ship a script you cannot read without a human check, because the failure mode there is invisible.&lt;/p&gt;

&lt;p&gt;Short display text is close to solved. Everything below about 20 pixels of cap height is still yours to handle.&lt;/p&gt;

&lt;p&gt;You can run the same test on your own character at &lt;a href="https://eap.pixai.art/go/balazs" rel="noopener noreferrer"&gt;https://eap.pixai.art/go/balazs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>design</category>
    </item>
    <item>
      <title>One Reference Image, Eight Character Sheet Runs, and What the Model Made Up</title>
      <dc:creator>Merl Merl</dc:creator>
      <pubDate>Tue, 01 Sep 2026 17:48:55 +0000</pubDate>
      <link>https://dev.to/merl985/one-reference-image-eight-character-sheet-runs-and-what-the-model-made-up-1h7p</link>
      <guid>https://dev.to/merl985/one-reference-image-eight-character-sheet-runs-and-what-the-model-made-up-1h7p</guid>
      <description>&lt;p&gt;Character sheets are a reference format. Front, side, and back views, a range of expressions, a set of poses, enough detail that another person could work from the sheet without asking you questions.&lt;/p&gt;

&lt;p&gt;The interesting engineering question is what happens when the input is underspecified. One image of a character does not contain the back of the coat. It does not contain the object hanging off a strap that runs behind the hip. Ask a model to expand that image into a full sheet, and it has to produce values for fields that were never set.&lt;/p&gt;

&lt;p&gt;So I ran it as a controlled test on &lt;a href="https://eap.pixai.art/go/balazs2" rel="noopener noreferrer"&gt;Tsubaki.3&lt;/a&gt;, the model PixAI currently has in early access, and measured what came back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test setup
&lt;/h2&gt;

&lt;p&gt;One original character, generated once from text, then used as the only reference for every run after it. Eight generations: a turnaround, the same turnaround again on a different seed, a third with one sentence added, a six-panel expression sheet, a nine-panel expression sheet, a four-pose sheet, a single pose, and an outfit sheet.&lt;/p&gt;

&lt;p&gt;Every setting held constant across runs: style preset off, Pro mode, Prompt Helper off, default negative prompt untouched, square format, one reference image attached.&lt;/p&gt;

&lt;p&gt;The character design is the instrument, and it splits into three groups.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAMED IN EVERY PROMPT      hair length and color, eye color,
                           red scarf, olive coat over grey sweater

REFERENCE ONLY             which side the hair tucks behind the ear,
                           which side the scarf tail hangs on,
                           strap across the chest with a metal slider,
                           notebook in the left chest pocket

ABSENT FROM THE REFERENCE  the back of the coat
                           the object on the end of the strap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first group is the control. If those drift, nothing else is worth reading. They did not drift in any of the eight runs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs2o668mfszzyz3msyodw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs2o668mfszzyz3msyodw.jpg" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 1: silence is deterministic, promises are not
&lt;/h2&gt;

&lt;p&gt;The turnaround came back with three genuine views at a matched scale: 983, 978, and 978 pixels tall in a 1024 pixel frame. The back view had to be invented, since the reference never showed it. It came out as a plain quilted panel with a center seam.&lt;/p&gt;

&lt;p&gt;Then I ran the identical prompt, byte for byte, on a different seed. Same invented back. Same center seam.&lt;/p&gt;

&lt;p&gt;That is the useful finding. An unset field gets a default, and the default is stable enough to rely on.&lt;/p&gt;

&lt;p&gt;The strap behaves differently. The reference shows it crossing the chest and running to something behind the hip. Both turnaround runs dropped it entirely from the back view rather than resolving it, on two different seeds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffq4ivwehvhpoyb8ppdi6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffq4ivwehvhpoyb8ppdi6.jpg" alt=" " width="800" height="779"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the third run, I held the first run's seed and appended one sentence naming the bag. The bag appeared, correct material, correct hip. Two things came with it: a second strap crossing the first on the back, which no single shoulder bag produces, and the disappearance of the strap from the front and side views of that same sheet.&lt;/p&gt;

&lt;p&gt;One added constraint, satisfied at the point of the constraint, paid for elsewhere in the same output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 2: panel count is a real budget
&lt;/h2&gt;

&lt;p&gt;Six expressions in a two-by-three grid was the strongest output in the set. All six visually distinct, the face measuring between 243 and 260 pixels wide across the panels, and a metal slider a few pixels across surviving at roughly 341 by 512 pixels per portrait.&lt;/p&gt;

&lt;p&gt;Nine expressions in a three by three grid did something I did not predict. The faces stayed on model. The framing simplified: every panel squared up to the camera, the hair fell symmetrically, and a reference-only detail that held through all six panels of the smaller sheet vanished from all nine of the larger one. Two emotion pairs also converged, so nine slots produced seven clearly separate faces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result 3: the sheet format itself costs resolution
&lt;/h2&gt;

&lt;p&gt;The pose sheet held proportions and broke layout. Four requested poses produced three distinct ones, and the crouching figure landed in the gap between two others at a different camera height instead of on the row.&lt;/p&gt;

&lt;p&gt;More useful was running the same crouch as a single figure in the full frame. The notebook in the chest pocket renders at 71 pixels wide there against 32 on the sheet, with the cover, page block and spine thickness all readable. The reaching hand resolved into five separated fingers.&lt;/p&gt;

&lt;p&gt;A quarter of a 1024 pixel frame has no room for that. The sheet was not failing at drawing; it was failing at budget.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiynma9kgn4w2aivnywk1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiynma9kgn4w2aivnywk1.jpg" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What survived, ranked
&lt;/h2&gt;

&lt;p&gt;Across every figure, the reference-only details came out in a clear order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;notebook in the chest pocket   25 of 26 figures wearing the coat
strap across the chest         23 of 26 front and side views
scarf tail on one side         10 of 17 full body figures
hair tucked behind one ear     14 of 26 views that face the viewer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ordering is not random. The notebook is a high-contrast object in a fixed place on the garment, and every format keeps that place in frame. The strap depends on which side of the body is visible. The hair parting has no object holding it, so it goes first.&lt;/p&gt;

&lt;p&gt;One caveat that cuts across all of it. The notebook and the strap are missing from the outfit sheet completely, because the coat they live on was replaced. Identity carried by an object lasts exactly as long as the object does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways if you try this
&lt;/h2&gt;

&lt;p&gt;Design for the format. Put the identifying details on objects, keep those objects on a garment you plan to keep, and treat anything that lives purely in the silhouette as the first thing you will lose.&lt;/p&gt;

&lt;p&gt;Run the turnaround twice before you trust the back. The second run tells you whether the invented answer is a stable default or a coin flip.&lt;/p&gt;

&lt;p&gt;If a detail matters, generate it as a single image rather than a panel. The overview and the detail are different jobs.&lt;/p&gt;

&lt;p&gt;One last thing. Treat the output as a working reference rather than a production model sheet. Everything on it that your original image never showed is a plausible guess, which is a different thing from correct.&lt;/p&gt;

&lt;p&gt;If you have one good picture of your OC sitting in a folder, the whole experiment costs you a few generations. &lt;a href="https://eap.pixai.art/go/balazs" rel="noopener noreferrer"&gt;Try it on PixAI&lt;/a&gt; and see which of your character's details are carried by an object and which are carried by luck.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>design</category>
    </item>
    <item>
      <title>Adding an Instruction Moved the Bug Instead of Fixing It</title>
      <dc:creator>Merl Merl</dc:creator>
      <pubDate>Mon, 31 Aug 2026 19:35:52 +0000</pubDate>
      <link>https://dev.to/merl985/adding-an-instruction-moved-the-bug-instead-of-fixing-it-1m90</link>
      <guid>https://dev.to/merl985/adding-an-instruction-moved-the-bug-instead-of-fixing-it-1m90</guid>
      <description>&lt;p&gt;Image models fail in a way that is hard to debug: the output looks fine. There is no stack trace, no assertion error, just a picture that is plausible and quietly different from what you asked for.&lt;/p&gt;

&lt;p&gt;So I built a test fixture and ran nine controlled generations against it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fixture
&lt;/h2&gt;

&lt;p&gt;One scene, described in exactly the same words in every prompt, with four objects placed so that I could check each one afterwards:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- red toolbox      -&amp;gt; viewer's left of the character
- metal ladder     -&amp;gt; viewer's right of the character
- ticket booth     -&amp;gt; further back, behind the wheel
- the character    -&amp;gt; standing at the foot of the Ferris wheel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model under test was &lt;a href="https://eap.pixai.art/go/balazs2" rel="noopener noreferrer"&gt;Tsubaki.3&lt;/a&gt; on PixAI. Two rules kept the runs comparable. Only the camera sentence changed between prompts, and it came first, since these models read a prompt roughly in order of importance. Every test ran as a single generation instead of a batch, because selecting the best of four measures what the model can produce on the fourth attempt, which is a different question.&lt;/p&gt;

&lt;h2&gt;
  
  
  The baseline
&lt;/h2&gt;

&lt;p&gt;The first prompt named no camera at all, and I ran it four times. All four came back the same way: eye level, character centered, full body, wheel behind him at roughly equal width on both sides.&lt;/p&gt;

&lt;p&gt;The left and right assignments held in all four images. The booth, described as standing behind the wheel, ended up beside it every time. That split showed up in every later run too, so it is worth stating early: &lt;strong&gt;left and right are properties of the frame, behind is a property of the camera&lt;/strong&gt;, and only one of those two moves when the lens does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test 1: camera height
&lt;/h2&gt;

&lt;p&gt;Two prompts, identical except for one sentence. One asked for an extreme low angle with the camera almost on the concrete, the other for a bird's-eye view from the top of the wheel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjxorx4e84wzd0vzmg4za.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjxorx4e84wzd0vzmg4za.jpg" alt=" " width="800" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both moved the lens instead of bending the pose. Boots large and close, horizon low, base legs splaying outward in the first. Hard hat crown dominant, legs foreshortened, structural shadows consistent with the viewpoint in the second.&lt;/p&gt;

&lt;p&gt;The failure here is partial. In the low-angle run, the steel base directly behind the character reacted to the new viewpoint, while the wheel itself stayed a clean frontal circle with evenly spaced spokes, exactly as it looked at eye level. In the high-angle run, the same wheel turned correctly, its rim running out of both sides of the frame as two curves. Near geometry followed the camera, while distant geometry sometimes kept the view it already had.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test 2: the regression
&lt;/h2&gt;

&lt;p&gt;The depth prompt asked for three layers: toolbox very close to the lens, character in the middle distance beside the ladder, booth far behind him and much smaller than he is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdzkcbvkpzw9ewift6rp5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdzkcbvkpzw9ewift6rp5.jpg" alt=" " width="800" height="615"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Result of run one:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Assertion&lt;/th&gt;
&lt;th&gt;Outcome&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;toolbox in the immediate foreground, large&lt;/td&gt;
&lt;td&gt;pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;character readable in the middle distance&lt;/td&gt;
&lt;td&gt;pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;booth far back, much smaller than him&lt;/td&gt;
&lt;td&gt;pass, around 40 percent of his height&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;character stands beside the ladder&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;fail&lt;/strong&gt;, ladder moved to the booth&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One failing assertion, so I patched the prompt. I added two phrases and changed nothing else: the booth got a frame position, near the right edge of the frame, and the character got one too, in the center of the frame.&lt;/p&gt;

&lt;p&gt;Result of run two:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Assertion&lt;/th&gt;
&lt;th&gt;Outcome&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;character stands beside the ladder&lt;/td&gt;
&lt;td&gt;pass, fixed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;booth near the right edge of the frame&lt;/td&gt;
&lt;td&gt;pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;booth far back, half his height&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;fail&lt;/strong&gt;, around 110 percent of his height&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;character in the center of the frame&lt;/td&gt;
&lt;td&gt;partial, sits right of the center line&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The patch fixed the failing assertion and broke a passing one. The booth moved to the right edge as instructed and came forward while doing it, its awning now above the character's hard hat. Two runs of the same scene, two different failure profiles, and the second was not obviously better than the first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test 3: the lens is a separate control
&lt;/h2&gt;

&lt;p&gt;Fisheye has two parts. The lens has to bend the image, and the camera has to be somewhere specific for the bend to make sense. I asked for both: a fisheye shot from directly beneath the wheel looking straight up.&lt;/p&gt;

&lt;p&gt;The distortion arrived, and it is convincing, with the concrete apron bowing into a wide arc. The camera position was ignored, and what came back has two viewpoints in one frame. The character is drawn from above, crown of the hard hat toward the lens, legs foreshortened, shadow pooled beneath him. The wheel behind him is drawn from below, base legs splaying downward, top edge tilting away.&lt;/p&gt;

&lt;p&gt;The lens effect applied to the whole frame, while the camera position resolved separately for the figure and for the structure behind him.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test 4: five constraints in one prompt
&lt;/h2&gt;

&lt;p&gt;The last prompt stacked five requirements: low camera, toolbox in the immediate foreground on the viewer's left, character in the middle distance climbing the ladder with his back to the camera, an older man in a green coverall further back on the viewer's right holding a clipboard and looking up, wheel filling the background.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7uron0bbwr5p4xqbrdmm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7uron0bbwr5p4xqbrdmm.jpg" alt=" " width="768" height="1280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All five landed, including the back-turned pose, which I expected to be the weak point since turning a character away removes the face.&lt;/p&gt;

&lt;p&gt;The busiest prompt in the test produced the cleanest result. The wording difference is that every element here carried a frame side alongside its distance, while the depth prompt named only layers. Whether the frame side is what carried the result, two runs cannot tell me.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the nine runs support
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Side of the frame:&lt;/strong&gt; honored in every run where it appeared, including ground level, overhead, and fisheye.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Camera height:&lt;/strong&gt; three clear results out of four, with the overhead run understating the distance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lens distortion:&lt;/strong&gt; present in both runs that asked for it, independent of camera position.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Depth, near layer:&lt;/strong&gt; landed in all three prompts that asked for one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Depth, far layer:&lt;/strong&gt; correct in two runs, slid forward in the third.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Size ratio between two objects:&lt;/strong&gt; returned as written in neither of the two runs that asked for one. Much smaller than he is produced 40 percent; half his height produced 110 percent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The camera is controllable on this model. The spatial relationships between objects are not deterministic across runs of the same prompt, and adding instructions to fix one relocated the variance rather than eliminating it. If you are building a pipeline on top of this, treat camera position as a parameter and object-to-object geometry as something you verify per output.&lt;/p&gt;

&lt;p&gt;If you want to run the same experiment, the method is cheap: fix three or four nameable objects in your scene, write down where each one belongs, change one sentence per run, and check the output against your list instead of against your impression of it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://eap.pixai.art/go/balazs" rel="noopener noreferrer"&gt;Try your own composition challenge on PixAI&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>design</category>
    </item>
    <item>
      <title>Moving a Value Is Two Operations, and One of Them Is a Delete</title>
      <dc:creator>Merl Merl</dc:creator>
      <pubDate>Wed, 26 Aug 2026 18:31:24 +0000</pubDate>
      <link>https://dev.to/merl985/moving-a-value-is-two-operations-and-one-of-them-is-a-delete-a8m</link>
      <guid>https://dev.to/merl985/moving-a-value-is-two-operations-and-one-of-them-is-a-delete-a8m</guid>
      <description>&lt;p&gt;An image editor that takes natural language looks like a function call with named arguments. You describe a target, an operation, and a set of things that should stay put, and something comes back. The interesting failures are the ones where every argument you passed is present in the output, and the result is still wrong.&lt;/p&gt;

&lt;p&gt;Here is the smallest example I have. The instruction was to move an object from A to B. The output contained the object at B. It also still contained the object at A. Every requirement satisfied, one implicit requirement missed: a move is a copy plus a delete, and the delete is the half nobody writes down.&lt;/p&gt;

&lt;p&gt;I spent a session testing which implicit requirements PixAI's Tsubaki.3 model infers on its own. Eight edits, four categories, one fixture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test fixture
&lt;/h2&gt;

&lt;p&gt;A single generated scene, built so every element is countable and nameable afterwards:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;subject:   greenhouse gardener
worn:      one yellow rubber glove, left hand only
held_by:   crow -&amp;gt; the matching right glove, in its beak
markers:   4 wooden plant labels, red shears in one pocket,
           straw hat on a cord down her back
bench:     tipped terracotta pot (centre), watering can (right edge)
control:   second terracotta pot, same clay, never named in any instruction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last line is the important one. Two objects of the same material, only one of them ever mentioned, gives you a free assertion on every material edit.&lt;/p&gt;

&lt;p&gt;Fixed parameters across all runs: Pro mode, no style preset, default negative prompt untouched, prompt rewriting disabled, one edit per run from the same source. Free seeds, so single runs are observations rather than proofs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft9gp70lc7uffveifnm2c.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft9gp70lc7uffveifnm2c.jpg" alt=" " width="800" height="1067"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Category 1: reference reassignment
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Move the yellow rubber glove from the crow's beak onto her bare right hand,
so that she is now wearing a glove on both hands.
The crow's beak is empty and open.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Passed on all three assertions: object present at destination, absent at origin, and bound by the right relation (worn, rather than held). The duplicate-instance failure never appeared in this run.&lt;/p&gt;

&lt;p&gt;The second spatial test asked for containment with specified occlusion: the crow inside the tipped pot, only its head visible, legs and body and twine hidden.&lt;/p&gt;

&lt;p&gt;The bird went in tail-first, which inverts the occlusion spec exactly. Two unrequested mutations came with it: the pot rotated to face the opposite direction, and the twine unbound from the crow's leg and rebound around the pot. Both are consistent with making a tail-first insertion physically renderable at that camera angle. Read charitably, the model mutated whatever was not explicitly frozen until the requested relation became satisfiable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Category 2: change the type, keep the instance
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Change the terracotta pot she is holding to clear transparent glass,
so that the soil and tangled roots inside become visible.
The pot keeps exactly the same shape, size, and position in her hand.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Assertion&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Material changed to glass&lt;/td&gt;
&lt;td&gt;pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interior contents invented plausibly&lt;/td&gt;
&lt;td&gt;pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Silhouette preserved&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;fail&lt;/strong&gt;, returned a straight-sided jar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No parts added&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;fail&lt;/strong&gt;, gained a metal screw lid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Control object unchanged&lt;/td&gt;
&lt;td&gt;pass, second pot still terracotta&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The control assertion is the useful one. Material change scoped to the named instance rather than to the type, which is the behaviour you want in a cluttered frame.&lt;/p&gt;

&lt;p&gt;The silhouette failure repeated on the second material edit in a different direction. Asked to turn a straw hat on the character's back into hammered copper while keeping its shape and cord, the model delivered the copper and the brim, then relocated the hat onto her head and swapped the thin cord for a thick knotted rope. A single argument about material mutated a spatial relation that was never in the call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Category 3: one instruction, derived consequences
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Show this same greenhouse one second after the whole potting bench
tipped over onto the floor.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No consequences listed on purpose. The dependency chain resolved without being told: the bench is overturned and everything that had been resting on it is on the floor with the soil spilled.&lt;/p&gt;

&lt;p&gt;Garbage collection was less tidy. The crow is gone from the scene with no trace. A second pair of shears appeared on the floor while the original instance stayed in the character's pocket. The watering can landed upright and undamaged. And with nothing airborne, the render reads as an aftermath state rather than the requested t+1s frame.&lt;/p&gt;

&lt;h2&gt;
  
  
  Category 4: text and layout
&lt;/h2&gt;

&lt;p&gt;Three string operations plus one physical dependency, since the crow was perched on the title being replaced.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Assertion&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Title replaced, exact string&lt;/td&gt;
&lt;td&gt;pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Date line added below, exact string&lt;/td&gt;
&lt;td&gt;pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Badge added with exact string&lt;/td&gt;
&lt;td&gt;pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Size hierarchy preserved&lt;/td&gt;
&lt;td&gt;pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Crow re-perched on the new title&lt;/td&gt;
&lt;td&gt;pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Badge placed in the named corner&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;fail&lt;/strong&gt;, landed below the title on the right&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Surrounding layout preserved&lt;/td&gt;
&lt;td&gt;pass&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Worth noting from the generation side: producing the source poster took three attempts. The first two used a compound word in the display title, and across eight images none came back usable, with the same stray consonant inserted between the two halves every time all the letters were legible. The smaller caption line rendered correctly on every attempt. Text accuracy in generation and text accuracy in editing behaved like separate subsystems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvuox5f47hx074p6b7056.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvuox5f47hx074p6b7056.jpg" alt=" " width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Does adding constraints help?
&lt;/h2&gt;

&lt;p&gt;Two of the failures got a second pass with the missing constraint written out.&lt;/p&gt;

&lt;p&gt;Pinning the hat's position worked completely. One clause stating that the hat stays on her back was enough to keep it there, keep the cord thin, and leave both control pots alone.&lt;/p&gt;

&lt;p&gt;Pinning the pot's shape produced a mixed result. Naming the lid removed the lid. Naming the root direction fixed the root direction. Naming the category ("do not turn it into a jar") and describing the overall form did nothing, and the vessel came back as a jar with a threaded neck. The blast radius also widened rather than narrowing: on that run the control pot turned to glass as well.&lt;/p&gt;

&lt;p&gt;The pattern across those two, at one run per variant: constraints naming a relation or a specific removable part held, constraints naming a class or a whole shape did not, and a longer defensive instruction bought no extra protection for anything else in the frame.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would take into a workflow
&lt;/h2&gt;

&lt;p&gt;Relations between separate objects are safe to attempt in one pass, including the delete half of a move. Strings inside an existing design are safe. Type changes on an object need verification every time, and if two objects of the same material sit in one frame, check both.&lt;/p&gt;

&lt;p&gt;The one-line version: name the relation you care about, including the one you want left alone, and put your assertions on the objects rather than on the scene.&lt;/p&gt;

&lt;p&gt;If you want to run your own version, the cheapest possible test is two similar objects in one image and an instruction that names exactly one of them. Try your own advanced editing scenario with Tsubaki.3 on PixAI: &lt;a href="https://eap.pixai.art/go/balazs" rel="noopener noreferrer"&gt;https://eap.pixai.art/go/balazs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>design</category>
    </item>
    <item>
      <title>Measuring the Blast Radius of an AI Image Edit</title>
      <dc:creator>Merl Merl</dc:creator>
      <pubDate>Mon, 24 Aug 2026 19:31:25 +0000</pubDate>
      <link>https://dev.to/merl985/measuring-the-blast-radius-of-an-ai-image-edit-cam</link>
      <guid>https://dev.to/merl985/measuring-the-blast-radius-of-an-ai-image-edit-cam</guid>
      <description>&lt;p&gt;Instruction-based image editing has a failure mode that is easy to describe and hard to pin down: the requested change lands, and something you never mentioned comes back different. The face is a little off, an accessory is gone, the background warmed up by a few degrees.&lt;/p&gt;

&lt;p&gt;The usual way to evaluate this is to look at the output and form an impression. I wanted numbers instead, so I set up something closer to a controlled experiment against PixAI's Tsubaki.3 and ran nine edits, the four main tests all starting from the same source image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;One source image, held constant. Same model, same mode, no style preset, no LoRA, prompt rewriting disabled, default negative prompt untouched, and a pinned seed. Once a base image is loaded the panel exposes no strength control, so there was nothing else to hold fixed.&lt;/p&gt;

&lt;p&gt;The source was built as a test fixture rather than as a picture. Every identifying detail sits on one side only, which turns drift into something you can count:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;left ear      silver hoop          right ear     nothing
right wrist   watch                left wrist    bare
right side    stethoscope head     left arm      two bandage squares
table         ginger tabby cat, white chest patch, one white front paw, red collar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cat is the control. It sits in the middle of the frame, adjacent to everything I was about to modify, and exactly one of the nine instructions mentions it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measurement
&lt;/h2&gt;

&lt;p&gt;For each result, I compared regions against the same regions of the source and took the mean per-pixel difference. Calibration matters more than the absolute values here:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Region type&lt;/th&gt;
&lt;th&gt;Value when untouched&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Flat wall&lt;/td&gt;
&lt;td&gt;1 to 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Detailed area, table edge&lt;/td&gt;
&lt;td&gt;3 to 6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A region the edit changed&lt;/td&gt;
&lt;td&gt;tens&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0u4koev1yskyt74ok55w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0u4koev1yskyt74ok55w.jpg" alt=" " width="800" height="1056"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;One instruction.&lt;/strong&gt; Recolor a garment. Face 3.2, cat fur 5.0, cat eyes 3.8, watch 5.6, bandage 2.4, background 1.6. The change stayed inside the garment it named.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One structural instruction.&lt;/strong&gt; Replace the outfit entirely, which forces the model to rebuild shape rather than repaint color. Stethoscope survived on top of the rebuilt torso. Both bandages survived. Cat at 4.5. Face at 10.1, against 3.2 in the recolor, with nothing in the prompt referring to the face.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three instructions in one prompt.&lt;/strong&gt; Cardigan color, held object swap, facial expression. All three landed. I then ran the same prompt twice more, once with a list of elements to preserve and once with that list plus the cat named by its markings. Whole-frame difference between the three variants: 1.4 to 2.6, which is background noise. The preservation list changed nothing measurable, because nothing in that run was under threat.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7ab0uie9zpsimgqyf9kf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7ab0uie9zpsimgqyf9kf.jpg" alt=" " width="799" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Four instructions plus an environment change.&lt;/strong&gt; New location, new light source, new jacket, new held object, and a rendered sign reading ROOM 2. All four landed and the lettering came out clean. Color did not survive. The cat's fur went from an average RGB of (233, 181, 122) to (142, 149, 148), collapsing the channel spread from 111 to 7. Skin turned bluish grey and hair went near black, on a run whose preservation list named the face and hair explicitly, as most of the other runs did too.&lt;/p&gt;

&lt;h2&gt;
  
  
  The finding
&lt;/h2&gt;

&lt;p&gt;Instruction count was the wrong variable. One instruction and four were carried with the same accuracy, and nothing was ignored across nine edits.&lt;/p&gt;

&lt;p&gt;What scaled was reach. The disturbed area tracked how much of the picture the instruction obliged the model to reconstruct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;recolor a garment      -&amp;gt; stops at the garment edge
rebuild an outfit      -&amp;gt; reaches the face
change the light       -&amp;gt; reaches every surface whose color depends on light
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The preservation list follows the same curve. At one instruction it had nothing to save. At three it made no measurable difference. At four plus an environment change it named the face and hair and lost both. It costs nothing to include and it stops being sufficient at the point where you start needing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chaining is worse than batching
&lt;/h2&gt;

&lt;p&gt;The obvious instinct is to split a complex edit into steps. I ran the three-change instruction as three sequential edits, each starting from the previous result, and measured how broken up the flat wall behind the subject became:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Route&lt;/th&gt;
&lt;th&gt;Wall blockiness&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Source&lt;/td&gt;
&lt;td&gt;0.36&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One prompt, three changes&lt;/td&gt;
&lt;td&gt;0.40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chained, step 1&lt;/td&gt;
&lt;td&gt;0.43&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chained, step 2&lt;/td&gt;
&lt;td&gt;1.21&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chained, step 3&lt;/td&gt;
&lt;td&gt;7.35&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;By step three the breakup had spread onto the subject and the cat. Every pass re-encodes the whole image, and the artifacts compound in flat regions first. Instruction following survived the whole chain, and image quality did not.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr55sfc4ojgoh8g24i4ya.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr55sfc4ojgoh8g24i4ya.jpg" alt=" " width="800" height="633"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I ran step two twice and got byte-identical files, so the result is reproducible on these settings. Whether a different seed avoids it is untested. Worth noting for anyone reaching for a retry: with the seed pinned, rerunning changes nothing at all. Freeing the seed or rewriting the instruction are the only two levers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Batch related changes into one instruction. Four coordinated changes came through intact.&lt;/li&gt;
&lt;li&gt;Expect a structural rebuild to move the face slightly. Check it against the original.&lt;/li&gt;
&lt;li&gt;Expect a lighting or environment change to rewrite color on skin, hair and fur, and expect a preservation list to fail there.&lt;/li&gt;
&lt;li&gt;Avoid chained passes on the same file. The quality cost is real and compounds.&lt;/li&gt;
&lt;li&gt;Pin your settings before a comparison run. Half of this analysis only works because every edit ran on identical parameters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full write-up with all the before and after images is on Medium. If you want to run the same experiment on your own file, &lt;a href="https://eap.pixai.art/go/balazs" rel="noopener noreferrer"&gt;Tsubaki.3 is on PixAI&lt;/a&gt;. Take something you already like, change one small thing, and go audit the corners of the frame.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>design</category>
    </item>
    <item>
      <title>I ran 17 controlled generations to find out where AI manga panels break</title>
      <dc:creator>Merl Merl</dc:creator>
      <pubDate>Fri, 21 Aug 2026 11:08:29 +0000</pubDate>
      <link>https://dev.to/merl985/i-ran-17-controlled-generations-to-find-out-where-ai-manga-panels-break-32n4</link>
      <guid>https://dev.to/merl985/i-ran-17-controlled-generations-to-find-out-where-ai-manga-panels-break-32n4</guid>
      <description>&lt;p&gt;Garbled text inside generated images has been a standing complaint for as long as I have been using these tools. Recent releases claim to have fixed it, and I wanted to find out where the line actually sits.&lt;/p&gt;

&lt;p&gt;So I set up a small experiment: one character, one model, seventeen generations, and a rule that every comparison changes exactly one variable. The subject is manga panels, because a panel is the one image format that has to carry artwork and text in the same frame and make both readable. The model is Tsubaki.3 on PixAI. I cannot draw, which for this purpose is a feature: everything below comes out of the prompt, with nothing rescued by hand afterward.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Treat the prompt as a function call with five arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;panel(
  scene,       # what is happening
  character,   # who, in full, every run
  framing,     # camera position and how tight
  dialogue,    # the line, and which corner it goes in
  treatment    # panel border, screentone, speed lines
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The character argument stays identical across every run. That is what makes the rest of it measurable. Settings held constant too: no style preset, no LoRA, quality booster off, portrait 3:4, and the negative prompt left prefilled as it ships, with one deliberate exception below. Every comparison ran as a single generation rather than a batch of four, because picking the best of four is selection bias with extra steps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frg130v2s4huia37bhvf8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frg130v2s4huia37bhvf8.jpg" alt=" " width="799" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Same character description, same action, two different treatment arguments. The left is a color illustration, centered, no border, no text. The right is the manga instruction: panel border, screentone, a lower camera, and the bubble. The room is identical. The treatment is the whole delta.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 1: the negative prompt does not need touching
&lt;/h2&gt;

&lt;p&gt;The default negative prompt on this model ships with &lt;code&gt;text&lt;/code&gt; in it. That reads like a direct conflict with a speech bubble, so I ran the same panel twice, once as-is and once with &lt;code&gt;text&lt;/code&gt; deleted.&lt;/p&gt;

&lt;p&gt;There was no difference. Both runs produced the requested line, correctly spelled, in a clean hand-lettered balloon. Requested dialogue behaves like subject matter rather than like stray artifact text, so the negative prompt is not the thing standing between you and a bubble.&lt;/p&gt;

&lt;p&gt;Then I raised the input length from two words to eight, with punctuation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"PICK ANOTHER"                              -&amp;gt; correct
"THIS ONE IS BLURRY. THE CAPTION IS WRONG." -&amp;gt; correct, both periods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The bubble occupied about five percent of the frame in both cases. The model did not resize the balloon to fit more text; it shrank the glyphs and stacked them into three rows. Longer strings cost legibility, not area.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 2: naming the bubble's position rewrites the composition
&lt;/h2&gt;

&lt;p&gt;This is the result I did not expect, and it is the reason the whole experiment was worth running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1rjpq17gfvcwls782iqa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1rjpq17gfvcwls782iqa.jpg" alt=" " width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three runs, one scene, one variable:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Run&lt;/th&gt;
&lt;th&gt;Dialogue argument&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;line only, no position&lt;/td&gt;
&lt;td&gt;bubble self-placed on empty window area, cleared the face, no tail drawn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;line plus "upper left corner"&lt;/td&gt;
&lt;td&gt;bubble in that corner, &lt;strong&gt;and the character moved to the right side of the frame&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;B plus an explicit empty-third layout instruction&lt;/td&gt;
&lt;td&gt;requested layout delivered, character shrank, tail came out as an open line&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Run B is the interesting one. I changed four words in the dialogue argument and the model re-solved the whole composition around them: figure to the right, table rotated, upper left cleared. Nothing in the prompt said where she should stand.&lt;/p&gt;

&lt;p&gt;The model treats the bubble as a layout element that has to fit, and it resolves the constraint by moving the artwork. That gives you a clean rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Name the corner. Do not also specify the layout.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Run C is what over-constraining looks like. Two instructions competing for the same rectangle, and the subject is what yields.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 3: placement is reliable, the tail is not
&lt;/h2&gt;

&lt;p&gt;Across the full set, balloon placement never failed. The tail failed in four different ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;missing entirely&lt;/li&gt;
&lt;li&gt;doubled, two tails aimed at the same speaker&lt;/li&gt;
&lt;li&gt;drawn as a thin open line stopping in mid air, with the balloon outline broken where they should join&lt;/li&gt;
&lt;li&gt;hanging into the gap between two characters, pointing at neither&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are building anything on top of this, the tail is the element to flag for review. The balloon and the lettering held up without exception in my set.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 4: prompt order predicts which character degrades
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz34guythco2aqw9yy861.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz34guythco2aqw9yy861.jpg" alt=" " width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two characters in one frame, described in sequence: the editor first and at length, the photographer second and more briefly. The line belongs to the photographer.&lt;/p&gt;

&lt;p&gt;Visual separation held up: pale cropped hair against a black bob, a height difference, a camera on a strap. The bubble sat on his side of the frame and the tail angled toward him, so the association worked, if faintly.&lt;/p&gt;

&lt;p&gt;The degradation was asymmetric and it repeated across two runs. Of the second character's five specified details, two failed the same way both times: glasses that were supposed to sit pushed up on his forehead came back over his eyes, and a bandage across his nose never rendered. The first-described character lost nothing.&lt;/p&gt;

&lt;p&gt;I cannot see inside the model, so I will state it as a behavior rather than a cause: the subject written later and more briefly is the one that lost details, twice, in the same two places. Write the second subject at the same specificity as the first rather than summarizing it after.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 5: a detailed description left the reference image little to do
&lt;/h2&gt;

&lt;p&gt;Character drift is the standard complaint, so I measured it. Accessories and outfit survived well across the set. The face did not: it rounded out and aged up run to run, worst in an extreme close-up where the crop leaves the model the most to invent.&lt;/p&gt;

&lt;p&gt;The expected fix is a reference image, so I generated a new scene twice, once from the description alone and once with my character sheet loaded as a reference. It changed the framing and gave her more hair. The face came out about the same either way. With a description carrying seven specified identity details, the reference had little left to correct.&lt;/p&gt;

&lt;p&gt;Hairstyle was the outlier that nothing fixed. It ranged from close to the sheet in one panel to a tight pinned-up version in another, and the reference run produced the most extreme version of all.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would keep from this
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Lettering held for every line I tried, up to eight words. Budget your cleanup time elsewhere.&lt;/li&gt;
&lt;li&gt;Position the bubble by naming a corner, and let the model handle the rest of the arrangement.&lt;/li&gt;
&lt;li&gt;Review the tail on every panel. It is the least reliable element on the page.&lt;/li&gt;
&lt;li&gt;Write every subject in a multi-character prompt at full specificity, the second one included.&lt;/li&gt;
&lt;li&gt;Describe held objects with the grip stated separately. Every run that asked for a photo held between two fingers returned a raised finger and a floating photo.&lt;/li&gt;
&lt;li&gt;Compare with single generations. Batches let you pick winners and learn nothing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A four-panel strip also held together in one generation, with the beats in written order and set dressing holding its position across panels, which is the part that makes a sequence read as one scene.&lt;/p&gt;

&lt;p&gt;If you want to run your own version of this, the model is Tsubaki.3 and the useful discipline is changing one argument at a time: &lt;a href="https://eap.pixai.art/go/balazs" rel="noopener noreferrer"&gt;try it on PixAI&lt;/a&gt; and see which of these behaviors reproduce for you.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>design</category>
    </item>
    <item>
      <title>The Reference Carried the Count, the Prompt Carried the Layout</title>
      <dc:creator>Merl Merl</dc:creator>
      <pubDate>Tue, 18 Aug 2026 19:52:36 +0000</pubDate>
      <link>https://dev.to/merl985/the-reference-carried-the-count-the-prompt-carried-the-layout-ep9</link>
      <guid>https://dev.to/merl985/the-reference-carried-the-count-the-prompt-carried-the-layout-ep9</guid>
      <description>&lt;p&gt;There is a piece of advice that circulates around reference-based image generation: once you attach a reference image, keep your prompt short. Describe the new scene, leave the character alone, because re-describing what the reference already shows will fight it.&lt;/p&gt;

&lt;p&gt;I wanted a number on that, so I designed a character to fail in measurable ways.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing a character as a test fixture
&lt;/h2&gt;

&lt;p&gt;The character is an original design called Asagi, built on PixAI with the Tsubaki.3 model. The visible design has seven components, but two of them exist purely as assertions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A count.&lt;/strong&gt; Three small brass bells on a braided green cord at his sash. Countable at a glance, and wrong answers are unambiguous.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A side.&lt;/strong&gt; A black leather arm guard on one forearm, a white cloth wrap on the opposite wrist. An asymmetric pair, so a failure shows up as either symmetry or a swap.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything else in the design - the indigo haori with a mustard band, the jade green eyes, the pale ochre lock of hair, the thin scar across one eyebrow - serves as background signal. The bells and the arm pair are the assertions that either pass or fail.&lt;/p&gt;

&lt;p&gt;This matters because "does it look like the same character" is not a testable claim. "Are there three bells?" is.&lt;/p&gt;

&lt;h2&gt;
  
  
  The test matrix
&lt;/h2&gt;

&lt;p&gt;Three conditions, same scene, same model, same settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;condition A:  prompt only          (full character description, no reference)
condition B:  prompt + reference   (full character description, reference attached)
condition C:  reference only       (scene described, character not mentioned)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The scene was identical in all three: the character seated at a low table in a sunlit tea house. Condition C's prompt reads in full:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The same character sitting at a low table inside a sunlit tea house
in the daytime, a small cup in front of him, relaxed expression,
paper screens and warm wooden beams behind him, upper body and
both hands visible, anime illustration.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9kizt3acvt46bb8owj3s.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9kizt3acvt46bb8owj3s.jpg" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Condition&lt;/th&gt;
&lt;th&gt;Bell count&lt;/th&gt;
&lt;th&gt;Asymmetric pair&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A, prompt only&lt;/td&gt;
&lt;td&gt;5 (and 2 on a repeat run)&lt;/td&gt;
&lt;td&gt;correct&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B, prompt + reference&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;correct&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C, reference only&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;collapsed to matching cuffs on both arms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Condition A never got the count right across two runs. Two bells the first time, five the second. A number in a prompt behaves like a density hint rather than an integer.&lt;/p&gt;

&lt;p&gt;Condition C got the count right and lost the layout. The reference carries what a pixel-level encoder can carry: the shape and color of a bell cluster, the geometry of a face. Which forearm wears what is a relational fact, and the model resolved it toward the symmetric default.&lt;/p&gt;

&lt;p&gt;Condition B was the only pass on both assertions. The advice I started with is too broad: the reference and the description populate different fields, and supplying both costs one extra sentence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does stacking references help?
&lt;/h2&gt;

&lt;p&gt;Tsubaki.3 accepts up to three reference images, so the obvious follow-up is whether more references buy anything. I ran the hardest prompt in the set, a full-body low-angle shot in a storm, with one, two, and three references attached. Then I repeated the whole ladder with a second fixed seed, so the reference count was the only variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;seed 1:  1 ref -&amp;gt; 3 bells   2 refs -&amp;gt; 3 bells   3 refs -&amp;gt; 5 bells
seed 2:  1 ref -&amp;gt; 3 bells   2 refs -&amp;gt; 3 bells   3 refs -&amp;gt; 3 bells
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Five out of six correct, and the single failure did not reproduce. Run-to-run variance is larger than any effect from the extra reference slots. One good reference did the job, and I would treat the second and third as optional rather than an upgrade path.&lt;/p&gt;

&lt;p&gt;More inputs usually means more constraint. Here it did not, and the feature invites the opposite assumption.&lt;/p&gt;

&lt;h2&gt;
  
  
  What survives a wardrobe change
&lt;/h2&gt;

&lt;p&gt;The destructive test: I moved the character out of a period haori into a bomber jacket and jeans on a modern crosswalk, which deletes every clothing-bound component of the design by definition.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl8qiv36nctxoi5168w8g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl8qiv36nctxoi5168w8g.jpg" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Surviving: hair, the ochre lock, eye color, face.&lt;br&gt;
Gone with the outfit: haori, bells, arm guard, as expected.&lt;br&gt;
Gone unexpectedly: the eyebrow scar and the cord tying his hair at the nape.&lt;/p&gt;

&lt;p&gt;The useful abstraction here is that identity splits into body-bound and clothing-bound components, and a wardrobe change is a scoped delete on the second group. If a character's recognizability is entirely stitched onto one jacket, the character has a single point of failure.&lt;/p&gt;

&lt;p&gt;The scar went missing again in a six-panel expression sheet generated from the same reference. The pattern across both: the finest facial detail drops when the output format diverges sharply from the reference, and a grid of six small heads is a long way from one figure on a street.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpd5k4qtcb1awhgdqnvh3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpd5k4qtcb1awhgdqnvh3.jpg" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes from the panel
&lt;/h2&gt;

&lt;p&gt;Three implementation details that cost me runs before I understood them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attachment order matters.&lt;/strong&gt; Attach the reference, then write the prompt. Adding it afterward reset my settings more than once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The output inherits the reference's aspect ratio.&lt;/strong&gt; My reference was 16:9, and every reference-based generation came back wide regardless of what I set. My first prompt-only run, with nothing attached, defaulted to portrait and had to be set by hand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The prompt you send is not the prompt that runs.&lt;/strong&gt; PixAI displays a rewritten version beside your input, and that version had pulled a physical description of the character out of the attached image. Reading it told me which traits the system extracted and which it invented. If you are debugging an unexpected result, this field is the first place to look.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;Character consistency is not one property. It decomposes, and the components have different failure modes and different owners:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The reference owns counts, faces, palette, silhouette.&lt;/li&gt;
&lt;li&gt;The prompt owns arrangement, sides, and everything relational.&lt;/li&gt;
&lt;li&gt;Neither owns the finest details once the output format moves far enough away.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you work with recurring characters, build one or two countable, one-sided details into the design on purpose. They cost nothing, and they turn consistency into something you can check rather than something you squint at.&lt;/p&gt;

&lt;p&gt;Try it with &lt;a href="https://eap.pixai.art/go/balazs" rel="noopener noreferrer"&gt;Character Reference on PixAI&lt;/a&gt; if you have a character sitting in a folder that deserves more than one image.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>design</category>
    </item>
  </channel>
</rss>
