feat: blog build system + all HTML generated by Pi agent
build.js + templates copied from docs, 11 posts built to 14 HTML files. Generated by local Pi orchestrator task. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
<!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 Scale: Using fal.ai Flux for Game Asset Generation — Tinqs Blog</title>
|
||||
<meta name="description" content="How we use fal.ai Flux models to generate concept art, trailer frames, and UI assets for our game --- with a 4-layer prompt pattern that actually works.">
|
||||
<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 Scale: Using fal.ai Flux for Game Asset Generation">
|
||||
<meta property="og:description" content="fal.ai Flux for game art: 4-layer prompts, $0.01/image, and a pipeline that replaced our concept art bottleneck.">
|
||||
<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 Scale: Using fal.ai Flux for Game Asset Generation">
|
||||
<meta name="twitter:description" content="fal.ai Flux for game art: 4-layer prompts, $0.01/image, and a pipeline that replaced our concept art bottleneck.">
|
||||
<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 Scale: Using fal.ai Flux for Game Asset Generation",
|
||||
"datePublished": "2026-05-25",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Ozan Bozkurt"
|
||||
},
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "Tinqs Limited",
|
||||
"url": "https://www.tinqs.com"
|
||||
},
|
||||
"description": "How we use fal.ai Flux models to generate concept art, trailer frames, and UI assets for our game --- with a 4-layer prompt pattern that actually works."
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="icon" type="image/svg+xml" href="/img/favicon.svg">
|
||||
<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=IBM+Plex+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="../style.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- NAV -->
|
||||
<nav class="nav nav--scrolled" id="nav">
|
||||
<a href="/" class="nav__logo" aria-label="Tinqs home">
|
||||
<span class="nav__wordmark">TINQS</span>
|
||||
</a>
|
||||
<div class="nav__links">
|
||||
<a href="/#game" class="nav__link">Games</a>
|
||||
<a href="/#tech" class="nav__link">Technology</a>
|
||||
<a href="/#about" class="nav__link">About</a>
|
||||
<a href="/blog/" class="nav__link" style="color: var(--c-accent-l);">Blog</a>
|
||||
<a href="/#signup" class="nav__link">Contact</a>
|
||||
<a href="/press" class="nav__link">Press</a>
|
||||
</div>
|
||||
<button class="nav__burger" aria-label="Open menu" id="navBurger">
|
||||
<span></span><span></span><span></span>
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<!-- MOBILE MENU -->
|
||||
<div class="mobile-menu" id="mobileMenu">
|
||||
<a href="/#game" class="mobile-menu__link">Games</a>
|
||||
<a href="/#tech" class="mobile-menu__link">Technology</a>
|
||||
<a href="/#about" class="mobile-menu__link">About</a>
|
||||
<a href="/blog/" class="mobile-menu__link">Blog</a>
|
||||
<a href="/#signup" class="mobile-menu__link">Contact</a>
|
||||
<a href="/press" class="mobile-menu__link">Press</a>
|
||||
</div>
|
||||
|
||||
<!-- POST -->
|
||||
<article class="post">
|
||||
<a href="/blog/" class="post__back">← All Posts</a>
|
||||
<span class="post__date">25 May 2026</span>
|
||||
<h1 class="post__title">AI Art at Scale: Using fal.ai Flux for Game Asset Generation</h1>
|
||||
<p class="post__lead">We're a small indie studio building a survival colony sim. We don't have a concept artist on staff. Every piece of character art, trailer frame, and UI icon in our game was generated with fal.ai Flux models — at roughly a penny per image.</p>
|
||||
|
||||
<div class="post__body">
|
||||
<h2>The Problem with AI Art for Games</h2>
|
||||
<p>Most AI image generators produce beautiful images that are completely useless for game development. They look great on social media but fall apart when you need consistency: the same character from four angles, a UI icon that reads at 64x64, a trailer frame that matches your game's art style rather than whatever the model defaults to.</p>
|
||||
<p>The issue isn't the models — Flux is genuinely good. The issue is prompting. When you write "warrior on a beach," you get a different art style every time. Different skin tones, different proportions, different lighting. You can't build a game from that.</p>
|
||||
<p>We spent three months iterating on prompt patterns before we found something that works consistently. The result is a 4-layer system that anchors the model to your art direction and produces images you can actually ship.</p>
|
||||
<h2>Why fal.ai</h2>
|
||||
<p>We evaluated Midjourney, DALL-E 3, Stable Diffusion (self-hosted), and fal.ai:</p>
|
||||
<p><strong>API-first.</strong> Midjourney is Discord-only. DALL-E's API works but the model makes everything look like a stock photo. Self-hosted SD means maintaining GPU infrastructure. fal.ai gives you Flux models behind a simple REST API — POST a prompt, GET an image URL.</p>
|
||||
<p><strong>Cost.</strong> $0.01 per image with <code>flux-2-pro</code>. $0.004 with <code>schnell</code> for rapid iteration. A full character design session — 12 variants across 3 rounds of refinement — costs $0.12. A 20-frame trailer storyboard costs $0.20. At these prices, the bottleneck is creative direction, not budget.</p>
|
||||
<p><strong>Speed.</strong> <code>flux/schnell</code> returns an image in 4 seconds. <code>flux-2-pro</code> in 15 seconds. Fast enough that an AI agent can generate, display, get feedback, and regenerate in a single conversation turn.</p>
|
||||
<p><strong>No subscription.</strong> Pay per image. No monthly fee, no credit packs that expire, no tier-gated features.</p>
|
||||
<h2>The 4-Layer Prompt Pattern</h2>
|
||||
<p>This is the pattern that made AI art actually usable for our game. Each layer adds specificity, and the combination anchors the model to a consistent output.</p>
|
||||
<h3>Layer 1: Design Context</h3>
|
||||
<p>The most important layer and the one most people skip. It sets the overall art direction:</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>This paragraph appears at the start of every prompt. Same paragraph whether you're generating a character, a landscape, or an icon. It anchors the model to your art style.</p>
|
||||
<p><strong>The key insight:</strong> write this once, paste it everywhere. 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</h3>
|
||||
<p>Describe exactly what should appear, element by element:</p>
|
||||
<pre><code>Full body character in T-pose, front view. Young woman, mid-20s.
|
||||
Wearing a woven wrap skirt (mid-thigh length) and a fitted cloth top.
|
||||
Shell necklace with a carved bone pendant. Single bone bracelet on
|
||||
left wrist. Hair swept back over right shoulder. Bare feet.
|
||||
Matte skin, warm brown tones. Neutral confident expression ---
|
||||
not smiling, not angry. Dark grey background.</code></pre>
|
||||
<p>Not "tribal clothing" but "woven wrap skirt." Not "jewelry" but "shell necklace with a carved bone pendant." Vague prompts produce vague results. Specific prompts produce usable assets.</p>
|
||||
<h3>Layer 3: Negative Prompt</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>Extend per-subject. For characters: "no stereotypical elements, no overly shiny materials." The negative prompt is as important as the positive one.</p>
|
||||
<h3>Layer 4: Reference Images</h3>
|
||||
<p>When you need consistency — the same character from different angles, or a new character matching an existing one — pass a reference image:</p>
|
||||
<pre><code class="language-python">result = fal_client.subscribe("fal-ai/flux-2-pro", arguments={
|
||||
"prompt": "Same character, side view, same clothing and accessories...",
|
||||
"image_url": "https://your-approved-front-view.png",
|
||||
"image_size": "square_hd",
|
||||
})</code></pre>
|
||||
<p>The first approved image becomes the reference for all subsequent views. Without it, you get a different person every time.</p>
|
||||
<h2>The Model Lineup</h2>
|
||||
<p>| Model | Cost | Speed | When |</p>
|
||||
<p>|——-|——|——-|——|</p>
|
||||
<p>| <code>flux-2-pro</code> | $0.01 | ~15s | Final art. Default for anything you'll ship. |</p>
|
||||
<p>| <code>flux/schnell</code> | $0.004 | ~4s | Exploration and iteration. |</p>
|
||||
<p>| <code>ideogram/v2</code> | $0.008 | ~5s | Anything with readable text — logos, UI, posters. |</p>
|
||||
<p>| <code>flux-pro/v1.1-ultra</code> | $0.015 | ~8s | Highest quality, but can hang. |</p>
|
||||
<p>The workflow: explore with <code>schnell</code>, refine with <code>flux-2-pro</code>, add text with <code>ideogram/v2</code>.</p>
|
||||
<h2>How This Fits Our Pipeline</h2>
|
||||
<p>fal.ai is the first step in a pipeline from idea to in-game asset:</p>
|
||||
<pre><code>Brief --> fal.ai (2D concept art) --> Tripo Studio (3D model) --> Blender (decimate) --> Godot (in-game)</code></pre>
|
||||
<p>1. <strong>Brief.</strong> The designer describes the character or asset.</p>
|
||||
<p>2. <strong>2D generation.</strong> Generate 3 variants with <code>flux-2-pro</code>, score each on a rubric (style match, cultural accuracy, silhouette, expression, animatability), pick the best.</p>
|
||||
<p>3. <strong>Reference sheet.</strong> Generate front, side, three-quarter, and head closeup views using the winner as reference.</p>
|
||||
<p>4. <strong>3D model.</strong> Approved concept art goes into Tripo Studio for image-to-3D. Outputs ~1.5M faces with full PBR textures.</p>
|
||||
<p>5. <strong>Decimation.</strong> Blender CLI decimates to 25,000 faces.</p>
|
||||
<p>6. <strong>Rigging.</strong> Auto-rig the body (hair separated first if large).</p>
|
||||
<p>7. <strong>In-game.</strong> Import into the engine, set up materials, done.</p>
|
||||
<p>The entire pipeline from "I want a character" to "character walking around in the game" takes about 2 hours. The quality isn't AAA, but for an indie game with a stylised art style, it's more than good enough.</p>
|
||||
<h2>What We Learned</h2>
|
||||
<p><strong>The design context layer is everything.</strong> Without it, every image is a one-off. With it, every image belongs to the same game. The 50-word context block is worth more than the rest of the prompt combined.</p>
|
||||
<p><strong>Negative prompts prevent drift.</strong> 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>
|
||||
<p><strong>Score and iterate, don't accept the first output.</strong> Generate 3 variants, score on 5 criteria, approve only 8+/10. Three attempts at $0.01 each is $0.03 — cheaper than working around a mediocre image.</p>
|
||||
<p><strong>Reference images are the consistency mechanism.</strong> Without them, every generation is independent. With them, 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>
|
||||
<p><strong>Fast models for exploration, quality models for output.</strong> <code>schnell</code> at 4 seconds is for "what if..." iterations. <code>flux-2-pro</code> at 15 seconds is for "yes, this is the one."</p>
|
||||
<p><strong>Let the AI agent handle prompt engineering.</strong> We encode the 4-layer pattern, art style guide, and cultural guardrails in a <a href="../skills/image-generation.md" style="color: var(–c-accent-l);">skill file</a>. The agent writes the full prompt, generates images, displays them, and asks for scores. The human's job is creative direction.</p>
|
||||
<h2>The Numbers</h2>
|
||||
<ul>
|
||||
<li><strong>Characters designed:</strong> 10 (full roster for early access)</li>
|
||||
<li><strong>Total images generated:</strong> ~400 across all iterations</li>
|
||||
<li><strong>Total cost:</strong> ~$6 in fal.ai credits</li>
|
||||
<li><strong>Time per character:</strong> ~30 minutes from brief to approved reference sheet</li>
|
||||
<li><strong>Pipeline time:</strong> ~2 hours from concept art to in-game model</li>
|
||||
<li><strong>Models used:</strong> flux-2-pro (80%), schnell (15%), ideogram/v2 (5%)</li>
|
||||
</ul>
|
||||
<h2>Open-Source Skills</h2>
|
||||
<p>We've published the skill files that power this workflow. A skill is a markdown document that teaches an AI agent a specific procedure — like a runbook, but the reader is an LLM.</p>
|
||||
<ul>
|
||||
<li><strong><a href="../skills/image-generation.md" style="color: var(–c-accent-l);">Image Generation</a></strong> — fal.ai API, 4-layer prompt pattern, model comparison</li>
|
||||
<li><strong><a href="../skills/concept-art-pipeline.md" style="color: var(–c-accent-l);">Concept Art Pipeline</a></strong> — full 2D-to-3D character workflow</li>
|
||||
<li><strong><a href="../skills/tripo-browser-workflow.md" style="color: var(–c-accent-l);">3D Model Generation</a></strong> — Tripo Studio text-to-3D and image-to-3D</li>
|
||||
<li><strong><a href="../skills/sora2-video.md" style="color: var(–c-accent-l);">Video Generation</a></strong> — trailer clip generation with OpenAI Sora 2</li>
|
||||
</ul>
|
||||
<p>Drop any of these into your <code>.cursor/skills/</code> directory and your AI agent can follow them. Adapt the design context block to your game's art style and you're good to go.</p>
|
||||
<hr>
|
||||
<p>AI image generation isn't magic and it isn't free. But at a penny per image, with the right prompt structure, it eliminates the most expensive bottleneck in indie game development: the gap between "I know what this should look like" and "I have an image I can actually use."</p>
|
||||
<p>We're building all of this as part of <a href="https://tinqs.com" style="color: var(–c-accent-l);">Tinqs Studio</a> — a game development platform that brings together git hosting, AI tools, and creative workflows for game teams.</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>
|
||||
|
||||
<!-- FOOTER -->
|
||||
<footer class="footer">
|
||||
<div class="footer__inner">
|
||||
<span class="footer__wordmark">TINQS</span>
|
||||
<div class="footer__links">
|
||||
<a href="/#game">Games</a>
|
||||
<a href="/#tech">Technology</a>
|
||||
<a href="/#about">About</a>
|
||||
<a href="/blog/">Blog</a>
|
||||
<a href="mailto:hello@tinqs.com">hello@tinqs.com</a>
|
||||
<a href="/press">Press Kit</a>
|
||||
</div>
|
||||
<p class="footer__copy">Tinqs Limited — London, est. 2020</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
const burger = document.getElementById('navBurger');
|
||||
const mobileMenu = document.getElementById('mobileMenu');
|
||||
burger.addEventListener('click', () => {
|
||||
const open = mobileMenu.classList.toggle('mobile-menu--open');
|
||||
burger.classList.toggle('nav__burger--open', open);
|
||||
document.body.style.overflow = open ? 'hidden' : '';
|
||||
});
|
||||
mobileMenu.querySelectorAll('a').forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
mobileMenu.classList.remove('mobile-menu--open');
|
||||
burger.classList.remove('nav__burger--open');
|
||||
document.body.style.overflow = '';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
After
|
Reference in New Issue
Block a user