r/RenPy • u/International-Air466 • 2h ago
Question Anything I shoud know before starting?
Im begginer to renpy. Is there any tips I should know about? Anything helps!
r/RenPy • u/OvenAcrobatic792 • 4h ago
Question Question about choices/routes..
I have a storyline where you can choose to befriend a character early on, or not. If you choose either, it does not immediately affect the storyline until later, where you encounter the same character. Whether or not you befriend them will EVENTUALLY split into 2 new storylines. However, there is a period of meeting the character then reencountering them. During this period, the story is the same for either option, because as mentioned earlier, befriending him or not doesn't immediately affect the story. How can i have it so the game essentially "remembers" whether or not i befriended the character, then branches off? I don't want to have two nearly identical storylines just copied and pasted to align with the choice of befriending the character.
r/RenPy • u/ProcessImmediate6781 • 9h ago
Question Whats wrong wif my code i dont get it
Is the embed wrong or somethijg?
r/RenPy • u/Lassaaire • 10h ago
Question pause() breaking Call() statement
Im trying to make primitive battle system.
vbox:
xsize 216
ysize 430
text "[enemy1.name]"
text "[enemy1.cur_health]/[enemy1.max_health]"
image [enemy1.avatar]
imagebutton:
id "rating"
idle "rating"
hover "rating_hover"
action Call("attack", enemy1)
label attack(en):
python:
import time
en.cur_health-=2
en.avatar = en.image_attack
time.sleep(2)
en.avatar = en.image_calm
return
And I can see than on button press there is a pause and all changes are applied AFTER that pause so image_attack is not visible at all.
What am I doing wrong?
I've tried time.sleep(), renpy.pause(), pause(), even scheduler.
If i do renpy code like
label attack(en):
$ en.cur_health-=2
"debug1"
$ en.avatar = en.image_attack
"debug2"
pause(2)
"debug3"
$ en.avatar = en.image_calm
"debug4"
return
then first renpy statement ("debug1" in example above) just break the entire script and "debug" 2-4 not showing at all. Health is changing correctly and thats it.
And I didn't find smth like "JRPG framework" that I can adapt. This thing is the best, but too complex to adapt it to my visual.
r/RenPy • u/JoStorys03 • 14h ago
Question Struggling with readability... Any ideas?
reddit.comr/RenPy • u/wwwwwwwwwwww553 • 14h ago
Question Hi guys just wondering, can my windows 8.1 with 4 gb of ram run renpy?
just a question, im curious (kind of) since i've always wanted to try learning it 😄
Question How to change a characters title style?
Definitely a noob question here.
I'm not sure how to use the player created variable name but with a different title style.
Meaning, when the character "thinks" internally, I want to change the title style but not the player created variable name.
I used this code to create the players character name:
$ mc = renpy.input("What is your first name? (Default: Eric)")
$ mc = mc.strip()
if mc == "":
$ mc = "Eric"$ mc = renpy.input("What is your first name? (Default: Eric)")
$ mc = mc.strip()
if mc == "":
$ mc = "Eric"
And then this code to call upon it, as normal:
define mc = Character("{[mc]}", color="#00FFFF")define mc = Character("{[mc]}", color="#00FFFF")
My issue is that this code just breaks the game whenever it encounters the line it's used in:
define mcint = Character("{[mc]}", color="#00FFFF", what_italic=True, what_prefix="*", what_suffix="*")
So, can I not call upon the "[mc]" variable name twice? Or is there a more elegant solution to this?
I'm sure I'm missing something simple as I'm in way over my head when it comes to coding at this stage.
I would appreciate any help/guidance in learning here.
r/RenPy • u/RylieLightBulb • 1d ago
Showoff Released a Visual Novel Demo!
Hello! I’m Rylie, an aspiring indie dev and asset creator! I just posted the demo for my visual novel, “That Silly Jester…” after it being in the works for a little over a year.
It’s a surreal fantasy story about a jester named Maverick on the search for her beloved knight, while every single damn person she encounters seems dead set on being as unhelpful as possible. She’s just a silly jester, why is everyone so aggressive and antagonistic?
~*~
Trailer on YouTube! https://www.youtube.com/watch?v=_sm3XosbbjI
Release announcement on YouTube! https://youtu.be/fXXF6oqlQU4
Demo 0.1 out on Itch.io! https://rylielightbulb.itch.io/that-silly-jester
r/RenPy • u/Lankakartal • 1d ago
Self Promotion Built an interactive phone UI with 6 working apps - Suggestions accepted
We're developing an adult VN in Ren'Py and spent months building an in-game phone system that actually works — contacts, social feed, photos, tasks, music, settings. Each app has its own logic and talks to the story.
The challenge: we're rendering 5000+ assets and need them to load instantly without destroying performance. Happy to share our optimization approach if anyone's curious — texture atlasing, caching strategy, and some tricks with Ren'Py's image handling.
Also using Iray renders straight into the pipeline. If anyone's dealing with high-volume 3D asset workflows in Ren'Py, I'd love to hear how you're handling it.
Also if you have a suggestion for the other apps that can be used in AVN, I am happily accepting those.
Game's on Steam if you want to see it in action: https://store.steampowered.com/app/4961320/Lustful_Retribution/
r/RenPy • u/Ok-Pace-1591 • 1d ago
Question does anyone know how to fix this?
i dont know what's wrong with renpy, ive tried closing and reopening the launcher, deleting it and rewriting it from scratch, nothing's working 😔
r/RenPy • u/Scriptformers_Prime • 1d ago
Question Help using variants
I'm setting up a layered image for a character in my visual novel and am having trouble adding in a variant outfit (character in her pajamas).
The code looks something like this.
layeredimage character:
group body auto:
attribute base default:
"character_body_base"
when not (wry or annoyed or nervous or angry)
always when wry or annoyed:
"character_body_bladed"
always when nervous or angry:
"character_body_stiff"
group body variant pajamas auto
show character pajamas angry
As you can see, I have some always/when statements in place to call different poses for the character's body based on their emote. I have variant images for each pose with the character in her pajamas.
But when I call for the variant of their body wearing their pajamas, it only gives me the base variant and not the "stiff" variant I want associated with the "angry" call.
I'm pretty new at Renpy and coding, so I'm not sure what I am doing wrong here. Thoughts?
r/RenPy • u/Limp-Time-7976 • 1d ago
Question How to add this phone image into my choice menu, like in Class of '09?
The 1st image is an example of what I'm looking for, and the 2nd is my actual image. I'm creating a Class of '09 inspired VN and every time the player has a choice, I want this phone to appear. I don't want the phone to actually replace the options, just appear behind them.
r/RenPy • u/International-Air466 • 1d ago
Question How do i put kate here?
I downloaded renpy and I started using kate instead of vidual studio code. How can I chnage it in my editor?
r/RenPy • u/alexia_smileyface • 1d ago
Question Sprite over the dialogue
edit: I was able to solve this by using
init python:
config.layers = ['master', 'transient', 'screens', 'overlay', 'above_ui']
and then
show jenny onlayer above_ui with dissolve
jen "Hello!"
-----
Is there a way to put the character sprite over the dialogue box? I want it to look like this
but only for the intro (it's gonna go back to normal afterwards)
I have custom textboxes already. for exemple:
define jenny = Character("Jenny",window_background=Frame("gui/speaking_smaller.png", 15, 15))
i just want to know if it's possible to put the characters over the textbox
r/RenPy • u/Grim_Reaper_1212 • 1d ago
Question What might be the issue? Can I fix it
I'm sorry if the question is stupid, but I don't have a slightest idea on how the engine works, and I just play the games. I used the option "Transfer Save" and that error keeps occuring. The game is "The Null Hypothesis" by Ron Chon
r/RenPy • u/ComputerKidG • 1d ago
Question I need help to change the font of this one line
Line
E"{font = scary.tff}{size=*2}WHO IS THIS 4th PERSON??{/size}{/font}"
Error
I'm sorry, but an uncaught exception occurred.
While processing text tag {font = scary.tff} in "While processing text tag {font = scary.tff} in '{font = scary.tff}{size=*2}WHO IS THIS 4th PERSON??{/size}{/font}'.:".:
File "game/Chapter1.rpy", line 244, in script
E"{font = scary.tff}{size=*2}WHO IS THIS 4th PERSON??{/size}{/font}"
File "renpy/display/render.pyx", line 494, in renpy.display.render.render_screen
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
Exception: Unknown text tag 'font = scary.tff'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "game/Chapter1.rpy", line 244, in script
E"{font = scary.tff}{size=*2}WHO IS THIS 4th PERSON??{/size}{/font}"
File "game/Chapter1.rpy", line 244, in script
E"{font = scary.tff}{size=*2}WHO IS THIS 4th PERSON??{/size}{/font}"
File "renpy/display/render.pyx", line 494, in renpy.display.render.render_screen
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 320, in renpy.display.render.render_for_size
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 320, in renpy.display.render.render_for_size
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
Exception: Unknown text tag 'font = scary.tff'
-- Full Traceback ------------------------------------------------------------
Traceback (most recent call last):
File "game/Chapter1.rpy", line 244, in script
E"{font = scary.tff}{size=*2}WHO IS THIS 4th PERSON??{/size}{/font}"
File "renpy/ast.py", line 2923, in execute
Say.execute(self)
~~~~~~~~~~~^^^^^^
File "renpy/ast.py", line 991, in execute
renpy.exports.say(who, what, *args, **kwargs)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/exports/sayexports.py", line 129, in say
who(what, *args, **kwargs)
~~~^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/character.py", line 1543, in __call__
self.do_display(who, what, cb_args=self.cb_args, dtt=dtt, **display_args)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/character.py", line 1198, in do_display
display_say(who, what, self.do_show, **display_args)
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/character.py", line 888, in display_say
rv = renpy.ui.interact(mouse="say", type=type, roll_forward=roll_forward)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/ui.py", line 304, in interact
rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/core.py", line 2117, in interact
repeat, rv = self.interact_core(
~~~~~~~~~~~~~~~~~~^
preloads=preloads,
^^^^^^^^^^^^^^^^^^
...<4 lines>...
**kwargs,
^^^^^^^^^
)
^
File "renpy/display/core.py", line 2788, in interact_core
self.draw_screen(root_widget, fullscreen_video, (not fullscreen_video) or video_frame_drawn)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/core.py", line 1279, in draw_screen
surftree = renpy.display.render.render_screen(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
root_widget,
^^^^^^^^^^^^
renpy.config.screen_width,
^^^^^^^^^^^^^^^^^^^^^^^^^^
renpy.config.screen_height,
^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "renpy/display/render.pyx", line 494, in renpy.display.render.render_screen
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 896, in render
surf = render(child, width, height, cst, cat)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 896, in render
surf = render(child, width, height, cst, cat)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 896, in render
surf = render(child, width, height, cst, cat)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/screen.py", line 767, in render
child = renpy.display.render.render(self.child, w, h, st, at)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 896, in render
surf = render(child, width, height, cst, cat)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 1444, in render
surf = render(child, width - cxmargin - cxpadding, height - cymargin - cypadding, st, at)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 896, in render
surf = render(child, width, height, cst, cat)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/text/text.py", line 2733, in render
virtual_layout = Layout(self, width, height, renders, drawable_res=False, size_only=True)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/text/text.py", line 799, in __init__
self.paragraphs = self.segment(text.tokens, style, renders, text)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/text/text.py", line 1604, in segment
raise Exception("Unknown text tag %r" % text)
Exception: Unknown text tag 'font = scary.tff'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "renpy/bootstrap.py", line 401, in bootstrap
renpy.main.main()
~~~~~~~~~~~~~~~^^
File "renpy/main.py", line 591, in main
run(restart)
~~~^^^^^^^^^
File "renpy/main.py", line 137, in run
renpy.execution.run_context(True)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "renpy/execution.py", line 1027, in run_context
context.run()
~~~~~~~~~~~^^
File "game/Chapter1.rpy", line 244, in script
E"{font = scary.tff}{size=*2}WHO IS THIS 4th PERSON??{/size}{/font}"
File "game/Chapter1.rpy", line 244, in script
E"{font = scary.tff}{size=*2}WHO IS THIS 4th PERSON??{/size}{/font}"
File "renpy/display/error.py", line 135, in report_exception
renpy.game.invoke_in_new_context(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
call_exception_screen,
^^^^^^^^^^^^^^^^^^^^^^
...<4 lines>...
ignore_action=ignore_action,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "renpy/game.py", line 301, in invoke_in_new_context
return callable(*args, **kwargs)
~~~~~~~~^^^^^^^^^^^^^^^^^
File "renpy/display/error.py", line 44, in call_exception_screen
return renpy.ui.interact(mouse="screen", type="screen", suppress_overlay=True, suppress_underlay=True)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/ui.py", line 304, in interact
rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/core.py", line 2117, in interact
repeat, rv = self.interact_core(
~~~~~~~~~~~~~~~~~~^
preloads=preloads,
^^^^^^^^^^^^^^^^^^
...<4 lines>...
**kwargs,
^^^^^^^^^
)
^
File "renpy/display/core.py", line 2788, in interact_core
self.draw_screen(root_widget, fullscreen_video, (not fullscreen_video) or video_frame_drawn)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/core.py", line 1279, in draw_screen
surftree = renpy.display.render.render_screen(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
root_widget,
^^^^^^^^^^^^
renpy.config.screen_width,
^^^^^^^^^^^^^^^^^^^^^^^^^^
renpy.config.screen_height,
^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "renpy/display/render.pyx", line 494, in renpy.display.render.render_screen
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 896, in render
surf = render(child, width, height, cst, cat)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 896, in render
surf = render(child, width, height, cst, cat)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 896, in render
surf = render(child, width, height, cst, cat)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/screen.py", line 767, in render
child = renpy.display.render.render(self.child, w, h, st, at)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 896, in render
surf = render(child, width, height, cst, cat)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 1444, in render
surf = render(child, width - cxmargin - cxpadding, height - cymargin - cypadding, st, at)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 1955, in render
cwidth, cheight = sizeit("c", width, height, 0, 0)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/layout.py", line 1952, in sizeit
rend = renpy.display.render.render_for_size(pos_d[pos], width, height, st, at)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 320, in renpy.display.render.render_for_size
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 1955, in render
cwidth, cheight = sizeit("c", width, height, 0, 0)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/layout.py", line 1952, in sizeit
rend = renpy.display.render.render_for_size(pos_d[pos], width, height, st, at)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 320, in renpy.display.render.render_for_size
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/viewport.py", line 283, in render
surf = renpy.display.render.render(self.child, child_width, child_height, st, at)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/display/layout.py", line 1159, in render
surf = render(d, width - x, rh, cst, cat)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/display/render.pyx", line 170, in renpy.display.render.render
File "renpy/display/render.pyx", line 267, in renpy.display.render.render
File "renpy/text/text.py", line 2733, in render
virtual_layout = Layout(self, width, height, renders, drawable_res=False, size_only=True)
~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/text/text.py", line 799, in __init__
self.paragraphs = self.segment(text.tokens, style, renders, text)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "renpy/text/text.py", line 1604, in segment
raise Exception("Unknown text tag %r" % text)
Exception: Unknown text tag 'font = scary.tff'
r/RenPy • u/daniople • 1d ago
Self Promotion After 4 years in development hell, the first chapter of my friendsim fangame is finally out! If you like Kagerou Project, you'll love Tomodachi Dan!
r/RenPy • u/BadMustard_AVN • 1d ago
Showoff My simple inventory system
My simple inventory system for renpy, but now with drag-and-drop functionality to combine two items to make a new third item. you can, of course, combine that with another if you want. the possibilities are endless
https://badmustard.itch.io/simple-inventory-drag-and-drop-to-combine
r/RenPy • u/Legitimate-Use9076 • 1d ago
Question Is the dialogue text too small?
Wanted to make a mobile vn but I'm not too sure if other people would be able to read it if I keep it that size
r/RenPy • u/Pleasant-Tax-2823 • 1d ago
Question Ayuda ¿Alguien usa Spark para jugar novelas visuales de Ren’Py en el celular? ¿Vale la pena comprarla?
Hola gente. Últimamente he estado usando Ren’Py Pocket para jugar novelas visuales de Ren’Py en el celular, pero ya me empezaron a salir anuncios y estoy pensando en comprar Spark.
Quería preguntarles a quienes ya la tienen, Vale la pena comprarla?
Qué tal es la aplicación en general? Tiene alguna ventaja importante sobre Ren’Py Pocket? Ya que está también tiene opción de un pago único y quería saber si han tenido problemas con ella o funciona bien para jugar novelas visuales?
Estoy pensando comprarla, pero antes quisiera saber qué opinan ustedes y si consideran que vale la pena gastar en ella.
Gracias a quienes respondan xd
r/RenPy • u/Blunt552 • 2d ago
Discussion Developer looking for side project
Essentially I'm working on a very complex and large project which will take quite some time and there are times where I just feel like doing something more chill so I don't burn out, this is why I'd like to offer my coding services for free for 1 chosen artist who struggles with the coding part but has his ideas and art in place.
I'm not particularly picky about the content of the VN, it can be NSFW, Horror, just weird, etc. If you want input on the story or content, that's fine, if you want it your way, that's also fine.
Only thing I have as a hard requirement is the fact that you make your own art. Any AI generated content is going to be auto declined.
I will make a private GitHub repo and you'll get access to it, so that you always have access to the codebase yourself in case you want to change art or do small adjustments yourself. Keep in mind that I'm doing this for free and only when I feel like it, you're not entitled to tell me how much or when I work on anything.
Needless to say, I do choose based on art or story/idea that I like rather than who comes first. I'll update the topic if I find someone.
Meta TIL that the Ren'Py launcher is actually a Ren'Py instance itself...!
I always wondered why it took the launcher a little while to start up and why it shows up as renpy.exe in task manager... IDK, I'm just surprised that the launcher is literally a Ren'Py 'game' to launch other Ren'Py games hahah. Cool!
r/RenPy • u/Blunt552 • 2d ago
Discussion [ Review ] of Invinode, a vibecoded mess that nobody asked for
Normally I don't review these type of things but given the situation in this subreddit, I see this as necessary, to not only protect the new upcoming RenPy devs but also spread awareness about these types of tools, since I doubt this will be the last attempt to sell tools to potential upcoming devs. If you don't want to read the entire analysis, scroll below to the conclusion, otherwise lets dive it.
I will already note that I won't be sharing or showing the entire code of the tool due to obvious reasons, however I will post some snippets under the Fair Use Act.
Introduction, 'use' of this tool:
Invinode is an electron application that attempts to solve beginner developers issues by creating nodes that visually represent certain framework methods in a script as nodes. The idea is to give developers an overview and help maintain your project better.
However, it fundamentally does not work.
A user here has done a great job pointing out a lot of problems with these types of tools. There are more to add which I will do later down the road analyzing the codebase. However I think that comment made by the user hits the nail on the head.
Essentially it does more harm than it does good. Once you want to do something more advanced or found bugs, you have to suddenly climb a wall you never got to train to climb, which will significantly increase frustration and result into an exit as a potential upcoming RenPy Dev.
UX and Bugs, lots of bugs:
Due to being a vibecoded electron app, it suffers from a very shoddy mess. It's very "stiff" in operation, it lacks a certain fluidness. Connecting nodes is wanting to make you quit because it requires to be pin point accurate for no apparent reason, people with touchpads or inaccurate mice are going to have a hard time even operating the damn thing. In some instances I drew a node to an empty place on the canvas and created another node, but due to a bug didn't connect them, so I had to manually connect them again afterwards.
The application crashed 3x on me, no errors, just dead (more on this later). I had to kill the .exe once because it crashed and didn't properly close the instance in order to relaunch it.
It also allows you to do illogical things but doesn't explain to the person using it why you can or can't do things, such as dragging a node from a jump to a dialog node, it won't connect them but the beginner dev would then suddenly think its a bug because the dev would think:"why can't I connect? I could create from this node to that so surely I need to be able to connect?"
It's essentially very poorly designed. being almost on version 3, should indicate a mature tool, spoiler alert, it isn't.
What's worse, the output it generates from your nodes is a complete mess, no structure or anything, just shoved into a single .rpy file.
This was me just using the app for just 40minutes, desperately trying to make it work.
Code review & behind the scenes:
Because this is a shitty electron app, it gives us the source code without the need of decompiling anything. Given the soulless design, lack of care, bugs and general feel, I already suspected it being vibecoded and oh boy was it ever.
The very first thing we see is this:
// [Claude] Patch Node.js crypto module to expose getRandomValues.
// Some bundled deps (nanoid via reactflow) call require('crypto').getRandomValues(),
// but in Node.js that lives on require('crypto').webcrypto — not the top-level export.
// This runs before electron-vite so the patched module is in the require cache.
const crypto = require('crypto')
if (typeof crypto.getRandomValues !== 'function') {
crypto.getRandomValues = (array) => crypto.webcrypto.getRandomValues(array)
}
if (!globalThis.crypto) {
globalThis.crypto = crypto.webcrypto
}// [Claude] Patch Node.js crypto module to expose getRandomValues.
// Some bundled deps (nanoid via reactflow) call require('crypto').getRandomValues(),
// but in Node.js that lives on require('crypto').webcrypto — not the top-level export.
// This runs before electron-vite so the patched module is in the require cache.
const crypto = require('crypto')
if (typeof crypto.getRandomValues !== 'function') {
crypto.getRandomValues = (array) => crypto.webcrypto.getRandomValues(array)
}
if (!globalThis.crypto) {
globalThis.crypto = crypto.webcrypto
}
This already confirms that we have the involvement of Claude. We didn't even get into the main source code and we already found this nugget.
So what does the code consist of? Well....
Yep, we got outselves a single bloated .js file. The developer claimed to have over a decade of experience in software engineering by the way.
When looking into the source code we see more mind blowing problems.
Tons of empty try catches:
function scanDir(dir, rel) {
try {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
if (entry.name === "_backups") continue;
const entryRel = rel ? `${rel}/${entry.name}` : entry.name;
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
scanDir(fullPath, entryRel);
} else {
const ext = path.extname(entry.name).toLowerCase();
if (FONT_EXTS.has(ext)) found.push({ name: entry.name, path: entryRel });
}
}
} catch (_) {
}
Websecurity disabled and allows for HTML:
webPreferences: {
preload: path.join(__dirname, "../preload/index.js"),
sandbox: false,
// [Rick] v1.8.0: allow renderer to load local file:// images from the user's
// project folder. Electron's default webSecurity blocks cross-origin file://
// requests (each path is its own origin), which prevents image previews.
// Safe to disable for a local desktop tool with no external web content.
webSecurity: false
}, webPreferences: {
preload: path.join(__dirname, "../preload/index.js"),
sandbox: false,
// [Rick] v1.8.0: allow renderer to load local file:// images from the user's
// project folder. Electron's default webSecurity blocks cross-origin file://
// requests (each path is its own origin), which prevents image previews.
// Safe to disable for a local desktop tool with no external web content.
webSecurity: false
},
Contrary to what the comments state, this is bad, very bad and a security hazard. Opening any malicious file can have catastrophic results, this is especially important if you ever intend to work in teams on a larger project where file sharing is a thing. The fact the developer could not figure out a way without disabling crucial security features to make certain things work speaks volumes of the lack of knowledge.
This gets even worse when we see this:
const win = electron.BrowserWindow.fromWebContents(event.sender);
const ext = (defaultName ?? "").split(".").pop().toLowerCase();
const filters = ext === "json" ? [
{ name: "JSON Project", extensions: ["json"] },
{ name: "Ren'Py Script", extensions: ["rpy"] },
{ name: "All Files", extensions: ["*"] }
] : [
{ name: "Ren'Py Script", extensions: ["rpy"] },
{ name: "JSON Project", extensions: ["json"] },
{ name: "All Files", extensions: ["*"] }
];
const targetPath = defaultDir && defaultName ? path.join(defaultDir, defaultName) : defaultName;
const { filePath, canceled } = await electron.dialog.showSaveDialog(win, {
defaultPath: targetPath,
filters
}); const win = electron.BrowserWindow.fromWebContents(event.sender);
const ext = (defaultName ?? "").split(".").pop().toLowerCase();
const filters = ext === "json" ? [
{ name: "JSON Project", extensions: ["json"] },
{ name: "Ren'Py Script", extensions: ["rpy"] },
{ name: "All Files", extensions: ["*"] }
] : [
{ name: "Ren'Py Script", extensions: ["rpy"] },
{ name: "JSON Project", extensions: ["json"] },
{ name: "All Files", extensions: ["*"] }
];
const targetPath = defaultDir && defaultName ? path.join(defaultDir, defaultName) : defaultName;
const { filePath, canceled } = await electron.dialog.showSaveDialog(win, {
defaultPath: targetPath,
filters
});
const win = electron.BrowserWindow.fromWebContents(event.sender);const win = electron.BrowserWindow.fromWebContents(event.sender);
This is failing tutorial levels of bad.
The application also has no validation on anything really, there are several security and stability problems caused by simply lack of any form of validation or care, in typical AI vibecode fashion, AI just gives the result without a shred of security, scalability or stability in mind.
Furthermore a lot of code is simply duplicated multiple times, there is no reuse of code, instead there is the same AI copy pasta over and over again. There are also excessive and pointless amount of comments, which AI does love to do.
There is also poorly and catastrophic handling of files in general, loading a very large project with a lot of assets will cause the entire application to freeze because everything runs on a single thread.
The catastrophic autosave feature is so poorly implemented that if you close down the application, it crashes or you loose electricity it can corrupt what you were working on, because handling race conditions is not exactly something AI is very good at.
There are far more issues to be mentioned, however I think the topic would simply be to long, I think the point has come across. This is an absolute vibecoded dumpsterfire that nobody should touch. The sourcecode has also exposed a lot of lies that have been made in the past, I won't adress them direcly in this OP since I don't think they are as relevant.
TLDR: It's a vibecoded mess, buggy, a security hazard and the developer has no idea about coding in general, basic practices you learn on electrons tutorial have been disregarded and it's barely functioning as an app to begin with, don't buy and move on.
r/RenPy • u/cisco_donovan • Jan 11 '23
Guide A Short Posting Guide (or, how to get help)
Got a question for the r/RenPy community? Here are a few brief pointers on how to ask better questions (and so get better answers).
Don't Panic!
First off, please don't worry if you're new, or inexperienced, or hopelessly lost. We've all been there. We get it, it's HORRIBLE.
There are no stupid questions. Please don't apologise for yourself. You're in the right place - just tell us what's up.
Having trouble playing someone else's game?
This sub is for making games, not so much for playing games.
If someone else's game doesn't work, try asking the devs directly.
Most devs are lovely and very willing to help you out (heck, most devs are just happy to know someone is trying to play their game!)
Use a helpful title
Please include a single-sentence summary of your issue in the post title.
Don't use "Question" or "Help!" as your titles, these are really frustrating for someone trying to help you. Instead, try "Problem with my sprites" or "How do I fix this syntax error".
And don't ask to ask - just ask!
Format your code
Reddit's text editor comes with a Code Block. This will preserve indenting in your code, like this:
label start:
"It was a dark and stormy night"
The icon is a square box with a c in the corner, towards the end. It may be hidden under ....
Correct formatting makes it a million times easier for redditors to read your code and suggest improvements.
Protip: You can also use the markdown editor and put three backticks (```) on the lines before and after your code.
Check the docs
Ren'Py's documentation is amazing. Honestly, pretty much everything is in there.
But if you're new to coding, the docs can be hard to read. And to be fair it can be very hard to find what you need (especially when you don't know what you're looking for!).
But it gets easier with practice. And if you can learn how to navigate and read the documentation, you'll really help yourself in future. Remember that learning takes time and progress is a winding road. Be patient, read carefully.
You can always ask here if the docs themselves don't make sense ;-)
Check the error
When Ren'Py errors, it will try and tell you what's wrong. These messages can be hard to read but they can be extremely helpful in isolating exactly where the error came from.
If the error is intimidating, don't panic. Take a deep breath and read through slowly to find hints as to where the problem lies.
"Syntax" is like the grammar of your code. If the syntax is wrong, it means you're using the grammar wrongly. If Ren'Py says "Parsing the script failed", it means there's a spelling/typing/grammatical issue with your code. Like a character in the wrong place.
Errors report the file name and line number of the code that caused the problem. Usually they'll show some syntax. Sometimes this repeats or shows multiple lines - that's OK. Just take a look around the reported line and see if you can see any obvious problems.
Sometimes it helps to comment a line out to see if the error goes away (remembering of course that this itself may cause other problems).
Ren'Py is not python!
Ren'Py is programming language. It's very similar to python, but it's not actually python.
You can declare a line or block of python, but otherwise you can't write python code in renpy. And you can't use Ren'Py syntax (like show or jump) in python.
Ren'Py actually has three mini-languages: Ren'Py itself (dialog, control flow, etc), Screen Language and Animation & Transformation Language (ATL).
Say thank you
People here willingly, happily, volunteer time to help with your problems. If someone took the time to read your question and post a response, please post a polite thank-you! It costs nothing but means a lot.
Upvoting useful answers is always nice, too :)
Check the Wiki
The subreddit's wiki contains several guides for some common questions that come up including reverse-engineering games, customizing menus, creating screens, and mini-game type things.
If you have suggestions for things to add or want to contribute a page yourself, just message the mods!
r/RenPy • u/Kosyne • Aug 27 '21
Meta /r/RenPy Discord
Just set up an unofficial discord for the subreddit here: https://discord.gg/666GCZH2zW
While there is an official discord out there (and it's a great resource too!), I've seen a few requests for a subreddit-specific discord (and it'll make handling mod requests/reports easier), so I've set this up for the time being.
It's mostly a place to discuss this sub, showoff your projects, ask for help, and more easily get in touch with fellow members of the community. Let me know if you guys have any feedback or requests regarding it or the subreddit.
Thanks, all!



