From 2417dcc0906bdf9c83a3fc6b85abb41959cdeb0b Mon Sep 17 00:00:00 2001 From: Aodhan Collins Date: Mon, 29 Dec 2025 20:50:25 +0000 Subject: [PATCH] Initial commit --- README.md | 83 +++++++++++++ __init__.py | 3 + deploy.sh | 20 +++ nodes/__init__.py | 20 +++ nodes/__pycache__/__init__.cpython-314.pyc | Bin 0 -> 580 bytes nodes/character_reader/__init__.py | 9 ++ nodes/character_reader/character_reader.py | 117 ++++++++++++++++++ .../characters/aerith_gainsborough.json | 35 ++++++ .../characters/android_18.json | 35 ++++++ .../characters/anya_forger.json | 35 ++++++ nodes/character_reader/characters/bulma.json | 35 ++++++ .../character_reader/characters/camilla.json | 35 ++++++ nodes/character_reader/characters/cammy.json | 35 ++++++ .../character_reader/characters/chun_li.json | 35 ++++++ nodes/character_reader/characters/ciri.json | 35 ++++++ .../characters/hatsune_miku.json | 35 ++++++ nodes/character_reader/characters/jessie.json | 35 ++++++ .../characters/kda_all_out_ahri.json | 35 ++++++ .../characters/kda_all_out_akali.json | 35 ++++++ .../characters/kda_all_out_evelynn.json | 35 ++++++ .../characters/kda_all_out_kaisa.json | 35 ++++++ .../characters/lara_croft_classic.json | 35 ++++++ nodes/character_reader/characters/lulu.json | 35 ++++++ .../characters/majin_android_21.json | 35 ++++++ .../characters/marin_kitagawa.json | 35 ++++++ nodes/character_reader/characters/nessa.json | 35 ++++++ .../characters/princess_peach.json | 35 ++++++ .../characters/princess_zelda_botw.json | 35 ++++++ nodes/character_reader/characters/riju.json | 35 ++++++ .../character_reader/characters/rosalina.json | 35 ++++++ .../characters/rouge_the_bat.json | 35 ++++++ .../characters/samus_aran_zero_suit.json | 35 ++++++ .../characters/sucy_manbavaran.json | 35 ++++++ .../characters/tifa_lockhart.json | 35 ++++++ nodes/character_reader/characters/urbosa.json | 35 ++++++ .../characters/yor_briar.json | 35 ++++++ .../characters/yshtola_rhul.json | 35 ++++++ .../character_reader/characters/yuna_ffx.json | 35 ++++++ nodes/lora_from_string/__init__.py | 9 ++ .../__pycache__/__init__.cpython-314.pyc | Bin 0 -> 310 bytes .../lora_from_string.cpython-314.pyc | Bin 0 -> 1837 bytes nodes/lora_from_string/lora_from_string.py | 35 ++++++ nodes/reenforcer/__init__.py | 9 ++ nodes/reenforcer/reenforcer.py | 18 +++ nodes/resolution_reader/__init__.py | 9 ++ nodes/resolution_reader/resolution_reader.py | 79 ++++++++++++ .../resolutions/resolutions.txt | 4 + project-goal.md | 44 +++++++ requirements.txt | 2 + update_nails.py | 50 ++++++++ 50 files changed, 1596 insertions(+) create mode 100644 README.md create mode 100644 __init__.py create mode 100644 deploy.sh create mode 100644 nodes/__init__.py create mode 100644 nodes/__pycache__/__init__.cpython-314.pyc create mode 100644 nodes/character_reader/__init__.py create mode 100644 nodes/character_reader/character_reader.py create mode 100644 nodes/character_reader/characters/aerith_gainsborough.json create mode 100644 nodes/character_reader/characters/android_18.json create mode 100644 nodes/character_reader/characters/anya_forger.json create mode 100644 nodes/character_reader/characters/bulma.json create mode 100644 nodes/character_reader/characters/camilla.json create mode 100644 nodes/character_reader/characters/cammy.json create mode 100644 nodes/character_reader/characters/chun_li.json create mode 100644 nodes/character_reader/characters/ciri.json create mode 100644 nodes/character_reader/characters/hatsune_miku.json create mode 100644 nodes/character_reader/characters/jessie.json create mode 100644 nodes/character_reader/characters/kda_all_out_ahri.json create mode 100644 nodes/character_reader/characters/kda_all_out_akali.json create mode 100644 nodes/character_reader/characters/kda_all_out_evelynn.json create mode 100644 nodes/character_reader/characters/kda_all_out_kaisa.json create mode 100644 nodes/character_reader/characters/lara_croft_classic.json create mode 100644 nodes/character_reader/characters/lulu.json create mode 100644 nodes/character_reader/characters/majin_android_21.json create mode 100644 nodes/character_reader/characters/marin_kitagawa.json create mode 100644 nodes/character_reader/characters/nessa.json create mode 100644 nodes/character_reader/characters/princess_peach.json create mode 100644 nodes/character_reader/characters/princess_zelda_botw.json create mode 100644 nodes/character_reader/characters/riju.json create mode 100644 nodes/character_reader/characters/rosalina.json create mode 100644 nodes/character_reader/characters/rouge_the_bat.json create mode 100644 nodes/character_reader/characters/samus_aran_zero_suit.json create mode 100644 nodes/character_reader/characters/sucy_manbavaran.json create mode 100644 nodes/character_reader/characters/tifa_lockhart.json create mode 100644 nodes/character_reader/characters/urbosa.json create mode 100644 nodes/character_reader/characters/yor_briar.json create mode 100644 nodes/character_reader/characters/yshtola_rhul.json create mode 100644 nodes/character_reader/characters/yuna_ffx.json create mode 100644 nodes/lora_from_string/__init__.py create mode 100644 nodes/lora_from_string/__pycache__/__init__.cpython-314.pyc create mode 100644 nodes/lora_from_string/__pycache__/lora_from_string.cpython-314.pyc create mode 100644 nodes/lora_from_string/lora_from_string.py create mode 100644 nodes/reenforcer/__init__.py create mode 100644 nodes/reenforcer/reenforcer.py create mode 100644 nodes/resolution_reader/__init__.py create mode 100644 nodes/resolution_reader/resolution_reader.py create mode 100644 nodes/resolution_reader/resolutions/resolutions.txt create mode 100644 project-goal.md create mode 100644 requirements.txt create mode 100644 update_nails.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..2c4e2d9 --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +# AODH Pack + +A set of custom ComfyUI nodes designed to streamline the creation of images for anime and video game characters using structured JSON data. + +## Nodes + +### Character JSON Reader + +The **Character JSON Reader** node allows you to load character definitions from JSON files stored in the `characters` directory. It parses the JSON and outputs individual strings for various character attributes, making it easy to build complex prompts. + +#### Features: +- **Automatic File Discovery**: Scans the `nodes/character_reader/characters/` folder for `.json` files. +- **Selection Modes**: + - `manual`: Select a specific file from the dropdown. + - `sequential`: Cycles through files based on the `index` input. + - `random`: Picks a random file using the `index` as a seed. +- **Structured Outputs**: Provides 21 distinct output pins covering identity, wardrobe, and style. +- **Prompt-Ready Formatting**: Automatically appends a comma to every non-empty output string. +- **Robustness**: Ensures all outputs are valid strings, even if fields are missing from the JSON. + +### Resolution Reader + +The **Resolution Reader** node reads resolution configurations from text files. Each line in the text file should follow the format: `width, height, upscale`. + +#### Features: +- **Selection Modes**: + - `manual`: Uses the first line of the selected file. + - `sequential`: Cycles through lines in the file based on the `index` input. + - `random`: Picks a random line from the file using the `index` as a seed. +- **Outputs**: Provides `width` (INT), `height` (INT), and `upscale` (FLOAT). + +#### JSON Structure: + +Place your character JSON files in the `nodes/character_reader/characters/` directory. The expected format is: + +```json +{ + "character_id": "unique_id", + "identity": { + "base_specs": "...", + "hair": "...", + "eyes": "...", + "expression": "...", + "hands": "...", + "arms": "...", + "torso": "...", + "pelvis": "...", + "legs": "...", + "feet": "...", + "distinguishing_marks": "..." + }, + "wardrobe": { + "inner_layer": "...", + "outer_layer": "...", + "lower_body": "...", + "footwear": "...", + "gloves": "...", + "accessories": "..." + }, + "styles": { + "aesthetic": "...", + "primary_color": "...", + "secondary_color": "...", + "tertiary_color": "..." + }, + "lora":{ + "lora_name": "...", + "lora_Weight": "...", + "lora_triggers": "..." + } +} +``` + +## Installation + +1. Clone this repository into your `ComfyUI/custom_nodes/` directory. +2. Add your character JSON files to the `nodes/character_reader/characters/` folder. +3. Add your resolution text files to the `nodes/resolution_reader/resolutions/` folder. +4. Restart ComfyUI. + +## Usage + +Find the node under the `AODH Pack` category in the ComfyUI node menu. Select your character file from the dropdown, and connect the output pins to your prompt encoding nodes. diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..3d998ea --- /dev/null +++ b/__init__.py @@ -0,0 +1,3 @@ +from .nodes import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS + +__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS'] diff --git a/deploy.sh b/deploy.sh new file mode 100644 index 0000000..b8b9270 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Deployment script for AODH Pack + +TARGET_DIR="/home/aodhan/gitclones/ComfyUI/custom_nodes/aodh-pack" +SOURCE_DIR="$(pwd)" + +echo "Deploying AODH Pack to $TARGET_DIR..." + +# Create target directory if it doesn't exist +mkdir -p "$TARGET_DIR" + +# Sync files, excluding git and other unnecessary files +# Using cp -r for simplicity, but rsync would be better if available +cp -r "$SOURCE_DIR/__init__.py" "$TARGET_DIR/" +cp -r "$SOURCE_DIR/nodes" "$TARGET_DIR/" +cp -r "$SOURCE_DIR/README.md" "$TARGET_DIR/" +cp -r "$SOURCE_DIR/requirements.txt" "$TARGET_DIR/" + +echo "Deployment complete!" diff --git a/nodes/__init__.py b/nodes/__init__.py new file mode 100644 index 0000000..46967a7 --- /dev/null +++ b/nodes/__init__.py @@ -0,0 +1,20 @@ +from .character_reader import NODE_CLASS_MAPPINGS as CR_CLASS, NODE_DISPLAY_NAME_MAPPINGS as CR_DISPLAY +from .resolution_reader import NODE_CLASS_MAPPINGS as RR_CLASS, NODE_DISPLAY_NAME_MAPPINGS as RR_DISPLAY +from .reenforcer import NODE_CLASS_MAPPINGS as RE_CLASS, NODE_DISPLAY_NAME_MAPPINGS as RE_DISPLAY +from .lora_from_string import NODE_CLASS_MAPPINGS as LFS_CLASS, NODE_DISPLAY_NAME_MAPPINGS as LFS_DISPLAY + +NODE_CLASS_MAPPINGS = { + **CR_CLASS, + **RR_CLASS, + **RE_CLASS, + **LFS_CLASS +} + +NODE_DISPLAY_NAME_MAPPINGS = { + **CR_DISPLAY, + **RR_DISPLAY, + **RE_DISPLAY, + **LFS_DISPLAY +} + +__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS'] diff --git a/nodes/__pycache__/__init__.cpython-314.pyc b/nodes/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aaa4b69a2ea8b438e83b9eca6218c7f2a58eae59 GIT binary patch literal 580 zcmX|;&raJw5XNWyCw5F?9HOcchoHhKLV_1SR8a^eQb<$#)B~)nWC2UYt~LgV8{$gry*>M&Ql*Wehz7+CnsGR_ZvJt+I=Hl5wY;#htHQ9RDP_&vGK7+ccyl5Un1E-A_l^RxE5=H@!;A5;@H zuaUKxTZOX8^71;=g4(%jcEEaIJ77Jqosw;Vg#x<;wgYxMcd7AZv3tC5zCKy9jidhq DF=v-F literal 0 HcmV?d00001 diff --git a/nodes/character_reader/__init__.py b/nodes/character_reader/__init__.py new file mode 100644 index 0000000..7011ad6 --- /dev/null +++ b/nodes/character_reader/__init__.py @@ -0,0 +1,9 @@ +from .character_reader import CharacterJsonReader + +NODE_CLASS_MAPPINGS = { + "CharacterJsonReader": CharacterJsonReader +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "CharacterJsonReader": "Character JSON Reader" +} diff --git a/nodes/character_reader/character_reader.py b/nodes/character_reader/character_reader.py new file mode 100644 index 0000000..db67a5a --- /dev/null +++ b/nodes/character_reader/character_reader.py @@ -0,0 +1,117 @@ +import json +import os +import random + +class CharacterJsonReader: + @classmethod + def INPUT_TYPES(s): + base_path = os.path.dirname(os.path.realpath(__file__)) + char_dir = os.path.join(base_path, "characters") + + characters = [] + if os.path.exists(char_dir): + characters = sorted([f for f in os.listdir(char_dir) if f.endswith('.json')]) + + return { + "required": { + "character_file": (characters, ), + "selection_mode": (["manual", "sequential", "random"], {"default": "manual"}), + "repeat_count": ("INT", {"default": 1, "min": 1, "max": 100, "step": 1}), + } + } + + @classmethod + def IS_CHANGED(s, character_file, selection_mode, repeat_count): + if selection_mode == "random" or selection_mode == "sequential": + return float("nan") + return character_file + + RETURN_TYPES = ( + "STRING", "STRING", "STRING", "STRING", "STRING", "STRING", "STRING", "STRING", "STRING", "STRING", "STRING", "STRING", + "STRING", "STRING", "STRING", "STRING", "STRING", "STRING", + "STRING", "STRING", "STRING", "STRING", + "STRING", "FLOAT", "STRING" + ) + RETURN_NAMES = ( + "name", "base_specs", "hair", "eyes", "expression", "hands", "arms", "torso", "pelvis", "legs", "feet", "distinguishing_marks", + "inner_layer", "outer_layer", "lower_body", "footwear", "gloves", "accessories", + "aesthetic", "primary_color", "secondary_color", "tertiary_color", + "lora_name", "lora_weight", "lora_triggers" + ) + + FUNCTION = "read_character" + CATEGORY = "AODH Pack" + + _current_index = 0 + _current_count = 0 + _last_selection = None + + def read_character(self, character_file, selection_mode, repeat_count): + base_path = os.path.dirname(os.path.realpath(__file__)) + char_dir = os.path.join(base_path, "characters") + + characters = sorted([f for f in os.listdir(char_dir) if f.endswith('.json')]) + + if not characters: + return ("",) * 22 + ("", 0.0, "") + + if selection_mode == "manual": + selected_file = character_file + elif selection_mode == "sequential": + if self.__class__._current_count >= repeat_count: + self.__class__._current_index += 1 + self.__class__._current_count = 0 + selected_file = characters[self.__class__._current_index % len(characters)] + self.__class__._current_count += 1 + elif selection_mode == "random": + if self.__class__._current_count >= repeat_count or self.__class__._last_selection is None or self.__class__._last_selection not in characters: + self.__class__._last_selection = random.choice(characters) + self.__class__._current_count = 0 + selected_file = self.__class__._last_selection + self.__class__._current_count += 1 + else: + selected_file = character_file + + file_path = os.path.join(char_dir, selected_file) + + with open(file_path, 'r') as f: + data = json.load(f) + + identity = data.get("identity", {}) + wardrobe = data.get("wardrobe", {}) + styles = data.get("styles", {}) + lora = data.get("lora", {}) + + def get_val(obj, key, prepend_comma=True): + val = obj.get(key, "") + if val and prepend_comma and not val.startswith(","): + val = ", " + val + return val + + return ( + get_val(data, "character_id", prepend_comma=False), + get_val(identity, "base_specs"), + get_val(identity, "hair"), + get_val(identity, "eyes"), + get_val(identity, "expression"), + get_val(identity, "hands"), + get_val(identity, "arms"), + get_val(identity, "torso"), + get_val(identity, "pelvis"), + get_val(identity, "legs"), + get_val(identity, "feet"), + get_val(identity, "distinguishing_marks"), + get_val(wardrobe, "inner_layer"), + get_val(wardrobe, "outer_layer"), + get_val(wardrobe, "lower_body"), + get_val(wardrobe, "footwear"), + get_val(wardrobe, "gloves"), + get_val(wardrobe, "accessories"), + get_val(styles, "aesthetic"), + get_val(styles, "primary_color"), + get_val(styles, "secondary_color"), + get_val(styles, "tertiary_color"), + get_val(lora, "lora_name", prepend_comma=False), + float(lora.get("lora_weight", 0.0) if lora.get("lora_weight") else 0.0), + get_val(lora, "lora_triggers"), + ) diff --git a/nodes/character_reader/characters/aerith_gainsborough.json b/nodes/character_reader/characters/aerith_gainsborough.json new file mode 100644 index 0000000..43100c6 --- /dev/null +++ b/nodes/character_reader/characters/aerith_gainsborough.json @@ -0,0 +1,35 @@ +{ + "character_id": "aerith_gainsborough", + "identity": { + "base_specs": "1girl, slender build, fair skin", + "hair": "long brown hair, braided, pink ribbon", + "eyes": "green eyes", + "expression": "cheerful expression", + "hands": "pink nails", + "arms": "", + "torso": "small breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "pink dress, red bolero jacket", + "lower_body": "long skirt", + "footwear": "brown boots", + "gloves": "", + "accessories": "gold bracelets, flower basket" + }, + "styles": { + "aesthetic": "floral, gentle, final fantasy style", + "primary_color": "pink", + "secondary_color": "red", + "tertiary_color": "brown" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/android_18.json b/nodes/character_reader/characters/android_18.json new file mode 100644 index 0000000..5a9c5ca --- /dev/null +++ b/nodes/character_reader/characters/android_18.json @@ -0,0 +1,35 @@ +{ + "character_id": "android_18", + "identity": { + "base_specs": "1girl, slender build, fair skin", + "hair": "shoulder-length blonde hair, tucked behind one ear", + "eyes": "blue eyes", + "expression": "cool, indifferent expression", + "hands": "blue nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "gold hoop earrings" + }, + "wardrobe": { + "inner_layer": "black short-sleeved shirt", + "outer_layer": "blue denim vest, Red Ribbon logo on back", + "lower_body": "blue denim skirt, black leggings", + "footwear": "brown boots", + "gloves": "", + "accessories": "" + }, + "styles": { + "aesthetic": "90s casual, anime, dragon ball style", + "primary_color": "blue", + "secondary_color": "black", + "tertiary_color": "white" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/anya_forger.json b/nodes/character_reader/characters/anya_forger.json new file mode 100644 index 0000000..9e07e41 --- /dev/null +++ b/nodes/character_reader/characters/anya_forger.json @@ -0,0 +1,35 @@ +{ + "character_id": "anya_forger", + "identity": { + "base_specs": "1girl, small build, fair skin", + "hair": "short pink hair, two small horns (hair ornaments)", + "eyes": "green eyes", + "expression": "smirk", + "hands": "pink nails", + "arms": "", + "torso": "flat chest", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "black Eden Academy uniform, gold trim", + "lower_body": "uniform skirt", + "footwear": "black shoes, white socks", + "gloves": "", + "accessories": "black and gold hair cones" + }, + "styles": { + "aesthetic": "cute, academic, spy x family style", + "primary_color": "pink", + "secondary_color": "black", + "tertiary_color": "gold" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/bulma.json b/nodes/character_reader/characters/bulma.json new file mode 100644 index 0000000..213d735 --- /dev/null +++ b/nodes/character_reader/characters/bulma.json @@ -0,0 +1,35 @@ +{ + "character_id": "bulma", + "identity": { + "base_specs": "1girl, slender build, fair skin", + "hair": "turquoise hair, ponytail", + "eyes": "blue eyes", + "expression": "energetic smile", + "hands": "turquoise nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "pink dress, 'Bulma' text on front", + "lower_body": "dress", + "footwear": "purple sneakers, white socks", + "gloves": "purple gloves", + "accessories": "red hair ribbon, dragon radar" + }, + "styles": { + "aesthetic": "retro-futuristic, anime, dragon ball style", + "primary_color": "pink", + "secondary_color": "turquoise", + "tertiary_color": "purple" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/camilla.json b/nodes/character_reader/characters/camilla.json new file mode 100644 index 0000000..c5fafd8 --- /dev/null +++ b/nodes/character_reader/characters/camilla.json @@ -0,0 +1,35 @@ +{ + "character_id": "camilla", + "identity": { + "base_specs": "1girl, curvaceous build, fair skin", + "hair": "long wavy lavender hair, hair covering one eye", + "eyes": "purple eyes", + "expression": "seductive smile", + "hands": "purple nails", + "arms": "", + "torso": "large breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "black headband with horns" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "black armor, cleavage", + "lower_body": "black leggings, armored plates", + "footwear": "black armored boots", + "gloves": "", + "accessories": "purple cape, large axe" + }, + "styles": { + "aesthetic": "dark fantasy, gothic, fire emblem style", + "primary_color": "black", + "secondary_color": "gold", + "tertiary_color": "purple" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/cammy.json b/nodes/character_reader/characters/cammy.json new file mode 100644 index 0000000..a64dfad --- /dev/null +++ b/nodes/character_reader/characters/cammy.json @@ -0,0 +1,35 @@ +{ + "character_id": "cammy", + "identity": { + "base_specs": "1girl, muscular build, fair skin", + "hair": "long blonde hair, twin braids", + "eyes": "blue eyes", + "expression": "serious look", + "hands": "green nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "scar on left cheek, green camouflage paint on legs" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "green high-leg leotard", + "lower_body": "bare legs", + "footwear": "black combat boots, green socks", + "gloves": "red gauntlets", + "accessories": "red beret" + }, + "styles": { + "aesthetic": "military, athletic, street fighter style", + "primary_color": "green", + "secondary_color": "red", + "tertiary_color": "black" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/chun_li.json b/nodes/character_reader/characters/chun_li.json new file mode 100644 index 0000000..2a76026 --- /dev/null +++ b/nodes/character_reader/characters/chun_li.json @@ -0,0 +1,35 @@ +{ + "character_id": "chun_li", + "identity": { + "base_specs": "1girl, muscular build, fair skin", + "hair": "black hair, hair buns", + "eyes": "brown eyes", + "expression": "determined smile", + "hands": "blue nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "thick thighs", + "feet": "", + "distinguishing_marks": "" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "blue qipao, gold embroidery, white accents", + "lower_body": "brown tights", + "footwear": "white combat boots", + "gloves": "", + "accessories": "white hair ribbons, spiked bracelets" + }, + "styles": { + "aesthetic": "martial arts, traditional, street fighter style", + "primary_color": "blue", + "secondary_color": "white", + "tertiary_color": "gold" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/ciri.json b/nodes/character_reader/characters/ciri.json new file mode 100644 index 0000000..f1fde54 --- /dev/null +++ b/nodes/character_reader/characters/ciri.json @@ -0,0 +1,35 @@ +{ + "character_id": "ciri", + "identity": { + "base_specs": "1girl, athletic build, pale skin", + "hair": "ashen grey hair, messy bun", + "eyes": "emerald green eyes. mascara", + "expression": "determined look", + "hands": "brown nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "scar over eye" + }, + "wardrobe": { + "inner_layer": "white blouse", + "outer_layer": "brown leather vest, silver studs", + "lower_body": "brown leather trousers", + "footwear": "brown leather boots", + "gloves": "brown leather gloves", + "accessories": "silver sword on back, witcher medallion" + }, + "styles": { + "aesthetic": "gritty, fantasy, witcher style", + "primary_color": "white", + "secondary_color": "brown", + "tertiary_color": "silver" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/hatsune_miku.json b/nodes/character_reader/characters/hatsune_miku.json new file mode 100644 index 0000000..de6e1d8 --- /dev/null +++ b/nodes/character_reader/characters/hatsune_miku.json @@ -0,0 +1,35 @@ +{ + "character_id": "hatsune_miku", + "identity": { + "base_specs": "1girl, slender build, fair skin", + "hair": "long turquoise hair, twin tails, floor-length", + "eyes": "turquoise eyes", + "expression": "cheerful smile", + "hands": "turquoise nails", + "arms": "01 tattoo on left shoulder", + "torso": "small breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "grey sleeveless shirt, turquoise tie", + "lower_body": "grey miniskirt, turquoise trim", + "footwear": "black thigh-high boots, turquoise trim", + "gloves": "black arm warmers, turquoise trim", + "accessories": "hair ornament, headset" + }, + "styles": { + "aesthetic": "vocaloid, futuristic, anime style", + "primary_color": "teal", + "secondary_color": "grey", + "tertiary_color": "black" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/jessie.json b/nodes/character_reader/characters/jessie.json new file mode 100644 index 0000000..35a9e7a --- /dev/null +++ b/nodes/character_reader/characters/jessie.json @@ -0,0 +1,35 @@ +{ + "character_id": "jessie", + "identity": { + "base_specs": "1girl, slender build, fair skin", + "hair": "long magenta hair, curved back", + "eyes": "blue eyes", + "expression": "arrogant smirk", + "hands": "white nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "green earrings" + }, + "wardrobe": { + "inner_layer": "black crop top", + "outer_layer": "white Team Rocket uniform jacket, bare stomach, red R logo", + "lower_body": "white miniskirt", + "footwear": "black thigh-high boots", + "gloves": "black gloves", + "accessories": "" + }, + "styles": { + "aesthetic": "villainous, anime, pokemon style", + "primary_color": "white", + "secondary_color": "magenta", + "tertiary_color": "black" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/kda_all_out_ahri.json b/nodes/character_reader/characters/kda_all_out_ahri.json new file mode 100644 index 0000000..a32e8f0 --- /dev/null +++ b/nodes/character_reader/characters/kda_all_out_ahri.json @@ -0,0 +1,35 @@ +{ + "character_id": "k/da_all_out_ahri", + "identity": { + "base_specs": "1girl, slender build, fair skin, fox ears", + "hair": "long blonde hair, flowing", + "eyes": "yellow eyes", + "expression": "charming smile", + "hands": "silver nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "whisker markings on cheeks, crystal tails" + }, + "wardrobe": { + "inner_layer": "silver crop top", + "outer_layer": "white and silver jacket", + "lower_body": "black leather shorts", + "footwear": "black thigh-high boots", + "gloves": "", + "accessories": "crystal orb, silver jewelry" + }, + "styles": { + "aesthetic": "pop star, mystical, k/da style", + "primary_color": "silver", + "secondary_color": "white", + "tertiary_color": "blue" + }, + "lora": { + "lora_name": "Illustrious/Looks/KDA AhriIlluLoRA.safetensors", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/kda_all_out_akali.json b/nodes/character_reader/characters/kda_all_out_akali.json new file mode 100644 index 0000000..0a1eca9 --- /dev/null +++ b/nodes/character_reader/characters/kda_all_out_akali.json @@ -0,0 +1,35 @@ +{ + "character_id": "k/da_all_out_akali", + "identity": { + "base_specs": "1girl, athletic build, fair skin", + "hair": "long dark blue hair, blonde streaks, high ponytail", + "eyes": "blue eyes", + "expression": "cool, rebellious look", + "hands": "blue nails", + "arms": "tattoos on arms", + "torso": "small breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "" + }, + "wardrobe": { + "inner_layer": "black crop top", + "outer_layer": "blue and silver motorcycle jacket", + "lower_body": "black leather pants", + "footwear": "blue sneakers", + "gloves": "black fingerless gloves", + "accessories": "kama and kunai" + }, + "styles": { + "aesthetic": "pop star, street, k/da style", + "primary_color": "blue", + "secondary_color": "purple", + "tertiary_color": "silver" + }, + "lora": { + "lora_name": "Illustrious/Looks/KDAAkaliIlluLoRA.safetensors", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/kda_all_out_evelynn.json b/nodes/character_reader/characters/kda_all_out_evelynn.json new file mode 100644 index 0000000..71dcfb6 --- /dev/null +++ b/nodes/character_reader/characters/kda_all_out_evelynn.json @@ -0,0 +1,35 @@ +{ + "character_id": "k/da_all_out_evelynn", + "identity": { + "base_specs": "1girl, curvaceous build, fair skin", + "hair": "light blue hair,", + "eyes": "yellow glowing eyes, slit pupils", + "expression": "seductive, confident look", + "hands": "long black claws, blue nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "two long lashers (shadow tendrils)" + }, + "wardrobe": { + "inner_layer": "black leather bra", + "outer_layer": "iridescent blue jacket, fur collar", + "lower_body": "black leather skirt", + "footwear": "black high-heeled boots", + "gloves": "", + "accessories": "diamond earrings" + }, + "styles": { + "aesthetic": "pop star, glamorous, k/da style", + "primary_color": "blue", + "secondary_color": "purple", + "tertiary_color": "silver" + }, + "lora": { + "lora_name": "Illustrious/Looks/KDA EvelynnIlluLoRA.safetensors", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/kda_all_out_kaisa.json b/nodes/character_reader/characters/kda_all_out_kaisa.json new file mode 100644 index 0000000..1e52a33 --- /dev/null +++ b/nodes/character_reader/characters/kda_all_out_kaisa.json @@ -0,0 +1,35 @@ +{ + "character_id": "k/da_all_out_kai'sa", + "identity": { + "base_specs": "1girl, athletic build, fair skin", + "hair": "long hair, purple hair, hair ornament, ponytail, green highlights", + "eyes": "purple eyes", + "expression": "focused expression", + "hands": "silver nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "purple markings under eyes, floating crystal cannons" + }, + "wardrobe": { + "inner_layer": "silver bodysuit", + "outer_layer": "white and silver jacket", + "lower_body": "silver leggings", + "footwear": "silver high-heeled boots", + "gloves": "", + "accessories": "crystal shoulder pods" + }, + "styles": { + "aesthetic": "pop star, futuristic, k/da style", + "primary_color": "silver", + "secondary_color": "white", + "tertiary_color": "purple" + }, + "lora": { + "lora_name": "Illustrious/Looks/KDA KaisaIlluLoRA.safetensors", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/lara_croft_classic.json b/nodes/character_reader/characters/lara_croft_classic.json new file mode 100644 index 0000000..61a48ec --- /dev/null +++ b/nodes/character_reader/characters/lara_croft_classic.json @@ -0,0 +1,35 @@ +{ + "character_id": "lara_croft_classic", + "identity": { + "base_specs": "1girl, athletic build, tan skin", + "hair": "long brown hair, single braid", + "eyes": "brown eyes", + "expression": "determined", + "hands": "", + "arms": "", + "torso": "", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "teal tank top, crop top", + "lower_body": "brown shorts", + "footwear": "brown combat boots, red laces", + "gloves": "black fingerless gloves", + "accessories": "dual thigh holsters, backpack, circular sunglasses" + }, + "styles": { + "aesthetic": "adventure, retro, 90s style", + "primary_color": "teal", + "secondary_color": "brown", + "tertiary_color": "black" + }, + "lora": { + "lora_name": "lara_croft_classic", + "lora_weight": 0.8, + "lora_triggers": "lara croft, classic outfit" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/lulu.json b/nodes/character_reader/characters/lulu.json new file mode 100644 index 0000000..6663471 --- /dev/null +++ b/nodes/character_reader/characters/lulu.json @@ -0,0 +1,35 @@ +{ + "character_id": "lulu (ffx)", + "identity": { + "base_specs": "1girl, curvaceous build, fair skin", + "hair": "long black hair, complex braids, hairpins", + "eyes": "red eyes", + "expression": "stern expression", + "hands": "black nails", + "arms": "", + "torso": "large breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "dark purple lipstick" + }, + "wardrobe": { + "inner_layer": "black corset", + "outer_layer": "black fur-trimmed dress, many belts on front", + "lower_body": "long skirt made of belts", + "footwear": "black boots", + "gloves": "", + "accessories": "moogle doll, silver jewelry" + }, + "styles": { + "aesthetic": "gothic, ornate, final fantasy x style", + "primary_color": "black", + "secondary_color": "white", + "tertiary_color": "purple" + }, + "lora": { + "lora_name": "Illustrious/Looks/Lulu DG illuLoRA_1337272.safetensors", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/majin_android_21.json b/nodes/character_reader/characters/majin_android_21.json new file mode 100644 index 0000000..b044fdf --- /dev/null +++ b/nodes/character_reader/characters/majin_android_21.json @@ -0,0 +1,35 @@ +{ + "character_id": "majin_android_21", + "identity": { + "base_specs": "1girl, curvaceous build, pink skin", + "hair": "long voluminous white hair", + "eyes": "red eyes, black sclera", + "expression": "playful yet menacing smile", + "hands": "black claws, pink nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "pink skin, long tail, pointed ears" + }, + "wardrobe": { + "inner_layer": "black tube top", + "outer_layer": "", + "lower_body": "white baggy pants", + "footwear": "black and yellow boots", + "gloves": "", + "accessories": "gold bracelets, gold neck ring" + }, + "styles": { + "aesthetic": "supernatural, anime, dragon ball style", + "primary_color": "pink", + "secondary_color": "white", + "tertiary_color": "gold" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/marin_kitagawa.json b/nodes/character_reader/characters/marin_kitagawa.json new file mode 100644 index 0000000..8cf087a --- /dev/null +++ b/nodes/character_reader/characters/marin_kitagawa.json @@ -0,0 +1,35 @@ +{ + "character_id": "marin_kitagawa", + "identity": { + "base_specs": "1girl, slender build, fair skin", + "hair": "long blonde hair, pink tips", + "eyes": "pink eyes (contacts)", + "expression": "excited smile", + "hands": "long pink nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "piercings" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "white school shirt, loosely tied blue tie", + "lower_body": "blue plaid miniskirt", + "footwear": "black loafers, black socks", + "gloves": "", + "accessories": "choker, various bracelets" + }, + "styles": { + "aesthetic": "gyaru, modern, anime style", + "primary_color": "white", + "secondary_color": "blue", + "tertiary_color": "pink" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} diff --git a/nodes/character_reader/characters/nessa.json b/nodes/character_reader/characters/nessa.json new file mode 100644 index 0000000..2b1d371 --- /dev/null +++ b/nodes/character_reader/characters/nessa.json @@ -0,0 +1,35 @@ +{ + "character_id": "nessa", + "identity": { + "base_specs": "1girl, athletic build, dark skin", + "hair": "long hair, light blue highlights", + "eyes": "blue eyes", + "expression": "confident smile", + "hands": "blue nails", + "arms": "", + "torso": "small breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "blue earrings" + }, + "wardrobe": { + "inner_layer": "white and blue bikini top", + "outer_layer": "gym uniform, number 049", + "lower_body": "white and blue shorts", + "footwear": "blue and white sandals", + "gloves": "", + "accessories": "wristband, life buoy, pokeball" + }, + "styles": { + "aesthetic": "sporty, aquatic, pokemon style", + "primary_color": "blue", + "secondary_color": "white", + "tertiary_color": "orange" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/princess_peach.json b/nodes/character_reader/characters/princess_peach.json new file mode 100644 index 0000000..4f8092e --- /dev/null +++ b/nodes/character_reader/characters/princess_peach.json @@ -0,0 +1,35 @@ +{ + "character_id": "princess_peach", + "identity": { + "base_specs": "1girl, slender build, fair skin", + "hair": "long blonde hair, voluminous, crown", + "eyes": "blue eyes, long eyelashes", + "expression": "gentle smile", + "hands": "pink nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "pink lips, blue earrings" + }, + "wardrobe": { + "inner_layer": "white petticoat", + "outer_layer": "pink floor-length ball gown, puffy sleeves, dark pink panniers", + "lower_body": "long skirt", + "footwear": "red high heels", + "gloves": "white opera gloves", + "accessories": "gold crown with red and blue jewels, blue brooch" + }, + "styles": { + "aesthetic": "royal, whimsical, nintendo style", + "primary_color": "pink", + "secondary_color": "gold", + "tertiary_color": "blue" + }, + "lora": { + "lora_name": "Princess_Peach_Shiny_Style_V4.0_Illustrious_1652958.safetensors", + "lora_weight": 0.8, + "lora_triggers": "princess peach, crown, pink dress, shiny skin, royal elegance" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/princess_zelda_botw.json b/nodes/character_reader/characters/princess_zelda_botw.json new file mode 100644 index 0000000..1b2cdf3 --- /dev/null +++ b/nodes/character_reader/characters/princess_zelda_botw.json @@ -0,0 +1,35 @@ +{ + "character_id": "princess_zelda_botw", + "identity": { + "base_specs": "1girl, slender build, fair skin, pointed ears", + "hair": "long blonde hair, braided, gold hair clips", + "eyes": "green eyes", + "expression": "determined look", + "hands": "gold nails", + "arms": "", + "torso": "small breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "tri-force symbol, elf ears" + }, + "wardrobe": { + "inner_layer": "blue tunic", + "outer_layer": "blue champion's tunic, brown leather belts", + "lower_body": "tan trousers", + "footwear": "brown leather boots", + "gloves": "brown fingerless gloves", + "accessories": "sheikah slate, gold jewelry" + }, + "styles": { + "aesthetic": "fantasy, adventurous, zelda style", + "primary_color": "blue", + "secondary_color": "gold", + "tertiary_color": "brown" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/riju.json b/nodes/character_reader/characters/riju.json new file mode 100644 index 0000000..7a47f0f --- /dev/null +++ b/nodes/character_reader/characters/riju.json @@ -0,0 +1,35 @@ +{ + "character_id": "riju", + "identity": { + "base_specs": "1girl, young, dark skin, gerudo", + "hair": "short red hair, braided ponytail, gold hair ornament", + "eyes": "green eyes", + "expression": "serious", + "hands": "", + "arms": "", + "torso": "small breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "blue lipstick,gerudo markings" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "gerudo top, colorful sash", + "lower_body": "gerudo pants, puffy pants", + "footwear": "sandals", + "gloves": "", + "accessories": "gold jewelry, crown, earrings" + }, + "styles": { + "aesthetic": "fantasy, desert, gerudo style", + "primary_color": "gold", + "secondary_color": "teal", + "tertiary_color": "red" + }, + "lora": { + "lora_name": "riju_botw", + "lora_weight": 0.8, + "lora_triggers": "riju, gerudo" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/rosalina.json b/nodes/character_reader/characters/rosalina.json new file mode 100644 index 0000000..0ffeef3 --- /dev/null +++ b/nodes/character_reader/characters/rosalina.json @@ -0,0 +1,35 @@ +{ + "character_id": "rosalina", + "identity": { + "base_specs": "1girl, tall, slender build, fair skin", + "hair": "long platinum blonde hair, side-swept bangs covering one eye", + "eyes": "light blue eyes", + "expression": "serene expression", + "hands": "turquoise nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "star-shaped earrings" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "turquoise off-the-shoulder gown, silver trim", + "lower_body": "long skirt", + "footwear": "silver high heels", + "gloves": "", + "accessories": "silver crown with blue jewels, star wand, luma" + }, + "styles": { + "aesthetic": "celestial, elegant, nintendo style", + "primary_color": "turquoise", + "secondary_color": "silver", + "tertiary_color": "yellow" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/rouge_the_bat.json b/nodes/character_reader/characters/rouge_the_bat.json new file mode 100644 index 0000000..ae41893 --- /dev/null +++ b/nodes/character_reader/characters/rouge_the_bat.json @@ -0,0 +1,35 @@ +{ + "character_id": "rouge_the_bat", + "identity": { + "base_specs": "1girl, anthro, bat girl, white fur", + "hair": "short white hair", + "eyes": "teal eyes", + "expression": "sly smirk", + "hands": "white gloves", + "arms": "", + "torso": "large breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "bat wings, eyeshadow" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "black skin-tight jumpsuit, pink heart-shaped chest plate", + "lower_body": "jumpsuit", + "footwear": "white boots, pink heart motifs", + "gloves": "white gloves, pink cuffs", + "accessories": "blue eyeshadow" + }, + "styles": { + "aesthetic": "sleek, spy, sonic style", + "primary_color": "white", + "secondary_color": "pink", + "tertiary_color": "black" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/samus_aran_zero_suit.json b/nodes/character_reader/characters/samus_aran_zero_suit.json new file mode 100644 index 0000000..acbbd98 --- /dev/null +++ b/nodes/character_reader/characters/samus_aran_zero_suit.json @@ -0,0 +1,35 @@ +{ + "character_id": "samus_aran", + "identity": { + "base_specs": "1girl, athletic build, fair skin", + "hair": "long blonde hair, ponytail", + "eyes": "blue eyes", + "expression": "serious expression", + "hands": "blue nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "beauty mark on chin" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "blue skin-tight bodysuit, pink symbols", + "lower_body": "bodysuit", + "footwear": "blue high-heeled boots", + "gloves": "", + "accessories": "paralyzer pistol" + }, + "styles": { + "aesthetic": "sci-fi, sleek, metroid style", + "primary_color": "blue", + "secondary_color": "pink", + "tertiary_color": "yellow" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/sucy_manbavaran.json b/nodes/character_reader/characters/sucy_manbavaran.json new file mode 100644 index 0000000..2bae0d1 --- /dev/null +++ b/nodes/character_reader/characters/sucy_manbavaran.json @@ -0,0 +1,35 @@ +{ + "character_id": "sucy_manbavaran", + "identity": { + "base_specs": "1girl, lanky build, pale skin", + "hair": "mauve hair, hair covering one eye", + "eyes": "droopy red eyes", + "expression": "deadpan expression", + "hands": "purple nails", + "arms": "", + "torso": "small breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "dark circles under eyes" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "dark purple witch robes", + "lower_body": "long skirt", + "footwear": "brown boots", + "gloves": "", + "accessories": "pointed witch hat, potion bottle" + }, + "styles": { + "aesthetic": "gothic, whimsical, little witch academia style", + "primary_color": "purple", + "secondary_color": "mauve", + "tertiary_color": "green" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/tifa_lockhart.json b/nodes/character_reader/characters/tifa_lockhart.json new file mode 100644 index 0000000..31a20e1 --- /dev/null +++ b/nodes/character_reader/characters/tifa_lockhart.json @@ -0,0 +1,35 @@ +{ + "character_id": "tifa_lockhart", + "identity": { + "base_specs": "1girl, athletic build, fair skin", + "hair": "long black hair, tied end", + "eyes": "red eyes", + "expression": "kind smile", + "hands": "dark red nails", + "arms": "", + "torso": "large breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "" + }, + "wardrobe": { + "inner_layer": "black sports bra", + "outer_layer": "white tank top, black suspenders", + "lower_body": "black miniskirt", + "footwear": "red boots, black socks", + "gloves": "red combat gloves", + "accessories": "silver earrings" + }, + "styles": { + "aesthetic": "urban, martial arts, final fantasy style", + "primary_color": "white", + "secondary_color": "black", + "tertiary_color": "red" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/urbosa.json b/nodes/character_reader/characters/urbosa.json new file mode 100644 index 0000000..ee5ef92 --- /dev/null +++ b/nodes/character_reader/characters/urbosa.json @@ -0,0 +1,35 @@ +{ + "character_id": "urbosa", + "identity": { + "base_specs": "1girl, tall, muscular, dark skin, gerudo", + "hair": "long red hair, wild hair", + "eyes": "green eyes", + "expression": "confident", + "hands": "gold nails", + "arms": "muscular arms", + "torso": "abs", + "pelvis": "wide hips", + "legs": "muscular legs", + "feet": "", + "distinguishing_marks": "blue lipstick, gerudo markings" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "gold breastplate, blue champion's skirt", + "lower_body": "", + "footwear": "gold heels", + "gloves": "", + "accessories": "gold jewelry, scimitar" + }, + "styles": { + "aesthetic": "fantasy, warrior, gerudo style", + "primary_color": "gold", + "secondary_color": "blue", + "tertiary_color": "red" + }, + "lora": { + "lora_name": "urbosa_botw", + "lora_weight": 0.8, + "lora_triggers": "urbosa, gerudo" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/yor_briar.json b/nodes/character_reader/characters/yor_briar.json new file mode 100644 index 0000000..d5d81b0 --- /dev/null +++ b/nodes/character_reader/characters/yor_briar.json @@ -0,0 +1,35 @@ +{ + "character_id": "yor_briar", + "identity": { + "base_specs": "1girl, slender build, fair skin", + "hair": "long black hair, styled with gold headband", + "eyes": "red eyes", + "expression": "gentle yet mysterious smile", + "hands": "black nails", + "arms": "", + "torso": "medium breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "black backless halter dress, red rose pattern inside", + "lower_body": "black thigh-high boots", + "footwear": "black boots", + "gloves": "black fingerless gloves", + "accessories": "gold rose-themed headband, gold needle weapons" + }, + "styles": { + "aesthetic": "elegant, assassin, spy x family style", + "primary_color": "black", + "secondary_color": "red", + "tertiary_color": "gold" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/yshtola_rhul.json b/nodes/character_reader/characters/yshtola_rhul.json new file mode 100644 index 0000000..0a9d268 --- /dev/null +++ b/nodes/character_reader/characters/yshtola_rhul.json @@ -0,0 +1,35 @@ +{ + "character_id": "y'shtola_rhul", + "identity": { + "base_specs": "1girl, miqo'te, slender build, fair skin, cat ears", + "hair": "short white hair, bangs", + "eyes": "blind white eyes", + "expression": "stoic expression", + "hands": "black nails", + "arms": "", + "torso": "small breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "facial markings, cat tail" + }, + "wardrobe": { + "inner_layer": "", + "outer_layer": "black sorceress robes, fur trim", + "lower_body": "long skirt", + "footwear": "black boots", + "gloves": "", + "accessories": "wooden staff" + }, + "styles": { + "aesthetic": "magical, scholarly, final fantasy xiv style", + "primary_color": "black", + "secondary_color": "white", + "tertiary_color": "purple" + }, + "lora": { + "lora_name": "", + "lora_weight": 1.0, + "lora_triggers": "" + } +} \ No newline at end of file diff --git a/nodes/character_reader/characters/yuna_ffx.json b/nodes/character_reader/characters/yuna_ffx.json new file mode 100644 index 0000000..ee90551 --- /dev/null +++ b/nodes/character_reader/characters/yuna_ffx.json @@ -0,0 +1,35 @@ +{ + "character_id": "yuna_ffx", + "identity": { + "base_specs": "1girl, slender, fair skin", + "hair": "short brown hair, bob cut", + "eyes": "heterochromia, blue eye, green eye", + "expression": "gentle", + "hands": "", + "arms": "", + "torso": "small breasts", + "pelvis": "", + "legs": "", + "feet": "", + "distinguishing_marks": "" + }, + "wardrobe": { + "inner_layer": "white kimono top, yellow obi", + "outer_layer": "", + "lower_body": "long blue skirt, floral pattern", + "footwear": "boots", + "gloves": "detached sleeves", + "accessories": "summoner staff, necklace" + }, + "styles": { + "aesthetic": "fantasy, final fantasy x style", + "primary_color": "white", + "secondary_color": "blue", + "tertiary_color": "yellow" + }, + "lora": { + "lora_name": "yuna_ffx", + "lora_weight": 0.8, + "lora_triggers": "yuna, summoner outfit" + } +} \ No newline at end of file diff --git a/nodes/lora_from_string/__init__.py b/nodes/lora_from_string/__init__.py new file mode 100644 index 0000000..12be96c --- /dev/null +++ b/nodes/lora_from_string/__init__.py @@ -0,0 +1,9 @@ +from .lora_from_string import LoraFromString + +NODE_CLASS_MAPPINGS = { + "LoraFromString": LoraFromString +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "LoraFromString": "Lora From String" +} diff --git a/nodes/lora_from_string/__pycache__/__init__.cpython-314.pyc b/nodes/lora_from_string/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..97af428064a7cb118e58420ffa65dd1e0e17702f GIT binary patch literal 310 zcmdPqer|9{QD$Cx5i?M@N&qCN01{Pz2>WTW+!DwE z3dW}a1>=hmYHtbq`MbErJNq~W2gmz51_XHexd-2p0t>o$1_$^!M#lR&`ntm9Rx*4B zx%HM(UVchyu|B$?`tk9Zd6^~g@p=W7w>WHa^HWN5QtgUBJ_otDSRF`wU}j`wyvv~T lfsKJxbVA+-W+ri_3k<>^xPaUXVj4ic9MdHRsUi-bS^ytnP~89k literal 0 HcmV?d00001 diff --git a/nodes/lora_from_string/__pycache__/lora_from_string.cpython-314.pyc b/nodes/lora_from_string/__pycache__/lora_from_string.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..afbc8a92218841421de32aac633164e291b1ef3b GIT binary patch literal 1837 zcmZuyO>7fK6rQzr?Op%GPHd783YZ3xx>QaJK~z8rfh1rxIA(AhA|-6M-gRQJ_L|wT zDCxzAN=l}m4~a-he)*|n2Y?Ht~`_jcdkx8Ka3 z?TLmEtRH^5Q~6m$=nrmm7ufFFI|o}6-A7o+BI@k|^|`j6`i`Je2>S*Q_K*9#04ic( z7^THOxtS|@PEU5;KzrB0)*$OLq5?*cO``sOWT9n<9YEuq7%Jf)4PYM)Vn3C!IDn{v zB^oLs8pZ*rA+w%Yi)b^%s@|ofQd=nrhsq^D_ah|l?#-~d%nHUcn6=LX2s#>~XGO=V<>P#`AA+@Ge z4Hmdtz}ehQrc@gyt(cXXF~fRnN{reHT~)mxX=ZkAvcQ76QP$wC6|epFRpzh4IG%O- z8d%zAOth&{U->-wA;0w7{g>b5ql^polkSv-xiD?)L~>f^BnXM%cSG zXx1KcyDS54DrA95|8ZpMk6AdI%g-0o!eV~K6xw?JqiQ&9+#W_CFil??NZZGcmcjkAepI&fq(Ybfu`9yc#Gn}`}t@z2U z(e3OLduMw0!qYR(oq1zCL7ePD zai8jSAZI;T42*W((1&@RCCKKj{NYZzKBfEgU@rzZB`Arig=VJ$YS6k>?phan1^6W=YjchDz@R`#A!fP{$BWdRfKp4f=$_5~- z>1%QRx7Q#XiO*XXLvqALbf%MH_XZ6=khYWXpf8o+v+#oTX1 zEmB%l%N5gLQXLpana|c)a{v3OWs7)c!cK>P>V{b+{M!+k3yvA#W0F1)okPZJGm*E< zLhfmDiNF+o99-4rx7&!jQn1JXPjHMU7~~@zTpOAFHu~YIy#b<$TH&LccV2`~Y)w3w zd@+2Xl|1^@gcC`*Ue@zU2bNTDbFB6$(iOlxn z-6=(yTlr;b;#q29$9OvKXtn1l>zRCf zJ=BU1Ik6E(9w9@#>mwj?X&>Qt8cBjkN0_X-_l&BtkjkNJmOQvSqRfDctIvIpSEP|&C^ElTz=JL#Z?nWUymt*pc$-?x_IlSmWc0`4% zLZg+Es!_NyK5bCLhJ3xM>Soj{C0a6o0V7o3GQ|F!)6CC6Hd z|K(Gp(4HR!dfQxU_oL*Q=4>lA)V$@2H)2#8Z6gpKB0Nc2A}3*kp*Z0(F5k#0?vXu@ wt-Hls_`ERA0VZGZ;QEMM0+Y9Ab12$=K@eV{#4FVI3dP=tCxp>G1j3E{2gGI67ytkO literal 0 HcmV?d00001 diff --git a/nodes/lora_from_string/lora_from_string.py b/nodes/lora_from_string/lora_from_string.py new file mode 100644 index 0000000..e30185a --- /dev/null +++ b/nodes/lora_from_string/lora_from_string.py @@ -0,0 +1,35 @@ +import folder_paths +import comfy.utils +import comfy.sd + +class LoraFromString: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "model": ("MODEL",), + "clip": ("CLIP",), + "lora_name": ("STRING", {"multiline": False}), + "strength_model": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}), + "strength_clip": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}), + } + } + + RETURN_TYPES = ("MODEL", "CLIP") + FUNCTION = "load_lora" + CATEGORY = "AODH Pack" + + def load_lora(self, model, clip, lora_name, strength_model, strength_clip): + if strength_model == 0 and strength_clip == 0: + return (model, clip) + + lora_path = folder_paths.get_full_path("loras", lora_name) + lora = None + if lora_path: + lora = comfy.utils.load_torch_file(lora_path, safe_load=True) + else: + print(f"Lora not found: {lora_name}") + return (model, clip) + + model_lora, clip_lora = comfy.sd.load_lora_for_models(model, clip, lora, strength_model, strength_clip) + return (model_lora, clip_lora) diff --git a/nodes/reenforcer/__init__.py b/nodes/reenforcer/__init__.py new file mode 100644 index 0000000..8ff2aeb --- /dev/null +++ b/nodes/reenforcer/__init__.py @@ -0,0 +1,9 @@ +from .reenforcer import ReEnforcer + +NODE_CLASS_MAPPINGS = { + "ReEnforcer": ReEnforcer +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "ReEnforcer": "ReEnforcer" +} diff --git a/nodes/reenforcer/reenforcer.py b/nodes/reenforcer/reenforcer.py new file mode 100644 index 0000000..519d54c --- /dev/null +++ b/nodes/reenforcer/reenforcer.py @@ -0,0 +1,18 @@ +class ReEnforcer: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "string": ("STRING", {"multiline": True}), + "count": ("INT", {"default": 1, "min": 1, "max": 100}), + } + } + + RETURN_TYPES = ("STRING",) + RETURN_NAMES = ("string",) + FUNCTION = "reenforce" + CATEGORY = "AODH Pack" + + def reenforce(self, string, count): + result = ", ".join([string] * count) + return (result,) diff --git a/nodes/resolution_reader/__init__.py b/nodes/resolution_reader/__init__.py new file mode 100644 index 0000000..d637fe5 --- /dev/null +++ b/nodes/resolution_reader/__init__.py @@ -0,0 +1,9 @@ +from .resolution_reader import ResolutionReader + +NODE_CLASS_MAPPINGS = { + "ResolutionReader": ResolutionReader +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "ResolutionReader": "Resolution Reader" +} diff --git a/nodes/resolution_reader/resolution_reader.py b/nodes/resolution_reader/resolution_reader.py new file mode 100644 index 0000000..128c2b5 --- /dev/null +++ b/nodes/resolution_reader/resolution_reader.py @@ -0,0 +1,79 @@ +import os +import random + +class ResolutionReader: + @classmethod + def INPUT_TYPES(s): + base_path = os.path.dirname(os.path.realpath(__file__)) + file_path = os.path.join(base_path, "resolutions", "resolutions.txt") + + lines = [] + if os.path.exists(file_path): + with open(file_path, 'r') as f: + lines = [line.strip() for line in f.readlines() if line.strip()] + + if not lines: + lines = ["1024,1024,1.0"] + + return { + "required": { + "resolution": (lines, ), + "selection_mode": (["manual", "sequential", "random"], {"default": "manual"}), + "repeat_count": ("INT", {"default": 1, "min": 1, "max": 100, "step": 1}), + } + } + + @classmethod + def IS_CHANGED(s, resolution, selection_mode, repeat_count): + if selection_mode == "random" or selection_mode == "sequential": + return float("nan") + return resolution + + RETURN_TYPES = ("INT", "INT", "FLOAT") + RETURN_NAMES = ("width", "height", "upscale") + + FUNCTION = "read_resolution" + CATEGORY = "AODH Pack" + + _current_index = 0 + _current_count = 0 + _last_selection = None + + def read_resolution(self, resolution, selection_mode, repeat_count): + base_path = os.path.dirname(os.path.realpath(__file__)) + file_path = os.path.join(base_path, "resolutions", "resolutions.txt") + + lines = [] + if os.path.exists(file_path): + with open(file_path, 'r') as f: + lines = [line.strip() for line in f.readlines() if line.strip()] + + if not lines: + return (0, 0, 0.0) + + if selection_mode == "manual": + selected_line = resolution + elif selection_mode == "sequential": + if self.__class__._current_count >= repeat_count: + self.__class__._current_index += 1 + self.__class__._current_count = 0 + selected_line = lines[self.__class__._current_index % len(lines)] + self.__class__._current_count += 1 + elif selection_mode == "random": + if self.__class__._current_count >= repeat_count or self.__class__._last_selection is None: + self.__class__._last_selection = random.choice(lines) + self.__class__._current_count = 0 + selected_line = self.__class__._last_selection + self.__class__._current_count += 1 + else: + selected_line = resolution + + try: + # Format: width, height, upscale + parts = [p.strip() for p in selected_line.split(',')] + width = int(parts[0]) + height = int(parts[1]) + upscale = float(parts[2]) + return (width, height, upscale) + except (ValueError, IndexError): + return (0, 0, 0.0) diff --git a/nodes/resolution_reader/resolutions/resolutions.txt b/nodes/resolution_reader/resolutions/resolutions.txt new file mode 100644 index 0000000..f16d7b3 --- /dev/null +++ b/nodes/resolution_reader/resolutions/resolutions.txt @@ -0,0 +1,4 @@ +1280,720,3.0 +720,1280,3.0 +1376,576,2.5 +1024,1024,2.0 diff --git a/project-goal.md b/project-goal.md new file mode 100644 index 0000000..24313a3 --- /dev/null +++ b/project-goal.md @@ -0,0 +1,44 @@ +# AODH Pack + +Author: Aodhan Collins + +## Overview + + A set of custom ComfyUI nodes that aid in the creation of images of anime/video game characters. + +## Character JSON Reader + +Reads a character JSON file and outputs the character's attributes for diverse image generation use cases. The basic format is as follows + +```json +{ + "character_id": "cyber_huntress_01", + "identity": { + "base_specs": "1woman, athletic build, pale skin", + "hair": "neon pink bob cut, undercut", + "eyes": "glowing violet eyes", + "expression": "stoic, focused", + "hands": "pink nails", + "arms": "cat tattoo on arm", + "torso": "small breasts", + "pelvis": "narrow waist", + "legs": "flower tattoo on leg", + "feet": "pink toenails", + "distinguishing_marks": "cybernetic interface port on neck, facial tattoos" + }, + "wardrobe": { + "inner_layer": "black mesh bodysuit", + "outer_layer": "oversized holographic bomber jacket", + "lower_body": "high-waisted tactical shorts", + "footwear": "platform combat boots", + "gloves": "fingerless leather gloves", + "accessories": "cybernetic visor, choker, utility belt" + }, + "styles": { + "aesthetic": "cyberpunk, synthwave", + "primary_color": "pink", + "secondary_color": "violet", + "tertiary_color": "cyan" + } +} +``` diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..3f38837 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +# No external dependencies required for the current nodes. +# Standard library (json, os) is used. diff --git a/update_nails.py b/update_nails.py new file mode 100644 index 0000000..279b6ff --- /dev/null +++ b/update_nails.py @@ -0,0 +1,50 @@ +import json +import os + +characters_dir = 'nodes/character_reader/characters' + +print(f"Looking for characters in: {os.path.abspath(characters_dir)}") + +if not os.path.exists(characters_dir): + print(f"ERROR: Directory {characters_dir} does not exist.") + exit(1) + +files = [f for f in os.listdir(characters_dir) if f.endswith('.json')] +print(f"Found {len(files)} JSON files.") + +for filename in files: + filepath = os.path.join(characters_dir, filename) + print(f"Processing {filename}...") + + try: + with open(filepath, 'r') as f: + data = json.load(f) + except Exception as e: + print(f" Error reading {filename}: {e}") + continue + + primary_color = data.get('styles', {}).get('primary_color') + + if primary_color: + if 'identity' not in data: + data['identity'] = {} + + hands = data['identity'].get('hands', '') + nail_string = f"{primary_color} nails" + + # Check if nails are already mentioned + if "nails" not in hands and "polish" not in hands: + if hands and hands.strip(): + new_hands = f"{hands}, {nail_string}" + else: + new_hands = nail_string + + data['identity']['hands'] = new_hands + print(f" UPDATING: '{hands}' -> '{new_hands}'") + + with open(filepath, 'w') as f: + json.dump(data, f, indent=2) + else: + print(f" Skipping: Nails already present ('{hands}')") + else: + print(f" Skipping: No primary color found.")