Skip to content

Character Consistency Master Guide ​

The definitive guide to creating and maintaining consistent characters across unlimited image generations with Go Bananas!


Table of Contents ​


Part 1: Foundations ​

What is Character Consistency? ​

Character consistency is the ability to generate the same character—with identical facial features, body type, clothing, and style—across multiple images, scenes, and sessions. It's the difference between:

Without Consistency:
"Generate a girl with red hair" → Character A
"Generate a girl with red hair in a forest" → Different Character B
"Generate a girl with red hair at the beach" → Different Character C

With Consistency:
Create character "Luna" with detailed description + reference images
"Generate Luna in a forest" → Consistent Luna
"Generate Luna at the beach" → Same Luna
"Generate Luna flying a kite" → Same Luna

Why Character Consistency Matters ​

1. Token Limit Problem ​

When generating multiple scenes with the same character, repeating the full description in every prompt causes:

typescript
// Scene 1
"10-year-old boy, stocky build, freckles, buzz cut, red jacket, standing at playground"

// Scene 2
"10-year-old boy, stocky build, freckles, buzz cut, red jacket, riding a bicycle"

// Scene 3
"10-year-old boy, stocky build, freckles, buzz cut, red jacket, eating lunch"

// ... after 4-6 scenes, you've hit the conversation token limit!

2. Visual Coherence Problem ​

Even with identical prompts, AI models interpret text differently each time:

GenerationSame PromptResult
1"girl with red hair"Curly red hair, green eyes
2"girl with red hair"Straight red hair, blue eyes
3"girl with red hair"Short red hair, brown eyes

The model doesn't remember what it generated before.

3. Storytelling Problem ​

For sequential content (children's books, comics, marketing campaigns), character inconsistency breaks immersion:

  • Page 1: Hero has curly hair
  • Page 2: Hero has straight hair
  • Page 3: Hero looks completely different

The Solution: Character Reference System ​

Go Bananas! solves these problems with a persistent character reference system:

┌─────────────────────────────────────────────────────────────┐
│                    CHARACTER REFERENCE SYSTEM                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐     │
│  │   CREATE    │ -> │    SAVE     │ -> │   REUSE     │     │
│  │  Character  │    │  to D1 DB   │    │  Anywhere   │     │
│  └─────────────┘    └─────────────┘    └─────────────┘     │
│                                                             │
│  Benefits:                                                  │
│  • No token bloat (data stored in database)                │
│  • Session independence (works across sessions)            │
│  • Visual consistency (reference images dominate)          │
│  • Usage tracking (analytics per character)                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Key Concepts ​

ConceptDescription
Base PromptText description of character's permanent features
Reference ImagesVisual examples that anchor the character's appearance
Identity LockingTechnique to maintain facial features across generations
Scene PromptWhat the character is doing in this specific image
Character LibraryDatabase of all saved characters for a tenant

Part 2: Quick Start ​

3-Step Workflow ​

Step 1: Generate Initial Character Design ​

First, create your character using standard image generation:

typescript
generate_image({
  prompt: "10-year-old boy, stocky build, round face, freckles across nose,
           buzz cut brown hair, wearing red varsity jacket, jeans, white sneakers,
           confident stance, children's book illustration style",
  negative_prompt: "adult, teenager, thin, long hair, glasses, beard",
  system_instruction: "Children's book illustration, vibrant colors, friendly design",
  aspect_ratio: "portrait"
})

// Result: Image ID 42 (note this from the response)

Step 2: Save Character for Reuse ​

Save the character design to the database:

typescript
create_character({
  character_name: "Bully Bob",
  description: "Stocky 10-year-old schoolyard bully with tough exterior",
  base_prompt: "10-year-old boy, stocky build, round face, freckles across nose,
                buzz cut brown hair, wearing red varsity jacket, jeans, white sneakers,
                confident stance",
  negative_prompt: "adult, teenager, thin, long hair, glasses, beard",
  system_instruction: "Children's book illustration, vibrant colors, friendly design",
  reference_image_ids: [42],  // Link to the image you just generated
  preferred_aspect_ratio: "portrait",
  tags: ["protagonist", "child", "school"]
})

// Result: Character ID 1 created

Step 3: Generate Multiple Scenes ​

Now generate scenes with your character—even in new sessions:

typescript
// Scene 1
generate_with_character({
  character_name: "Bully Bob",
  scene_prompt: "standing at the playground with arms crossed",
  additional_details: "golden hour lighting, warm atmosphere"
})

// Scene 2 (can be in a completely new conversation!)
generate_with_character({
  character_name: "Bully Bob",
  scene_prompt: "riding a bicycle down a suburban street",
  additional_details: "sunny day, motion blur on wheels"
})

// Scene 3
generate_with_character({
  character_name: "Bully Bob",
  scene_prompt: "eating lunch in school cafeteria",
  additional_details: "cafeteria background, sitting at table"
})

Each scene automatically includes Bully Bob's full character design without you repeating it!

What Happens Behind the Scenes ​

When you call generate_with_character:

1. Load character from database (base_prompt, reference_image_ids)
2. Download reference images from R2 storage
3. Build final prompt:

   WITH reference images:
   "The character in Image 1 — keep the face, hair, and outfit EXACTLY the same.
    Character details: {base_prompt}. Scene: {scene_prompt}"

   WITHOUT reference images:
   "{base_prompt}, {scene_prompt}, {additional_details}"

4. Send to Gemini with reference images
5. Update character usage stats
6. Return consistent image

Part 3: Reference Images ​

Why Reference Images are Critical ​

Text-only prompts have inherent variability:

Text: "young woman with red hair"
→ Could be: short/long hair, light/dark red, any style, any face shape

Reference images anchor the visual output:

Reference Image + "The character in Image 1 — keep face, hair, outfit EXACTLY the same"
→ Consistent facial features, hair color, body type, style

The Ideal Reference Image ​

QualityGoodBad
ClarityClear, well-lit, focusedBlurry, dark, cluttered
PoseNeutral, full-body visibleExtreme angles, cropped
BackgroundSimple, non-distractingBusy, competes with subject
ExpressionNeutral or characteristicExtreme expressions
LightingEven, naturalHarsh shadows, overexposed

Reference Image Strategy ​

1. Generate 2-3 Variations First ​

typescript
// Generate initial variations to find the best design
generate_image({ prompt: "character description...", aspect_ratio: "portrait" })
generate_image({ prompt: "character description...", aspect_ratio: "portrait" })
generate_image({ prompt: "character description...", aspect_ratio: "portrait" })

2. Pick the Best One ​

Review all generations and select the image that:

  • Best matches your vision
  • Has clear facial features
  • Shows distinctive characteristics
  • Has good lighting and composition

3. Create Character with That Reference ​

typescript
create_character({
  character_name: "Luna",
  base_prompt: "Young witch with silver hair...",
  reference_image_ids: [42]  // The best image ID
})

4. Add More References Over Time ​

As you generate more images, add the best ones as additional references:

typescript
// After generating a great scene
update_character({
  character_name: "Luna",
  reference_image_ids: [42, 67, 89]  // Add new reference
})

Reference Image Limits by Model ​

ModelMax Character RefsBest Practice
Lite (Nano Banana 2 Lite)14Use for fast, low-cost 1K drafts
Flash (Nano Banana 2)4Use all 4 slots with front-facing, well-lit refs
Pro (Go Bananas! Pro)5Use 3-5 high-quality refs

Minimum size: All reference images must be at least 512x512 pixels. Smaller images are rejected at character creation to prevent consistency degradation.

Reference Quality Assessment Checklist ​

Before adding an image as a reference, verify:

  • [ ] Image is at least 512x512 pixels (enforced by the system)
  • [ ] Face clearly visible (no obstruction, blur, or extreme angle)
  • [ ] Front-facing or 3/4 angle (side profiles reduce consistency)
  • [ ] Distinctive features captured (hair, eyes, defining characteristics)
  • [ ] Consistent style with other references
  • [ ] Good resolution (not pixelated)
  • [ ] Even, well-lit (not harsh shadows or extreme contrast)
  • [ ] Neutral background (doesn't dominate)

Part 4: Identity Locking Deep Dive ​

What is Identity Locking? ​

Identity Locking is a prompting technique that explicitly instructs the AI to maintain specific visual features from reference images. It's the most powerful tool for character consistency.

The Magic Phrase ​

"Keep the person's facial features exactly the same as Image 1."

This single phrase dramatically improves consistency by:

  1. Explicitly anchoring to the reference image
  2. Focusing attention on facial features (most recognizable)
  3. Allowing other elements (pose, setting) to vary

Identity Locking Variations ​

SituationPhrase to Use
Facial Features"Keep facial features exactly the same as Image 1"
Full Identity"Maintain the character's identity and attire from the reference"
Pose Changes"The subject should be identical to reference, only change the pose"
Expression Changes"Same person as Image 1, but with excited expression"
Clothing Changes"Same person as Image 1, but wearing summer clothes"

Advanced Identity Locking Techniques ​

Clothing Consistency ​

When you need the same outfit across scenes:

json
{
  "prompt": "The character in Image 1 — keep the face, hair, and outfit EXACTLY the same. Scene: walking through a shopping mall in the exact same red varsity jacket and jeans",
  "system_instruction": "Maintain identical clothing details, colors, and accessories"
}

Pose Variations (Same Person, Different Poses) ​

json
{
  "prompt": "The exact same person from Image 1, now in a running pose. Keep all facial features, hair, and clothing identical. Only the pose changes.",
  "scene_prompt": "running through a park"
}

Expression Consistency ​

Keep the character recognizable while changing emotions:

json
{
  "prompt": "Same character as Image 1, but with a surprised expression. Facial structure, hair, and skin tone must remain identical.",
  "additional_details": "wide eyes, raised eyebrows, open mouth"
}

Age Consistency ​

When creating age variants, maintain recognizable features:

typescript
// Young version
create_character({
  character_name: "Luna - Age 10",
  base_prompt: "10-year-old girl, silver hair, purple eyes, round face..."
})

// Teen version
create_character({
  character_name: "Luna - Age 16",
  base_prompt: "16-year-old girl, same silver hair and purple eyes as younger Luna,
                more mature face shape but same features..."
})

Lighting Adaptation ​

Character should look the same under different lighting:

json
{
  "prompt": "The character from Image 1 under dramatic sunset lighting. Keep all physical features identical—only the lighting changes.",
  "scene_prompt": "silhouetted against orange sunset sky"
}

When Identity Locking Fails ​

Problem: Character Looks Different Despite Identity Locking ​

Causes:

  1. Reference image quality is poor
  2. Scene prompt contradicts character description
  3. Extreme pose/angle obscures defining features
  4. Aspect ratio change distorts proportions

Solutions:

CauseSolution
Poor referenceGenerate new reference with clearer features
Prompt conflictRemove conflicting descriptions from scene prompt
Extreme poseUse moderate poses that show face clearly
Aspect ratioUse character's preferred aspect ratio

Problem: Facial Features Drift Over Multiple Generations ​

Cause: Each generation introduces small variations that compound.

Solution: Always generate from original reference, not from previous generations:

❌ Wrong: Generate → Edit → Edit → Edit (drift accumulates)
✅ Right: Generate from Reference → Generate from Reference → Generate from Reference

Problem: Identity Locking Works for Face but Not Body ​

Cause: The phrase focuses on facial features only.

Solution: Expand the locking phrase:

"Keep the person's facial features, body type, height, and build exactly the same as Image 1"

Flash vs Pro Identity Locking ​

AspectFlashPro
Max reference images1414 (6 high-fidelity)
Identity locking strengthGoodExcellent
Multi-scene consistencyModerateStrong
Expression variationLimitedAdvanced
Recommended forQuick iterations, testingFinal production assets

Part 5: Multi-Character Scenes ​

Overview ​

Generate 2-5 characters together in the same scene:

typescript
generate_with_multiple_characters({
  character_names: ["Luna", "Felix"],
  scene_prompt: "exploring a haunted mansion together",
  aspect_ratio: "landscape"  // Recommended for multi-character
})

Multi-Character Best Practices ​

1. Use Landscape Aspect Ratio ​

Multiple characters need horizontal space:

CharactersRecommended Aspect
2landscape or 16:9
3landscape or 16:9
4-516:9 or 21:9

2. Describe Interactions ​

Don't just place characters in scene—describe their relationship:

❌ "Luna and Felix in a forest"

✅ "Luna teaching magic to Felix in her study,
    Luna demonstrating a spell while Felix watches attentively"

3. Use Distinct Visual Features ​

Characters should be easily distinguishable:

Good pair:
• Luna: Silver hair, purple cloak, human girl
• Felix: Black cat, wizard hat, glowing eyes

Bad pair:
• Character A: Brown hair, blue shirt
• Character B: Brown hair, blue jacket

4. Keep Scenes Simple ​

More characters = simpler background:

CharactersScene Complexity
1Complex scenes OK
2-3Moderate complexity
4-5Simple backgrounds

Multi-Character Positioning ​

Use spatial language to control character placement:

PositionLanguage
Side by side"standing next to each other"
One behind"Character A in front, Character B behind"
Facing each other"looking at each other"
Circle/group"gathered in a circle"
Action"chasing", "following", "walking together"

Example: 2-Character Scene ​

typescript
generate_with_multiple_characters({
  character_names: ["Kishy", "Crusher"],
  scene_prompt: "playing together at the playground,
                 Kishy on the swing while Crusher pushes gently",
  additional_details: "sunny day, cheerful atmosphere,
                       other children playing in background",
  aspect_ratio: "landscape"
})

Example: 3+ Character Scene ​

typescript
generate_with_multiple_characters({
  character_names: ["Luna", "Felix", "Shadow"],
  scene_prompt: "epic confrontation in magical forest clearing,
                 Luna and Felix standing together on left,
                 Shadow emerging from shadows on right",
  additional_details: "dramatic lighting, magical particles,
                       tension in the air",
  aspect_ratio: "16:9"
})

Multi-Character Limitations ​

LimitationDetails
Minimum2 characters
Maximum5 characters
Reference imagesCombined total should not exceed model limit
Same tenantAll characters must belong to same tenant

Troubleshooting Multi-Character Scenes ​

ProblemSolution
Characters blend togetherAdd more distinctive visual features
Wrong character positioningUse explicit spatial language
One character dominatesBalance scene description equally
Reference images not loadingVerify character has valid references
"Character not found"Check spelling and tenant ownership

Part 6: Flash vs Pro for Characters ​

Feature Comparison ​

FeatureFlash (Standard)Pro
Resolution1K1K, 2K, 4K
Character Refs45
Identity LockingGood (Image-1 lock + base_prompt)Excellent
Text RenderingBasicAdvanced (SOTA)
Thinking ModeNoYes
Web GroundingNoYes
Speed~3-5 sec~8-15 sec
CostLowerHigher

When to Use Flash ​

Flash is best for:

  • Quick iterations: Testing character designs
  • Simple scenes: Single character, straightforward setting
  • High volume: Many generations where speed matters
  • Budget-conscious: Lower cost per generation
  • Non-critical work: Internal use, drafts, exploration
typescript
// Flash for iteration
generate_image({
  prompt: "character design...",
  model_id: "gemini-flash-image"  // Default
})

When to Use Pro ​

Pro is best for:

  • Final production: Marketing materials, published content
  • Complex identity locking: Multiple reference images needed
  • Multi-scene stories: Storyboarding with consistent characters
  • Text-heavy images: Infographics, thumbnails with text
  • High-resolution needs: 4K output required
  • Viral thumbnails: YouTube/social media thumbnails
typescript
// Pro for production
generate_image({
  prompt: "character design...",
  model_id: "gemini-pro-image",
  resolution_tier: "4k"  // Optional: high-res
})
1. ITERATE with Flash
   • Develop character concept
   • Test multiple variations
   • Refine base prompt
   • Generate reference candidates

2. SAVE best reference
   • Pick the best Flash generation
   • Create character with reference

3. PRODUCE with Pro (when needed)
   • Final marketing images
   • High-resolution assets
   • Complex multi-character scenes

Character Consistency Comparison ​

ScenarioFlash ResultPro Result
Single sceneGoodExcellent
2-3 scenesGoodExcellent
5+ scenesSome driftHighly consistent
Expression changesModerateStrong
Pose changesModerateStrong
Lighting changesGoodExcellent
Multi-characterGoodExcellent

Cost-Benefit Analysis ​

ApproachCostConsistencySpeed
All Flash$GoodFast
Flash → Pro$$BetterMedium
All Pro$$$BestSlower

Recommendation: Use Flash for 80% of work (iteration, testing), Pro for 20% (final assets).


Part 7: Advanced Techniques ​

Character Expression Matrix ​

Create a grid of expressions for animation or game assets:

typescript
const expressions = [
  "neutral expression",
  "happy, smiling broadly",
  "sad, looking down",
  "angry, furrowed brow",
  "surprised, wide eyes",
  "confused, tilted head"
];

for (const expr of expressions) {
  generate_with_character({
    character_name: "Hero",
    scene_prompt: `headshot portrait, ${expr}`,
    additional_details: "white background, front facing",
    aspect_ratio: "square"
  });
}

Style Preset + Character Combination ​

Combine saved characters with saved style presets:

typescript
// First, create a style preset
create_style_preset({
  name: "Watercolor Fantasy",
  prompt: "watercolor painting style, soft edges, dreamy atmosphere",
  negative_prompt: "photorealistic, sharp lines, digital art"
})

// Then use character with style
generate_with_character({
  character_name: "Luna",
  scene_prompt: "walking through enchanted forest",
  style_preset_name: "Watercolor Fantasy"  // Apply style
})

Character Evolution ​

Create variants for character development over time:

typescript
// Original character
create_character({
  character_name: "Bob - Age 10",
  base_prompt: "10-year-old boy, stocky build, buzz cut, red jacket",
  tags: ["bob", "child", "original"]
})

// Teenager version
create_character({
  character_name: "Bob - Age 16",
  base_prompt: "16-year-old teenager, same stocky build and round face as younger Bob,
                longer hair but same brown color, letterman jacket, taller",
  tags: ["bob", "teen", "evolution"]
})

// Adult version
create_character({
  character_name: "Bob - Age 30",
  base_prompt: "30-year-old man, same round face and build as younger Bob,
                short professional haircut, business casual, confident stance",
  tags: ["bob", "adult", "evolution"]
})

360° Turnaround Generation ​

Generate character from multiple angles:

typescript
const angles = [
  { view: "front view, facing camera", suffix: "front" },
  { view: "3/4 view, slight turn to left", suffix: "34left" },
  { view: "side profile, facing left", suffix: "sideleft" },
  { view: "3/4 back view", suffix: "34back" },
  { view: "back view, facing away", suffix: "back" },
  { view: "side profile, facing right", suffix: "sideright" },
  { view: "3/4 view, slight turn to right", suffix: "34right" }
];

for (const angle of angles) {
  generate_with_character({
    character_name: "Luna",
    scene_prompt: `character turnaround sheet, ${angle.view}, neutral pose`,
    additional_details: "white background, full body, character design reference",
    aspect_ratio: "portrait"
  });
}

Character Sheet Creation ​

Generate a reference sheet in a single image:

typescript
generate_with_character({
  character_name: "Luna",
  scene_prompt: "character reference sheet showing:
                 full body front view (center),
                 headshot (top left),
                 side profile (top right),
                 3/4 view (bottom left),
                 back view (bottom right)",
  additional_details: "white background, clean layout,
                       character design sheet format",
  aspect_ratio: "landscape",
  model_id: "gemini-pro-image"  // Pro handles complex layouts better
})

Conversational Editing with Characters ​

Use continue_editing for iterative refinement:

typescript
// Generate initial scene
generate_with_character({
  character_name: "Luna",
  scene_prompt: "standing in magical library"
})

// Refine with continue_editing (no character needed—uses last image)
continue_editing({ prompt: "add glowing magical books floating around her" })
continue_editing({ prompt: "make the lighting more dramatic" })
continue_editing({ prompt: "add a small owl on her shoulder" })

Multi-Reference Style Transfer ​

Use reference images for both character AND style:

typescript
generate_image({
  prompt: "Portrait of the character from Image 1,
           rendered in the artistic style of Image 2",
  reference_images: [
    "character_reference.png",  // Image 1: Character
    "style_reference.png"       // Image 2: Style
  ],
  model_id: "gemini-pro-image"  // Pro handles multiple refs better
})

Part 8: Troubleshooting Guide ​

Issue: "My Character Looks Different Each Time" ​

This is the most common issue. Systematic diagnosis:

Cause 1: No Reference Images ​

Symptoms: Character varies significantly with each generation.

Diagnosis:

typescript
get_character({ character_name: "Luna" })
// Check: reference_image_ids is empty or null

Solution: Add reference images:

typescript
// Generate a good reference
generate_image({ prompt: "character description..." })
// Note the image ID

// Update character with reference
update_character({
  character_name: "Luna",
  reference_image_ids: [42]
})

Cause 2: Poor Quality Reference Images ​

Symptoms: Character is somewhat consistent but details vary.

Diagnosis: View reference images:

  • Are faces clearly visible?
  • Is the image blurry or low resolution?
  • Does background compete with character?

Solution: Generate new, higher-quality references:

typescript
generate_image({
  prompt: "character description, clear face, simple background",
  aspect_ratio: "portrait"  // Face more prominent
})

Cause 3: Scene Prompt Conflicts with Base Prompt ​

Symptoms: Character looks correct sometimes, wrong other times.

Example conflict:

base_prompt: "wearing red varsity jacket"
scene_prompt: "in summer clothes at the beach"
// Conflict! Which outfit?

Solution: Keep scene prompts about action/location, not appearance:

typescript
// ❌ Wrong
scene_prompt: "wearing a swimsuit at the beach"

// ✅ Correct
scene_prompt: "at the beach"
additional_details: "beach setting, sunny day"
// Let the character's saved outfit be worn

Cause 4: Missing Identity Locking Phrase ​

Symptoms: Face changes between generations.

Solution: Use explicit identity locking:

typescript
generate_with_character({
  character_name: "Luna",
  scene_prompt: "at the market",
  additional_details: "Keep facial features exactly the same as reference"
})

Issue: "Character Not Found" Error ​

Cause 1: Spelling Mistake ​

Diagnosis: Check exact character name:

typescript
list_characters({ search: "Lun" })  // Partial search

Solution: Use correct spelling or character ID:

typescript
generate_with_character({
  character_id: 1  // ID never has spelling issues
})

Cause 2: Wrong Tenant ​

Symptoms: Character exists but isn't found.

Diagnosis: Characters are tenant-isolated. Verify you're using the correct API key for the tenant that owns the character.

Cause 3: Character Was Deleted ​

Diagnosis:

typescript
list_characters()  // List all characters

Solution: Recreate the character if needed.

Issue: Multi-Character Scene Not Working ​

Cause 1: Characters Blend Together ​

Symptoms: Hard to distinguish characters in scene.

Solution: Add distinctive features and spatial separation:

typescript
generate_with_multiple_characters({
  character_names: ["Luna", "Felix"],
  scene_prompt: "Luna (silver hair, purple cloak) on the LEFT,
                 Felix (black cat) on the RIGHT,
                 standing apart with space between them"
})

Cause 2: Wrong Character Count ​

Symptoms: Error about character count.

Solution: Use exactly 2-5 characters:

typescript
// ❌ Wrong
character_names: ["Luna"]  // Only 1!

// ✅ Correct
character_names: ["Luna", "Felix"]  // 2-5

Cause 3: Reference Image Limit Exceeded ​

Symptoms: Generation fails or quality degrades.

Calculation:

  • Each character has N reference images
  • Total references = sum of all characters' references
  • Flash limit: 4 total | Pro limit: 5 total

Solution: Reduce references per character. Each character gets up to 3 refs in multi-char scenes (MAX_MULTI_CHAR_IMAGES_EACH), and the total across all characters is capped at the model's limit.

Issue: Reference Images Not Loading ​

Cause 1: Invalid Image IDs ​

Diagnosis: Check if image IDs exist:

typescript
get_image_info({ image_id: 42 })  // Verify image exists

Solution: Use valid image IDs that belong to your tenant.

Cause 2: Images Were Deleted ​

Symptoms: Reference image URLs return 404.

Solution: Generate new reference images and update character:

typescript
// Generate new reference
generate_image({ prompt: "character description..." })
// -> Image ID 100

// Update character
update_character({
  character_name: "Luna",
  reference_image_ids: [100]
})

Issue: Style Inconsistency Across Scenes ​

Symptoms: Same character but different art styles.

Solution: Use consistent system_instruction:

typescript
// In character creation
create_character({
  character_name: "Luna",
  system_instruction: "Studio Ghibli anime style, soft lighting,
                       detailed backgrounds, warm color palette"
})

Or use style presets for all generations:

typescript
generate_with_character({
  character_name: "Luna",
  scene_prompt: "...",
  style_preset_name: "Anime Fantasy"  // Consistent style
})

10-Point Debugging Checklist ​

When character consistency fails, check:

  1. [ ] Reference images exist - get_character() shows reference_image_ids
  2. [ ] Reference quality is good - Clear faces, simple backgrounds
  3. [ ] Base prompt is specific - Physical features, not actions
  4. [ ] Scene prompt doesn't conflict - Action/location only
  5. [ ] Negative prompt is set - Prevents unwanted variations
  6. [ ] System instruction is consistent - Same style across scenes
  7. [ ] Identity locking phrase used - "Keep facial features..."
  8. [ ] Aspect ratio is appropriate - Portrait for single, landscape for multi
  9. [ ] Model is appropriate - Pro for complex identity locking
  10. [ ] Spelling is correct - Character name exactly matches

Part 9: Performance & Scale ​

Managing Large Character Libraries (100+ Characters) ​

Organization Strategy: Tags ​

Use tags to categorize characters:

typescript
create_character({
  character_name: "Luna",
  tags: ["protagonist", "fantasy", "book-1", "child"]
})

create_character({
  character_name: "Shadow",
  tags: ["antagonist", "fantasy", "book-1", "adult"]
})

// Filter by tag
list_characters({ search: "book-1" })
CategoryExample Tags
Roleprotagonist, antagonist, supporting, background
Projectbook-1, game-chars, marketing-2024
Typehuman, animal, creature, robot
Agechild, teen, adult, elderly
Statusactive, archived, draft

Naming Conventions ​

PatternExampleUse Case
Simple name"Luna"Main characters
Name + variant"Luna - Winter Outfit"Character variants
Project prefix"Book1-Luna"Multi-project organization
Name + age"Bob - Age 10"Age evolution

Pagination Best Practices ​

For large libraries, always paginate:

typescript
// Page 1
let result = await list_characters({ limit: 20, offset: 0 });

// Page 2
result = await list_characters({ limit: 20, offset: 20 });

// Search within results
result = await list_characters({
  search: "protagonist",
  sort_by: "used",  // Most used first
  limit: 10
});

Sort Options ​

Sort ByDescriptionUse Case
nameAlphabeticalBrowse library
createdNewest firstFind recent
usedMost used firstFind popular
recentRecently usedActive characters

Query Optimization Tips ​

  1. Use search instead of listing all:

    typescript
    // ❌ Slow for large libraries
    list_characters()
    
    // ✅ Faster with filter
    list_characters({ search: "Luna" })
  2. Limit results:

    typescript
    list_characters({ limit: 10 })  // Don't fetch 100+ at once
  3. Use IDs when known:

    typescript
    // ✅ Direct lookup (fastest)
    get_character({ character_id: 42 })
    
    // Slightly slower (name lookup)
    get_character({ character_name: "Luna" })

Storage Considerations ​

ComponentStorage LocationSize Considerations
Character metadataD1 Database~1KB per character
Reference imagesR2 Storage~500KB-2MB per image
Usage logsD1 Database~100 bytes per generation

Archiving Old Characters ​

For characters no longer actively used:

typescript
// Option 1: Tag as archived
update_character({
  character_name: "OldCharacter",
  tags: ["archived", "2023"]
})

// Option 2: Delete if truly unused
delete_character({ character_name: "OldCharacter" })
// Note: Deleting character doesn't delete generated images

Part 10: Tools Reference ​

Quick Reference: 7 Character Tools ​

ToolPurposeKey Parameters
create_characterSave new charactercharacter_name, base_prompt, reference_image_ids
update_characterModify charactercharacter_id/name, fields to update
delete_characterRemove charactercharacter_id/name
list_charactersBrowse librarysearch, sort_by, limit, offset
get_characterGet full detailscharacter_id/name
generate_with_characterGenerate scenecharacter_name, scene_prompt
generate_with_multiple_charactersMulti-charactercharacter_names[], scene_prompt

create_character ​

typescript
create_character({
  // Required
  character_name: "Luna",           // Unique per tenant (max 100 chars)
  base_prompt: "Young witch...",    // Appearance (10-2000 chars)

  // Optional
  description: "Main protagonist",   // Notes (max 500 chars)
  negative_prompt: "realistic...",   // What to avoid (max 1000 chars)
  system_instruction: "Anime...",    // Style guidance (max 1000 chars)
  reference_image_ids: [42, 43],     // Up to 10 image IDs
  preferred_aspect_ratio: "portrait", // Default aspect ratio
  tags: ["protagonist", "fantasy"]   // Up to 20 tags (50 chars each)
})

generate_with_character ​

typescript
generate_with_character({
  // Required (one of)
  character_name: "Luna",    // OR
  character_id: 42,

  // Required
  scene_prompt: "exploring magical forest",  // 5-1500 chars

  // Optional
  additional_details: "golden hour...",  // max 500 chars
  aspect_ratio: "landscape",             // override default
  override_negative_prompt: "...",       // override character's
  session_id: "custom-session"           // tracking
})

generate_with_multiple_characters ​

typescript
generate_with_multiple_characters({
  // Required (one of)
  character_names: ["Luna", "Felix"],  // OR
  character_ids: [1, 2],               // 2-5 characters

  // Required
  scene_prompt: "playing together...",  // 10-1500 chars

  // Optional
  additional_details: "sunny day...",
  aspect_ratio: "landscape",  // default for multi
  session_id: "custom-session"
})

REST API Quick Reference ​

EndpointMethodDescription
/api/charactersGETList characters
/api/characters/:idGETGet character
/api/charactersPOSTCreate character
/api/characters/:idPUTUpdate character
/api/characters/:idDELETEDelete character
/api/characters/:id/generatePOSTGenerate with character
/api/characters/generate-multiPOSTMulti-character generation

Storytelling & Comics ​

Goal: Generate consistent illustrations for a children's book.

typescript
// Setup: Create all characters
create_character({
  character_name: "Hero Henry",
  base_prompt: "brave 8-year-old boy, curly brown hair, blue cape,
                determined expression, children's book illustration",
  system_instruction: "Pixar-style 3D animation, vibrant colors,
                       friendly character design"
})

// Generate story scenes
const scenes = [
  "discovering a mysterious map in the attic",
  "setting off on adventure with backpack",
  "crossing a rickety bridge over a river",
  "meeting a friendly dragon in a cave",
  "celebrating victory with friends"
];

for (const scene of scenes) {
  generate_with_character({
    character_name: "Hero Henry",
    scene_prompt: scene,
    aspect_ratio: "landscape"
  });
}

Brand Mascots ​

Goal: Create consistent mascot for marketing materials.

typescript
create_character({
  character_name: "Banana Bob",
  base_prompt: "anthropomorphic banana character, big friendly eyes,
                wearing small chef hat, white gloves, cheerful smile",
  negative_prompt: "scary, realistic, photographic",
  system_instruction: "Cartoon mascot style, bold outlines,
                       bright yellow, family-friendly"
})

// Marketing variations
generate_with_character({
  character_name: "Banana Bob",
  scene_prompt: "waving hello, front facing"
})

generate_with_character({
  character_name: "Banana Bob",
  scene_prompt: "holding up product packaging proudly"
})

generate_with_character({
  character_name: "Banana Bob",
  scene_prompt: "giving thumbs up next to 5-star review"
})

Game Asset Generation ​

Goal: Create character sprites for game development.

typescript
create_character({
  character_name: "Warrior Kira",
  base_prompt: "female warrior, silver armor, red hair ponytail,
                battle-ready stance, fantasy RPG style",
  system_instruction: "2D game sprite art, clean lines,
                       suitable for animation, side-scrolling game aesthetic"
})

// Generate sprite variations
const poses = [
  { scene: "idle stance, facing right", name: "idle" },
  { scene: "walking animation frame, right foot forward", name: "walk1" },
  { scene: "walking animation frame, left foot forward", name: "walk2" },
  { scene: "sword attack swing, facing right", name: "attack" },
  { scene: "jumping in air, arms up", name: "jump" },
  { scene: "taking damage, recoiling back", name: "hurt" },
  { scene: "victory pose, sword raised", name: "victory" }
];

for (const pose of poses) {
  generate_with_character({
    character_name: "Warrior Kira",
    scene_prompt: `sprite sheet frame: ${pose.scene}`,
    additional_details: "transparent background, consistent scale",
    aspect_ratio: "square"
  });
}

Marketing Campaigns ​

Goal: Generate consistent influencer-style content.

typescript
create_character({
  character_name: "Marketing Sarah",
  base_prompt: "young professional woman, blonde bob haircut,
                warm smile, business casual, approachable",
  system_instruction: "Professional photography style,
                       natural lighting, lifestyle aesthetic"
})

// Campaign variations
generate_with_character({
  character_name: "Marketing Sarah",
  scene_prompt: "presenting at whiteboard in modern office"
})

generate_with_character({
  character_name: "Marketing Sarah",
  scene_prompt: "working on laptop in coffee shop"
})

generate_with_character({
  character_name: "Marketing Sarah",
  scene_prompt: "shaking hands with client in meeting room"
})

Educational Characters ​

Goal: Create characters for educational content.

typescript
// Create teacher character
create_character({
  character_name: "Professor Pixel",
  base_prompt: "friendly robot teacher, round body, screen face,
                antenna, blue and white colors, helpful expression",
  system_instruction: "Educational illustration style,
                       friendly, approachable, suitable for children"
})

// Educational scenarios
generate_with_character({
  character_name: "Professor Pixel",
  scene_prompt: "pointing at math equation on chalkboard"
})

generate_with_character({
  character_name: "Professor Pixel",
  scene_prompt: "demonstrating science experiment with beakers"
})

generate_with_character({
  character_name: "Professor Pixel",
  scene_prompt: "reading story book to group of children"
})

Appendix A: Parameter Reference ​

create_character Parameters ​

ParameterTypeRequiredMaxDescription
character_namestringYes100Unique name per tenant
base_promptstringYes2000Appearance description
descriptionstringNo500Human-readable notes
negative_promptstringNo1000What to avoid
system_instructionstringNo1000Style guidance
reference_image_idsnumber[]No10Image IDs as references
preferred_aspect_ratiostringNo-Default aspect ratio
tagsstring[]No20Organizational tags

generate_with_character Parameters ​

ParameterTypeRequiredMaxDescription
character_namestringOne of100Character name
character_idnumberOne of-Character ID
scene_promptstringYes1500Scene description
additional_detailsstringNo500Extra scene details
aspect_ratiostringNo-Override default
override_negative_promptstringNo1000Override character's
session_idstringNo-Custom session

Aspect Ratio Options ​

ValueRatioUse Case
square1:1Icons, avatars
portrait3:4Character focus
landscape4:3Scene with context
16:916:9Widescreen, multi-char
9:169:16Mobile stories
4:54:5Instagram
21:921:9Cinematic

Appendix B: Prompt Templates ​

Character Creation Template ​

[Age]-year-old [gender], [body type], [face shape],
[hair: color, length, style], [eyes: color, shape],
[distinctive features: freckles, scars, etc.],
wearing [outfit: top, bottom, footwear, accessories],
[pose/stance], [art style]

Scene Prompt Template ​

[action/pose] in [location], [additional context]

Identity Locking Template ​

Go Bananas! automatically generates this prompt format when you use generate_with_character:

The character in Image 1 — keep the face, hair, and outfit EXACTLY the same.
Character details: [base_prompt].
Scene: [scene description], [additional details]

For multi-character scenes, each character gets its own Image index:

[Name1] is the character in Image 1 ([base_prompt_1]);
[Name2] is the character in Image 2 ([base_prompt_2]).
Keep every character's face, hair, and outfit EXACTLY the same as their reference image.
Scene: [scene description]

Multi-Character Template ​

[Character 1 name] and [Character 2 name] [interaction verb] in [location].
[Character 1 name] is [position/action],
[Character 2 name] is [position/action].
[atmosphere/lighting]

Appendix C: Troubleshooting Decision Tree ​

Character looks different?
│
├─ No reference images?
│  └─ Add reference images → Problem solved
│
├─ Poor reference quality?
│  └─ Generate better references → Problem solved
│
├─ Scene prompt conflicts?
│  └─ Remove appearance from scene prompt → Problem solved
│
├─ Missing identity lock phrase?
│  └─ Add "Keep facial features..." → Problem solved
│
├─ Style inconsistent?
│  └─ Set system_instruction or use style preset → Problem solved
│
├─ Using Flash for complex scene?
│  └─ Switch to Pro model → Problem solved
│
└─ Still not working?
   └─ Recreate character with new, high-quality references

Appendix D: Glossary ​

TermDefinition
Base PromptText description of character's permanent physical features
Character LibraryCollection of all saved characters for a tenant
Identity LockingTechnique to explicitly instruct AI to maintain visual identity
Multi-TenantArchitecture where each user/organization has isolated data
Reference ImageVisual example that anchors character appearance
Scene PromptDescription of what character is doing in specific image
SessionSingle conversation/workflow context
Style PresetReusable prompt template for consistent artistic style
TenantIsolated user account with own characters, images, and data

Summary ​

Character consistency in Go Bananas! follows these principles:

  1. Create once, use everywhere - Save characters with detailed base prompts
  2. Reference images are critical - They anchor visual appearance
  3. Use identity locking - Explicitly instruct AI to maintain features
  4. Keep scene prompts simple - Action/location, not appearance
  5. Match model to task - Flash for iteration, Pro for production
  6. Organize at scale - Use tags and naming conventions

With these techniques, you can generate unlimited consistent images of any character across any number of scenes and sessions.


For additional help:

Released under the MIT License.