feat: add horror prompt library with severity tiers and voice texts
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
"""Horror prompt library — severity-tiered SDXL prompts + XTTS voice texts."""
|
||||
|
||||
import random
|
||||
|
||||
# Negative prompt applied to all SDXL generations
|
||||
NEGATIVE_PROMPT = (
|
||||
"cheerful, bright, colorful, cartoon, anime, text, watermark, "
|
||||
"logo, signature, pleasant, happy, cute, well-lit, clean"
|
||||
)
|
||||
|
||||
# (min_severity, [prompt_templates])
|
||||
# Each tier's prompts are available when severity >= min_severity.
|
||||
# Prompts use {detail} placeholder for procedural variation.
|
||||
SEVERITY_TIERS: list[tuple[float, list[str]]] = [
|
||||
(0.0, [
|
||||
"dark abstract void, deep shadows, {detail}, horror atmosphere, cinematic",
|
||||
"black fog rolling over dark water, {detail}, ominous, photorealistic",
|
||||
"concrete corridor stretching into darkness, {detail}, liminal space, unsettling",
|
||||
"dark gradient with subtle organic texture, {detail}, dread, macro photography",
|
||||
"abandoned room in total darkness, single light source, {detail}, eerie silence",
|
||||
"static noise pattern forming almost-shapes, {detail}, analog horror aesthetic",
|
||||
"deep underground cavern, no visible exit, {detail}, claustrophobic, dark",
|
||||
]),
|
||||
(1.0, [
|
||||
"distorted human face emerging from darkness, {detail}, uncanny valley, horror",
|
||||
"long dark hallway with a figure at the end, {detail}, found footage aesthetic",
|
||||
"room where the walls are slightly wrong, {detail}, liminal horror, photorealistic",
|
||||
"mirror reflection that doesn't match, {detail}, psychological horror",
|
||||
"staircase descending into impossible depth, {detail}, surreal horror",
|
||||
"doorway opening into a void, {detail}, threshold horror, dark atmosphere",
|
||||
"familiar room but every proportion is wrong, {detail}, dreamlike horror",
|
||||
]),
|
||||
(2.0, [
|
||||
"face melting into dark liquid, {detail}, body horror, visceral, photorealistic",
|
||||
"impossible architecture folding in on itself, {detail}, Escher nightmare, dark",
|
||||
"multiple overlapping faces fused together, {detail}, uncanny, disturbing",
|
||||
"corridor with too many doors, all slightly open, {detail}, psychological horror",
|
||||
"human figure with wrong number of limbs, {detail}, body horror, dark",
|
||||
"room full of eyes watching from every surface, {detail}, paranoid horror",
|
||||
"teeth growing from walls, {detail}, organic horror, visceral, photorealistic",
|
||||
]),
|
||||
(3.0, [
|
||||
"screaming void, flesh merging with architecture, {detail}, extreme body horror",
|
||||
"reality fracturing into bleeding shards, {detail}, cosmic horror, overwhelming",
|
||||
"mass of tangled human forms, {detail}, hellscape, Beksinski inspired, photorealistic",
|
||||
"sky replaced by a massive watching face, {detail}, cosmic dread, surreal",
|
||||
"ground made of writhing organic matter, {detail}, Giger inspired, dark",
|
||||
"impossible geometry that hurts to perceive, {detail}, Lovecraftian, extreme",
|
||||
"world turned inside out, organs as landscape, {detail}, visceral cosmic horror",
|
||||
]),
|
||||
]
|
||||
|
||||
# Procedural detail fragments inserted into {detail} placeholders
|
||||
_DETAILS = [
|
||||
"wet surfaces", "rust and decay", "dim red light", "flickering fluorescent",
|
||||
"peeling paint", "fog and mist", "dripping liquid", "cracked surfaces",
|
||||
"organic growths", "shadow patterns", "reflected light on water",
|
||||
"dust particles", "cobwebs", "stained walls", "scratched metal",
|
||||
"condensation", "mold patterns", "burned edges", "frozen in time",
|
||||
"overlapping shadows", "single bare bulb", "moonlight through cracks",
|
||||
"bioluminescent", "blood-red sky", "green pallor", "bruise-purple tint",
|
||||
]
|
||||
|
||||
# Whisper fragments — sentence fragments, numbers, names, nonsense
|
||||
_WHISPERS = [
|
||||
"seven", "behind you", "don't turn around", "it remembers",
|
||||
"the door", "counting", "almost time", "in the walls",
|
||||
"not alone", "watching", "three two one", "forgetting",
|
||||
"underneath", "the wrong room", "teeth", "it knows your name",
|
||||
"listen", "the sound", "nobody left", "opening",
|
||||
"he's here", "she won't stop", "the children", "below",
|
||||
"always here", "never gone", "the dark", "it follows",
|
||||
"coming closer", "just outside", "the mirror", "look",
|
||||
"run", "too late", "the floor", "above you",
|
||||
"inside", "the old house", "breathing", "footsteps",
|
||||
"scratching", "dripping", "humming", "whispers",
|
||||
"ha ha ha ha", "one two three four five", "again again again",
|
||||
"please", "help me", "let me in", "let me out",
|
||||
]
|
||||
|
||||
# Direct address phrases — "it sees you" moments
|
||||
_DIRECT_ADDRESS = [
|
||||
"you're still here",
|
||||
"don't leave",
|
||||
"I can see you",
|
||||
"why",
|
||||
"stay",
|
||||
"you came back",
|
||||
"I've been waiting",
|
||||
"don't close your eyes",
|
||||
"you can't leave",
|
||||
"I know you're there",
|
||||
"look at me",
|
||||
"do you hear it",
|
||||
"it's behind you",
|
||||
"we see you",
|
||||
"you're one of us now",
|
||||
"don't you remember",
|
||||
"you were here before",
|
||||
"this is yours",
|
||||
"you did this",
|
||||
"welcome home",
|
||||
]
|
||||
|
||||
|
||||
def get_image_prompt(severity: float) -> str:
|
||||
"""Select and fill a horror prompt appropriate for the given severity.
|
||||
|
||||
Higher severity unlocks more extreme prompt tiers.
|
||||
A random prompt is chosen from all available tiers, weighted toward
|
||||
the highest unlocked tier.
|
||||
"""
|
||||
available: list[tuple[float, str]] = []
|
||||
for threshold, templates in SEVERITY_TIERS:
|
||||
if severity >= threshold:
|
||||
for tmpl in templates:
|
||||
available.append((threshold, tmpl))
|
||||
|
||||
if not available:
|
||||
available = [(0.0, t) for t in SEVERITY_TIERS[0][1]]
|
||||
|
||||
# Weight toward higher tiers: tier_weight = 1 + tier_index
|
||||
tier_thresholds = sorted(set(t[0] for t in available))
|
||||
tier_map = {t: i + 1 for i, t in enumerate(tier_thresholds)}
|
||||
weights = [tier_map[threshold] for threshold, _ in available]
|
||||
|
||||
_, template = random.choices(available, weights=weights, k=1)[0]
|
||||
detail = random.choice(_DETAILS)
|
||||
return template.format(detail=detail)
|
||||
|
||||
|
||||
def get_voice_text() -> str:
|
||||
"""Random whisper fragment for XTTS voice generation."""
|
||||
return random.choice(_WHISPERS)
|
||||
|
||||
|
||||
def get_direct_address_text() -> str:
|
||||
"""Random direct address phrase for 'it sees you' moments."""
|
||||
return random.choice(_DIRECT_ADDRESS)
|
||||
Reference in New Issue
Block a user