v1 is so catcore to me. like gabriel sits down anywhere for more than a millisecond and it IMMEDIATELY tries to jump on his lap. and any time he’s not sitting down it will follow him around the house like it’s his shadow. this mf probably knocks cups off counters smhing my head……
Lengthy discussion under the cut of how Ren'py makes it easy to get started making your own VN! TL;DR: this 100% free engine gives you a working template right out of the box; read the quickstart guide and you can have a prototype running in minutes :)
This ramble has been in the works for a while; I'd been wanting to yap about the engine since I finished DxM but it was a bit tricky to figure out a balance in detail/length/focus/etc. I've opted to simply highlight some advantages that make it easy to get started, since my goal is to show how good Ren'py is at doing what it does and that everyone should try it >:)
-
What I find particularly great about is that it does so much right out of the box. It is very conscious of what a VN needs, and does as much as it can to make that as easy as possible, even to people who are complete newbies to both the engine and programming. It: (1) gives you a fully functional template, (2) makes script-writing as dumb and easy as possible, (3) provides both relatively straightforward and immensely flexible customization options, and (4) is meticulously documented and has a well-established community/support base.
(1) The Functional Template
The way it gives basically comes with a working VN right out of the box is a great feature of Ren'py, perfect for anyone who wants to hit the ground running. You download it, run the application, click "Create New Project", pick between a small number of size/theme options, and then it spits out a package that is essentially a functional VN without any content. The default template comes pre-packaged with a fully functional UI that you can run right away, just like any other application on your computer.
[Screenshot of the default project template that gets output]
Even if you don't want your VN to look like the default GUI, rearranging things to match your vision is something that can be done later (unless you know exactly how you want it to look, like it was for me & DxM. In that case, establishing the right dimensions early on can save a lot of hassle). The nice thing about this functional template is that you can dive right into writing/drawing the actual script & images, to get that first proof of concept up and running, without having to worry about lots of setup or configuration. And Ren'py's script support is in my personal opinion, very very accessible.
(2) Easy script writing
When you think of something like a movie or play script, you might imagine something with this kind of format:
SCENE 1: A dark forest.
[Gabriel walks to the centre, holding a torch]
GABRIEL: "WHERE IS THAT DAMNED MACHINE."
[Gabriel looks around frustratedly]
GABRIEL: "I HAVE BEEN WAITING FOR TWELVE HOURS TO GIVE IT THIS BATCH OF COOKIES AND NOW THEY ARE NO LONGER FRESH."
[Gabriel walks off the right, scene fades to black]
Ren'py makes this user-friendly format as their basis for writing the VN script. This is what I would consider a second major advantage. A Ren'py script.py file that does the above would look something like this:
label start:
scene dark_forest_background
show gabriel with_torch at center
"GABRIEL" "WHERE IS THAT DAMNED MACHINE."
show gabriel looking
"GABRIEL" "I HAVE BEEN WAITING FOR TWELVE HOURS TO GIVE IT THIS BATCH OF COOKIES AND NOW THEY ARE NO LONGER FRESH."
show gabriel leaving at right
show black_background with dissolve
Writing a Ren'py script feels a lot like writing/directing a play. Each line in the script is executed sequentially, whether it's a dialogue line or a change in scene, with a click from the player required by default to move to the next line. You have the images and you have the dialogue; you decide how they show up on-screen in what order, and with what special effects/positioning they use (most of which are built-in).
In the example above, all character dialogue will automatically be shown in a dialogue box labelled with the name provided ("GABRIEL"). All changes take effect instantly, so you can see them in-game immediately. You can set something up in literal minutes if you have all the parts; the work lies only in putting them together.
[Award-winning VN in the works???]
What about offering dialogue options and diverging routes? That is also made as easy as possible via the engine. Say you want to give the player 3 options, for example - (1) Go up the hill, (2) Leave the forest; or (3) Eat the cookies yourself.
To translate this to Ren'py, all you have to do is add a menu statement at the point in the script where you want it to show up. To extend the example above:
[...]
show gabriel_leaving at right
show black_background with dissolve
menu:
"Go up the hill":
jump up_hill
"Leave the forest":
jump leave_forest
"Eat the cookies yourself":
jump eat_cookies
(As this ramble is not meant to be a syntax guide, I won't go into the depths of Renpy's syntax, but I will mention that the colons and indentations are important!)
Then once the script reaches the fade-to-black, the "menu" line is run, and Renpy will automatically show the three options on-screen as clickable buttons. When the player clicks on the appropriate button, the control flow will jump to the corresponding label, which can then be defined anywhere else in the script.
The "up_hill"/"leave_forest"/"eat_cookies" labels are names you make up, and they should correspond to landing points for those jump statements, where the script will continue from. For example:
label up_hill:
"GABRIEL" "GUESS I'LL TRY GOING UP THE HILL."
[...]
label leave_forest:
"GABRIEL" "MAYBE I SHOULDN'T BE LOOKING FOR IT HERE."
[...]
label eat_cookies:
"GABRIEL" "OKAY I'M JUST EATING THESE MYSELF THEN."
[...]
The job of the creator then becomes scripting all the routes, defining menus + options, and creating jump/label pairs that will connect in the way they want the flow to go. When the script reaches an end with no further statements to execute, it ends on its own and returns to the main menu.
For simple decision-based and dialogue-centric VNs like DxM, this was basically all that was needed to convey the story!
(3) Straightforward Customization
The third thing I really liked is how Ren'py exposes customization options extremely easily. Virtually anything you want to change or set is available in the form of a relevant property, part of Ren'py's robust, overarching "style" system. And since the sheer number of options can get overwhelming to a new user, by default Ren'py exposes - via very clearly labelled variables - a good number of properties that could be considered "frequently used", such as the system font, the dialogue text size, text colour, the size of the dialogue window, etc. If you want finer control, you can go in and set the property values for each and every UI element that you like.
Adding your own UI elements is also very easy. There's a slightly steeper learning curve because anything you want on-screen that's not a static image needs something called a "screen" that you can define (for example, the +BONUSES box in DxM was a custom screen, as was the clock in the top left corner). But screens can be ridiculously basic:
screen example_screen():
text "This is an example"
That's it that's a screen, that simply shows the text "This is an example" in the default position on-screen. Again since the lines in the script are executed sequentially, simply adding "show screen example_screen" at the right point will cause the text to appear on-screen like magic :)
DxM obviously looks nothing like the default template shown above, and that was quite easily achievable by adding & removing various UI elements, then rearranging things until they were all in the right spots.
(4) Read the docs (or don't, it works either way)
The fourth and most important advantage of Ren'py in my book is how long it's been around, resulting in the extremely well-established community/documentation/resources. I joke to myself that I brute-forced Ren'py because I skimmed the quickstart guide in their documentation, then spent the next month or so simply googling "renpy how do I do X" and trying out each result until I got what I wanted, without actually really understanding what the heck I was doing 80% of the time. And it worked! Because searching for Ren'py help for basic things like how to arrange things in a grid or add a scrollbox always yielded helpful results - there's a forum full of responsive Ren'py veterans where almost any question you can think of has been asked, and the Ren'py subreddit turned out to be a great resource as well. I also saw several dedicated tutorial websites that had posts on how to employ certain features of Ren'py, in case friendlier language than that of the docs would be a benefit.
Eventually I did read through most of the docs (I am a nerd who enjoys doing that) - they definitely get more technical and there are lots of things I still don't understand well, but they really helped expose me to new features that I wouldn't have known were possibilities (like the drop-down menus, tooltips, custom transitions, and of course browser support). Wading through the docs also led to several major overhauls of my code when I realized I was doing stuff in the stupidest way possible, brute-forcing a workaround when Ren'py already had seamless built-in handling of that (hi, using global variables for literally everything, I don't miss you). To use advanced features of Ren'py, knowledge of Python & programming principles is required, but the bare minimum can already get you really far with Ren'py.
-
If you've made it all the way down here, thanks for reading, I hope that was at least somewhat informative/interesting! I tried to keep this as a relatively brief "taster" and had to leave out a lot of detail to that end, but would be happy to expand on anything specific. For anyone interested in trying it out though, the proper place to start would be the official quickstart guide, which covers everything I mentioned here in a better level of detail for getting started.
i am devastated . they make me sick . they make me ill oh my god . thank yous arent enough for you mothcpu you created a piece that will stick with a lot of us for the rest of our lives . bless you
happy anniversary to a true work of art, i made this little humble piece as a little piece of my immense gratitude for dream's end come true
Hiya! Wanted to say i thoroughly enjoyed dxm! May I ask what spurred you on to make this and how long it took you?
Hi!! I'm really glad to hear that you enjoyed the game, thank you! 🥺 And I would love to take your questions as my free pass to ramble a bit about the process ahaha.
I got the idea to make the game after getting sucked into the GabV1el ship + hearing about 2-S, though it started out as simply making some static mock-ups/fake screenshots of a Gabriel dating sim. My friend who got me into the fandom started coming up with dialogue & responses to my mock-ups, which included an ending sequence (the exact one in the game). I liked that ending so much that my determination to make it real gave me the motivation to spend the next six months filling in a whole script for it (the ending image of them was one of the very first things I drew for the game). It wasn't going to be playable at first (I think I considered making a video at one point?) but then I found & tried Ren'py, and immediately loved it! As a playable game it also wasn't going to be anywhere near as long as it is now, but as I got more invested in Gabriel/Ultrakill/making it into a passable VN, it gradually expanded to its current size :)
Which is to say it felt like this the whole time:
In a nutshell, I had a very specific goal in mind, and I was crazy enough to spend half a year writing a script, learning Ren'py, and drawing Gabriels to achieve that goal 👍