44 lines
2.9 KiB
Python
44 lines
2.9 KiB
Python
# Portrait prompts for the bestiary (high-res style). Descriptions come from the sprite pipeline.
|
|
import importlib.util, os
|
|
|
|
ROOT = "/home/zink/Projects/dungeoncraft"
|
|
_spec = importlib.util.spec_from_file_location("creatures", f"{ROOT}/art/generated/sprites/scripts/creatures.py")
|
|
_cr = importlib.util.module_from_spec(_spec)
|
|
_spec.loader.exec_module(_cr)
|
|
|
|
IMP = dict(id="imp", kind="Worker", name="Pit Imp",
|
|
desc="A small goblin-like worker demon: big head, oversized pointed ears and two small black horns, orange skin, glowing yellow eyes, a wide mischievous grin with tiny fangs, a ragged dark-red tunic with a rope belt, carrying a small iron pickaxe with a wooden handle over its right shoulder.")
|
|
CREATURES = [IMP] + [dict(id=c["id"], kind=c["kind"], name=c["name"], desc=c["desc"]) for c in _cr.CREATURES]
|
|
BY_ID = {c["id"]: c for c in CREATURES}
|
|
SIEGE = {"ram", "catapult"}
|
|
BEAST = {"spider", "bat", "owl", "wyrm", "beetle", "cavebear", "gargoyle"}
|
|
|
|
|
|
def sheet(cid):
|
|
if cid == "imp":
|
|
return f"{ROOT}/assets/sprites/imp-64.png"
|
|
return f"{ROOT}/art/generated/sprites/{cid}-64.png"
|
|
|
|
|
|
TEMPLATE = """The attached image shows a small pixel art game sprite of the "{name}" (left: front view, right: three-quarter view). {desc}
|
|
|
|
Paint a PORTRAIT of exactly this {thing} for the illustrated monster compendium of a dark-fantasy dungeon strategy game: {framing}, three-quarter view turned slightly to the side, looking at the viewer, filling most of the square picture. It must clearly be the same {thing} as in the sprite: the same colours, clothing, armour, markings, gear and weapon (show the weapon or tool where it fits in the frame), but drawn with much more detail and slightly more natural, characterful proportions.
|
|
|
|
Style: hand-painted pixel art, like a detailed 128x128 pixel portrait scaled up with hard square pixels, a limited colour palette, clean dark outlines, no anti-aliasing blur, no smooth gradients, no photo realism.
|
|
|
|
Lighting and background: a little dramatic - a warm torch light from one side (the torch itself outside the picture) and a deep shadow on the other side, a rim light on the silhouette. Dark atmospheric dungeon background: rough stone wall in darkness, a faint glow and drifting dust or mist, darkening to near black at the edges.
|
|
|
|
Exactly one {thing}, no text, no letters, no name, no labels, no frame, no border, no signature, no UI."""
|
|
|
|
|
|
def prompt_for(cid, extra=""):
|
|
c = BY_ID[cid]
|
|
if cid in SIEGE:
|
|
thing, framing = "siege engine", "a close-up of the front part of the machine with its crew-less wooden frame and iron parts"
|
|
elif cid in BEAST:
|
|
thing, framing = "creature", "a close-up of its head and the front of its body (bust portrait)"
|
|
else:
|
|
thing, framing = "character", "a head-and-shoulders bust portrait"
|
|
p = TEMPLATE.format(name=c["name"], desc=c["desc"], thing=thing, framing=framing)
|
|
return p + ("\n\n" + extra if extra else "")
|