Hello everyone, Duhop here!
Since the last devlog, my remaining few weeks of July and almost all of August were dedicated to one, singular task; making Act 2 look amazing.
I’m happy to say that a full round of visual polish is now finished, and that playtesting for Act 2 has officially begun! If you’re interested in participating, head over to our Discord and check out #playtesting for instructions on how to join 😀
Now, for today’s topic 😎
Move Your Everything!!
If you’re a long-time reader, you might remember another devlog about visual scripting from last October titled Move Your Sprites!. I thought I was cooking at the time, but some of what I’ve learned over the last month or so has pretty much completely eclipsed the methods I was using back then.
You can go back and take a look a look at that previous devlog for the basics, but herein lies some of the biggest lessons I’ve learned and improvements I’ve made since then, and why finishing the scripting for Act 2 took me so much longer than I expected 😅
Let’s start with the flashy stuff, shall we?
Think cinematically. Move the camera, not just the sprites!
When I originally started on the visual scripting for Act 2, I wasn’t even calling it that. At the time, it was just “sprite scripting” to me.
But now, my third eye has been opened!
Instead of focusing solely on the visuals sprites in a scene, you get a far better end result if you try to think about the visual direction of the scene as a whole. After all, how can you make something truly cinematic if you don’t think about the camera?!
Case in point, here’s a direct comparison of how Jenna’s initial introduction looked before and after my most recent round of visual scripting for Act 2:
Big difference, right? Which version do you like better?
I chose the latter, obviously, and much of my recent visual polish work went toward more creative experimentation with similar background and camera shots/animations wherever I felt like a scene could benefit from it. I’m so in love with the cinematic effect these have brought to the game, I’m definitely going to add some to Act 1, and I’ll probably end up adding even more to Act 2 as well when I go back to the start of the game for its final round of polish before release.
I would add more examples here, but if you really want to see them, go participate in the playtest!! >:D
Use shaders and other visual effects to give scenes unique & immersive visuals.
Speaking of cinema, here’s another technique you can use to absolutely knock the player’s socks off!

Can you believe this scene is nothing but a regular sprite on a completely blank white background? And the light beams are even animated?
True, we do still need to tweak this scene a little bit to get exactly the effect we’re after, but that essentially just comes down to replacing the lighting on F’s sprite with our usual overlay technique, and changing the background image to something that shows the beams a little better than the pure white one we have now.
Literally all I’ve done to this so far is apply shaders to it.
Shaders and particle effects are some of the most difficult things to program in Ren’Py, especially since Ren’Py’s shaders are written in a language completely separate from Ren’Py or even Python itself…
But thankfully, the community has already done that for us! The shaders in this scene are from the Make Visual Novels Ren’Py and Romance shader packs, available for free to download and use even in commercial projects 😀
Itch.io houses a plethora of other amazing free or absurdly cheap visual effect assets for Ren’Py as well, including Feniks’ Immersive Particle VFX that I’m so in love with I’m tempted to change the setting of some scenes just for an excuse to use them XD
Practice and experiment yes, but learn how to build standardized systems that makes your life easier.
Aaaaand here comes the boring stuff.
Directing and implementing visuals is not easy, especially without experience. For a very creativity-focused person, it can quickly become difficult to keep up with the technical side of things as your ideas grow in complexity—and a more technical or book-type learner could easily struggle with the very subjective and imaginative nature of the process itself.
So if you’re working on it alone, you have to get good at both.
At first, that looks like a lot of experimentation and practice with different techniques (and that never really goes away completely). Thankfully, though, once you start identifying specific techniques and movements that you like, you can re-use them wherever applicable!
The longer you work on visual scripting, the larger your toolbelt for the process will grow. You could choose to store all of that mentally and redo the implementation manually each time, oooor you could actually be intelligent about it and create standardized transforms that speed up your process immeasurably.
I touched on it in the original devlog, but at that point I didn’t yet employ standardization to nearly the extent I should have. I’ve learned a lot more about Ren’Py since then, and I applied that knowledge this time around to create a system that should streamline future scripting substantially.
…though it did come at the sacrifice of a good few weeks of my time in August. I’m pretty sure I spent at least as much time redoing the systems for visual scripting as actually doing the scripting itself 🙂
Allowing for easy zooms.
To start off with, I completely replaced all of the basic positional transforms I had been using with versions that use a properly defined central anchor point instead of align or offset, allowing for the easy adjustment of zoom on sprites:
transform f_center: # Old
    zoom 1.0 xalign 0.65 xoffset 0 yalign 0 yoffset 0
transform f_center_new(z=1.0): # New
    transform_anchor True
    anchor (710, 540) pos (960, 540)
    zoom z
If you read the original devlog, you would’ve seen me whinging about the zooming alignment issues this change fixed. As it turns out, the anchor property exists pretty much specifically to fix those issues, and I just didn’t know about it 🙂
Are these transforms 10x easier to work with than the old ones?
Yes!
Were there consequences to adopting them this late in the game?
Of course, also yes!
Just due to this one change alone, I had to go back and redo every single transform applied to a sprite that had a base transform offset other than (0,0), which was pretty much everything besides the f_center example above 🙂🙂🙂
And of course I ended up needing to redo the rest of them too anyway, after my next big change.
Using relative instead of absolute values for properties.
Normally in Ren’Py, your transform properties have to be provided with absolute values, and you need to take into account the previous value of a property when you make animations with it.
This means that when you’re scripting:
- You need to mentally track the ongoing value of every displayable’s transform properties.
- You can’t reuse standardized transforms without manually giving them those values (which I didn’t even know you could do until recently 🙂).
- If you want to change the value of one single transform property in a scene with multiple animations, you also then need to change the value of the same property for EVERY SINGLE SUBSEQUENT MOVEMENT OF THAT DISPLAYABLE.
The realization of that last point is what broke me, and why I spent days of my life creating a python function that retrieves the previous value of a transform property for me >:)
And now, wielding the immense power of, uhh, being able to use relative values, I’m absolutely swimming in standardized transforms that I can call on at a moment’s notice without a single care in the world.
Here’s just a piece of the collection I’ve amassed so far through my work on Act 2:

As for the function itself, it’s a little… well, let’s just say I’m not quite brave enough to share it publicly as it is now ðŸ˜
If you do happen to be a Ren’Py dev interested in a solution for relative transform property values, I’d happily share my approach with you on our Discord. Maybe you could help me improve mine?
Oh by the way, so far I’ve only redone the transforms I’d already been working on in Act 2. At some point I still need to go back and replace every last transform in Act 1 as well 🙂
This is all a lot easier if you know what you’re doing and make a good system from the start. If you’re noticing cracks later on in the process, you have to decide whether there’s enough work left in your game to make revamping a system like this worthwhile.
For me, I think it was most definitely worth the extra time taken now. With 4 acts worth of scripting left, the math here definitely maths on time savings alone, not to even mention the noticeable bump in quality and the sheer amount of mental anguish I’ve probably saved myself from.
And that’s pretty much all from me. As always, thank you all so much for reading and supporting Violet Horizons!
I may have procrastinated finishing this devlog for ages, but I really do enjoy writing them. A lot of introspective thoughts come up in this process that I might have missed out on otherwise, and it really helps my motivation to look back on and appreciate my recent accomplishments.
I look forward to ranting to you all again next month!
-Duhop
