Files
blog/fal-image-generation.html

371 lines
17 KiB
HTML

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Art at Every Price Point: How We Generate Game Assets with fal.ai — Tinqs Blog</title>
<meta name="description" content="From $0.002 to $0.09 per image, across 12 models. How we built a prompt pattern that actually produces usable game art, and a model-picking strategy that keeps costs at $8/month.">
<meta name="robots" content="index, follow">
<link rel="canonical" href="https://www.tinqs.com/blog/fal-image-generation">
<meta property="og:type" content="article">
<meta property="og:url" content="https://www.tinqs.com/blog/fal-image-generation">
<meta property="og:title" content="AI Art at Every Price Point: How We Generate Game Assets with fal.ai">
<meta property="og:description" content="12 fal.ai models, $0.002-$0.09/image, 4-layer prompt pattern. Game art that actually ships.">
<meta property="og:image" content="https://www.tinqs.com/img/og-cover.jpg">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="AI Art at Every Price Point: How We Generate Game Assets with fal.ai">
<meta name="twitter:description" content="12 fal.ai models, $0.002-$0.09/image, 4-layer prompt pattern. Game art that actually ships.">
<meta name="twitter:image" content="https://www.tinqs.com/img/og-cover.jpg">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "AI Art at Every Price Point: How We Generate Game Assets with fal.ai",
"datePublished": "2026-05-25",
"author": {
"@type": "Person",
"name": "Ozan Bozkurt"
},
"publisher": {
"@type": "Organization",
"name": "Tinqs Limited",
"url": "https://www.tinqs.com"
},
"description": "From $0.002 to $0.09 per image, across 12 models. How we built a prompt pattern that actually produces usable game art, and a model-picking strategy that keeps costs at $8/month."
}
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
/* ── Tinqs Studio brand — post styles ── */
:root {
/* Studio near-black base */
--c-bg: #0B0C0E;
--c-bg-raised: #15171A;
/* Foreground */
--c-fg: #ECEEF1;
--c-muted: #8A95A3;
/* Family accents */
--c-lime: #B6FF3C;
--c-violet: #7C5CFF;
/* Borders */
--c-border: rgba(255,255,255,.07);
--c-border-strong: rgba(255,255,255,.12);
}
*, *::before, *::after { box-sizing: border-box; }
html { background: var(--c-bg); }
body {
margin: 0;
padding: 0;
background: var(--c-bg);
color: var(--c-fg);
font-family: 'Inter', system-ui, -apple-system, sans-serif;
font-size: 16px;
line-height: 1.6;
-webkit-font-smoothing: antialiased;
}
/* ── Post container ── */
.post {
background: var(--c-bg);
max-width: 720px;
margin: 0 auto;
padding: 48px 24px 60px;
}
/* ── Back link ── */
.post__back {
color: var(--c-muted);
text-decoration: none;
font-size: 0.875rem;
display: inline-block;
margin-bottom: 24px;
transition: color 0.15s;
}
.post__back:hover { color: var(--c-lime); }
/* ── Gradient title — lime → violet ── */
.post__title {
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
background: linear-gradient(90deg, var(--c-lime), var(--c-violet));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
font-weight: 700;
font-size: 2.2rem;
line-height: 1.2;
margin: 0 0 16px;
}
/* ── Date pill ── */
.post__date {
display: inline-block;
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
font-size: 0.72rem;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--c-muted);
border: 1px solid var(--c-border);
border-radius: 999px;
padding: 4px 14px;
margin-bottom: 16px;
}
/* ── Lead ── */
.post__lead {
color: var(--c-muted);
font-size: 1.08rem;
line-height: 1.7;
}
/* ── Body ── */
.post__body { font-size: 1rem; line-height: 1.7; }
.post__body p { margin: 14px 0; }
.post__body h2 {
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
font-weight: 600;
font-size: 1.6rem;
margin: 54px 0 6px;
padding-left: 16px;
border-left: 4px solid var(--c-lime);
line-height: 1.3;
}
.post__body h3 {
font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
font-weight: 500;
color: var(--c-violet);
font-size: 1.15rem;
margin: 30px 0 4px;
}
.post__body h4, .post__body h5, .post__body h6 {
margin: 20px 0 4px;
}
/* ── Inline code ── */
.post__body code {
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
font-size: 0.84em;
background: var(--c-bg-raised);
color: var(--c-lime);
padding: 2px 6px;
border-radius: 4px;
border: 1px solid var(--c-border);
}
/* ── Code blocks ── */
.post__body pre {
background: var(--c-bg);
border: 1px solid var(--c-border);
border-radius: 8px;
padding: 16px 18px;
overflow-x: auto;
margin: 14px 0;
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
font-size: 0.83rem;
line-height: 1.55;
color: var(--c-fg);
}
.post__body pre code {
background: transparent;
padding: 0;
border: none;
font-size: inherit;
color: inherit;
border-radius: 0;
}
/* ── Blockquote ── */
.post__body blockquote {
background: rgba(124, 92, 255, 0.06);
border: 1px solid rgba(124, 92, 255, 0.15);
border-left: 4px solid var(--c-violet);
border-radius: 0 8px 8px 0;
padding: 16px 18px;
margin: 18px 0;
color: var(--c-fg);
font-size: 0.94rem;
}
/* ── Links ── */
.post__body a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
.post__body a:hover { color: var(--c-violet); }
/* ── Strong ── */
.post__body strong { color: var(--c-lime); font-weight: 600; }
/* ── HR ── */
.post__body hr {
border: none;
border-top: 1px solid var(--c-border);
margin: 32px 0;
}
/* ── Figures ── */
.post__body figure { margin: 20px 0; }
.post__body figure img {
max-width: 100%;
border-radius: 12px;
border: 1px solid var(--c-border);
}
.post__body figcaption {
color: var(--c-muted);
font-size: 0.85rem;
margin-top: 6px;
}
/* ── Lists ── */
.post__body ul, .post__body ol { padding-left: 1.5em; margin: 10px 0; }
.post__body li { margin: 4px 0; }
/* ── Author ── */
.post__author {
display: flex;
align-items: center;
gap: 14px;
margin-top: 48px;
padding-top: 24px;
border-top: 1px solid var(--c-border);
}
.post__author-avatar {
width: 48px;
height: 48px;
border-radius: 50%;
background: var(--c-violet);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 0.85rem;
flex-shrink: 0;
}
.post__author-info {
font-size: 0.85rem;
color: var(--c-muted);
line-height: 1.4;
}
.post__author-name {
color: var(--c-fg);
font-weight: 600;
}
</style>
</head>
<body>
<!-- POST -->
<article class="post">
<a href="/blog/" class="post__back">&larr; All Posts</a>
<span class="post__date">25 May 2026</span>
<h1 class="post__title">AI Art at Every Price Point: How We Generate Game Assets with fal.ai</h1>
<p class="post__lead">Every visual asset in our game — character art, app icons, trailer frames, logo variants, Steam capsules — was generated through a single API. No Photoshop. No concept artist on staff. Last month: 673 images, $8.30 total. Here's the prompt pattern that makes AI art actually usable for game development, and how we pick between 12 models spanning $0.002 to $0.09 per image.</p>
<div class="post__body">
<h2>The problem with AI art for games</h2>
<p>Most AI-generated images look beautiful on social media and useless in a game. The character looks different from every angle. The art style drifts between generations. The text in the logo is garbled. The icon doesn't read at 64×64.</p>
<p>The issue isn't the models — Flux, Ideogram, and Recraft are genuinely good. The issue is prompting. "Warrior on a beach" gives you a different art style, different skin tone, different proportions every time. You can't build a game from one-offs.</p>
<p>We spent three months iterating before we found a prompt structure that anchors the model to a consistent art direction and produces images you can actually ship. It has four layers.</p>
<h2>The 4-layer prompt pattern</h2>
<h3>Layer 1: Design context (the anchor)</h3>
<p>This is the most important paragraph and the one most people skip. It sets the art direction for every single generation:</p>
<pre><code>Art direction: stylized 3D render for a survival colony sim. Warm earthy
palette — browns, tans, dark reds, cream, ocean blues. Carved wood
textures, traditional patterns, woven natural fibres. Game engine quality,
not photorealistic.</code></pre>
<p>Same paragraph whether you're generating a character, a landscape, or an icon. It's your art bible compressed into 50 words. Every time we skipped it — "just a quick test" — the output drifted into generic fantasy art.</p>
<h3>Layer 2: Scene description (be specific)</h3>
<p>Not "tribal clothing" — "woven wrap skirt, mid-thigh length." Not "jewelry" — "shell necklace with a carved bone pendant." Vague prompts produce vague results. Specific prompts produce usable assets. Describe element by element.</p>
<h3>Layer 3: Negative prompt (prevent drift)</h3>
<p>Always include what you don't want:</p>
<pre><code>Do not include: cartoon style, anime style, photorealistic render,
extra text or taglines, watermark, deformed elements, modern or sci-fi.
No extra fingers, no merged limbs, no floating accessories.</code></pre>
<p>AI models have strong defaults — they want to make things shiny, symmetrical, and photorealistic. If your game isn't those things, say so explicitly.</p>
<h3>Layer 4: Reference images (consistency)</h3>
<p>When you need the same character from different angles, pass the first approved image as reference. Without it, every generation is independent — a different person every time. With it, every generation builds on the last approved output. This is how you get a roster of characters that look like they belong in the same game.</p>
<h2>The model lineup (and when to use each)</h2>
<p>Not every image needs the best model. A throwaway mockup doesn't justify $0.09. A final logo doesn't deserve $0.002.</p>
<p>| Model | Cost | Speed | Use for |</p>
<p>|&mdash;&mdash;-|&mdash;&mdash;|&mdash;&mdash;-|&mdash;&mdash;&mdash;|</p>
<p>| Flux 2 Pro | $0.03 | 15s | Final art, characters, environments |</p>
<p>| Flux Schnell | $0.003 | 3s | Exploration drafts, 20-variant grids |</p>
<p>| Ideogram v3 Quality | $0.09 | 12s | Anything with readable text |</p>
<p>| Recraft v3 | $0.04-0.08 | 10s | Logos, brand assets, SVG vectors |</p>
<p>| Seedream v4.5 | $0.04 | 8s | Photorealistic scenes |</p>
<p>| Flux Dev | $0.025 | 10s | LoRA fine-tuning base |</p>
<p>| Nano Banana Edit | $0.039 | 12s | Style transfer, material variants |</p>
<p>| BiRefNet | $0.001 | 3s | Background removal |</p>
<h3>The Schnell-to-Pro pipeline (never iterate on expensive models)</h3>
<p>Every generation session follows the same pattern:</p>
<p>1. <strong>Explore with Schnell</strong> ($0.003) — 10-20 variants, different angles, color palettes. Cost: $0.03-0.06</p>
<p>2. <strong>Pick 2-3 directions.</strong> Human looks at the grid, picks winners.</p>
<p>3. <strong>Refine with Flux 2 Pro</strong> ($0.03) — regenerate winners at full quality. Cost: $0.06-0.09</p>
<p>4. <strong>Post-process</strong> — BiRefNet for background removal ($0.001), Recraft for vector ($0.08)</p>
<p>A full session — blank canvas to final assets — costs under $0.20. Most of the creative work happens at $0.003/image. The expensive model just polishes a decision you already made.</p>
<h3>Typography: one model rules them all</h3>
<p>Every model except Ideogram fails at text. Flux gives you beautiful art with garbled letters. SDXL doesn't try. If your image has words in it, Ideogram v3 Quality is the only answer. We learned to accept the $0.09 cost rather than waste $0.30 on ten failed Flux attempts.</p>
<h3>Logo variants at scale</h3>
<p>Our game logo has 18 material variants — mahogany, mother-of-pearl, obsidian, molten lava, bronze with verdigris. Each generated with Nano Banana Edit ($0.039) + BiRefNet ($0.001) for transparency. Total: $0.72. A designer would quote hundreds of dollars and a week.</p>
<h2>The numbers (one month of generation)</h2>
<p>| Category | Images | Cost | Avg/Image |</p>
<p>|&mdash;&mdash;&mdash;-|&mdash;&mdash;&ndash;|&mdash;&mdash;|&mdash;&mdash;&mdash;&ndash;|</p>
<p>| Concept art (flux-2-pro) | 120 | $3.60 | $0.03 |</p>
<p>| Exploration (schnell) | 400 | $1.20 | $0.003 |</p>
<p>| Logo variants | 18 | $0.72 | $0.04 |</p>
<p>| Icons | 30 | $1.20 | $0.04 |</p>
<p>| Typography (ideogram) | 25 | $1.50 | $0.06 |</p>
<p>| Background removal | 80 | $0.08 | $0.001 |</p>
<p>| <strong>Total</strong> | <strong>673</strong> | <strong>$8.30</strong> | <strong>$0.012</strong> |</p>
<p>Six hundred images. Eight dollars.</p>
<h2>The pipeline: from prompt to in-game asset</h2>
<p>fal.ai is step one of a pipeline that goes from idea to walking character in about two hours:</p>
<pre><code>Brief → fal.ai (2D concept) → Tripo Studio (3D model) → Blender (decimate) → Godot (in-game)</code></pre>
<p>1. Designer describes the character</p>
<p>2. Generate 3 variants with Flux 2 Pro, score on 5 criteria (style match, cultural accuracy, silhouette, expression, animatability)</p>
<p>3. Generate front/side/three-quarter reference views using the winner</p>
<p>4. Tripo Studio image-to-3D (~1.5M faces, PBR textures)</p>
<p>5. Blender CLI decimates to 25k faces</p>
<p>6. Auto-rig, import into engine, done</p>
<p>Quality isn't AAA, but for an indie game with a stylized art style, it's more than good enough. Ten characters designed, total fal.ai spend: $6.</p>
<h2>What we learned</h2>
<p><strong>The design context block is worth more than the rest of the prompt combined.</strong> Without it, every image is a one-off. With it, every image belongs to the same game.</p>
<p><strong>Never iterate on expensive models.</strong> Schnell at $0.003/image is for exploration. Flux 2 Pro at $0.03 is for final output. The cheap model does 90% of the creative work.</p>
<p><strong>Aggregation beats loyalty.</strong> No single model is best at everything. Flux for art, Ideogram for text, Recraft for design, Nano Banana for edits, BiRefNet for masks. Use the right tool for each job.</p>
<p><strong>Let the agent handle prompting.</strong> We encode the 4-layer pattern, art style guide, and model selection rules in an <a href="../skills/image-generation.md" style="color: var(--c-lime);">agent skill file</a>. The AI writes the full prompt, generates images, displays them, and asks for scores. The human's job is creative direction.</p>
<p>AI art isn't magic and it isn't free. But at a penny per image, with the right prompt structure and model strategy, it eliminates the most expensive bottleneck in indie game development: the gap between "I know what this should look like" and "I have an asset I can actually use."</p>
<hr>
<p><em>Image generation is built into <a href="https://tinqs.com" style="color: var(--c-lime);">Tinqs Studio</a>. We've open-sourced the <a href="../skills/image-generation.md" style="color: var(--c-lime);">prompt engineering skill</a> and <a href="../skills/concept-art-pipeline.md" style="color: var(--c-lime);">concept art pipeline skill</a>. We're building <a href="https://arikigame.com" style="color: var(--c-lime);">Ariki</a> with these tools.</em></p>
</div>
<div class="post__author">
<div class="post__author-avatar">OB</div>
<div class="post__author-info">
<span class="post__author-name">Ozan Bozkurt</span><br>
CTO & Developer, Tinqs
</div>
</div>
</article>
</body>
</html>