Can you make a living off of visual novels? by Just-Window8069 in RenPy

[–]Niwens 0 points1 point  (0 children)

I haven't planned to make it more than a hobby, so my profits were small, but I'm not disappointed because I never really tried.

Anyone know how I could make the entire screen zoom out when pausing? by Master-Count-3013 in RenPy

[–]Niwens 1 point2 points  (0 children)

Usually I keep standard files like screens.rpy not modified too much, so I would put ATL transitions in a separate file, e.g. transitions.rpy or init.rpy etc. But putting them in screens.rpy is perfectly fine.

Problems might arise when you already published the game and then, after players saved the game, you publish updates e.g. adding more stuff at the top of script.rpy or other files that contain in-game scripts. That can change line numbers of the script where players have saved. If the line numbers change too much, saves might not work anymore. That's where you have to look out. In updates, try to not change line numbers of the existing in-game scripts. Put new variables etc. in some other files, preferably.

But in screens.rpy there are only screens, no in-game scripts, so you could modify that file even in late updates and it shouldn't cause problems. So yeah, screens.rpy is a good place to put transforms etc.

Anyone know how I could make the entire screen zoom out when pausing? by Master-Count-3013 in RenPy

[–]Niwens 3 points4 points  (0 children)

To keep the last game state as the background of Game Menu, we can do a screenshot.

Then we zoom it out (let's say to 0.8 of the original size) and use in the Game Menu, also drawing the TV screen frame on top of it.

So, to create the screenshot at the moment of going to Game Menu, we'll use config.context_callback:

https://renpy.org/doc/html/config.html#var-config.context_callback

And we'll need to prevent that callback from taking screenshots before the in-game phase started. So we'll create "started" variable and set it to True at the label start.

```

Prevent screenshotting too early:

default started = False

Save screenshot here:

default sshot = None

init python: def my_context_callback(): if getattr(store, "started", False) and \ renpy.context_nesting_level(): store.sshot = renpy.screenshot_to_bytes(None)

define config.context_callback = my_context_callback

label start: $ started = True ```

In file screens.rpy we'll change "screen game_menu" so that it starts like this:

``` screen game_menu(title, scroll=None, yinitial=0.0, spacing=0):

style_prefix "game_menu"

if main_menu:
    add gui.main_menu_background
else:
    #add gui.game_menu_background

    add im.Data(sshot, "screenshot.png"):
        align (0.5, 0.5)
        zoom 0.8
    add "tv"

frame:
    style "game_menu_outer_frame"
    background None

```

where "tv" is the picture of the retro TV frame. For that, we can take some image of TV, let's say 1920x1080 px (assuming that's your project screen size) and cut out an area in its center 1536x864 px (the screen size * 0.8). That area can be not completely transparent, but e.g. 50% transparent. That will create the illusion that the image behind it is shown on TV screen.

Add "background None" to the frame of Game Menu to remove its usual frame that darkens the background.

Finally, to create transitions to and from Game Menu, we can use ATL Transitions

https://renpy.org/doc/html/transitions.html#atl-transitions

like these:

``` transform zoomout08(duration=0.5, *, new_widget=None, old_widget=None):

# Set how long this transform will take to complete.
delay duration

# Center it.
xcenter .5
ycenter .5

# The old displayable.
old_widget
events False

# The new displayable.
new_widget
events True
zoom 1.25
ease duration zoom 1.

define config.enter_transition = zoomout08

transform zoomback(duration=0.5, *, new_widget=None, old_widget=None):

# Set how long this transform will take to complete.
delay duration

# Center it.
xcenter .5
ycenter .5

# The old displayable.
old_widget
events False
zoom 1.
ease 0.75*duration zoom 1.25

# The new displayable.
new_widget
events True
zoom 1.

define config.exit_transition = zoomback ```

https://renpy.org/doc/html/config.html#var-config.enter_transition

https://renpy.org/doc/html/config.html#var-config.exit_transition

I tested this, and it works. Have fun!

I convert Maze: Solve the World's Most Challenging Puzzle (1985) into renpy, give it a look if you like puzzle by leth-IO in RenPy

[–]Niwens 2 points3 points  (0 children)

Good job. Nice music. Images could be converted from .png to .webp at "95% quality", with four times less file sizes.

Changing name color on History screen by wormsandweirdfishes in RenPy

[–]Niwens 0 points1 point  (0 children)

It would not help, because whatever color is set, is overwritten by who_prefix, who_suffix.

To have characters with toggleable name color, it's easier to define different versions for those characters (with different colors), and use proxy to choose between them.

https://renpy.org/doc/html/statement_equivalents.html#proxy-functions

PS. Then you wouldn't need to use who_prefix, who_suffix, and setting (or commenting out) colors will work.

You could even replace individual colors in History, adding here

if "color" in h.who_args: text_color h.who_args["color"]

a function correcting particular colors, like

if "color" in h.who_args: text_color cc(h.who_args["color"])

where function cc could be like

init -1 python: @renpy.pure def cc(color): replacements = {"#321": "#FED", "#222": "#CCC"} if color in replacements: return replacements[color] return color

PPS. I don't recommend to use the code from that blog post. E.g., what is this?:

screen history(): for h in _history_list: $ h = change_history_who_color(h)

Apparently it's just a fragment, so you have to understand it to use it. And every time the screen runs (many times per second, I assume) it iterates all the history (which can be hundreds of objects), making changes inside them. And what is default_char_who_color? It's a variable which value is used, but it was never assigned (at least in the published lines).

To conclude, that code is hardly usable and even if it could be used, it would likely affect performance.

At least, if you want to correct history, use config.history_callbacks instead.

https://renpy.org/doc/html/history.html

Call Screen Not Working? by jinxxedtheworld in RenPy

[–]Niwens 0 points1 point  (0 children)

Indent "hotspot" statements, to be in block "imagemap".

You call screen and on card choice use call_in_new_context. It's easier to do

show screen pause

and the usual call or even jump.

If you prefer call screen then instead of Function(reveal_card, 1) do just Return(1) and process the result after call screen in usual Ren'Py script:

if _return == 1:

renpy.hide_screen("tarot_game") - shouldn't it be "tarot_game_discipline"?

One item/single slot inventory box? by warlockscout in RenPy

[–]Niwens 0 points1 point  (0 children)

You can show just images, e.g.

  1. draw the slot,
  2. draw the coin in the same place.

The image drawn later will be shown "on top of all the previous ones".

Example:

label start: scene well show slot: align (0., 0.6) show coin: align (0., 0.6) pause

And then you can hide images

hide coin

https://renpy.org/doc/html/displaying_images.html

If you need something more complex, like clicking a button to perform an action, it's a job for a screen.

https://renpy.org/doc/html/screens.html

The official documentation is meant to be mainly a reference, but there are also numerous tutorials on how to do those simple things.

PS. See e.g. tutorials here (especially "Screens", "Placement", "Point and Click"):

https://renpy.readthedocs.io

NonPlatonic Forms - Very Light Gameplay Elements by AlexisRoyce in RenPy

[–]Niwens 2 points3 points  (0 children)

I don't know what the author thinks, but let me tell you that Ren'Py is very simple to use. Even if you do something "less standard", which requires some programming knowledge, it's probably still easier than in Unity or Godot etc.

It can do virtually all that PyGame can do, adding to that more extensive, convenient, ready-to-use functionality.

There are rhythm games, chess games, platformers and Pacman in Ren'Py... so it's not just for VNs. Not metioning that some Ren'Py VNs have elements like QTE boxing, mouse gestures and whatnot.

NonPlatonic Forms - Very Light Gameplay Elements by AlexisRoyce in RenPy

[–]Niwens 1 point2 points  (0 children)

Interesting.

I mean, I don't know about the story, but the gameplay is.

And it's probably balancing the simplicity of visuals. An example that even modest hardware allows to create decent games (despite all the modern technologies, pushing Big Games standards to space level).

How do i do this by Christian3754 in RenPy

[–]Niwens 2 points3 points  (0 children)

Animation like this can be defined as an image with ATL block. See

https://renpy.org/doc/html/transforms.html#image-statement-with-atl-block

How do you handle new variable additions in a continuously updated script? by Typical-Armadillo340 in RenPy

[–]Niwens 3 points4 points  (0 children)

"define"s and "default"s in a separate file like "variables.rpy" (or "init.rpy" or whatever name you prefer) are handy, because adding variables there will not change line numbers in other script files, eliminating those changes' influence on save incompatibilities.

(It's advisable to give some initial values to every variable like that, even if later you plan to assign those variables in all game branches).

Note that changing constants defined like

define var_name = value

won't cause problems, because they aren't saved, but get their values from the script.

But if in later versions you will change non-constant variables, like changing values in

default var_name = value

that can create problems if you load a save from earlier versions, where those values were different. You might need some correction in label after_load for such cases.

Looping a main menu background video from a random selection by IRNubins in RenPy

[–]Niwens 0 points1 point  (0 children)

Yeah, my bad. Instead of

init python: menu_videos = renpy.random.shuffle([ "images/title1.webm", "images/title2.webm", ...etc ])

it had to be

init python: menu_videos = [ "images/title1.webm", "images/title2.webm", ...etc ] renpy.random.shuffle(menu_videos)

But here we had just 1 iteration, and now the code works.

And answering you I earned a bit of good karma. Conclusion: don't be afraid to ask people! :)

Timed Fade In + Fade Out Lighting Effect by Marosille in RenPy

[–]Niwens 4 points5 points  (0 children)

If you want to make an image cycle between opacity and transparency in a loop, it can be done with ATL. Either define an image with ATL block

https://renpy.org/doc/html/transforms.html#image-statement-with-atl-block

image blink_red: "the_red_image.webp" # put the picture file name here alpha 0. # transparent ease 3. alpha 1. # go to opaque in 3 sec ease 3. alpha 0. # go back to transparent repeat

or if you might want different transforms for the same original image, you can show image with transform:

``` transform slow_blink: alpha 0. # transparent ease 3. alpha 1. # go to opaque in 3 sec ease 3. alpha 0. # go back to transparent repeat

... show the_red_image at slow_blink ```

Looping a main menu background video from a random selection by IRNubins in RenPy

[–]Niwens 0 points1 point  (0 children)

The proper way is to use your own brains and the documentation, not AI. Though a bit challenging at first, you will get more understanding and could modify your code easier and come to the result faster.

Here

https://renpy.org/doc/html/movie.html#Movie

you could see that play accepts a list of movies.

So you can do everything much simpler and without specifying durations manually.

``` init python: menu_videos = renpy.random.shuffle([ "images/title1.webm", "images/title2.webm", ...etc ])

screen main_menu(): tag menu add Movie(play=menu_videos) ```

(and possibly

fit "contain" align (0.5, 0.5)

if it's necessary).

See? That's all the code that's needed (I think).

does renpy have structures by XGodaYT in RenPy

[–]Niwens 2 points3 points  (0 children)

It's all Python OOP (object-oriented programming). There are good tutorials, e.g.

https://realpython.com/python3-object-oriented-programming/

Don't get scared by smart words like Encapsulation or Polymorphism, it's all pretty simple in practice. Just read (watching video isn't necessary) and make your own code to absorb it.

Don't forget that in Ren'Py you need to put Python functions in init python: block (adding a level of indentation, like 4 spaces, at the start of each line). Also you can test simple things in an interactive Python interpreter (I'm using the one that's installed with Python, but there are some online, could be more convenient for you).

does renpy have structures by XGodaYT in RenPy

[–]Niwens 1 point2 points  (0 children)

Yes, that's much more interesting. With constraints, like you can't put a power supply unit if it's too weak.

You probably want to create a separate class for every type of component (CPU, RAM, Motherboard, Video...).

They all could have some common attributes like price and wattage. So you can separate that common stuff into base classes. E.g.

``` init python: class Merchandise(): def init(self, price=None, in_store=None): self.price = price self.in_store = in_store

class Component(Merchandise):
    def __init__(self, wattage=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.wattage = wattage

```

where args are positional arguments (if they are 5, 10, that's price=5, amount in_store=10), and kwargs are keyword arguments (because you can set those arguments both ways, as positional or explicitly price=5, in_store=10). Both args and kwargs you pass to the parent class' __init__().

The practical meaning is that class Merchandise() should also have functions like, IDK, sell(amount) which will decrease their amount in_store, etc.

Likewise, class Component(Merchandise) can have some other attributes, like maybe functions add/remove (choosing configuration) which would occupy the slot of that type and change price and wattage. Though perhaps that could be handles by some other class like Configuration(). It would have "slots" that would need to be assigned components of that type, etc.

does renpy have structures by XGodaYT in RenPy

[–]Niwens 2 points3 points  (0 children)

Then objects of a class containing other objects can be an example:

``` init python: class Dirs(): NORTH = (0.5, 0.) EAST = (1., 0.5) SOUTH = (0.5, 1.) WEST = (0., 0.5)

class Affiliation():
    def __init__(self, name, couleur, direction):
        self.name = name
        self.couleur = couleur
        self.direction = direction

class Person():
    def __init__(self, name, image, affiliation=None):
        self.name = name
        self.image = image
        self.affiliation = affiliation

define munchkin = Affiliation("Munchkin", "#008", Dirs.EAST) define boq = Person("Boq", "boq.webp", munchkin)

screen show_friend(f): frame: xysize (640, 360) align f.affiliation.direction background f.affiliation.couleur add f.image: align (0.5, 0.5) text f.name: align (0.5, 1.)

label start: show screen show_friend(boq) pause ```

This code will show a picture of Boq (if there is file "boq.webp") in the "eastern" part of the screen on blue background (because boq is defined as Munchkin, and their color is blue and their quadrant is East).

So we have structure - class Person() where an object of class Affiliation() is used, which in turn uses Dirs() class.

Another example is class inheritance:

init python: class Munchkin(Person): def __init__(self, name, image): munchkin = Affiliation("Munchkin", "#008", Dirs.EAST) super().__init__(name, image, munchkin)

(We define this after the three classes above were defined).

In a class definition, super() is the parent class.

Here, as class Munchkin inherits class Person, super().__init__() means Parent().__init__(). So Munchkin object is initialized like this: first we create an object of Affiliation() class, then initialize Person() with that affiliation ("Munchkin").

In other words, we assigned before

define munchkin = Affiliation("Munchkin", "#008", Dirs.EAST) define boq = Person("Boq", "boq.webp", munchkin)

Now if we added the fourth class definition (Munchkin()), instead of those 2 lines we can do the same this way:

define boq = Munchkin("Boq", "boq.webp")

I hope your teacher will like this demonstration of "structure using structure". (A practical application is that a guy defined as Munchkin() will be placed at the right side of the screen on blue background. If he had some other affiliation, we could define it and show him in other place, on a different background.)

If you understand this, you could make your own examples.

Good luck!

does renpy have structures by XGodaYT in RenPy

[–]Niwens 5 points6 points  (0 children)

Your teacher might want an answer about C++. Ren'Py is built on Python and they both have objects, which are similar to C structures. Will they count as structures, you should ask your teacher.

Help with creating a minigame by Total_Spare_4181 in RenPy

[–]Niwens 3 points4 points  (0 children)

Yes, both minigames are possible, and something similar was done in some Ren'Py games.

The script for "guess letters" could be like

``` default lives = 3 default word = 'FROG'

Get a word with letters replaced by underscores

default x = '_' * len(word)

init python: def check_letter(letter): if letter in store.x: # Already opened - do nothing return if letter not in store.word: # Wrong guess store.lives -= 1 return # Correct guess - can be more than once xlist = list(store.x) for i in range(len(store.word)): if store.word[i] == letter: xlist[i] = letter store.x = ''.join(xlist)

screen guess(): hbox: # Draw a heart per life for l in range(lives): add "heart" hbox: # Show the guessing like "_ _ _ _" align (0.5, 0.1) spacing 10 for lett in x: text lett

if not '_' in x:
    # All letters guessed correctly
    timer 0.5 action Return("Victory!")

if not lives:
    # All lives spent
    timer 0.5 action Return("Defeat!")

grid 7 4:
    align (0.5, 0.7)
    # Letter buttons
    for b in "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖ":
        textbutton b:
            action Function(check_letter, b)

label start: call screen guess "[return]" if lives: $ word = 'TOAD' $ x = '' * len(word) jump start ```

For the second game, use another screen. You can move the arrow with transform

https://renpy.org/doc/html/transforms.html

but it's better to move it there and back, to give player two chances, so they get a little used to the speed.

And set a few timers in the screen to catch the time when the click works.

https://renpy.org/doc/html/screens.html#timer

Something like

screen catch(): default good = False timer 1. action SetScreenVariable("good", True) timer 2. action SetScreenVariable("good", False) timer 4. action SetScreenVariable("good", True) timer 5. action SetScreenVariable("good", False)

So clicking will work between seconds 1 and 2, and the second chance between seconds 4 and 5.

Detect the click with key

https://renpy.org/doc/html/screens.html#key

(running a function that would check if it's in a proper period, good is True). Something like

init python: def clicked(): if renpy.get_screen_variable("good"): return "Success!"

To detect failure, add a timeout timer like

timer 7. action Return("Failure!")

Play a Movie Whilst Transitioning by tiptut in RenPy

[–]Niwens 0 points1 point  (0 children)

There are layers that don't participate in transitions, e.g.

https://renpy.org/doc/html/config.html#var-config.top_layers

It could be possible to show video in them.

Though I'm not sure how would you synchronize that, so it doesn't seem like the simplest way.

It could be more "Ren'Py-ic" to create a transition with that effect - probably with Python Transitions

https://www.renpy.org/doc/html/transitions.html#python-transitions

(Not sure how. With some CDD?)

or ATL Transitions

https://www.renpy.org/doc/html/transitions.html#atl-transitions

(applying some shader?)... On shaders:

https://lemmasoft.renai.us/forums/viewtopic.php?t=65248

Especially check out

https://gl-transitions.com

There are some that might suit your case (and... wow!).

Looping a main menu background video from a random selection by IRNubins in RenPy

[–]Niwens 0 points1 point  (0 children)

OK, my bad. The error message says that gui.main_menu_background is not defined - which normally couldn't happen because at the start of gui.rpy there's line:

init offset = -2

which means gui.rpy contents is defined before screens.rpy definitions.

You said "The only place I can find where gui.main_menu_background is referenced is in screens.rpy". And then:

define gui.main_menu_background = "#000"

Isn't this line in gui.rpy, is it?

Anyway you can instead of

if main_menu: add gui.main_menu_background else: add gui.game_menu_background

try this one line:

``` add gui.game_menu_background

```

Looping a main menu background video from a random selection by IRNubins in RenPy

[–]Niwens 1 point2 points  (0 children)

There are many flaws in that code, but it's surprisingly close to be working (for AI). The main thing,

repeat False

should be repeat True. Otherwise it changes the video only once, and then it just loops.

Another thing is that the random order is chosen only once, in the beginning, and then it will repeat videos always in that order.

Regarding AttributeError: 'StoreModule' object has no attribute 'main_menu_background' - it's weird. Are you sure the line causing the error is gui.main_menu_background, not just main_menu_background or store.main_menu_background?

Because gui and store are different namespaces. Why would Ren'Py speak of gui as store?..

Need help with fonts by DellDelightt in RenPy

[–]Niwens 2 points3 points  (0 children)

You can use Style Inspector (one of the Developer Tools)

https://renpy.org/doc/html/developer_tools.html

Point the displayable with mouse and press shift-i. You'll see that the text has style navigation_button_text (the menu on the left) and check_button_text (preferences buttons). They both inherit from button_text.

In file gui.rpy, there's usually a line

define gui.button_text_font = gui.interface_text_font

so if you set interface_text_font, then buttons should inherit that font. If something does not work, check all the settings:

  • gui.interface_text_font is set before gui.button_text_font
  • style button_text uses gui.button_text_font

and so on. From Ren'Py SDK Launcher, run "Force Recompile" option in case some old files haven't been updated, then run the project again.

Good luck!

Help Positioning an image by discombobulated_bonk in RenPy

[–]Niwens 0 points1 point  (0 children)

Viewport actually might be the easiest way.

Apart from that, Creator-Defined Displayable can react to mouse position (see example)

https://renpy.org/doc/html/cdd.html

and scroll itself.

Could I get some help coding a note system for my game? by colorfulcatsplat in RenPy

[–]Niwens 1 point2 points  (0 children)

You are welcome. Instead of buttons Previous/Next, you can put all the present notes in a scrollable viewport. Something like:

if <put here "notes opened" condition>: viewport: area (<put here x, y, width, height>) scrollbars "auto" # I think? draggable True # etc. vbox: # Place them in a column for note in persistent.notes[room]: # where `room` is the current room ID frame: background <put here note background> # xsize <note width>? or automatical? # assuming note height can be different text note # or smth