⭐ Star Character Builder
Roll a whole person out of dropdowns, reference sheet included
- description
- character_sheet
- system_prompt
This node produces zero pixels. It writes text. Twenty dropdowns of traits - sex, ethnicity, build, hair, outfit, style - get assembled into one comma-separated character description, plus a second output that's a full character reference sheet prompt. If you wanted a faster way to fill a CLIP Text Encode box with a person, that's the pitch. It calls no API and needs no model; it's a JSON file with a UI on top.
Why you'd reach for it
Character consistency is the problem everyone bangs their head on: the model makes one great character, then a completely different person on the next run. The answer the community landed on wasn't "encode and re-inject," it was "generate the character once, then edit that image." Which makes the reference sheet - front, back, face close-ups, one grid - the artifact that survives contact with edit models.
Writing that sheet prompt by hand is miserable. You forget the back view. You forget to forbid text labels. You end up with two panels of the same face and no profile. This node writes it for you, strict layout included.
How it works
Everything is driven by json/star_character_builder.json inside the pack folder. Each key that's a list becomes one dropdown. Every dropdown starts with three special values: none skips the trait, random picks an entry, and exclude leaves it out - the difference only shows when random_all is on, where exclude protects the category you deliberately left blank. Otherwise exclude behaves exactly like none.
Randomness runs through Python's random.Random(seed): a fixed seed gives you the same character, seed: 0 gives a fresh roll every queue. The node forces itself to re-run each queue anyway (its IS_CHANGED returns the current time), so a 0 seed genuinely re-rolls rather than being cached.
Two assembly quirks: hairstyle and hair colour get merged (long wavy hair + blonde → long wavy blonde hair), and eye colour gets eyes appended if the word isn't in it. Otherwise traits come out in a fixed order, lead first, so the result reads like a person rather than a keyword dump.
The inputs and outputs that matter
You'll set random_all, seed and style and leave the rest alone most of the time. style defaults to photorealistic - the one dropdown whose default isn't none. age is free text where a bare number becomes 25 year old, or you flip random_age for a random 18–100 from the JSON settings. additional is your escape hatch for quality tags and scene dressing.
The wear rule is the fiddly bit: pick wear categories by hand and they get joined with "and", but under random_all only one of clothing / female_outfit / male_outfit / lingerie / kinky_outfit is chosen per run. Sensible - nobody wears a three-piece suit and a latex catsuit.
Three outputs, all STRING. description is the plain comma-separated prompt - wire it into a positive CLIP Text Encode and go. character_sheet is the grid prompt; it ignores pose, and the character is naked in the main body views unless you select a wear category. system_prompt goes into an LLM node's system message with description as the user message, so the model expands your character into a sheet prompt itself.
Heads-up: the sheet output is written for uncensored models. It asks for anatomical close-up panels with explicit single-sex genitalia wording and a no-hermaphroditic-traits safeguard, and a filtered checkpoint will either ignore those clauses or fight them. The description output is the tame one.
Installing it
ComfyUI Manager, search Starnodes, install, restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/Starnodes2024/ComfyUI_StarNodes
cd ComfyUI_StarNodes
pip install -r requirements.txt
That requirements file is for the pack's PSD, video, palette and Ollama nodes. This node needs nothing beyond the standard library and its own JSON file.
Worth knowing what you're installing: StarNodes is a one-developer pack of 100+ nodes (v3.1.0), announced by its author on r/comfyui in low-engagement update posts. Actively maintained, not battle-tested.
Common issues
- Your JSON edits don't show up in the dropdown. Expected - new entries appear after a ComfyUI restart.
randompicks read the file immediately, though, so you can add an entry and randomize into it in the same session. - Prompts come out nearly empty. Check the console for
StarNodes: Could not load star_character_builder.json. Malformed JSON makes every list load empty, so random picks resolve to nothing and you're left withstyleandadditional. Validate withpython -m json.tool json/star_character_builder.json. random_allwon't give you a naked sheet. It always picks a wear category unless you set all five of those dropdowns toexclude, or list them in the JSONsettings.excludearray.- You found a character you liked and lost it. Set the seed control to
fixedbefore you queue, or switch the global "widget control mode" setting to Before - otherwise the number in the box is the seed for the next run, not the one that just rendered.
Inputs (25)
| Name | Type | Default | Description |
|---|---|---|---|
| sex | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| type | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| ethnicity | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| skin_tone | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| body_build | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| hairstyle | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| hair_color | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| eye_color | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| makeup | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| clothing | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| female_outfit | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| male_outfit | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| lingerie | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| kinky_outfit | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| accessories | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| sextoy | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| expression | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| pose | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| custom | COMBO | none | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| style | COMBO | photorealistic | 'none' skips this trait, 'random' picks a random entry, 'exclude' keeps it out of the prompt even when random_all is on. Add your own entries in json/star_character_builder.json (restart ComfyUI to see them in this list, 'random' uses them right away). |
| age | STRING | Free text. Empty = skipped. Type 'random' or enable the random_age toggle for a random age (18-100 by default, change age_random_min/max in the json settings). A plain number becomes 'X year old'. | |
| random_age | BOOLEAN | false | If enabled each run, picks a random age between age_random_min and age_random_max from the json settings and ignores the age text field. |
| additional | STRING | Free text that is appended to the end of the prompt. Empty = skipped. | |
| seed | INT | 00–18446744073709550000 | Seed for all 'random' picks. 0 = new random picks every run. |
| random_all | BOOLEAN | false | If enabled, every category gets a random pick regardless of its widget setting. Only one of clothing/female_outfit/male_outfit/lingerie/kinky_outfit is picked. Categories set to 'exclude' stay out of the prompt. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| description | STRING | The plain generated comma-separated description prompt. |
| character_sheet | STRING | The ready-to-use strict character sheet image prompt for the same character (multi-panel grid, gender-correct anatomy panels). Note: an outfit appears if one is selected or randomized - set all wear categories to 'exclude' for a naked sheet. |
| system_prompt | STRING | The system prompt to feed into your LLM so it can write character sheet prompts itself. Editable as 'system_prompt' in json/star_character_builder.json. |