Monday, 27 July 2026

How to Use ElevenLabs for Game Development: AI Voice Acting, NPC Dialogue, and Sound Design

Most indie games ship without voice acting. Not because developers do not want it, but because hiring voice actors is expensive, scheduling them is slow, and revising recorded lines after the script changes means paying them again. So the game gets subtitles and silence, and it is a little bit flatter for it.

ElevenLabs has made this calculation genuinely worth revisiting. The voice quality is not "pretty good for AI." On certain voice types and delivery styles it is difficult to distinguish from a recorded human performance without a direct A/B comparison. It is not perfect across the board, but it is good enough that the question "should I voice my game?" now has a different answer for solo developers than it did two years ago.

This guide covers what ElevenLabs can and cannot do for game development specifically, how the credit and pricing system actually works, how to set up a voice cloning workflow for consistent character voices, and how to get the audio into Unity.



What ElevenLabs Does

ElevenLabs converts text to speech using AI models trained on large amounts of human voice recordings. You type a line of dialogue, pick a voice, and get an audio file back. The voices have natural variation in pacing, emphasis, and emotional tone — not the flat robotic cadence of older TTS systems.

There are three main ways to get voices:

  • Pre-made voices — a library of built-in voice options across different accents, ages, and tones. No setup required.
  • Voice Design — generate a synthetic voice with specific characteristics (age, accent, tone, gender) without providing any recording. Good for creating unique character voices that do not sound like a specific real person.
  • Voice Cloning — upload recordings of a real voice (your own, a voice actor's with permission, or a custom character recording) and generate new lines in that voice.

For game development, Voice Design and Voice Cloning are where the practical value lives. The pre-made voices are fine for narrators and generic NPCs, but any character who appears repeatedly needs a consistent, distinctive voice — which means either picking one pre-made voice and sticking to it, or cloning a voice specifically for that character.



Pricing and the Credit System

ElevenLabs bills based on credits. Credits are consumed by every generation, with different models and quality settings costing different amounts per character of text. The relationship between credits and usable audio time is not straightforward, and the pricing page is not the most transparent thing to read.

Here is what the relevant tiers actually get a solo game developer, as of mid-2026:

Plan Monthly Price Credits Approx. Audio Commercial Rights Voice Cloning
Free $0 10,000/month ~10 min (Multilingual) or ~20 min (Flash) No — attribution required No
Starter $5/month 30,000/month ~30 min (Multilingual) or ~60 min (Flash) Yes Instant cloning only
Creator $22/month 100,000/month ~100 min (Multilingual) Yes Professional cloning
Pro $99/month 500,000/month ~500 min Yes Professional cloning

Two things about this table worth flagging before you make any decisions.

First: the free plan has no commercial usage rights. Content created on the free plan requires ElevenLabs attribution and cannot be used in a monetized product, client work, or anything revenue-adjacent. For a game you plan to sell or distribute through any store, you need at minimum Starter at $5/month. This trips up a lot of people who test the free tier, like the results, and then discover the fine print when they try to ship.

Second: instant voice cloning versus professional voice cloning is a meaningful quality difference. Instant cloning works from a minute or two of audio and is available on Starter. Professional cloning requires more training data and is available from Creator upward — it produces more stable, natural results across long dialogue sessions. For a main character who speaks hundreds of lines, professional cloning is worth the upgrade. For a minor NPC with a dozen lines, instant cloning is probably fine.

Annual billing saves roughly 17% across all tiers. Always verify current pricing at elevenlabs.io before subscribing — plans and credit allocations change frequently and the pricing page is the authoritative source.



Part 1: Setting Up a Character Voice

The fastest way to get started is using one of the pre-made voices from the Voice Library. Go to the Voices section, browse by category (narrator, villain, young adult, and so on), preview them, and save the ones that feel right for your character types. Each saved voice appears in your generation panel.

For characters who need a distinctive, custom voice, Voice Design is the better option.

Voice Design Workflow

  1. Go to Voices > Voice Design in the ElevenLabs interface.
  2. Describe the voice in the text prompt: "A gruff middle-aged man, slightly raspy, slight Eastern European accent, sounds like he has seen too much war." ElevenLabs generates multiple voice variants matching that description.
  3. Preview each variant with a sample line. Generate more variants until one fits.
  4. Save the voice to your voice library. It now appears in every generation panel as a selectable option.

Voice Design voices are synthetic — they are not trained on or derived from any specific real person's recordings. They are consistent across generations, unlike a cloned voice that can sometimes drift slightly on unusual phoneme combinations.

Instant Voice Cloning (Starter and Above)

If you want to record your own voice and use it as a character voice, or if you have hired a voice actor for a short session and want to generate additional lines without rebooking:

  1. Go to Voices > Add a New Voice > Instant Voice Clone.
  2. Upload 1-3 minutes of clean audio with minimal background noise. A phone recording works; a recording with music underneath does not.
  3. Name the voice and save it.
  4. Generate new lines in that voice.

For instant cloning, one to three minutes of clean mono audio at 22 kHz or higher produces a usable clone. The voice holds up for short lines but can sound slightly off on very long sentences or unusual phrases. Test across a range of your actual dialogue before committing to it for a main character.

Part 2: Generating Dialogue

Go to Text to Speech in the navigation. Select your character voice, paste a dialogue line, and generate. The output is a .mp3 or .wav file you can download immediately.

Settings That Change the Output

Setting What It Does Game Dev Starting Point
Model Eleven Multilingual v2 for best quality; Flash v2.5 for faster/cheaper generation at slightly lower quality. Use Multilingual for final lines, Flash for draft review.
Stability Higher stability = more consistent but flatter delivery. Lower = more expressive but can drift between generations. 0.4-0.6 for most NPC dialogue. Lower for emotional scenes.
Similarity Boost For cloned voices, how closely the output matches the original recording. Higher values can cause artifacts. 0.7-0.8. Above 0.9 often sounds unnatural.
Style Exaggeration Emphasizes the speaking style in the voice. Can add character but also amplify oddities. 0-0.3 for normal dialogue. Higher for stylized characters.

The Speaker Boost checkbox is worth enabling for any voice that sounds slightly muddy on playback — it adds a processing pass that clarifies the audio. It costs slightly more credits per generation.

Directing Delivery Through Text

ElevenLabs does not have a separate emotion selector for most models. You direct the emotional delivery through the text itself — punctuation, pacing cues, and in some cases explicit stage direction in brackets.

These techniques actually work:

  • Ellipsis for hesitation: "I... I don't know what to say."
  • Capitalization for stress: "I told you NOT to open that door."
  • Dashes for interrupted speech: "Wait, before you go — listen to me."
  • Brackets for tone direction (Eleven v3): "[whispering] They're still out there."

The bracket-based direction is a v3 feature and not available on all models. Test which techniques work on your specific voice and model combination rather than assuming all of them apply.

Part 3: Getting Audio Into Unity

Unity supports .mp3 and .wav imports directly. The workflow is simple but there are a few things that will save you time at scale.

Basic Import

  1. Download generated audio as .wav (higher quality, larger file) or .mp3 (smaller, fine for most dialogue).
  2. Drag into a designated folder in your Unity Project window — something like Assets/Audio/Dialogue/CharacterName/.
  3. Select the imported clip and check the Inspector settings: set Compression Format to Vorbis for dialogue (better compression than PCM), set Load Type to Streaming for long files or Decompress on Load for short lines.
  4. Assign to an AudioSource component in your NPC's script, or reference it in your dialogue system's audio playback logic.

Managing a Large Dialogue Library

A game with dozens of NPCs and hundreds of dialogue lines generates a lot of audio files. A naming convention from the start prevents the folder from becoming unmanageable:

NPC_Guard_Line001_Idle.wav
NPC_Guard_Line002_Alert.wav
NPC_Merchant_Line001_Greeting.wav

If your dialogue system uses a ScriptableObject-based structure (covered in the ScriptableObjects guide from this series), you can store AudioClip references directly in the dialogue data assets alongside the text. This keeps dialogue text and audio tied together in the same place rather than scattered across separate folders that drift out of sync as the script changes.

What Works Well and What Does Not

ElevenLabs is genuinely impressive for certain voice types and delivery styles. Calm narration, conversational NPC chatter, villain monologues with measured delivery, elderly characters with gravelly voices — these tend to come out well without much tweaking.

It struggles with:

  • Shouting and extreme emotion. Screaming, rage, and intense fear often come out sounding strained or artificial. These are the lines worth recording with a real voice actor if any lines in your game are.
  • Non-English phonemes in otherwise English text. A character name like "Xrathul" or a place name like "Aelionthar" will be mispronounced in ways that vary between generations. Test proper noun pronunciation early.
  • Very long lines without natural pause points. Lines over 200-300 characters sometimes have pacing issues. Break long dialogue into multiple shorter generations and edit them together in an audio editor if needed.
  • Singing. ElevenLabs has a music feature but it is not designed for character singing in the way game vocals usually work. For anything sung, a real recording remains the practical option.

The Sound Effects Generator is worth knowing about but is not a replacement for a proper game audio library. It generates short sound effects from text prompts — "heavy wooden door creaking open," "distant thunderstorm," "coins dropping on stone floor." The results are inconsistent. Sometimes usable, sometimes clearly artificial. Worth testing on any specific sound you need and cannot source elsewhere, but not something to build a full audio pipeline around.



ElevenLabs vs Alternatives

Tool Strengths Weaknesses Price
ElevenLabs Best overall voice quality in 2026, voice cloning, large voice library, good emotional range on supported delivery styles. No commercial rights on free tier, credit system is confusing, struggles with extreme vocal delivery. Free; $5/month (Starter); $22/month (Creator)
Murf AI Clean interface, good for narration and corporate-style voices, integrated editing tools. Lower emotional range than ElevenLabs, less convincing for character acting versus narration. Free tier; paid from $19/month
Play.ht Wide voice selection, API-friendly for automation, good multilingual support. Quality ceiling slightly below ElevenLabs on character voices. Free tier; paid from $31/month
Real voice actors Authentic delivery, natural extreme emotion, human direction, fully licensable. Cost, scheduling, revision cycles, not scalable for large NPC casts on indie budgets. $100-500+ per hour session

The honest comparison to real voice actors is worth thinking through rather than dismissing. For a protagonist with 500+ lines across 20 hours of gameplay, ElevenLabs is not going to produce the same emotional performance a professional actor would. For 50 lines of ambient dialogue across 30 different minor NPCs, it absolutely is the practical choice.

Common Problems

The voice sounds right sometimes but inconsistent across multiple generations of the same line.

Stability is too low. Raise the Stability slider toward 0.6-0.7. If consistency still varies, the voice itself may be inherently unstable on this model — try a different model (Multilingual v2 tends to be more consistent than Flash for character work) or regenerate and use the most consistent take.

Proper nouns and character names are being mispronounced.

Spell them phonetically in the text input. "Xrathul" becomes "Zrathool" or "Zr-ath-ul" depending on which phonetic spelling produces the correct sound on your specific voice. Test phonetic spelling early in production — going back through hundreds of lines to fix a name pronunciation is slow.

The audio has a slight robotic or unnatural quality at certain points.

Speaker Boost is the first thing to try — it adds clarity and reduces the uncanny valley quality on some voices. Also check whether the model is set to Flash (faster, lower quality) rather than Multilingual v2. For voice clones specifically, lowering Similarity Boost from above 0.85 to around 0.75 often improves naturalness.

Free tier audio cannot be used in the game.

This is not a technical problem, it is a terms of service issue. The free tier has no commercial usage rights. Upgrade to at least Starter ($5/month) before generating any audio you intend to include in a distributed or monetized game.



A Practical Dialogue Pipeline for Solo Developers

This is the workflow that makes ElevenLabs actually manageable when you have more than a handful of lines to generate.

  1. Finalize the script first. Generate audio for lines that are locked. Generating audio for dialogue that later changes costs credits twice and creates file management headaches.
  2. Create one voice per major character. Either a pre-made voice you have tested across a range of line types, a Voice Design voice you have generated and saved, or a cloned voice. Stick to it throughout production.
  3. Generate in batches by character. Generate all lines for one character in one session while the settings and voice are loaded. Switching between characters mid-session wastes time on setup and makes it harder to catch inconsistencies.
  4. Name files consistently from the start using the convention described above. No renaming later.
  5. Keep a generation log. A simple spreadsheet with line ID, text, voice used, generation date, and Unity file path. When the script changes and you need to regenerate specific lines, you can find exactly which file needs replacing without listening through everything.

What to Do With It Now

Create a free account at elevenlabs.io — no credit card required. Generate ten lines using the pre-made voice library to get a feel for quality before worrying about custom voices or cloning. Try the same line with different Stability settings to see how much that single slider changes the output. Then try Voice Design with a specific character concept from your current project.

If the quality is good enough for your game's dialogue needs, upgrade to Starter before generating anything you plan to actually ship. Five dollars a month for commercial rights and thirty minutes of high-quality dialogue audio per month is genuinely good value for an indie developer.

Next Topics To Learn

Friday, 24 July 2026

How to Build Unity Games for iOS: Xcode Setup, Player Settings, and App Store Submission

iOS builds are more complicated than Android builds. Not dramatically more, but there is one constraint that catches every Windows developer off guard: Xcode is only available on macOS, so if your development machine does not run macOS, you cannot build an iOS application locally. You need either a Mac or Unity Build Automation, which handles the Xcode step in the cloud.

That aside, the Unity side of the setup is straightforward. The hard parts are almost always Apple-specific — provisioning profiles, signing certificates, bundle identifiers that have to match exactly across three different places, and Xcode's occasional tendency to refuse to trust a connected device for no obvious reason. None of those are Unity problems. They are Apple problems.

This guide covers the full pipeline: installing iOS Build Support, configuring Player Settings correctly, running on a physical device for testing, signing for the App Store, and fixing the errors that show up on every first iOS build. It pairs directly with the Android Build guide from this series — same structure, iOS-specific details throughout.



What You Need Before Starting

  • A Mac running macOS. Xcode only runs on Mac. An M1/M2/M3/M4 Mac Mini is the cheapest viable option if you are buying specifically for iOS development — they run Xcode without any issues and are significantly faster than older Intel Macs for IL2CPP builds.
  • Xcode 15 or later. Unity recommends Xcode 15 or later for iOS development. Apps submitted to the App Store must be built with Xcode 16.0 or later and the iOS 18 SDK. Install Xcode from the Mac App Store — it is free but large (around 15GB).
  • iOS Build Support module installed through Unity Hub.
  • An Apple ID for local device testing (free). An Apple Developer Program membership ($99/year) for App Store distribution.
  • A physical iPhone or iPad for testing. The iOS Simulator in Xcode runs on your Mac but does not test actual GPU performance, touch input, or device-specific behavior accurately enough to replace real hardware.

If you are on Windows and cannot access a Mac, Unity Build Automation can build iOS applications for you in the cloud. You still need to register for an Apple Developer account, generate certificates and provisioning profiles through the Apple Developer portal, and upload your credentials to Unity Build Automation. That workflow is worth knowing about but is more advanced than a local build — for a first iOS build, a Mac is the significantly simpler path.


 

Part 1: Installing iOS Build Support

  1. Open Unity Hub.
  2. Go to the Installs tab.
  3. Click the gear icon next to your Unity version and select Add Modules.
  4. Check iOS Build Support.
  5. Click Install and wait for the download.

Unlike Android, iOS Build Support has no sub-modules to check — there is no separate SDK or NDK to worry about. Apple's toolchain lives entirely in Xcode. The Unity module just adds the ability to generate an Xcode project from your Unity project. Xcode then handles the actual compilation.

After installation, confirm it worked by opening Unity and going to File > Build Settings. iOS should now appear in the platform list. If it is missing or shows "Install with Unity Hub," the module did not install correctly — go back to Hub and try again.

Part 2: Switching Platform to iOS

  1. In Unity, go to File > Build Settings.
  2. Select iOS from the platform list.
  3. Click Switch Platform.

This reimports your assets for iOS — same process as Android, same warning about it taking a while on larger projects. After the switch, the iOS icon appears next to scene files in the Project window confirming the active platform changed.

Part 3: Player Settings That Matter

Open through Edit > Project Settings > Player, then select the iOS icon tab.

Bundle Identifier

This is the most important iOS-specific setting and the one that causes the most pain when it is wrong. The bundle identifier is the unique ID for your app across Apple's entire ecosystem — it must match exactly between Unity, Xcode, and the Apple Developer portal. If any of the three disagree, the build fails or the app cannot be signed.

Format: com.yourcompany.gamename — same reverse domain notation as Android's package name, same rules: lowercase, no spaces, globally unique for App Store distribution.

Set this before doing anything else. Changing it mid-project is possible but requires updating it in multiple places simultaneously, which is how mismatches happen.

Signing Team

This is your Apple Developer Team ID. You can leave it blank for local device testing with a free Apple ID, but it must be set for any App Store build. It appears as a dropdown once you have signed into Xcode with your Apple ID — set it in Unity Player Settings to match what Xcode will use, or let Xcode manage it automatically by checking "Automatically manage signing" in the Xcode project settings.

Target iOS Version

The minimum iOS version your app supports. Setting it lower means more devices can install it; higher lets you use newer iOS features. For most games in 2026, iOS 15 or 16 as the minimum covers the vast majority of active iPhones while still giving access to modern APIs. Check Apple's App Store analytics for current device distribution if you want data to back the decision.

Architecture

Set to ARM64. All iPhones and iPads from 2017 onward use 64-bit ARM processors. There is no reason to support ARMv7 for new projects — Apple dropped 32-bit app support in iOS 11. ARM64 only.

Scripting Backend

IL2CPP is the only option for iOS — Mono is not supported on iOS due to Apple's restrictions on just-in-time compilation. This is already the default. You cannot accidentally use Mono on iOS; Unity will not let you.



Part 4: Generating the Xcode Project

Unity does not compile your game directly into an iOS app. Instead, it generates an Xcode project, and then Xcode builds that project into the final application. This two-step process is important to understand because it means you will sometimes need to make changes in Xcode rather than in Unity.

  1. In Build Settings, click Build (not Build and Run — we will get to that).
  2. Choose an output folder. Create a new folder called something like "iOSBuild" outside your Unity project folder.
  3. Unity generates the Xcode project files in that folder. It does not install anything to a device yet.
  4. Navigate to that folder in Finder and open the .xcodeproj file. Xcode opens the generated project.

If you use Build and Run instead of Build, Unity generates the project AND tells Xcode to compile and install it to a connected device in one step. Build and Run is faster once everything is set up correctly. Use Build first until you have confirmed the Xcode project generates without errors.

The Replace vs Append Dialog

Every subsequent build to the same output folder shows a dialog asking whether to Replace or Append the existing Xcode project.

  • Replace — completely overwrites the Xcode project. Use this during normal development. Any manual changes you made to the Xcode project are lost.
  • Append — merges Unity's new output into the existing Xcode project, preserving manual changes you added. Use this if you have edited the Xcode project directly to add frameworks or capabilities that Unity does not handle automatically.

Most beginners should always choose Replace until they have a specific reason to edit the Xcode project directly.

Part 5: Testing on a Physical Device

With a Free Apple ID (No Developer Program)

  1. Open the generated .xcodeproj in Xcode.
  2. Connect your iPhone or iPad via USB.
  3. In Xcode, go to Signing & Capabilities and sign in with your Apple ID if prompted.
  4. With a free Apple ID, Xcode creates a personal team that allows you to install apps on up to 3 devices with a 7-day certificate validity. The app will stop working after 7 days and needs to be reinstalled.
  5. Select your connected device from the device dropdown at the top of Xcode.
  6. Press the Play button (or Cmd+R) to build and install.
  7. The first time, your iPhone will show a prompt about trusting the developer — go to Settings > General > VPN & Device Management and trust your Apple ID there.

The 7-day limit is annoying during active development but works fine for quick tests. The Apple Developer Program ($99/year) removes the limit and enables App Store distribution.

With an Apple Developer Program Account

Log into your Apple Developer account at developer.apple.com, register your device's UDID, and create a Development provisioning profile for your bundle identifier. In Xcode, under Signing & Capabilities, either let Xcode manage signing automatically (simplest) or manually select the provisioning profile you created. The certificate validity extends to one year rather than seven days.



Part 6: App Store Submission

Getting to the App Store requires a few steps beyond just building correctly.

Archive the Build in Xcode

  1. In Xcode, set the target device to Any iOS Device (arm64) — not a specific connected device.
  2. Go to Product > Archive.
  3. Xcode builds the app and adds it to the Archives list in the Organizer window.

Upload to App Store Connect

  1. In the Xcode Organizer, select the archive and click Distribute App.
  2. Choose App Store Connect and follow the wizard.
  3. Xcode validates and uploads the build to App Store Connect.

TestFlight First

Before submitting for App Store review, test through TestFlight. Any build uploaded to App Store Connect is automatically available for TestFlight testing with external testers. Testing with real users on TestFlight before App Store submission catches device-specific bugs that neither the Unity editor nor Xcode's simulator will surface.

App Store review typically takes 24 to 48 hours for a new app with no prior rejections. Apple reviews both the app's functionality and its metadata — screenshots, description, and privacy disclosures. Rejections almost always come with an explanation and are fixable.

Common Errors and How to Fix Them

Error: "No profiles for [bundle identifier] were found"

Cause: The bundle identifier in Unity Player Settings does not match what is registered in the Apple Developer portal, or no provisioning profile exists for this identifier.

Fix: Confirm the bundle identifier matches exactly — including case — across Unity, Xcode, and the Apple Developer portal. If using automatic signing, let Xcode create the profile. If using manual signing, create the profile at developer.apple.com and download it.

Error: "IL2CPP C++ code builder is unable to build C++ code. In order to build C++ code for Mac, you must have Xcode installed."

Cause: Xcode is installed but its Command Line Tools are not configured, or Xcode is installed in a non-standard location.

Fix: Open Terminal and run sudo xcode-select --switch /Applications/Xcode.app to point the system to the correct Xcode location. Also open Xcode once and accept the license agreement — it is required before any command-line tools work.

Error: Build succeeds but app crashes immediately on device.

Cause: A script or plugin has a runtime error that does not surface in the editor, or a missing capability (like Push Notifications or Camera access) causes an immediate termination.

Fix: Connect the device to Xcode, go to Window > Devices and Simulators, select your device, and open the device log while reproducing the crash. The actual exception appears there. For missing capabilities, add them under Signing & Capabilities in the Xcode project.

Error: "Untrusted Developer" when opening the app on device.

Cause: The signing certificate is from a free Apple ID and has not been trusted on this device yet.

Fix: On the iPhone, go to Settings > General > VPN & Device Management, find your Apple ID under Developer App, and tap Trust.

Error: App Store submission rejected for privacy reasons.

Cause: The app uses a system API (camera, microphone, location, contacts) without including the corresponding privacy usage description string in Player Settings, or without declaring data collection in App Store Connect's privacy nutrition label.

Fix: In Unity Player Settings > Other Settings, fill in every usage description string for APIs your app uses. In App Store Connect, complete the App Privacy section accurately before submission. Apple's rejections here are specific — they tell you exactly which API triggered the issue.



iOS vs Android Build: Key Differences

Area iOS Android
Build machine requirement Mac required for local builds Windows, Mac, or Linux
Build output Xcode project, then .ipa via Xcode APK or AAB directly from Unity
Scripting backend IL2CPP only — Mono not supported Mono for dev, IL2CPP for release
Signing for device testing Free Apple ID, 7-day certificate Debug keystore auto-generated, no expiry
Store distribution fee $99/year Apple Developer Program $25 one-time Google Play fee
Review process Manual review, 24-48 hours typical Largely automated, hours to days
Primary graphics API Metal (Apple's API, only option) Vulkan or OpenGL ES

Best Practices

  • Set the bundle identifier before your first build. Changing it later means updating it in Unity, Xcode, and the Apple Developer portal simultaneously — missing any one causes signing failures.
  • Use automatic signing in Xcode during development. Switch to manual signing only when you need specific provisioning profiles for distribution.
  • Test on at least two physical devices before App Store submission — an older model and a current one. Performance that looks fine on an iPhone 15 can be unacceptable on an iPhone XR that your players still use.
  • Archive builds in Xcode using the Any iOS Device (arm64) target, not a connected device. Archiving to a specific device creates a build that cannot be distributed.
  • Use TestFlight for beta testing before App Store submission. It finds real-device bugs that nothing else catches.
  • Fill in all privacy usage description strings in Player Settings before building. Missing them causes App Store rejection, and adding them requires a full rebuild and resubmission.
  • Keep your Apple Developer certificates backed up. Certificate expiration mid-submission cycle is a preventable headache.

What Comes Next

Getting the build pipeline working is the foundation. Once you have a device build running, the next iOS-specific considerations are performance profiling using Xcode's Instruments tool (far more detailed than Unity's Profiler for GPU-side issues on Metal), implementing iOS-specific features like Game Center achievements and leaderboards through Unity's Services, and setting up automatic builds using Unity Build Automation or a CI system like GitHub Actions so you are not manually triggering Xcode builds every time you need a test build.

The Mobile Optimization guide from this series covers the Unity-side performance work. The GitHub Actions guide teased at the end of the Git tutorial covers the automation side. Both are worth reading once this build pipeline is stable.

Next Topics To Learn

Wednesday, 22 July 2026

How to Use Leonardo AI for Game Development: Free Concept Art, 3D Textures, and Custom Models

Every AI image guide in this series has mentioned Leonardo AI as the free alternative to try before paying for Midjourney. That framing undersells it. Leonardo AI is not a consolation prize — it has features that Midjourney and DALL-E do not have at any price, and a free tier generous enough for serious visual development work.

The features that make it specifically interesting for game developers: 3D texture generation that creates albedo, normal, and roughness maps directly from text prompts, custom model training on your own reference images, and a token-based free tier that resets daily rather than expiring at the end of a month. None of those exist in Midjourney. Stable Diffusion can do all of it but requires significant technical setup. Leonardo does it through a web interface with no installation.

One thing worth knowing upfront: Leonardo AI was acquired by Canva in 2025. The product has continued developing under Canva's ownership and the feature set has expanded, but it is worth keeping in mind when evaluating long-term platform stability. The pricing and feature set described in this guide reflect the current state as of mid-2026.



Pricing: What the Free Tier Actually Gets You

Most AI tool pricing sections bury the free tier in caveats. Leonardo's free tier is different enough that it deserves an honest upfront assessment.

The free plan gives you 150 tokens per day, which resets every 24 hours. A standard image generation using the Leonardo Diffusion XL model costs 4-6 tokens, which means roughly 25-37 images per day. That is a meaningful daily allowance — enough for active concept art exploration during visual development, not just enough to click around and evaluate the interface.

The catch on the free tier: free generations are public, meaning anyone browsing Leonardo's community feed can see what you generate. If your game's visual direction is confidential, you need a paid plan for private generations.

Plan Monthly Price Annual Price Tokens/Month Private Images Custom Model Training
Free $0 $0 150/day (~4,500/month) No — all public No
Apprentice $12 $10/month ($120/year) 8,500 Yes 1 LoRA slot/month
Artisan $30 $24/month ($288/year) 25,000 Yes 20 personal model slots
Maestro $60 $48/month ($576/year) 60,000 Yes 50 personal model slots

When fast tokens run out, Artisan and Maestro subscribers can switch to relax mode, which uses basic models at no token cost but joins a lower-priority queue. Relax mode is not available on Apprentice or Free plans.

The honest recommendation for a solo developer: start on the free tier for at least a week before paying anything. If 150 tokens per day is enough for your workflow and you do not need private images, the free tier is genuinely sustainable long-term. Apprentice at $12/month is one of the cheapest premium AI image generators available when you do upgrade — significantly cheaper than Midjourney Standard at $30.


The Models Worth Knowing

Leonardo AI has its own proprietary models alongside access to third-party community models. The ones that matter most for game development:

Model What It Produces Game Dev Use Case
Phoenix Leonardo's current flagship model. Produces highly detailed, coherent images with strong prompt adherence. Character concepts, environment art, promotional material. The default starting point for most generations.
Leonardo Diffusion XL SDXL-based model with Leonardo's refinements. Faster and cheaper than Phoenix. High-volume concept exploration where speed and token cost matter more than maximum quality.
PhotoReal v2 Hyper-realistic photography-style output. Realistic environment references, character face references for later LoRA training.
Anime / Illustration models Several community fine-tuned models for anime and stylized illustration styles. 2D game art, mobile game UI character art, visual novel assets.

Alchemy and Prompt Magic v2/v3 are not models but processing pipelines that run on top of any model. Alchemy unlocks higher quality output and the Alchemy Refiner at no additional per-use charges on Apprentice and above. They cost more tokens per generation but produce meaningfully better results on character faces and fine detail. Worth enabling for final concept iterations, not for broad style exploration where you are generating dozens of variations.

Part 1: Concept Art Workflow

The basic text-to-image workflow is similar to Midjourney: open a generation canvas, enter a prompt, pick a model, generate. The interface is more button-heavy than Midjourney's clean chat-style interface, but everything is visible and labeled rather than hidden behind command syntax.

A few Leonardo-specific settings that change the result meaningfully:

Guidance Scale

This is equivalent to CFG Scale in Stable Diffusion — how strictly the model follows the text prompt. Higher values (12-20) produce images that literally match the prompt but can look stiff or over-saturated. Lower values (6-9) give the model more creative latitude and often produce more interesting images for concept exploration. Start around 7-10 and adjust based on whether your prompt's details are being followed correctly.

Image2Image

Upload a reference image and generate variations from it. This is the feature that closes the gap between "generate random concepts" and "iterate toward a specific design." Draw a rough sketch in any drawing app, upload it, and use Image2Image to generate polished versions while keeping the general composition and proportions. Works with any model.

I spent a full day trying to get Midjourney to produce a specific character silhouette through prompt iteration and never quite got there. Took the rough sketch into Leonardo's Image2Image, ran it through Phoenix with the right denoising strength, and had the silhouette I wanted in three generations. Different category of precision.

Negative Prompts

Available directly in the interface unlike Midjourney where negative prompting (--no) is less reliable. Standard negative prompt for game concept art: blurry, deformed, extra limbs, bad anatomy, watermark, text, signature, low quality, oversaturated.


 

Part 2: 3D Texture Generation

This is the feature that separates Leonardo AI from every other tool covered in this AI Tools series. Leonardo includes a specialized 3D texture generation tool that creates albedo, normal, and roughness maps directly from text prompts — essential maps for PBR materials in Unity and Unreal.

Finding it: in the left sidebar of Leonardo's interface, look for 3D Texture Generation under the Tools section.

How It Works

  1. Enter a texture description: "rough mossy stone wall, medieval, aged" or "worn wooden planks, grey paint peeling, weathered."
  2. Choose a resolution (512x512 for draft testing, 1024x1024 for usable assets).
  3. Generate. Leonardo produces a set of maps: albedo (base color), normal map (surface detail), and roughness map (reflectivity variation).
  4. Download the map pack as individual files.
  5. In Unity, create a material using Standard (Built-In) or URP Lit shader, assign the albedo to Albedo/Base Color, the normal map to Normal Map, and the roughness map to Smoothness/Roughness.

The results are not perfect. Complex organic surfaces like human skin or fur do not generate well. Very regular geometric patterns like brick or tile come out better from procedural texture tools. Where Leonardo's texture generation shines is worn, irregular surfaces — stone, wood, rust, fabric, aged paint — exactly the kind of surfaces that populate most game environments.

For the crate from the Blender guides in this series: a "rough weathered wooden planks with metal corner reinforcements" prompt produces a usable texture pack in minutes without needing Substance Painter or any dedicated texture tool.



Part 3: Custom Model Training (LoRA)

This is Leonardo's most powerful feature for maintaining visual consistency across a game project — training a custom model on your own reference images so every generation automatically inherits that visual style without prompt engineering.

Available on Apprentice and above (one training slot per month on Apprentice, 20 slots on Artisan).

Training a Character LoRA

  1. Collect 10-20 high-quality reference images of the same character or style from consistent angles, in good lighting, with no busy backgrounds.
  2. In Leonardo, go to Training & Datasets in the left sidebar.
  3. Create a new dataset and upload your reference images.
  4. Click Train Model, name it, select the base model (Phoenix or Leonardo Diffusion XL), and set the training resolution to match your reference images.
  5. Start training. It runs on Leonardo's servers — typically 20-40 minutes depending on image count and resolution.
  6. Once complete, the model appears in your model selector and can be used in any generation.

With a trained LoRA, prompting "CHARACTER NAME in a combat stance, fantasy armor, dramatic lighting" produces consistent character identity across multiple generations in a way that neither Midjourney nor basic Stable Diffusion can match without the same training step.

The main limitation: 10-20 training images is not much data. The more consistent and diverse your reference set (different poses, same character), the better the model learns the character rather than overfitting to a specific pose or composition from the training set.

Leonardo AI vs Midjourney: Where Each Wins

Category Leonardo AI Midjourney
Free tier 150 tokens/day, genuinely useful No free tier in 2026
Starting paid price $12/month (Apprentice) $10/month (Basic, ~200 images total)
Image quality ceiling High, especially with Alchemy and Phoenix Higher for pure artistic illustration work
3D texture generation Yes — albedo, normal, roughness maps No
Custom model training Yes — LoRA training on paid plans No
Image2Image Yes — strong and accessible Limited through --cref and variation tools
Privacy on free tier No — all public N/A — no free tier
Best for Developers who need game-specific features, a free tier, or custom style training Developers who prioritize pure image quality and have no interest in technical features



What Does Not Work Well

The token system is confusing until you understand it, and even then it can be frustrating. Premium features like Alchemy and high-resolution generation consume significantly more tokens than standard generations. A free tier user who enables every premium setting will burn through 150 daily tokens in five or six images. Understanding token cost before enabling features saves a lot of disappointment.

The interface has more options than Midjourney and is less intuitive for a complete beginner. The model selector, Alchemy toggle, Prompt Magic settings, and Image2Image controls all exist in different parts of the interface and the relationship between them is not immediately obvious. Plan on spending an hour exploring the interface before expecting professional results.

Community models from third-party creators vary enormously in quality. The platform curates a featured selection but the broader library includes models that produce inconsistent or low-quality results. Stick to Leonardo's own models (Phoenix, Diffusion XL, PhotoReal) and community models with high ratings and large generation counts until you know what you are looking for.

Video generation is available but generating a 5-second clip using the best video model costs 2,500 tokens — on the Artisan plan at $30/month that is roughly $3 per clip in token value. Dedicated video tools like Runway are more cost-effective if video is your primary output.

Practical Workflow: Combining With Blender and Unity

The natural pipeline for a solo Unity developer using Leonardo:

  1. Generate character and environment concept art using Phoenix or Diffusion XL with Alchemy enabled, using Image2Image on rough sketches from the Blender modeling workflow.
  2. Use 3D Texture Generation for surface materials on models built in the Blender guides — stone, wood, metal, fabric.
  3. Download the map pack, import into Unity as textures, and assign to materials using the Unity PBR material system.
  4. If a character design is established, train a LoRA on the approved concept art so all subsequent character generation inherits that design without prompt repetition.

This pipeline keeps Midjourney's use case for pure artistic illustration while using Leonardo for the technical, game-specific work it does better. Using both tools for what each does best is more effective than picking one and forcing it to cover everything.

Getting Started: The First Session

Create an account at leonardo.ai — no credit card required. The interface asks you to select your use case on first login. Choose Game Development or Concept Art for the most relevant model recommendations on the home screen.

Start with the free tier for at least a week before evaluating paid plans. Generate at least fifty images across different models and settings before forming an opinion about quality. The first ten generations from any new AI tool are not representative of what it produces once you understand its quirks.

The 3D texture generation tool and Image2Image are worth finding on day one — they are the features that most directly differentiate Leonardo from the other tools in this series and are the clearest demonstration of why it is worth trying separately from Midjourney.

Common Issues and Fixes

Token counter shows zero but the day has not ended.

Premium features like Alchemy, high resolution, and multiple samples consume tokens faster than standard settings. Check your current token balance in the top navigation bar. Tokens reset at the same time each day, not at midnight in your local timezone — the reset time is shown in the account panel.

Generated images look low quality or blurry compared to examples.

Alchemy is likely disabled. Enable it in the generation settings (it shows as a toggle above the generate button) and confirm you are using a current model like Phoenix rather than an older community model. Quality also scales with resolution — generating at 512x512 with premium settings still produces lower quality than 1024x1024 at standard settings.

Custom model training fails or produces images that look nothing like the reference.

Reference image quality and consistency are the main factors. Images with varied backgrounds, different characters in the same set, or inconsistent lighting confuse the training process. Re-prepare the dataset with cleaner, more consistent references and retrain. Also confirm the training resolution matches the resolution of your reference images.

3D texture outputs look tileable but show visible seams when applied in Unity.

Enable Make Seamless in the texture generation settings before generating. For textures that are already generated, Unity's texture import settings include a Wrap Mode setting — ensure it is set to Repeat rather than Clamp, and enable the seamless tiling option in the texture importer.



Next Topics To Learn

  • Midjourney for Game Developers — the higher-quality-ceiling alternative to Leonardo for pure concept art work, at a higher price point with no free tier.
  • Stable Diffusion for Game Developers — the free, locally-run alternative that provides similar custom model training (LoRA) and texture generation capabilities without any subscription cost, at the price of technical setup.
  • ControlNet for Game Developers — pose and composition control that works alongside Leonardo's Image2Image workflow for precise character generation.

Friday, 17 July 2026

How to UV Unwrap in Blender for Game Assets: Fix Stretched Textures and Seam Problems

You made a model in Blender. You applied a texture in Unity. It looks like someone stretched a photograph over a crumpled piece of foil. The wood grain on your crate runs in three different directions on three different faces. The brick pattern on your wall tiles correctly on one side and is completely wrong on the adjacent face.

This is a UV problem. Specifically it is what happens when there is no UV map, or a bad one.

UV unwrapping is one of those topics that gets skipped in beginner tutorials because it is not glamorous and it is genuinely confusing the first time you encounter it. I avoided it for about two months by only texturing things in Unity using tiling materials that did not need a proper UV map. That worked until I tried to put a logo on a crate lid, bake a normal map for a rock, or give a character any clothing detail at all. Then I had to learn it properly.

This guide covers what UV coordinates actually are, how to mark seams and unwrap correctly for game assets, where seams should and should not go, how to check for distortion, and how to get clean UVs into Unity.



What UV Coordinates Actually Are

Every point on a 3D mesh has a position in 3D space — X, Y, and Z. UV coordinates are a second set of positions for the same points, but in 2D space — U and V instead of X and Y. They map each point on the 3D surface to a specific location on a flat 2D image.

Think of it like peeling an orange. The orange is your 3D model. The flat peel is your UV map. Unwrapping is the process of cutting the peel in specific places (seams) so it can lie flat without too much stretching. Where you put those cuts determines how the flat image wraps back onto the 3D surface when you apply a texture.

When there is no UV map, or a broken one, Unity and Blender have to guess how to map the texture — and the guess is almost always wrong for anything other than a perfect cube with tiling materials. When the UV map is correct, a texture maps exactly where you placed it, at the size and orientation you intended.



The Two Workspaces You Need

UV unwrapping in Blender happens across two panels that need to be visible simultaneously.

The 3D Viewport is where you mark seams on the actual mesh.

The UV Editor is where you see and adjust the resulting flat UV map.

The fastest way to set this up: go to the UV Editing workspace tab at the top of the Blender window. This opens a pre-configured split view with the UV Editor on the left and the 3D Viewport on the right. It is exactly the layout you need and it is already there — you do not need to build it manually.

Part 1: Marking Seams

Seams are the cuts you make in the mesh that allow it to unfold flat. They are invisible in the final rendered model — they only exist in the UV data. Getting seam placement right is most of the work in UV unwrapping.

The Golden Rule of Seam Placement

Put seams where they will be least visible on the final model. The inside of a jacket sleeve. The underside of a belt. The back of a character's head where hair covers it. The bottom of a crate that sits on the floor. Seams are cuts in the UV islands, and at the boundary of those cuts textures occasionally show a slight misalignment — hiding that in a place the player never looks costs nothing.

How to Mark Seams

  1. In the 3D Viewport, press Tab to enter Edit Mode.
  2. Press 2 to switch to Edge Select mode.
  3. Select the edges where you want to place seams. You can click individual edges, or hold Shift and click to select multiple. For a loop of edges, Alt+Click selects the entire edge loop at once.
  4. With edges selected, go to Edge menu > Mark Seam (or right-click and find Mark Seam in the context menu).
  5. Marked seams appear as red edges on the mesh.

For a basic crate: mark seams along four vertical edges (the corners) and along the bottom face edges. This lets the crate unfold into a cross shape — five faces of the box laid out flat, with the bottom face separate. Every face gets its own UV island with minimal distortion.



Part 2: Unwrapping

Once seams are marked, unwrapping is one shortcut:

  1. In Edit Mode, press A to select all geometry.
  2. Press U to open the UV menu.
  3. Choose Unwrap.

Look at the UV Editor on the left. Your mesh should now appear as a flat layout of UV islands within the UV square (the 0 to 1 UV space). Each disconnected region separated by your seams is a UV island.

If the result looks like a chaotic mess of overlapping shapes, either your seams are wrong, you did not select all geometry before unwrapping, or the mesh has some geometry issue like disconnected faces. Undo, check your seam placement, and try again.

Smart UV Project: The Shortcut That Is Not Always a Shortcut

The UV menu also has Smart UV Project, which automatically generates seams and unwraps without you doing any seam placement manually. It works well for simple objects like rocks and terrain chunks where you just need a usable UV map quickly and you will be using a tiling texture rather than a custom-painted one.

For anything with a custom texture, a character, or an object where texture direction matters, Smart UV Project produces UV islands at random angles that make applying directional textures (wood grain, fabric weave, brick courses) very difficult. It is a fast option, not always the right one.

Part 3: Checking for Distortion

Marking seams and pressing Unwrap is easy. Knowing whether the result is good requires checking for distortion — areas where the UV islands are stretched or compressed compared to the actual surface area of the 3D faces.

The Checker Texture Method

This is the fastest way to see distortion visually:

  1. In the 3D Viewport, go to the Material Properties panel (the sphere icon in the right sidebar).
  2. Add a new material and set its Base Color to an Image Texture.
  3. Click New in the image texture node to create a blank image, then in the dropdown next to the filename, choose Generated > UV Grid.
  4. Switch the 3D Viewport to Material Preview mode (the sphere icon in the viewport header, or press Z and choose Material Preview).

Your model should now display a black and white checkerboard. Look at the squares: if they are all roughly the same size and shape across the entire model, your UV map is good. If some squares are stretched into rectangles, squashed, or skewed, those UV islands have distortion that will show up on your final texture.

Fixing distortion usually means either adjusting seam placement and re-unwrapping, or manually moving UV vertices in the UV Editor to even out the island shapes. For most game assets, some minor distortion is acceptable as long as it is not in a prominent visible area.



Part 4: UV Islands and Texture Space

Once the basic unwrap looks clean, there are three things to do before exporting.

Pack Islands

In the UV Editor, select all UV islands with A, then go to UV > Pack Islands. This automatically repositions and scales all islands to fit efficiently within the 0-to-1 UV square without overlapping. Blender's packing is decent but not perfect — for complex models, dedicated UV packing tools do a better job, but Pack Islands is fine for most game assets.

Scale Islands by Surface Area

Islands that represent a large area of the 3D mesh should take up more UV space than small detail areas. A character's torso needs more texture resolution than the inside of their collar. In the UV Editor, you can manually scale individual islands (select the island, S to scale) to give more texture space to prominent areas and less to hidden ones.

This is called texel density — keeping the number of texture pixels per 3D surface unit consistent across a model. Perfect texel density means every part of the model has the same texture resolution. You rarely achieve perfect texel density but you want to avoid obvious mismatches like a character face being blurry while their belt buckle is sharp.

Avoid Overlapping Islands (Usually)

Overlapping UV islands mean two different parts of the 3D mesh are mapped to the same area of the texture. This is intentional in some workflows — mirrored characters often have the left and right sides share UV space to double the effective texture resolution on each side. For a beginner, avoid overlapping until you understand why you are doing it, because overlapping UVs cause baking errors and visual artifacts in most standard workflows.

Part 5: Exporting to Unity With Clean UVs

The UV map exports automatically with the FBX file using the same export settings from the Blender Basics guide. No extra steps are needed — the UVs travel with the mesh geometry in the FBX format.

What does require attention:

Multiple UV channels. Blender supports multiple UV maps per mesh. Unity uses UV channel 0 (the first UV map, called UVMap in Blender by default) for the main texture, and UV channel 1 for lightmapping. If you have more than one UV map in Blender, check which one is active (the camera icon in the UV Maps list in the Object Data Properties panel) — the active UV map exports as channel 0.

Flipped V coordinate. Blender and Unity use opposite vertical conventions for UV space — Blender's UV origin (0,0) is the bottom-left; Unity's is the top-left. In practice this means textures appear vertically flipped in Unity compared to Blender. The fix is to check Flip V in Unity's Import Settings under the Model tab, or to flip the texture vertically in Blender before export by selecting all UVs in the UV Editor and scaling them -1 on the Y axis (S, Y, -1, Enter).

Real Example: UV Unwrapping the Blender Basics Crate

If you followed the previous guide and built the crate, here is the UV unwrap process applied to it specifically.

  1. Enter Edit Mode on the crate. Press Alt+A to deselect everything.
  2. Switch to Edge Select mode (press 2).
  3. Alt+Click each of the four vertical corner edges to select those edge loops. Shift+Alt+Click to add to the selection.
  4. Also select the bottom face edges.
  5. Right-click and choose Mark Seam. The selected edges turn red.
  6. Press A to select all geometry, then U and choose Unwrap.
  7. In the UV Editor, you should see a cross-like layout of six UV islands — four side faces, the top, and the bottom.
  8. Apply a UV Grid checker texture and check the viewport. The squares should be roughly even across all faces.
  9. Select all in the UV Editor, go to UV > Pack Islands.
  10. Export as FBX using the settings from the Blender Basics guide.

In Unity, assign a material with a wood plank texture to the imported model. The planks should run consistently across the faces without the stretching or rotation errors you would get from a model with no UV map.



Where Beginners Go Wrong

  • Not marking any seams and expecting Unwrap to work anyway. Without seams, Blender cannot figure out where to cut the mesh to lay it flat. The result is a jumbled mess in the UV Editor. You must mark seams first.
  • Putting seams in visible, prominent areas. The seam itself is invisible, but texture misalignment at seam boundaries is not. Always put seams on edges that will be hidden, in shadow, or at natural material boundaries like where a sleeve meets a cuff.
  • Not checking with a checker texture before exporting. Distortion that is obvious with a checker pattern is almost impossible to see by just looking at the mesh without a texture. Apply the UV Grid and check every face before you spend time painting a texture onto a broken UV layout.
  • Overlapping UV islands by accident. Pack Islands usually prevents this, but manually moving islands in the UV Editor without checking for overlaps can create problems. The UV Editor has a Highlight Overlapping Islands overlay that turns overlapping areas red — enable it to check.
  • Forgetting to apply transforms before UV unwrapping. Unapplied scale on the mesh causes UV islands to come out at wrong proportions. Apply All Transforms (Ctrl+A in Object Mode) before entering Edit Mode and unwrapping, same as the export step in the Blender Basics guide.
  • Using Smart UV Project on organic shapes and wondering why the texture looks bad. Smart UV Project creates UV islands at whatever angle Blender decides. For organic geometry this usually means every island is at a different rotation, making directional textures (hair, scales, fabric grain) impossible to apply correctly without manual cleanup.

Troubleshooting

My UV map looks fine in Blender but the texture is still stretched in Unity.

Check the V coordinate flip issue described in the Export section. Also confirm you are using UV channel 0 in Unity's material setup — if a second UV channel was accidentally exported as the primary one, Unity reads the wrong coordinates.

Some faces do not appear in the UV Editor after unwrapping.

Those faces are not connected to any UV map, or they were not selected when you ran Unwrap. Select all (A) in Edit Mode and run Unwrap again. If faces still disappear, check for faces with zero area (completely flat, degenerate faces) that sometimes get dropped from the UV calculation.

My UV islands are all at different scales and some are tiny.

This happens when faces have very different sizes in 3D space — large faces get larger islands, small faces get small ones, and the range can be extreme. In the UV Editor, select all islands and go to UV > Average Island Scale to even them out before packing.

The seams are not visible in Edit Mode even after marking them.

Go to Viewport Overlays (the two overlapping circles icon in the viewport header) and make sure Seams is checked under the Mesh Edit section. Seam display is a viewport overlay that can be toggled off.

My texture has a visible line or gap at the seam boundary in Unity.

This is a texture bleeding issue. In Unity's texture import settings, enable Generate Mip Maps and set the texture's Filter Mode to Bilinear or Trilinear rather than Point. Also make sure there is a small amount of padding between UV islands (Pack Islands has an Margin slider — use a value around 0.02 to 0.05 to add padding between islands).



What to Learn Next in Blender

Once UV unwrapping feels comfortable, two things open up that were not possible before.

Texture baking — rendering lighting, ambient occlusion, and surface detail from a high-poly model into a texture that displays on a low-poly version. This is how game characters get detailed normal maps without needing millions of polygons. It requires a clean UV map on the low-poly model as its starting point.

Texture painting in Blender — painting directly onto the 3D surface using Blender's Texture Paint mode. The paint maps onto the UV layout, so a correct UV map is required before you can paint anything that looks right on the 3D model.

Both of those are deep enough topics for their own guides. The important thing is that neither is achievable without a working UV map — which is why UV unwrapping, despite being unglamorous, is the skill that unlocks most of the interesting things that come after it.

Next Topics To Learn

Tuesday, 14 July 2026

How to Use ControlNet for Game Development: Fix Random Poses and Get Consistent Character Art

Here is the problem with Stable Diffusion after you get it running: every image is a dice roll. You write a prompt for a warrior in a combat stance and get a warrior standing with their arms at their sides. You try again and get someone leaning casually against a wall. On the fifth attempt you get something close, but the sword arm is anatomically impossible and one hand has eight fingers.

This is not a prompt engineering problem. Text prompts are probability nudges, not instructions. When you type "perfect hands, five fingers, correct anatomy" into Stable Diffusion, you are nudging a statistical weighting system — you are not issuing a command. The model has no spatial awareness. It does not know where the hands are or how joints connect.

ControlNet is the fix. It takes a structural guide — an edge map, a body pose, a depth map — and forces the diffusion model to follow that structure. Same prompt, but now the output matches the layout you specified. That is a genuinely different category of control. This guide covers everything from installation to the specific workflows that actually matter for game concept art: character sheets, consistent poses across multiple images, and turning rough sketches into finished art.


 

What ControlNet Actually Does

Standard Stable Diffusion uses text prompts to guide image generation. ControlNet adds a second layer of guidance: input images. But it does not copy the input image like standard img2img. Instead, it extracts specific information — edges, depth maps, or human skeletons — and forces the AI to follow that structure while generating entirely new textures, lighting, and styles based on your prompt.

The workflow is: give ControlNet a reference image, it processes that image through a preprocessor to extract a control map (a skeleton wireframe, an edge outline, a depth gradient), and that map constrains what the diffusion model generates. Your warrior prompt now produces a warrior in the exact pose from your reference photo, not whatever pose the model felt like.

For game development specifically this matters because you need repeatable results. A character design sheet needs the same character from multiple angles. Your enemy AI needs five different attack poses that all look like the same design. Your environment concepts need consistent lighting across a zone. None of that is achievable with prompts alone.



Installing ControlNet

Assumes you have Forge or AUTOMATIC1111 set up from the Stable Diffusion guide. If you are using ComfyUI, the process is slightly different and covered at the end of this section.

In Forge or AUTOMATIC1111

  1. Open the webui and go to the Extensions tab.
  2. Click Install from URL.
  3. Paste: https://github.com/Mikubill/sd-webui-controlnet
  4. Click Install, then go to the Installed tab and click Apply and Restart UI.

After restart, a ControlNet section appears below the prompt fields in txt2img and img2img. It starts collapsed — click the arrow to expand it.

Downloading Models

The extension is just the interface. The actual ControlNet models are separate downloads. For SD 1.5, there are 14 official ControlNet models. For SDXL, the most practical option is xinsir's ControlNet Union — one file that covers 10+ control types. For Flux, Shakker Labs Union Pro 2.0 is the current best option.

You do not need all of them. For game development, download these three first and add others only when you have a specific use case for them:

  • control_openpose — for character poses
  • control_canny — for edge-based composition from sketches or photos
  • control_depth — for 3D spatial layout from reference images

Place downloaded .safetensors files in: stable-diffusion-webui-forge/models/ControlNet/

Restart the webui. The models now appear in the ControlNet model dropdown.

In ComfyUI

Install the comfyui_controlnet_aux node pack through ComfyUI Manager, then drop ControlNet models into models/controlnet/. The workflow is node-based — add a Load ControlNet Model node, connect it through an Apply ControlNet node between your positive conditioning and KSampler. It takes fifteen minutes to build once you understand the node graph from the Stable Diffusion guide.



The Five Models Worth Knowing

There are over a dozen ControlNet models available, but you will spend 90% of your time using about five of them. Here is what each does and when to use it for game art specifically.

Model What It Controls Game Dev Use Case
OpenPose / DWPose Extracts a skeletal stick figure from a reference photo, transfers that exact pose to the generated character. Character design sheets, attack animations, idle poses, crowd scenes. The most-used model for character work.
Canny Extracts edge lines from an image or sketch and uses them as a structural guide. Turning rough concept sketches into finished AI art, preserving composition while changing style, reference-based environment blocking.
Depth Creates a grayscale depth map from a reference image, preserving the 3D spatial relationships between objects. Environment concept art where you want to lock the spatial layout, multi-character scenes where depth separation matters.
Lineart Similar to Canny but preserves line weight variation better for hand-drawn inputs. Converting your own sketches or existing lineart into fully rendered AI illustrations while keeping your original composition.
IP-Adapter Uses an image as a style/appearance reference rather than a structural guide. Injects the visual features of a reference into the generation. Keeping the same character face or design consistent across multiple images. Works best combined with OpenPose.

The preprocessor and model have to match. If you use a Canny preprocessor, you must select the control_canny model. If you use OpenPose, select control_openpose. Mismatching them is the most common beginner mistake and produces garbage output with no useful error message.

Real Workflow 1: Character Poses With OpenPose

This is where most game developers start, and for good reason. You want to generate a knight swinging a sword. Upload a photo of yourself swinging a broom, and OpenPose will transfer that exact motion to the fantasy character.

Here is the actual step-by-step:

  1. Take a reference photo of the pose you want — yourself, a friend, or a stock photo. The character's appearance does not matter at all, only the body position.
  2. In the ControlNet panel, enable it and upload the reference photo to the image canvas.
  3. Set Preprocessor to openpose (or dw_openpose for better hand detection).
  4. Set Model to control_openpose (or xinsir Union for SDXL).
  5. Click the preview icon — you should see a skeleton wireframe overlay on your reference image. This is what ControlNet is extracting.
  6. Write your normal character prompt and generate.

The generated character will match the extracted skeleton's pose. Body proportions, clothing, face, and style all come from your prompt and checkpoint. Only the pose transfers from the reference.

Pro tip: always photograph your own hand holding an object against a blank wall to use as the ControlNet reference. It is 100x faster than trying to articulate individual finger joint positions through text prompt iteration. I spent twenty minutes trying to prompt "hand gripping sword with correct finger wrap" and got nonsense every time. Took a photo of my own hand gripping a pen, ran it through OpenPose, generated in ten seconds. Different category of result.



Real Workflow 2: Sketch-to-Art With Canny

You sketch a rough environment layout — a ruined building on the left, open ground in the center, trees on the right. Canny extracts the edges from that sketch and forces the generation to follow your composition. The actual style, lighting, and detail all come from your prompt. Your terrible Quick sketch turns into a polished game environment concept.

  1. Upload your sketch or rough drawing to the ControlNet image canvas.
  2. Set Preprocessor to canny.
  3. Set Model to control_canny.
  4. Adjust the Canny Low Threshold and High Threshold sliders. Lower values pick up more edges including noise; higher values keep only the strongest structural lines. For a clean sketch, start at 100/200 and adjust from there.
  5. Generate with your environment prompt.

Canny works on any image, not just hand-drawn sketches. Taking a screenshot of a Unity greybox level and running it through Canny gives you a quick concept visualization of what that geometry could look like as finished art. This is genuinely useful for showing non-developers what a level will look like before any real assets exist.

Real Workflow 3: Stacking for Character Sheets

The most powerful ControlNet technique for game developers is stacking multiple units simultaneously. The professional approach is to decouple the elements: one slot handles identity, one handles structure, one handles environment.

For a character design sheet with the same character in multiple poses:

  • ControlNet Unit 1 (IP-Adapter) — upload your character's face/design reference. This locks who the character is.
  • ControlNet Unit 2 (OpenPose) — upload a reference photo for each pose. This locks how they are standing.

VRAM requirements stack. Running multiple ControlNet models simultaneously requires a minimum of 12GB in 2026. On a 6-8GB card, run one unit at a time and composite the results. On 12GB+, stacking gives you dramatically better consistency across a character sheet than either approach alone.

The Control Weight slider matters here. A weight of 1.0 means the structure is rigidly followed. Lower values (0.6-0.8) give the model more creative freedom while still respecting the general structure. For IP-Adapter identity control, 0.7-0.8 usually produces better-looking faces than forcing it to 1.0, which can make faces look plasticky.



ControlNet vs IP-Adapter: What is the Difference

This confuses almost everyone. Where ControlNet controls spatial structure — where things are — IP-Adapter controls appearance — what things look like. They solve different problems and work better together than either does alone.

If you need a character to be in a specific pose: ControlNet OpenPose.

If you need a character to look like a specific reference design: IP-Adapter.

If you need both at once: stack them.

T2I-Adapter is worth knowing about too. It is a lightweight alternative to ControlNet at only 158MB per model versus ControlNet's roughly 1.4GB. It runs conditioning once for the entire generation instead of every step, uses 93% less storage, and adds minimal extra VRAM. The control is less precise, but on a 6-8GB card where ControlNet is straining your VRAM budget, T2I-Adapter lets you get some structural control without the full cost.

What Does Not Work Well

Being straight about this is useful: ControlNet is not magic.

OpenPose struggles with extreme camera angles, particularly top-down or very low-angle shots where limb occlusion confuses the skeleton extraction. If the preprocessor preview looks wrong (missing limbs, incorrect joint positions), the generated image will also be wrong regardless of how good your prompt is.

Hands are still hard even with DWPose, which is specifically designed for better hand tracking than the original OpenPose. ControlNet inpainting is the workaround — generate the image, then inpaint only the hand area with a high denoising strength while keeping the rest intact. More steps, but the results are significantly better than hoping the full generation gets hands right.

On SDXL, ControlNet support is less mature than on SD 1.5. Xinsir's Union model covers most use cases, but some preprocessor types that work perfectly on SD 1.5 behave inconsistently on SDXL. SD 1.5 still offers the most control types, the smallest model files, the most community resources, and the lowest VRAM requirements if ControlNet is central to your workflow.

Common Errors and Fixes

The generated image ignores the ControlNet input completely.

Either the Enable checkbox in the ControlNet panel is not checked (it defaults to unchecked), or the preprocessor and model do not match. Check both. Also confirm the model file is in the correct ControlNet folder and appears in the dropdown — if you can not select it, the file is missing.

The skeleton preview looks correct but the generated character ignores the pose.

Control Weight is too low. Raise it toward 1.0. If it is already at 1.0, the base checkpoint you are using may not respond well to ControlNet — try a different SD 1.5 or SDXL checkpoint that is known to work with pose conditioning.

CUDA out of memory when using multiple ControlNet units.

Each additional ControlNet stacks VRAM usage — three ControlNets can add 4-6GB on SD 1.5. Solutions in order: reduce the number of active ControlNet units, lower the image resolution, enable the Low VRAM checkbox in the ControlNet settings panel, or switch to T2I-Adapter for units where you do not need full ControlNet precision.

IP-Adapter makes all characters look the same regardless of prompt.

IP-Adapter weight is too high. Drop it to 0.5-0.7. At high weights it overwrites the text prompt's influence — the reference image appearance dominates so strongly that changing the prompt makes little difference.


Practical Tips Before You Start

  • Always check the preprocessor preview before generating. If the skeleton, edge map, or depth map looks wrong, the output will be wrong. Fix the reference image or adjust thresholds before wasting generation time.
  • Start with a single ControlNet unit and get it working before adding a second. Stacking doubles the variables when something goes wrong.
  • Save working ControlNet configurations as presets using the save button in the ControlNet panel. Good OpenPose settings for character work are worth preserving across sessions.
  • For character sheets specifically: generate all poses at the same resolution and seed (or similar seeds) to reduce variation between outputs. The ControlNet handles pose consistency; seed consistency handles background and lighting.
  • Blender is genuinely useful here. You can pose a Blender character rig, screenshot it from Forge's ControlNet input, and use that as an OpenPose reference — Blender's 3D modeling capabilities make it useful for creating posing skeletons for Stable Diffusion workflows. This connects directly to the Blender guide from this series.

FAQ

Do I need ControlNet or can I just use better prompts?

For specific poses, no amount of prompt engineering reliably replaces ControlNet. Prompts nudge probabilities. ControlNet enforces structure. They are not substitutes for each other.

Which ControlNet model should I start with?

OpenPose for character work, Canny for environment sketches. Download those two first and learn them before anything else.

Can I use ControlNet with Midjourney or DALL-E?

No. ControlNet is a Stable Diffusion extension. Midjourney has its own --cref and --sref reference parameters (covered in the Midjourney guide), which offer some of the same character consistency features without the same level of pose precision. DALL-E has no equivalent system.

How much VRAM do I actually need?

Single ControlNet on SD 1.5: 8GB is comfortable. Single ControlNet on SDXL: 12GB recommended. Stacking two or more units: 12GB minimum, 16GB+ for reliability. T2I-Adapter is the workaround for lower VRAM budgets.

Does ControlNet work on Flux models?

Yes, with limitations. Shakker Labs Union Pro 2.0 is the current best ControlNet option for Flux, but Flux ControlNet support is less mature than SD 1.5. You also need 24GB VRAM total for Flux plus a ControlNet model running simultaneously.

What is the difference between OpenPose and DWPose?

DWPose is the newer, more accurate variant. It tracks hand and face keypoints more reliably than the original OpenPose, which makes a meaningful difference for character close-ups and poses where hand position matters. Use DWPose if your Forge or ComfyUI install has it — it is the better choice for most character work in 2026.

What to Try First

Install the extension, download control_openpose, take a photo of yourself in any pose, and generate a character concept using it as the reference. That alone will immediately show you what ControlNet actually does more clearly than any description can. Then try Canny on a rough sketch. Then look at IP-Adapter for the face consistency problem.

The stacking workflow for professional character sheets takes longer to set up but is worth learning if you are generating large amounts of concept art for a project. Once you have a working pose reference library and a character IP-Adapter reference image, generating a full character sheet becomes fast and repeatable in a way that pure prompt work simply is not.

Next Topics To Learn

How to Use ElevenLabs for Game Development: AI Voice Acting, NPC Dialogue, and Sound Design

Most indie games ship without voice acting. Not because developers do not want it, but because hiring voice actors is expensive, scheduling ...