Page 1 of 1

Custom Placeholder Portraits on the Fly

Posted: Thu Mar 17, 2022 11:05 am
by dovedozen
Since I write (script & code) for my game and someone else makes the assets, we're both new to this whole thing, and I very much have the devastating "impatient, yet fussy" combo personality trait, Ren'Py's default placeholder images majorly don't work for me. I don't know which attributes I'm going to need yet and won't until I've written a bunch and gone over it with my partner, but have trouble making sense of what's on the screen when everyone's represented by the same picture, even if they are all labeled.

To make things easier for us both while we're puzzling our way through learning to develop, I knew I would need 3 things:
  1. Distinct placeholder images for each character, distinguishable from one another in a split second (they could literally be rectangles that are all different colors, but still!)
  2. With the attributes of the relevant show statement emblazoned clearly on top of them
  3. WITHOUT having to duplicate and correctly name a file for, or otherwise define manually in any way, an appropriate image myself
...So I slapped together some python that will do that. Here it is; please use it. Be like me and live your "novice game dev with zero attention span" dream.

First, add this to your options.rpy:

Code: Select all

define config.missing_show = fancy_placeholder
Then add this init python block anywhere you like. I made a "custom" directory with an .rpy file inside it just for custom functions, and put it there.
You will have to define some "approved_tags", and should check the Composite() at the end to make sure its dimensions work for you.

Code: Select all

init python:
    def fancy_placeholder(name, what, layer):

        print("Generating placeholder portrait...")

        # Tags for which you have added a "[tag]_pl.png" to a Placeholders directory inside your images directory
        # Format: "tag1", "tag2", "tag3"
        approved_tags = "charname",

        # Checks whether the tag used in your show statement is part of the list above
        if not name[0] in approved_tags:
            print("Placeholder silhouette not defined. Returning control to ren'py...")
            # This should allow ren'py's default behavior for any missing images not covered by your placeholders
            return None
        else:
            pass

        # Makes a text displayable out of your "show" call
        temp_text = Text(" ".join(map(str, name)))

        # Creates a string pointing to your placeholder image
        temp_filename = "Placeholders/" + str(name[0]) + "_pl.png"

        # Composites your text displayable and your placeholder image
        # (720,1080) is my portrait size; change it to whatever works for you
        # (275,400) is a text position that looks good on my stuff; test this and change it as you see fit
        # Probably best to leave the (0,0) alone, though
        temp_displayable = Composite((720,1080), (0,0), temp_filename, (275,400), temp_text)

        # Hands the composite back to ren'py to display on the screen
        return temp_displayable
You will have to add a "Placeholders" folder to your "images" directory, then add a [tag]_pl.png for each tag you want to use this with.

ALSO: BEWARE: You CANNOT have anything in your images directory named just "[tag].png", or an exception will occur before this function can even be called. "[tag] happy.png" or anything else that's not JUST the tag name should be okay.

This is set up to handle my personal use case (character portraits only, pngs only, attribute lists won't ever be very long, etc.). It's quick & hyper-specific, but hopefully if you're like me and barely know python my comments will help a little in case you need to tweak something! (Personally, I might try changing the color of the text or something in a bit.)

Anyway, I hope it helps someone! :mrgreen: