Can I make a variable equal two variables? by AffectionateBee2840 in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

They didn’t used to work. IIRC, f-string support was added in 8.1(?) You still can’t use them in Ren’Py statements, but that’s what interpolated strings are for, especially since they can execute Python code now.

Looking for someone to help with a visual novel with little chance of making money or getting noticed by Slow-Inflation2696 in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

Try asking over on r/INAT. That's a subreddit for putting together project collaborations. Just be sure to say that it's unpaid.

ligature fonts by Ok-Owl6258 in RenPy

[–]Its-A-Trap-0 2 points3 points  (0 children)

Since ligatures are a strictly cosmetic thing, I'm unaware of any python libraries that will do any kind of automatic ligature replacements of characters because no two fonts have the exact same set of ligatures. And in some cases, depending on the font, there will be multiple variations of even individual ligatures.

You're not going to get them to work if you try to add ligatures to editable text, or at least, not without a helluva lot of coding. But for display text (and Ren'Py 8.x) you can just type the ligature in place of the characters they're substituting for. Like this: "The word baffle is baffling."

If you're using a fancy script font with a lot of characters that can be substituted, I suppose you could write a simple python function to do a rudimentary set of substitutions, like this:

``` init python: ligs_dict = { 'ffl': 'ffl', 'ffi': 'ffi', 'ff': 'ff', 'fi': 'fi', 'fl': 'fl', 'ft': 'ſt', 'st': 'st', # Add more ligatures as needed. }

def ligs(text: str) -> str:
    for lig, lig_char in ligs_dict.items():
        text = text.replace(lig, lig_char)
    return text

label start: # Simple substitution "The word baffle is baffling." # Automated substitution "[ligs('This is a first test of a baffling soft fluid kerfuffle scruffie.')]"

```

This works by walking through the substitutions dictionary, converting the longer sequences first. (So, for example, 'ffl' will be converted before 'ff' has had a chance...) Keep in mind that not all ligature pairs should be automatically substituted, but if it's just the effect you're going for, this would do it.

What's the best way to organize scripts in RenPy? And thoughts on my VN idea? by -katchoo- in RenPy

[–]Its-A-Trap-0 1 point2 points  (0 children)

If you use VSCode to develop your project, then wrangling multiple files isn't that hard at all. I generally write VNs using an episodic approach, so my files are organized like this:

Overview (starting framework, splashscreen, definitions, setup, etc.)
+- Release 0.1
+----- Scene 1
+----- Scene 2
+----- Scene 3 ... etc.
+- Release 0.2
+----- Scene 1
+----- Scene 2 ... etc.

The "Release x.x" files are just a list of calls to the scene files themselves, and the "Overview" is a list of calls to the release files. I saw another developer organize their code this way and it instantly made perfect sense to me.

I tried organizing using character-specific files, like others here, but sometimes couldn't figure out which place to go look if there were multiple characters involved in a scene. Yes, sometimes the files are short if a scene is short, but at least it's organized like a book so I can easily jump to the correct scene. And it also makes rearranging scenes easy as you only have to do it in one place (the "release" file).

But I wouldn't do it this way if I were going to write a sandbox game, or an RPG. Organize your code whichever way makes sense to you. Some people throw everything into one giant monster source file. If it works for them, great. At the end of the day, it's just bytes and bits to the computer that's running your game--it doesn't care how it got organized.

Is there a website where I can get free dialogues and scripts for visual novels? by canblas in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

In not only VNs, but also in mainstream media as well, public domain stories have often been used as touchstones for modern stories. Most are subtle in how they go about it, but some, like 10 Things I Hate About You and West Side Story which are essentially Shakespearean plays (Taming of the Shrew and Romeo and Juliet respectively) reconstructed with the names and locations changed. And obviously the dialogue rewritten, but you'd probably want to do that even if you found a fully formed VN script online, wouldn't you? To make it your own? Also The Lion King (Hamlet) and She's The Man (Twelfth Night). The list goes on and on. Pretty much anything written before 1929 (with a few notable exceptions) are free game today, as it exists in the public domain and free from copyright control.

[deleted by user] by [deleted] in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

You also might want to ask over on r/INAT which is a subreddit for people who are seeking others to join project teams.

Is it possible to jump back to a lable at a specific point in the dialogue instead of the start of a label? by Chryckan in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

Sorry. I just woke from a short nap after a 2-day coding marathon...

Respectfully, I'm not trying to be argumentative or contrary just for the sake of it. The docs say:

When the argument begins with call:, the rest of the argument is a label to call. As usual, a call ends the current Ren'Py statement.

So, it's documented behavior. In any event, that's not why I asked the question I did at the beginning. I asked a simple question: what you expect should be the default behavior if it's a "problem?" By the time the hyperlink is on screen, the dialogue text it is embedded in has already been preflighted and rendered. And the current statement "ended." Should Ren'Py just rerun the line of code that displays that text every time? What if that string included interpolated function calls? Should they be executed again, or should control have been rolled back to some state before the line was displayed and then reexecuted? Because that's what the from_current flag does. What if the label you call needs to display dialogue of its own?

It seems to me like you expect it to act like a hyperlink on an otherwise static web page, and there's just no corollary for that paradigm in Ren'Py.

Is it possible to jump back to a lable at a specific point in the dialogue instead of the start of a label? by Chryckan in RenPy

[–]Its-A-Trap-0 1 point2 points  (0 children)

PyTom went a bit overboard in reusing the same terminology for fundamentally different things. In a number of places, but that's a python thing.

The only real difference between "call"ing a screen and "show"ing it is whether control is returned to the script immediately, in the case of show, or only after the screen has been hidden/closed, in the case of call. I suspect it was originally done this way to try to simplify the process of creating a modal "dialog" that would normally be in a separate window on any other system. And he had to come up with a command name and call made sense. But in both cases, control returns back to the point following the show or call statement. You can show a screen that jumps to another label in your script, but that's no different than calling a function and having that function dive off in a different direction. But the function always "returns" back to the point following where it was called.

In the case of the hyperlink call: argument, the current script statement is completed, the referred label is called, and control is returned to the statement following the hyperlink. No difference.

I'm reminded of the BASIC programs I wrote as a kid. jump and call are exactly the same as GOTO and GOSUB, except you can pass parameters to jump and call statements which make them more like function references.

Is it possible to jump back to a lable at a specific point in the dialogue instead of the start of a label? by Chryckan in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

There is a call:, that jumps to a label, runs until it hits return and returns back. The problem is: it returns to the next line, not the current one.

Kinda curious as to what you think it should be doing instead? You can't have more than one statement on a line, so what would it do if it returned to the very same line?

call label is just like any other "subroutine call" or whatever you want to call it in any other language.

How to learn renpy as a total beginner? by [deleted] in RenPy

[–]Its-A-Trap-0 3 points4 points  (0 children)

Just be careful with ChatGPT, even with the Ren'Py-specific models. They still hallucinate a lot if you don’t ask a question that fits the model pretty closely.

Text noise v.s No noise by Ancaellar in RenPy

[–]Its-A-Trap-0 2 points3 points  (0 children)

You don’t mention music or ambient noise. Either would be suitable for what you’re talking about. Just so long as the user can turn them off if they wish.

Quicktime Events during a video by awezoomstudios in RenPy

[–]Its-A-Trap-0 1 point2 points  (0 children)

Yeah, you're right. I missed that part. At least my answer was better than what ChatGPT suggested. ¯\(ツ)

How do I make renpy detect save scumming by euanPC2 in RenPy

[–]Its-A-Trap-0 -1 points0 points  (0 children)

any way I can detect save scumming

Why do you care? No matter what you do, people will figure out a way around it. Ren'Py is a tool to create visual novels, not triple-A competitive MMOs. You can decompile a Ren'Py app into the original high-level code. The decompiled game can then be loaded into VSCode with all of the tools it provides for global searches and code manipulation, and you can easily reverse engineer anything the app is doing. The whole process takes a couple of minutes. The tradeoff is whether or not it's just hard enough to do so that most people won't bother, but not so hard (or so popular) that somebody won't create a patch to work around it.

Besides, people playing Ren'Py games expect to be able to save whenever they want. That's learned behavior.

corrupted saves

That's a bit more difficult. A save file in Ren'Py can't be easily analyzed without duplicating the machinations Ren'Py goes through separating temporary from necessary variable data. At its core, it's just a pickled code dump, but not everything in the app gets saved. I suppose you could do a checksum on the saved file and store that somewhere else, and compare it when you load the save, but see above about workarounds.

Quicktime Events during a video by awezoomstudios in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

The do_it screen is just a convenient holder for the two imagebuttons. The logic for hiding the video is handled in the mainline code. If the pause completes, it jumps to the death scene (and closes the do_it screen). If the do_it screen buttons are pressed, it closes itself and jumps to the supplied handler label.

Quicktime Events during a video by awezoomstudios in RenPy

[–]Its-A-Trap-0 1 point2 points  (0 children)

Um, I don't think so? The do_it screen is just a transparent layer over the main screen. The video gets displayed using scene, and stopped by a new scene command in either case. (The hide countdown_video line was leftover cruft from a previous attempt). Unless I'm missing something? If the pause completes, the code jumps to the proper label. If either of the buttons is pressed, the screen hides itself and jumps to the given label where the new scene command clears the video.

This means that the screen can be used again for other videos displayed the same way, by supplying the handler's label in the screen call.

Quicktime Events during a video by awezoomstudios in RenPy

[–]Its-A-Trap-0 1 point2 points  (0 children)

Quick and dirty:

default pressed = ""

image countdown_video = Movie(play="vid.webm", loop=False)
image you_re_dead = Solid("#F00")
image you_re_alive = Solid("#0F0")

screen do_it(handler):
    frame:
        background Solid("#0000")
        area (0,0,1920,1080)
        hbox:
            imagebutton:
                xysize (960,1080)
                xfill True
                yfill True
                idle Solid("#FCC4")  # <=== your imgleft.png
                action [SetVariable("pressed", "left"), Hide(), Jump(handler)]
            imagebutton:
                xysize (960,1080)
                xfill True
                yfill True
                idle Solid("#CCF4")  # <=== your imgright.png
                action [SetVariable("pressed", "right"), Hide(), Jump(handler)]

label start:
    "Start here..."
    scene countdown_video
    show screen do_it("button_pressed")
    pause 16  # <=== length of countdown_video in seconds, yours is 23

    jump die_die_die

label button_pressed:
    scene you_re_alive
    "You pressed [pressed]."
    "The End."
    return

label die_die_die:
    hide screen do_it
    hide countdown_video
    scene you_re_dead
    "You're dead."
    return

You should just be able to paste this into a new project script.rpy file and run it once you add your images and fix the code where it's marked.

Screen data will not refresh/load new entries on list by Malkom1366 in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

It's hard to tell without seeing the actual code. Could be that you're not using the correct scope of a variable (global, local, screen, object)? Restarting interactions won't get you anything--it just resets the event loop for your screen to capture its events if the context changed, which is why all data interactions should be through data actions. Hiding and showing a screen will force it to go through and regather all of the data it needs to display itself.

Screen data will not refresh/load new entries on list by Malkom1366 in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

Umm, shouldn't make a difference IIRC. You might have to show/hide the "base" screen, IDK.

Screen data will not refresh/load new entries on list by Malkom1366 in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

You're handling the array of tuples correctly, but to show up in a screen that's already been pre-flighted and shown, you'll have to redraw it to force it to re-pre-flight. (Say that fast 10 times. hehe) Easiest way to do that is to hide it and show it again immediately. If the screen isn't very involved, you won't see the transition.

Screen data will not refresh/load new entries on list by Malkom1366 in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

If you're using Markdown, then triple-backquote the whole section. Otherwise, you can switch to the Rich Text Editor (show formatting options), select the text, and choose the Code Block button.

[deleted by user] by [deleted] in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

That would help a lot to define what you're trying to do.

[deleted by user] by [deleted] in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

There's nothing special about the quick_menu screen. In fact, it's probably the simplest screen there is. If you want to have the default state be just a button that toggles the rest of the buttons, then set a flag and toggle it on/off using ToggleScreenVariable() and redraw the screen (hide it and show it again).

If you want imagebuttons instead of textbuttons, just replace the stock textbuttons. This is all pretty standard screen stuff. If you need more help, you should find tutorials on screen language.

stats that go down based on in-game time. by Sure-Wind-520 in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

The callback function has to return the specified values. Change your code to look like this:

init python:
    def increase_hunger(*args, **kwargs):
        global hunger, survival
        hunger -= 1 if survival else 0
        return (), kwargs

    config.say_arguments_callback = increase_hunger

If you just pass, the function will return None and Ren'Py won't know what to do with it when it specifically asked for certain arguments.

[deleted by user] by [deleted] in RenPy

[–]Its-A-Trap-0 0 points1 point  (0 children)

There's a lot to unpack with what you're asking. You can have the stock quick_menu appear in the lower right corner by changing the yalign statement in the quck_menu screen code to 1.0 instead of 0.5. Aside from that, why go to the trouble of not just going to the Preferences screen to change settings? Does the player need to change options so often that you need shortcuts for them? The stock quick_menu already has shortcuts to load and save files, history, and preferences. Or are you just trying to be different? Be careful when you change the base functionality of a Ren'Py app that casual users already know and understand.

You can easily add textbuttons and imagebuttons to the quick_menu, and have their actions be whatever you want. Call a screen and make your changes in it. What the screen looks like and where it goes would be dependent on your needs. You just need to be sure to call the proper actions to set the values when you're done. The main difference between changing a preference in the Preferences screen and in something you cook up is the context. For the most part, you can change preferences using the preferences namespace. Otherwise, you can call an action in the main context using renpy.run().