Skip to content

Chapter 29 — Image Generation

Part VII — Systems

Headless portrait generation pipeline with pluggable providers.

@ai-rpg-engine/image-gen — depends on @ai-rpg-engine/asset-registry for storage.

Terminal window
npm install @ai-rpg-engine/image-gen
PortraitRequest → Prompt Builder → Image Provider → Asset Registry
↓ ↓ ↓
genre presets ComfyUI / SVG content-addressed
trait flavor placeholder SHA-256 hash

The pipeline converts character metadata into a generation prompt, sends it to a provider, and stores the result in the asset registry. The returned hash becomes the portraitRef on the character build.

buildPortraitPrompt(request) assembles a prompt from:

  • Character name and title
  • Archetype and discipline class names
  • Background origin
  • Trait descriptions
  • Genre-specific style preset

Example output:

Portrait of Aldric, Grave Warden, Penitent Knight and Occultist,
Oath-Breaker origin, known for being Iron Frame and Cursed Blood,
dark fantasy oil painting, dramatic lighting, detailed armor and cloth textures
ProviderBackendDependenciesUse Case
PlaceholderProviderSVG with initialsNoneTesting, development
ComfyUIProviderComfyUI HTTP APIComfyUI serverLocal GPU generation

Generates deterministic SVG images with character initials on a color-coded background. Always available, zero dependencies.

Calls ComfyUI’s REST API directly:

  1. POST workflow to /prompt
  2. Poll /history/{id} for completion
  3. Fetch image from /view

Works with any ComfyUI installation, including comfy-headless.

Implement the ImageProvider interface:

interface ImageProvider {
readonly name: string;
generate(prompt: string, opts?: GenerationOptions): Promise<GenerationResult>;
isAvailable(): Promise<boolean>;
}

9 built-in presets map genres to art direction:

GenreStyle Direction
fantasyDark oil painting, dramatic lighting, medieval textures
cyberpunkNeon lighting, chrome, rain-slicked streets
mysteryVictorian noir, gaslight, fog and shadow
pirateGolden age maritime, weathered, dramatic ocean sky
horrorDark illustration, unsettling, muted palette
westernWeird west, dusty frontier, supernatural undertones
  • generatePortrait(request, provider, store) — generate and store a new portrait
  • ensurePortrait(request, provider, store) — return existing or generate new
  • buildPromptPair(request) — get both positive and negative prompts