Nodes/Identity Forge/Identity Forge
ComfyUI Node

Identity Forge

One queue, a brand-new person every time — ComfyUI's Identity Forge, explained

By EnragedAntelope·Created 2 months ago·Updated about 23 hours ago· 19
Identity Forge
    • prompt_text
    • prompt_json
    seed0
    genderAny
    wardrobeMatch gender
    size_scaleAuto
    hair_color_scopeNatural only
    accessory_densityBalanced
    location_settingAny indoor/outdoor
    set_all_fieldsOff
    ageRandom
    ethnicityRandom
    skin_toneRandom
    body_typeRandom
    heightRandom
    bustRandom
    waistRandom
    hipsRandom
    face_shapeRandom
    foreheadRandom
    cheekbonesRandom
    eyebrowsRandom
    eye_colorRandom
    eye_shapeRandom
    noseRandom
    lipsRandom
    smile_typeRandom
    jawlineRandom
    chinRandom
    complexionRandom
    skin_detailsRandom
    freckles_densityRandom
    hair_colorRandom
    hair_lengthRandom
    hair_textureRandom
    hair_styleRandom
    facial_hairRandom
    hair_accessoryRandom
    makeup_styleRandom
    eyebrow_makeupRandom
    eye_makeupRandom
    eyelinerRandom
    lashesRandom
    contourRandom
    highlightRandom
    blushRandom
    lips_makeupRandom
    skin_finishRandom
    earringsRandom
    necklaceRandom
    other_jewelryRandom
    piercingsRandom
    nailsRandom
    outfit_styleRandom
    bagRandom
    accessoriesRandom
    expressionRandom
    locationRandom
    lightingRandom
    shot_typeRandom
    shoulder_widthRandom
    neck_lengthRandom
    postureRandom
    fitness_levelRandom
    hair_partRandom
    hair_highlightsRandom
    ringsRandom
    braceletRandom
    watch_typeRandom
    footwearRandom
    clothing_colorRandom
    clothing_patternRandom
    seasonRandom
    moodRandom
    poseRandom
    compositionRandom
    tattoosRandom
    legwearRandom
    tattoo_placementRandom
    archetype_json

    You know the loop. You sit in ComfyUI trying to describe a person, type "young woman, auburn hair, green eyes," and get a face that's suspiciously close to every other face you generated this week. Or you batch for variety and half the outputs are the same person in a slightly different outfit. Identity Forge is the node that breaks that loop: it's a character generator built out of dropdowns. Pick the traits you care about, leave the rest on Random, and every queue hands you a new, internally consistent person described in clean prose you can wire straight into CLIP Text Encode.

    That's the whole pitch, and it earns it. The dropdowns run to roughly seventy fields across Demographics, Body, Face, Hair, Makeup, Jewelry & Nails, Clothing, and Setting & Shot - enough granularity that you can lock "redhead, freckled, 25, librarian-ish" and let everything else roll. But the real trick is what happens between the roll and the output.

    Why it doesn't produce prompt soup

    If you've come from the wildcard world ({brown|blonde|black} hair), you know the failure mode: nothing stops a randomizer from rolling a buzz cut and braids, or a handbag with gym gear, or an Irish subject in ebony skin. Identity Forge's answer is a constraint engine that resolves those clashes after the fact. A buzz cut never gets a braid, "no makeup" clears every cosmetic, an athletic outfit drops the handbag. The priority order is the part worth internalizing: a rule never overrides a field you locked. It logs an [IdentityForge] notice and keeps your value. So "lock what you care about, let the rest roll" isn't a tagline, it's the mechanism.

    One more design choice to know about: gender is a hard gate, not a coherence rule. Point a masculine preset at a Female node and it never produces a beard - the engine drops the incompatible value and re-rolls it inside the female pool. gender: Any resolves to a coherent man or woman per seed, so you never get a beard sitting next to a feminine bust.

    The inputs that actually matter

    • seed - the control below defaults to randomize, so every run is a new person. Flip it to fixed and the same character comes back exactly. That's your reproducibility story, and it works.
    • gender + wardrobe - gender: Any rolls a coherent man OR woman per run. Add wardrobe: Any and you unlock genuinely mixed-gender output. Want a man in feminine clothes without the mixed pools? wardrobe: Feminine.
    • accessory_density - drop it to Minimal or None for clean portraits without hand-locking two dozen fields.
    • location_setting - Studio / solid backdrop forces a plain, easily maskable background (grey, white, black, chroma-key green) plus clean studio light. Your inpaint-friendly backgrounds come from here.
    • set_all_fields - All to None blanks every field still on Random, so only the ones you lock appear. Ideal for a character-only description you want to splice into a scene you write yourself.

    The scene fields deserve their own warning because people trip on them. The location is what stands: if it rolls an indoor spot, the lighting adapts to it - you never get a spice-market stall lit by "dappled sunlight through forest canopy." Most locations are interiors, which is why random daylight is deliberately rare. Set location_setting: Outdoor when you want sunny golden-hour looks, or lock a light like harsh desert sun and the location re-rolls to fit it.

    Outputs

    The node emits two things: prompt_text (STRING) - the natural-language paragraph you connect to CLIP Text Encode - and prompt_json (STRING), the same character as structured JSON nested by group, with a small _meta block. The JSON is what you feed to the pack's own Vault Save node, or use however you like.

    Install

    Zero dependencies, fully offline - no LLM, no API keys, no model downloads. requirements.txt is a comment saying exactly that.

    cd ComfyUI/custom_nodes
    git clone https://github.com/EnragedAntelope/comfyui-identity-forge
    

    Then restart ComfyUI. Or use ComfyUI Manager and search "Identity Forge". One catch: the pack is built on ComfyUI's V3 API (comfy_api.latest) and needs ComfyUI 0.25.0 or newer - if it doesn't load after install, update ComfyUI first.

    Troubleshooting

    The one issue the maintainer documents: after a pack update you can hit a NoneType error or a blank/missing widget on a saved graph. The node's fields are built when it's created, so an old node holds stale widgets. Delete and re-add the node (or recreate it) and it clears - reselect any locked values afterward. Worth knowing that locking a field on a cosplay character you then chain upstream will respect it; the node closest to Identity Forge wins where presets overlap.

    Honest caveat before you go: this generates text, and the checkpoint renders the person. It won't give you the same face across fifty renders - that's LoRA/adapter territory, and Identity Forge is a complement to it, not a replacement. Use it to roll OCs until one clicks, then build consistency around that. For its actual job - fast, varied, coherent people for portraits, crowds, or just staring at fresh faces - it's hard to beat.

    Categoryconditioning/character

    Inputs (78)

    NameTypeDefaultDescription
    seedINT00–18446744073709550000Seed for reproducible randomization. The control below defaults to 'randomize' so every run differs; set it to 'fixed' to reproduce a character.
    genderCOMBOAnySteers gender-specific presentation and pronouns: 'Male' keeps the random fill masculine (no makeup, polish, feminine jewellery or hairstyles), 'Female' allows them. 'Any' rolls a coherent man OR woman each run (set wardrobe to 'Any' to instead unlock every mixed-gender combination). Locked / archetype / cosplayer values are always respected; 'Any' defers to a connected archetype's gender.
    wardrobeCOMBOMatch genderWhich outfit wardrobe to draw from -- and how the character presents. 'Match gender' keeps outfits typical for the chosen gender; 'Feminine' / 'Masculine' force a wardrobe (e.g. a man in feminine outfits). 'Any' mixes outfits -- and, when gender is also 'Any', unlocks fully mixed-gender features too. On a man, 'Feminine' / 'Any' also lift the masculine defaults for jewellery, nails and makeup so a full femme look is reachable. 'Auto (preset)' defers to a wired character's own saved wardrobe (use it when recalling a vault save made with 'Any').
    size_scaleCOMBOAutoForce an unrealistic body scale on an otherwise ordinary person -- a doll-sized office worker, a fifty-foot commuter. 'Auto' (the default) says nothing about scale and is NEVER chosen at random, so this control only ever does something when you pick a tier yourself -- it cannot affect normal randomized output. A tier replaces the height description in the opening sentence, and overrides a connected Cosplayer's own scale, so you can make any character giant or tiny.
    hair_color_scopeCOMBONatural onlyDefaults to realistic hair colours; choose 'Full spectrum' to allow fantasy shades (pink, blue, ...). 'Auto (preset)' defers to a wired character's own saved scope (use it when recalling a vault save made with 'Full spectrum').
    accessory_densityCOMBOBalancedHow often random characters carry bags / jewellery / accessories. 'Balanced' keeps it tasteful, 'None' strips them, 'Maximal' decks everyone out. (Fields you lock are unaffected.)
    location_settingCOMBOAny indoor/outdoorRestrict the random location. 'Any indoor/outdoor' (default) picks any real scene but never a studio. 'Studio / solid backdrop' forces a plain, easily-maskable background (grey, white, black, or chroma-key green screen) and a clean studio light. A locked location overrides this.
    set_all_fieldsCOMBOOffQuick reset for the fields below. 'All to None' omits every field left on 'Random', so only the fields you lock to a specific value appear in the output. A wired costume and the character's signature look (hair, eyes, physique) are kept. Handy for tweaking a cosplay: blank the random-person noise, then enable just the fields you want.
    ageCOMBORandomApparent age in years. Demographics · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    ethnicityCOMBORandomAlso nudges skin tone toward a plausible range; locking skin tone overrides that. Demographics · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    skin_toneCOMBORandomOverall skin colour. A costume that colours the whole body replaces this. Body · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    body_typeCOMBORandomOverall build and proportions. Muscle definition is separate - see fitness_level. Body · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    heightCOMBORandomRelative height. To force an unrealistic scale (doll-sized, fifty feet tall), use the size_scale control near the top instead. Body · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    bustCOMBORandomChest size and shape. Renders as 'chest' on a male subject. Body · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    waistCOMBORandomWaist width relative to the rest of the figure. Body · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    hipsCOMBORandomHip width relative to the rest of the figure. Body · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    face_shapeCOMBORandomOverall shape of the face - oval, square, heart. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    foreheadCOMBORandomForehead height and brow ridge. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    cheekbonesCOMBORandomHow high and prominent the cheekbones sit. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    eyebrowsCOMBORandomNatural brow shape and thickness. Grooming and product are eyebrow_makeup. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    eye_colorCOMBORandomIris colour. A cosplay character with non-human eyes overrides this. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    eye_shapeCOMBORandomEye shape and set - almond, hooded, deep-set. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    noseCOMBORandomNose shape and bridge. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    lipsCOMBORandomLip shape and fullness. Colour and finish are lips_makeup. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    smile_typeCOMBORandomWhat the mouth is doing - closed, toothy, smirking. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    jawlineCOMBORandomJaw width and definition. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    chinCOMBORandomChin shape and projection. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    complexionCOMBORandomSkin quality and undertone - rosy, sallow, weathered. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    skin_detailsCOMBORandomMoles, beauty marks, scars and other distinguishing marks. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    freckles_densityCOMBORandomHow heavily freckled the skin is. Face · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    hair_colorCOMBORandomLimited to realistic shades unless the hair_color_scope control is set to 'Full spectrum'. Hair · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    hair_lengthCOMBORandomHair length. Styles that need more length are automatically excluded on short cuts. Hair · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    hair_textureCOMBORandomCurl pattern and body - straight, wavy, coily, fine. Hair · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    hair_styleCOMBORandomHow the hair is worn. Styles needing gatherable length are dropped automatically on a pixie or a buzz cut, and the short barbered crops only appear on short hair. Hair · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    facial_hairCOMBORandomBeard and moustache. Randomized only on male subjects. Hair · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    hair_accessoryCOMBORandomHeadband, clip, scarf in the hair. Dropped automatically when a costume is supplied. Hair · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    makeup_styleCOMBORandomThe overall makeup look. Set it to 'no makeup' and every other Makeup field clears automatically; male subjects default to bare-faced. Makeup · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    eyebrow_makeupCOMBORandomBrow grooming and product. Natural brow shape is the eyebrows field. Makeup · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    eye_makeupCOMBORandomEyeshadow colour and finish. Makeup · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    eyelinerCOMBORandomLiner style and weight. Makeup · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    lashesCOMBORandomMascara or falsies. Makeup · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    contourCOMBORandomSculpting on the cheeks, nose and jaw. Makeup · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    highlightCOMBORandomWhere the skin catches the light. Makeup · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    blushCOMBORandomCheek colour and placement. Makeup · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    lips_makeupCOMBORandomLip colour and finish. Lip shape is the lips field. Makeup · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    skin_finishCOMBORandomHow the base reads - matte, dewy, glass. Makeup · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    earringsCOMBORandomEar jewellery. Name earrings in a costume only if you also lock this field, or you get two sets. Jewelry & Nails · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    necklaceCOMBORandomNeck jewellery. Same caution as earrings if a costume already describes one. Jewelry & Nails · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    other_jewelryCOMBORandomBrooches, anklets, body chains and the like. Jewelry & Nails · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    piercingsCOMBORandomPiercings other than earlobes. Jewelry & Nails · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    nailsCOMBORandomNail length, shape and polish. Jewelry & Nails · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    outfit_styleCOMBORandomHow dressed up, and for what occasion. Subculture and era themes live on the Archetype node instead. Clothing · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    bagCOMBORandomBag carried. Dropped automatically when a costume is supplied. Clothing · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    accessoriesCOMBORandomHats, glasses, gloves, belts and scarves. Dropped automatically when a costume is supplied, and gloves suppress nail polish and rings. Clothing · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    expressionCOMBORandomThe face the subject is pulling. Dropped automatically behind a full mask or helmet, unless you lock it. Setting & Shot · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    locationCOMBORandomWhere the shot happens, including named world landmarks. Narrow it with the location_setting control; a value locked here overrides that control. Setting & Shot · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    lightingCOMBORandomQuality and source of the light. Automatically kept coherent with whether the location is indoors or out. Set to 'None' if a downstream rendering pack owns this axis. Setting & Shot · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    shot_typeCOMBORandomThe camera only - distance, height, angle and lens. Never scene content. Setting & Shot · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    shoulder_widthCOMBORandomShoulder breadth relative to the hips. Body · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    neck_lengthCOMBORandomNeck length and thickness. Body · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    postureCOMBORandomHow the subject carries themselves - upright, slouched, confident. Body · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    fitness_levelCOMBORandomHow conditioned the body looks, from sedentary to muscular. This is where muscle lives, not body_type. Body · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    hair_partCOMBORandomWhere the hair is parted. Cleared automatically on a bald or buzzed head. Hair · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    hair_highlightsCOMBORandomColour worked through the hair - balayage, streaks, frosted tips. Hair · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    ringsCOMBORandomFinger rings. Jewelry & Nails · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    braceletCOMBORandomWrist jewellery. Jewelry & Nails · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    watch_typeCOMBORandomWristwatch. Dropped automatically when a costume is supplied, so no smartwatch on a samurai. Jewelry & Nails · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    footwearCOMBORandomShoes. Voiced with the generated outfit, so locking this actually changes the shoes. Narrowed to what the chosen outfit_style plausibly wears; a supplied costume overrides it. Clothing · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    clothing_colorCOMBORandomDominant palette of the outfit, voiced as an adjective in front of the garment ("a jewel-toned satin slip gown"). Yields to a garment that names its own colour. Clothing · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    clothing_patternCOMBORandomPrint or weave of the outfit. Yields to a garment that names its own (a denim or sequined piece), and a monochrome palette rules out multi-colour prints. Clothing · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    seasonCOMBORandomTime of year, which colours the setting and wardrobe. Setting & Shot · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    moodCOMBORandomOverall emotional tone of the image. Set to 'None' if a downstream rendering pack owns this axis. Setting & Shot · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    poseCOMBORandomWhat the body is doing. A pose needing something the subject lacks is dropped: hair or pockets to reach for, a free hand when a prop is held, a seat at giant scale. A lock wins. Setting & Shot · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    compositionCOMBORandomWhere the subject sits within the frame - layout, not camera position. Kept coherent with shot_type. Setting & Shot · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    tattoosCOMBORandomBody ink - style and how much of it. Deliberately uncommon at random, and scaled by the accessory density control. Where it sits is tattoo_placement. Body · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    legwearCOMBORandomTights, stockings or socks. Only rendered when the outfit actually shows leg, so it never appears under trousers. Feminine wardrobe only. Clothing · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    tattoo_placementCOMBORandomWhere the tattoo sits. Placements the clothing would hide are dropped automatically - no forearm ink under long sleeves, no thigh ink under a skirt-less outfit or opaque tights. Body · 'Random' = randomize, a value = lock, 'None' = omit from the output.
    archetype_jsonoptSTRINGConnect an IdentityForgeArchetype, IdentityForgeCosplayer or IdentityForgeCreature here (chain several via their 'upstream' inputs). Its fields seed the character; explicit non-'Random' widgets still override it. Leave unconnected (or use 'None') for no override.

    Outputs (2)

    NameTypeDescription
    prompt_textSTRING
    prompt_jsonSTRING