Nodes/comfyui-scene-generator/🎲 Scene Character Roller
ComfyUI Node

🎲 Scene Character Roller

Roll a whole cast of characters with one node each — no LoRAs required

By elliefox-ai·Created 3 months ago·Updated 11 days ago· 2
🎲 Scene Character Roller
    • character
    • components_json
    • seed_used
    genre🎲 random
    consistency0.70
    face_detaillow
    hair_modemodular
    body_detaillow
    emphasisoff
    heatoff
    character_registernone
    body_typerandom
    roleany
    name
    posefalse
    positioningfalse
    expressionfalse
    seed42
    age🎲 random
    sex🎲 random
    race🎲 random

    The Scene Character Roller answers the question nobody likes asking in ComfyUI: who the hell is the person in my image? You've built a nice venue, you've picked a mood, and now there's an empty spot in the frame. Drop one of these in, pick an era, and it writes you a complete character - identity, outfit family, palette, face, posture - as one text string.

    It's from the Scene Context pack (elliefox-ai/comfyui-scene-generator) by Ellie and Alexander Dutton, a small suite of procedural narrative-context nodes. The key rule: one node, one character. Have three people in your scene? Add three rollers. That's the whole design philosophy - and it's smart given how badly diffusion models merge two described characters into one blob. Since character is pure text, you can chain a roller into a Scene Context Picker or Composer slot, or just wire it into a CLIP Text Encode and forget the rest of the pack exists.

    How it rolls

    The mechanism is a seeded random walk over tagged banks, and it's refreshingly principled. Draw order is fixed and documented in the code: identity first, then genre, then everything downstream. The age, sex, and race inputs are each either 🎲 random or a firm value; the resolved identity is stated once in an opening phrase ("an older white woman") and then every feature draw is soft-weighted toward it. That's affinity, never a filter - the tooltip puts it bluntly: "the occasional age-mismatched detail is the point." Vocabulary maps through phrase banks, so nothing raw leaks into your prompt.

    The consistency slider (default 0.7) is the star. It's the probability that each garment honors one target outfit family pulled from the era's bank. At 1.0 you get head-to-toe coherence - one family, one palette, the full "this is a knight" look. At 0.0 every piece rolls independently - a thrift-store look, which for a drifter or scavenger is exactly what you want. detail flips between low - wide-shot legible: outer layer, face shape, hair, eyes, maybe one mark - and high, a portrait ladder of layers, wear, complexion, and build, sampled never exhaustive.

    Three outputs: character (the assembled string), components_json (each piece exposed separately, in case you want to remix), and seed_used - more on that below.

    The inputs that actually matter

    You can touch everything, but a beginner really sets four things:

    • genre - the era. Set a firm genre on every roller if you want a coherent cast; leave it 🎲 and each character rolls its own era (weird, but occasionally delightful).
    • consistency - how coherent the outfit is. 0.7 is a good default; push toward 1.0 for heroes, down toward 0.3 for street crowds.
    • detail - low for wide shots, high for close-ups/portraits.
    • seed - the node is a pure function of its inputs. Change the seed to re-roll, keep it to lock a character.

    name is optional but worth knowing: "Abigail" prefixes the whole description and acts as a binding handle that helps the renderer keep details attached to that figure. pose and positioning bake in a stance or a frame-position phrase - the tooltip warns the scene nodes have the same toggles, so if both fire you get doubled placement, and that's on you.

    Installing it

    Via ComfyUI Manager, search for "comfyui-scene-generator" (pack title: comfyui-scene-generator). Or the manual way:

    cd ComfyUI/custom_nodes/
    git clone https://github.com/elliefox-ai/comfyui-scene-generator.git
    

    Restart ComfyUI and look for the nodes under SceneGen in the menu. This is the good kind of node pack: zero extra Python dependencies, no models to download, no API keys. All local text logic over JSON banks - install takes seconds and it runs on anything.

    Gotchas

    The one real trap is the tag law. The pack validates every tag in its data files against tags.json at ComfyUI startup - an unknown tag is a hard startup failure that names the offending venue and stops ComfyUI from booting. By design (it catches data drift), but it means hand-editing the JSON banks and getting a tag wrong fails loudly and non-negotiably. Don't touch the data until you understand the registry.

    Second gotcha is the re-roll footgun. The node is deterministic per seed, so ComfyUI's cache treats it like any pure node - change the seed to force a new roll, or you'll get the same character forever. And if you wire seed_used into a sampler, the roller's seed silently controls your whole generation, which is easy to forget when debugging why two runs look identical.

    Is this the tool for locked, reusable characters? No - that's what LoRAs and reference/editing models are for. It's for the generative side: casting believable, varied people into scenes without hand-writing forty descriptions. For that, it's quietly excellent - one node per face, and your crowd scene stops looking like one person cloned six times.

    CategorySceneGen

    Inputs (18)

    NameTypeDefaultDescription
    genreCOMBO🎲 random🎲 rolls this character's era independently. For a shared-era cast, set the same firm genre on every roller node (a shared source input is the parked next step). A firm genre binds every draw to that era's families.
    consistencyFLOAT0.700–1How much this character honors the genre's substyle, garment by garment. 1 = full coherence: one outfit family head to toe, one palette. 0 = random character style: every piece rolls independently (firm genre keeps the mismatch within the era). Between = mostly-family with wandering pieces.
    face_detailCOMBOlowFace ladder. low = wide-shot legible: face shape, hair, eyes, maybe a mark — reads at distance. high = portrait ladder: complexion, nose, mouth, jaw, cheekbones, brow, ears sampled under a phrase budget (~6 face phrases, never the whole list).
    hair_modeCOMBOmodularModular: hair composed from facedetailer-style sections (length × color × bangs × style × parting × texture × hairline × grooming × accessory) into one sentence — thousands of coherent combinations, gated by length class (ties need length; shorn closes sections; pixie up, buzz/undercut rare by measurement). Legacy: the old static pool + slot compose. Same seed differs across modes (draw order changes).
    body_detailCOMBOlowBody depth. minimal = portrait companion: one guaranteed build word for proportions, single outer garment, no layers. low = wide-shot: outer garment + palette, build usually. high = garment ladder (wear state, layered pieces) + build. Pair with face_detail=high for closeup portraits.
    emphasisCOMBOoffCorroboration dial for the build — the trait diffusion under-reads. low = one independent restatement rides in the body sentence ('a lean build, no wasted weight on them'); high = two. Adds angles, never intensifiers: 'very lean' does nothing, a second physical observation does. Same seed + off reproduces the plain register exactly.
    heatCOMBOoffHeat dial — silhouette & reveal only, never color or material. off = the plain register (zero extra draws; same seed, same string). suggestive = one garment gains a fit-and-fabric state ('pulled taut across the chest'). flirty = one explicit reveal ('cropped above the navel'). smoldering = two garments at the hottest states — steamy-but-clothed by design (FlatDeep-safe). With pose on, the posture draw comes from the heat register instead. Needs garments to touch: pair with body_detail=high for the full effect.
    character_registerCOMBOnone🎲 What this character IS in the frame — the sheet says it in words and the dice follow. none = fair dice, silent sheet (the old cinematic). authentic = the real thing — wear up, marks up, but fine families (evening, office) keep their clothes; a role's full-rig reads as UNIFORM. pulp = romanticized — scars become backstory, swagger in every seam. costume = a person in costume — pristine, props, reads as COSTUME. cartoon = drawn for Saturday morning — pristine, marks rare, one exaggeration clause (known ceiling: sheet words can't bend the render style). random = rolls a mode per character, so mixed-register crowds come free. Retired dial mapping: documentary→authentic, stylized→costume, cinematic→none. Old seeds die.
    body_typeCOMBOrandom🎲 random rolls the build archetype each time; physique children (chest/legs/arms at body detail low/high) weight toward the drawn parent. A fixed value (muscular, willowy, heavyset…) forces the parent every roll — a distinct set of characters. Children stay soft-influenced, never locked.
    roleCOMBOanyPersona register — closed set of ten (warrior, worker, scholar, healer, leader, drifter, athlete, caregiver, charmer, gala) or any. Weights the draw: wardrobe family, garments, wear states, build. Soft affinity, never a lock.
    nameSTRINGOptional. 'Abigail'. Prefixes the description — a binding handle that helps the renderer cohere details to this specific figure. Blank = no name.
    poseBOOLEANfalseBake a posture phrase into the character ('weight sunk into one hip'). Static stance register — no actions.
    positioningBOOLEANfalseBake a position phrase into the character ('on the near side of the frame'). The scene nodes have the same toggle — if both fire, doubled placement is on you.
    expressionBOOLEANfalseBake a facial-expression sentence into the character ('brow knotted, lips a thin line'). Name-bound when the figure has a name, bare fragment otherwise — same pool as the scene nodes' expression toggle.
    seedINT420–4294967295
    ageCOMBO🎲 random🎲 rolls this figure's age, then weights every feature draw toward it (soft affinity — never a filter; the occasional age-mismatched detail is the point). Stated once in the identity phrase: 'an older…'. Fixed values weight the pools the same way.
    sexCOMBO🎲 random🎲 rolls this figure's sex and weights feature draws toward it. Stated once in the identity phrase ('…woman' / '…man'). The wardrobe banks stay unisex — sex never gates garments.
    raceCOMBO🎲 randomBroad-stroke, descriptive register. 🎲 rolls this figure's race, weights feature draws toward it, and (at face_detail=high) adds a complexion phrase keyed to it. Dropdown values never enter the string raw — vocabulary maps through phrase banks, stated once.

    Outputs (3)

    NameTypeDescription
    characterSTRING
    components_jsonSTRING
    seed_usedINT