Easy gallery system in Ren'Py

2021-08-14 13:37:00

In Ren'Py there is a system for creating a image gallery for whatever special images you want to show off. I didn't think it was necessary until I acknowledged that making more custom illustrations for my project will put more Visual in my Visual Novel. It also is a page that helps the player keep track of all they've experienced (out of my 3+ something-hours-and-growing-worth-of-content-one-person-made game)

In my game I call it the 'scrapbook' because one, my personal bias towards how awesome scrapbooks are and two, just because it adds more in game potential for my story personally, as one of my main characters learns important numbers and such.

I have yet to really make it look like a scrapbook, it may be impossible for Ren'Py, but so far I am proud of the functionality and aesthetic.

Guts and the Moon. And my Ouija shrinky dinks<3333

Although it may be easy for a lot of people to wrap their head around the code, I had to find an explanation on Lemma Soft forums to understand how to do this. I understand programming however, when it is worded more well, evocatively to put it nicely. thought I'd go through what I did, all the way to getting a nice notification to go off every time an image or what I call 'memory' is unlocked.

I am a beginner and hardly know how to talk about programming, so this is for any other beginners that want something that works and looks decent, but are less programming savy.

Lets get started. First you have define this is a Gallery system to my knowledge, which is an inbuilt Ren'Py thingo.

g.button is the button name, simple. Second line is basically when a button is unlocked, which I will show how it's implemented later. Third is the full sized image. Remember to keep the names super simple, as all programmers will tell you, and in my case, I'm preparing for adding more to one name such as with 'nigelart1'. Here are four for now, the thumbnails we click on.

init python: 
# Step 1. Create the gallery object.
    g = Gallery()

    g.button("map1")
    g.condition("persistent.map1")
    g.image("misc/map1.png")

    g.button("mametime")
    g.condition("persistent.mametime")
    g.image("misc/mametime.png")

    g.button("nigelart1")
    g.condition("persistent.nigelart1")
    g.image("misc/nigelart1.png")

    g.button("lachlan_meet1")
    g.condition("persistent.lachlan_meet1")
    g.image("misc/lachlan_meet1.png")

In the below code, I call this screen scrapbook2 because to my knowledge, we are avoiding the default gallery page for now and working around it. You can call yours gallery2 or whatever.

The grid will get annoying quick. I've edited this code for the sake of simplicity, but in my code, I have a grid 8 by 3! Only because I am preparing for a lot of art. In this example, I put grid 2 2 just to do four buttons.

screen scrapbook2:

    # Ensure this replaces the main menu.
    tag menu

    # The background.
    add "misc/bg_gallery.png"

    # A grid of buttons.
    grid 2 2:

        xfill True
        yfill True

        # Call make_button to show a particular button.
        add g.make_button("map1","misc/map1_t.png", locked = "lock", xalign=0.5, yalign=0.5) 
        add g.make_button("mametime","misc/mametime_t.png", locked = "lock", xalign=0.5, yalign=0.5) 
        add g.make_button("nigelart1","misc/nigelart1_t.png", locked = "lock", xalign=0.5, yalign=0.5) 
        add g.make_button("lachlan_meet1","misc/lachlan_meet1_t.png", locked = "lock", xalign=0.5, yalign=0.5) 


        

Within g.make_button we have the name of the buttons created above such as "nigelart1", then we have the thumbnails. Lastly locked = "lock" is the locked thumbnail image. Mine is 'lock' which is an animation I define in another script. You can put a still image from whatever folder it's in.

Thumbnails are vital for how the screen will look. I decided to go with 200 by 200px because I like the look of a large grid of 24 square images and am working towards drawings heaps more images.

xfill and yfill to True or False will basically expand or reduce the images to fill the space. If False they will all be cramped together, which might be a look you want.

You must put 'null' if you have no buttons in a spot on your grid! for example if I didn't have all 4 buttons set up, just put null. You can see how it becomes a pain if you have 24, that is what my code looks like. I put duplicate of one button, just to visualise the space better.

This stuff below is pretty basic, and defines the lock button, which doesn't seem to be working for me, lol. But the below 'hover' is really nice, and I'm sure someone can be more creative than me, making them tint red.

g.transition = dissolve
g.locked_button =  "misc/lock.png"
g.hover_border ="misc/ol_hover.png"

Lastly, we have buttons that take us to next and previous pages. You will break the game if you haven't duplicated this 'scrapbook2' screen and made a 'scrapbook3'. Below, it also will crash thinking that there is a page 1 gallery, so I commented out everything but a return button.

#textbutton "Previous" action ShowMenu("gallery") xalign 1.0 yalign 0.9

#textbutton "Next" action ShowMenu("scrapbook3") xalign 1.0 yalign 0.95

#text _("Click on image to minimise") xalign 0.95 yalign 0.95
textbutton "Return" action Return() xalign 1.0 yalign 1.0

Next we have a few things to implement unlocking of these memories. I placed an unlocking moment right underneath lachlan_meet1. This removes the lock on the art.

nvl clear 
    window hide
    scene illust_lachlan1 with fastdis:
        yalign 1.0
        linear 5.0 yalign 0.0
    $renpy.pause(delay=2,hard=False)
    play looper "audio/sfx_summer1.mp3" loop volume 4.0
    $persistent.lachlan_meet1 = True
    "Fierce pale eyes leered down at her from a dirt smeared face.
    {p}Next she spied the large maroon wrench held loosely in his hand." 

##################################################

play sound "audio/sfx_step_grit3_mid.mp3"
    "With the refreshing droplets pattering against her skin,
    she hoped those hazel eyes weren't still locked onto her back. "
    $renpy.notify(scrap)

$renpy.notify(scrap) creates a notify on the screen. In mine, I set it at the end of the scene, since placing it mid-story is far too distracting. Then somewhere else in your code you can put.

define scrap = "New memory unlocked. Check scrapbook!"

If this is done all in order, you will unlock the art, and then later on the player gets a notification in the top left telling them to go have a look.

Lastly, add this to your screen navigation()

textbutton "Scrapbook" action ShowMenu("scrapbook2")

I don't know why this was so hard for me to understand making a gallery in the manual! But this seems to be the case with learning, in Ren'Py or anything. I am still a massive beginner, and that probably shows.

Ren'Py is nothing but words. Words words words, it just goes on. That is why I'm trying to keep the variables I have to put within the story text to a minimum, not to much success unfortunately. The first time I tried understanding the gallery, I really couldn't do it, so this workaround actually works.

This has probably been useless, but I enjoyed writing it out. As I said I have 3+ hours of reading/playing content in my story, and its growing. I am more focused on art and writing over everything else, not programming really.

Thanks for reading!