21 April 2025

How to show different dialogue boxes for different characters

 Want to show different dialogue boxes depending on the character? You can create as many dialogue boxes (also called 'say screens') as you like, which can then be assigned to your characters when you define then. Then whenever that character is speaking, it will use the version of the dialogue box you set against it.

Here's a simple example demonstrating how to align a character's name to the right side of the say screen:

Here is an example for where I shift the character's name to the right side of their dialogue:

screen right_aligned_say(who, what):
        window:
                identifier "dialogue_window"
                if who is not None:
                window:
                        horizontal_alignment 1.0
                        identifier "character_name_box"
                        style "name_format"
                        text who identifier "speaker_name"
                text what identifier "spoken_text"

        define right_speaker = Character("Right", screen="right_aligned_say")

        label game_start:
        right_speaker "This is an example of the text appearing on the right."
        normal_speaker "This text should appear normally."
        return

In this code, we've taken the standard say screen as a base, renamed it shifted_name_say, and then used x_alignment 1.0 to position the character's name on the right edge of the dialogue box. We then define a character, right_nami, and instruct Ren'Py to use our shifted_name_say screen whenever this character speaks.

18 April 2025

Adding Tooltips for Your Ren'Py Image Buttons

 Want to give your players a little more information without cluttering your Ren'Py scenes? Tooltips are a fantastic way to do just that! When a player hovers their mouse over an interactive element, a small text box appears, providing extra context or a description. Let's explore how you can easily add tooltips to your image buttons in your Ren'Py scene files.


Imagine you have an image button in your game, perhaps representing an item your player can interact with. Instead of directly labeling it on the screen, you can use a tooltip to display the item's name or a short description when the player hovers over it. This keeps your UI clean and provides information only when needed.

Here's a basic example of how you can implement this in your Ren'Py screen file:

Code snippet
screen my_scene:
    imagebutton:
        idle "images/item_icon.png"
        hover "images/item_icon_hover.png"
        action Show("item_details_screen")
        tooltip "Examine the Mysterious Artifact"

In this simple example, we've added the tooltip parameter directly to our imagebutton. When the player hovers their mouse over the "images/item_icon.png", the text "Examine the Mysterious Artifact" will appear as a tooltip.

Taking it a Step Further (Dynamic Tooltips):

For more dynamic tooltips, where the text might change based on game state, you can use Python within your screen language. Let's adapt the code you provided as an example:

Code snippet
screen police_front:
    add gTimer.image("backgrounds/police_front{}.jpg")

    imagebutton:
        idle "images/door_icon.png"
        hover "images/door_icon_hover.png"
        action Jump("enter_police_station")
        mouse_hovered SetVariable("tooltip_text", "Enter the Police Station")
        mouse_unhovered SetVariable("tooltip_text", None)

    if tooltip_text:
        text "[tooltip_text]":
            yalign .99
            xalign .01

In this more advanced example:

  1. We define an imagebutton for the police station door.
  2. mouse_hovered SetVariable("tooltip_text", "Enter the Police Station") sets the tooltip_text variable when the mouse hovers over the button.
  3. mouse_unhovered SetVariable("tooltip_text", None) clears the tooltip_text variable when the mouse moves away.
  4. The if tooltip_text: block checks if the tooltip_text variable has a value. If it does, it displays a text element at the bottom-left of the screen (yalign .99, xalign .01) showing the content of the tooltip_text variable.

Important Considerations:

  • Readability: Keep your tooltip text concise and easy to understand.
  • Placement: Consider the placement of your tooltips so they don't obscure important parts of the screen.
  • Styling: You can customize the appearance of your tooltips using styles in your gui.rpy file. Look for styles starting with tooltip_.

By utilizing tooltips, you can enhance the user experience of your Ren'Py visual novel, providing helpful information in an elegant and unobtrusive way. Experiment with different approaches to find what works best for your game!

17 April 2025

How to show different background for day/night cycles in Renpy

 Here is a quick explanation for how I keep track of day/night cycles in my Renpy games, including how to show different background images depending on the time and day.

Adding a DayTracker class

Here is the python code I use which creates a dayTracker class. This class is used to keep track of the day of the week and time of day. There are a few other functions in there too.

class dayTracker:
        _tod = 1
        _dow = 0
        _game_day = 0
        weekdays = (
            'Mon',
            'Tue',
            'Wed',
            'Thu',
            'Fri',
            'Sat',
            'Sun',
            )
        weekdays_long = (
            'Monday',
            'Tuesday',
            'Wednesday',
            'Thursday',
            'Friday',
            'Saturday',
            'Sunday',
            )
       
        def is_morning(self):
            return self._tod == 1
       
        def is_afternoon(self):
            return self._tod == 2
       
        def is_evening(self):
            return self._tod == 3
        def is_night(self):
            return self._tod == 4
        def is_dark(self):
            return self._tod >= 3
        def set_tod(self,tod):
            self._tod = tod
        def set_dow(self,dow):
            self._dow = dow
       
        def image(self, name, layer = "master"):
            import re
            tmp = name
            if not re.search('\{}', name):
                name = name + '{}'
            if  not self.is_morning() and not self.is_afternoon():
                name = name.replace("_day", "")
                if self.is_evening():
                    tmp = name.format("_evening")
                    if renpy.exists("images/"+tmp):
                        return tmp
                else:
                    tmp = name.format("_night")
                    if renpy.exists("images/"+tmp):
                        return tmp
                if renpy.exists("images/"+tmp):
                        return tmp
                return name.format("_night")
            else:
                return name.format("")
       
        def is_weekend(self):
            return self._dow == 5 or self._dow ==6
       
        def dayOfWeek(self,full=False):
            if full:
                return self.weekdays_long[self._dow]
            else:
                return self.weekdays[self._dow]
       
        def gameDay(self):
            return self._game_day
       
        def tick(self,tod=None):
            if tod:
                self._tod = tod
            elif self._tod < 4:
                self._tod += 1

        
        def sleep(self):
            self._tod = 1
            self._dow = (self._dow +1) % 7
            self._game_day += 1
            renpy.force_autosave()


Time of day (tod) is split into 4 day parts (Morning = 1, Afternoon = 2, Evening = 3 , Night= 4)
To move time forward, I use dayTracker.tick(), which increments tod by 1 until it is night.
Once it is night, I use a dayTracker.sleep(), which resets the tod and increments the day of the week.

Setting a different background image for different day parts

First, set up your images correctly. I use the following naming conventions for my backgrounds.
Morning = IMAGENAME.jpg
Afternoon = IMAGENAME.jpg
Evening = IMAGENAME_evening.jpg
Night = IMAGENAME_night.jpg

Then I usage dayTracker.image() to handle updating the background image.
For example, let's say I have a background of a library called campus_library.jpg.
I'd also have campus_library_evening.jpg for the evening scene and campus_library_night.jpg for the night scene.
In Renpy, I'd write:

scene expression dayTracker.image("backgrounds/campus_library{}.jpg")

This will check the time of day, and then replace the {} with either _evening or _night, depending on the tod.

Hope this helps! Leave a comment if you have any issues.

15 April 2025

Sunrise, Sunset, Scripting: Handling Day/Night Cycles in Ren'Py with Labels

 Hi! I'm Lex, back with a quick tip for your Ren'Py projects. Today, let's tackle a common beginner question: how to handle different parts of the day in your visual novel using labels.

Creating a sense of time passing can significantly enhance immersion. One straightforward way to achieve this in Ren'Py is by using labels to define different time-of-day scenarios and then jumping between them based on your game's logic.

The core idea is to have separate labels for morning, afternoon, evening, and night (or any other time divisions you need). Within each label, you can define the appropriate background, character expressions, and dialogue.

Here's a basic example:

default current_time = "morning"

label start:
    if current_time == "morning":
        jump morning_scene
    elif current_time == "afternoon":
        jump afternoon_scene
    elif current_time == "evening":
        jump evening_scene
    elif current_time == "night":
        jump night_scene

label morning_scene:
    scene bg morning
    show character happy
    "The sun rises, casting a warm glow."
    $ current_time = "afternoon"
    jump start # Go back to check the time

label afternoon_scene:
    scene bg afternoon
    show character neutral
    "The day is in full swing."
    $ current_time = "evening"
    jump start

label evening_scene:
    scene bg evening
    show character worried
    "Shadows lengthen as dusk approaches."
    $ current_time = "night"
    jump start

label night_scene:
    scene bg night
    show character sleeping
    "The world is quiet."
    return # Or jump to the next day's start

Explanation:

  1. We initialize a variable current_time to keep track of the current time of day.
  2. The start label acts as a central point to check the current_time and jump to the corresponding scene label.
  3. Each time-of-day label (morning_scene, afternoon_scene, etc.) sets the appropriate background and character states.
  4. Crucially, within each scene, we update the current_time variable to the next part of the day.
  5. Finally, we jump start again to re-evaluate the current_time and move to the next appropriate scene.

Important Considerations:

  • Game Logic: You'll need to integrate the updating of current_time into your game's events (e.g., after a certain number of interactions, after a choice is made, etc.). Instead of a simple progression like in the example, you might have specific events trigger a time change.
  • Efficiency: For more complex games with many scenes, constantly jumping back to a central start label might become less efficient. Consider more direct jumps or using functions for more intricate time management.
  • Visuals: Ensure you have appropriate backgrounds and character sprites for each time of day to create a consistent atmosphere.

This simple label-based approach is a great starting point for implementing day/night cycles in your Ren'Py game. As your project grows, you can explore more advanced techniques, but mastering the use of labels for flow control is a fundamental skill for any Ren'Py developer. Happy scripting!

How to show different dialogue boxes for different characters

 Want to show different dialogue boxes depending on the character? You can create as many dialogue boxes (also called 'say screens')...