VN Ren'Py STWA: Unbroken [Book 1 Steam] [STWAdev]

4.60 star(s) 125 Votes

Mike the Red

Member
Apr 26, 2019
157
159
In defense of the dev, from what I see of the code for Unbroken, it does properly initialize any new variables. However, it does so only when they are added in a new chapter/update. This works just fine for how the game itself needs to use them, but unfortunately it doesn't support mods that will be trying to display those values right from the first scene of the game. This is really not the dev's fault, because even if they were to duplicate those variable init lines at the start of the game, that still doesn't fix a save from chapter 2 – for example – that a person loads with the mod active.
Declaring global variables at random points within the code is very bad form and really should be fixed. At the very least, global variables should be declared at the start and defined later, though I recommend giving the variables a default value (not relevant to Python, since you can't declare without defining). It is normal to declare, define, and (if the language requires it) delete local variables as needed.

I'm not that familiar with Python, but like most programming languages, it appears to have a way to check for null (none) values, which is what you probably used to get around this problem, but I thought I'd pass it along for anyone else who might be curious (Note: this is untested code, found from a quick search, so use at your own risk).

Code:
if my_variable is not None:
    # execute some code
This gives you a variable undefined error. You have to use a try/except/else block:
Code:
try: my_variable
except: my_variable = 0
else: print("Variable exists with value: "+str(my_variable))
Ren'Py has a built-in command called "default" that does this for you.
Code:
default my_variable = 0
is equivalent to
Code:
init 100 python:
    try: my_variable
    except: my_variable = 0
And, it can be important to note that delayed init, since most init blocks will be run before the default command.
 
Last edited:
Mar 2, 2022
90
1,716
Thanksfor700.png

As promised here's a little render that I would wanted to get out out for patron milestone, starring the two most popular Unbroken girls.
As of writing 3089 renders are posed, 2992 rendered. Slow scene is slow. What I'm trying to decide on if it'll be worth to just focus on posing this week and knock out the rest of the stills and then focus on actually rendering as I tap away at other things, or to stay the current course. The question just is what actually will save time in the long run.
Animations are mostly just waiting for time to move to active production again. Base scenes are set, characters ready to go and choreography planned. Once the render situation is solved we're onto these.
Nothing else happening at the moment, just trying to get, my first build ready and assembled. chipping away as best I can.
As always thank you so much for the support, I hope you have a lovely rest of the week.
Sláinte!
 

RoryTate

Member
May 15, 2018
182
403
Declaring global variables at random points within the code is very bad form and really should be fixed. At the very least, global variables should be declared at the start and defined later, though I recommend giving the variables a default value (not relevant to Python, since you can't declare without defining). It is normal to declare, define, and (if the language requires it) delete local variables as needed.
I understand the frustration, but writing a novel can be like fighting a war. And no battle plan survives the first arrow. So I accept that a VN developer will get inspiration, or need to change events, and sometimes have to create entirely new gameplay elements at any point within the code. Even with a good story outline in place, this kind of thing is going to happen. It may not look pretty or follow "proper" convention, and it may seem random – thought it's not – but I much prefer that over having to restart from the beginning because all save files are suddenly incompatible with a new update, which happens with many VNs unfortunately. In those cases I tend to lose interest in the project because I hate wasting my time having to redo all the previous choices. So again I have to come to the dev's defense on this one. I'm glad if the Unbroken developer is prioritizing function over form.

This gives you a variable undefined error. You have to use a try/except/else block:
I figure it wouldn't be that simple, and python would require having to catch an error. Yeah, that sucks. But good to know I guess.
 
  • Like
Reactions: Walter Victor

Mike the Red

Member
Apr 26, 2019
157
159
I understand the frustration, but writing a novel can be like fighting a war. And no battle plan survives the first arrow. So I accept that a VN developer will get inspiration, or need to change events, and sometimes have to create entirely new gameplay elements at any point within the code. Even with a good story outline in place, this kind of thing is going to happen. It may not look pretty or follow "proper" convention, and it may seem random – thought it's not – but I much prefer that over having to restart from the beginning because all save files are suddenly incompatible with a new update, which happens with many VNs unfortunately. In those cases I tend to lose interest in the project because I hate wasting my time having to redo all the previous choices. So again I have to come to the dev's defense on this one. I'm glad if the Unbroken developer is prioritizing function over form.
Sorry, but you're mistaken here. Despite how poorly most VN are coded (especially rife with spaghetti code), most games manage to organize their variables better. There is even a bold note in the warning developers to default all their variables. While I definitely appreciate the author's ability to tell a good story, their coding is rather clumsy and amateurish.

As to your implication that coding is like combat, there's a little truth to that, with veteran programmers keeping level-headed and organized, while the green programmers rush about, just trying to make it to the next day. My hope is that I can pass along some advice that will help others improve.

As to the issue of new versions of games breaking old saves, this can be resolved through the use of the "config.after_load_callbacks" array, as seen in my mod's code. Any Python function placed in this array is called at game start and after loading a saved game. This means that a developer can use a function to update any code from one version to another (which usually means updating variables). There is also a special "after_load" label that does the same thing in Ren'Py code (instead of Python), but each project is only allowed to use this label once, so adding functions to the array is the way to go for modders (and devs, if they desire).
 

RoryTate

Member
May 15, 2018
182
403
Sorry, but you're mistaken here. Despite how poorly most VN are coded (especially rife with spaghetti code), most games manage to organize their variables better. There is even a bold note in the warning developers to default all their variables. While I definitely appreciate the author's ability to tell a good story, their coding is rather clumsy and amateurish.

As to your implication that coding is like combat, there's a little truth to that, with veteran programmers keeping level-headed and organized, while the green programmers rush about, just trying to make it to the next day. My hope is that I can pass along some advice that will help others improve.
My point is that setting defaults in one section at the top of the code like you suggest is not always possible in a VN. Take the Ines variables I passed along as an example. It's reasonable to assume that the dev had not planned on making aspects of Ines' personality a path/choice for the player in the first release of Unbroken many moons ago, and they only decided to add that in recently. However, the story and game was already many versions deep by that point. So the only way to accommodate that late addition – given that the callback solution you noted wasn't in place – is to simply declare, initialize, and begin using those scores for Ines at the start of the code for the new chapter. It's functional, and it makes complete sense.

Some may argue that duplicate declarations should also be added at the top of the script when a new variable is required like this, mainly for documentation purposes. However, duel initialization can cause maintenance issues, where it's even allowed in the first place, so I can see why a dev would avoid it and only want a single entry in these cases.

The core issue here I think is that writing an iterative novel with multiple releases is a very different beast than pure software development, and some practices simply may not translate well between the two disparate projects. I can relate to the desire for organized and well-formed coding though. It just may not always be possible given the limits imposed on this type of endeavour.
 

Mike the Red

Member
Apr 26, 2019
157
159
My point is that setting defaults in one section at the top of the code like you suggest is not always possible in a VN. Take the Ines variables I passed along as an example. It's reasonable to assume that the dev had not planned on making aspects of Ines' personality a path/choice for the player in the first release of Unbroken many moons ago, and they only decided to add that in recently. However, the story and game was already many versions deep by that point. So the only way to accommodate that late addition – given that the callback solution you noted wasn't in place – is to simply declare, initialize, and begin using those scores for Ines at the start of the code for the new chapter. It's functional, and it makes complete sense.
I think there might be a misunderstanding about the as it works its way through the code.

It begins with engine startup (which is typically not edited by the developer). Next, "python early" blocks are run, though many developers don't use these. The first thing the developer typically influences is the "init phase", which occurs before anything is shown to the user (excluding an optional presplash). During the init phase, anything in an "init block" is set, such as defining Python classes and functions and constants. At the end of the init phase (typically) is when statements are run to set the value of variables. Once script execution begins, . Next, Ren'Py begins calling the special labels splashscreen, before_main_menu, and main_menu. From the main menu, things typically transfer to either the start special label or the "load" function. The load function will overwrite any variables from default statements with their saved value (the current value of "defaulted" variables is always included when creating a save file).

So, the point is that a developer can continually add new variables to an existing project over time, so long as they do so using the "default" keyword. Importantly, This means that if a variable is added with a simple Python command, as this game does with $ inessubmission = 0, it will not be saved if the user bypasses that line, such as when choosing a different route or loading an old saved game. This is especially bad when all other references to this variable are $ inessubmission += 1, meaning that they too will fail without the initial value.

As to the config.after_load_callback list and after_load label, these are built-in capabilities of Ren'Py that execute automatically prior to calling the "start" label and after the "load" function runs.

Some may argue that duplicate declarations should also be added at the top of the script when a new variable is required like this, mainly for documentation purposes. However, duel initialization can cause maintenance issues, where it's even allowed in the first place, so I can see why a dev would avoid it and only want a single entry in these cases.
As I think my above statement covers, declaring variables at init time actually occurs before any of the labels are processed, so it's before the script. Ren'Py will stop you from "defaulting" a variable more than once, so there's no way to have duel [sic] initialization. Putting them together "at the top of the script" isn't technically necessary, but it is the standard practice, due to the headaches that can be avoided if the code is well organized. Many developers, myself included, will have an entire file specifically for constants and variables, so that they can always be located easily.

The core issue here I think is that writing an iterative novel with multiple releases is a very different beast than pure software development, and some practices simply may not translate well between the two disparate projects. I can relate to the desire for organized and well-formed coding though. It just may not always be possible given the limits imposed on this type of endeavour.
The release of software in an iterative manner is more of the norm, rather than the exception, at least in my professional and personal experience. While there are certainly some peculiarities to a visual novel, I don't find it to be different from other forms of software development in any meaningful way. Applying industry-wide good coding practices and having an adequate understanding of how the engine runs means that writing visual novel code is far easier. It's because Ren'Py is so forgiving that software can be released with "sub-optimal" code.

Finally, I appologize if my responses come across as condescending, but I sincerely hope that I can contribute to others writing better code.
 
Last edited:

Elduriel

Forum Fanatic
Donor
Mar 28, 2021
4,463
7,958
Do we have an approximation when next release could come ?
well render counts are steadily increasing each update, we are currently sitting at 3k stills, last update was like 4k renders and that dropped early september. So just with very crude math and speculation, that's 3k renders in six months, so 500 renders a month. Let's say new update is 4500 renders, so that's 3 more months. But I could be speaking out of my ass for all we know, dev didn't give any estimates, could be next month if it's a shorter update.
 

RoryTate

Member
May 15, 2018
182
403
It begins with engine startup...
You know, I almost wrote something along the lines of: "There is probably some way these limits can be avoided with extra work or knowledge in setting up the project, but that's not what I'm talking about here." in my last response, but I figured I'd wait to see if that infinite abyss was where this was headed. And once I saw the wall of text response, I wished I had put that in of course. But just like coding, there's something to be said for avoiding overdesigning and putting in a whole bunch of unneeded stuff, even if it's just when writing a quick forum comment.

Time is the limiting factor in the end. Whether writing code or understanding the language, that takes time, which is a finite resource for every mortal being. And the simple and straightforward way this game is coded is clearly functioning just fine. Knowledgeable modders can add stuff to increase its accessibility. So I don't see a problem. If the only rationale for the extra setup work you are advocating for is that a couple of small variables for a less popular LI – sorry Ines, you're great, but the reality is that you are up against very strong competition in this story – might get overlooked in a mod used by a small percentage of users, then I'd say the KISS principle applies. "Just make it work" is not always the right attitude of course, but it's not always the wrong one either. In this case the dev would have spent what sounds like hours of reading, synthesizing, and applying new skills to at best do what? Save a few minutes of time? I'll leave it at that, because this is really not topical for this thread any more.
 

indio68

Engaged Member
Sep 26, 2020
3,912
3,283
ines desire to protect points ..to whom are directed ? versus her best friend o versus MC? i don't understand if this is a game where u can be with more than 1 girl at the same time or not...any hint?
 
Last edited:

Skrrt!

Member
Oct 19, 2021
100
151
Not sure if this has been asked recently but is Serena the Lawyer a side or is there just little content of her? Seems like everyone's relationships are getting more established with Valentine but outside of two scenes with Serena, i dont see much else however she's on the banner so i thought there would be more with her?

Or.. Are there more scenes & i just happened to be knocked off her path because the cat hates us or something? lol.
 

SerHawkes

Engaged Member
Oct 29, 2017
3,271
14,939
Not sure if this has been asked recently but is Serena the Lawyer a side or is there just little content of her? Seems like everyone's relationships are getting more established with Valentine but outside of two scenes with Serena, i dont see much else however she's on the banner so i thought there would be more with her?

Or.. Are there more scenes & i just happened to be knocked off her path because the cat hates us or something? lol.
Serena is more or less a fuck buddy for now. Nothing wrong with that.
 

Skrrt!

Member
Oct 19, 2021
100
151
Serena is more or less a fuck buddy for now. Nothing wrong with that.
Good to know i didn't necessarily miss anything with her. I enjoy her contrast compared to the other girls & her model is beautiful. But cool cool, good to know, appreciate the answer.
 

Elduriel

Forum Fanatic
Donor
Mar 28, 2021
4,463
7,958
ines desire to protect points ..to whom are directed ? versus her best friend o versus MC? i don't understand if this is a game where u can be with more than 12 girl at the same time or not...any hint?
those points are directed towards Vi, so lower the better. As for the other question, looking at the dev's other game, for the majority of the game you're free to do as you wish with the girls in the game... towards the end you'll most likely have to make a decision however who you want to end up with (not a harem game). But we're not there yet.
 

ImSenjou

Active Member
Apr 15, 2019
537
1,461
ines desire to protect points ..to whom are directed ? versus her best friend o versus MC? i don't understand if this is a game where u can be with more than 12 girl at the same time or not...any hint?
I think these points are for Vi, Ines knows that Vi has had a crush on the MC since forever, if the MC is a nice, loyal guy, she will approve the MC and will know that Vi will be safe with him, but if the MC is a stud, flirts with everyone, even the best friend of the girl who has a crush on him, then she will have misgivings about the MC, and she will try to show Vi who he really is, that he is not the prince charming that Vi imagines... To protect her.

That's what I think.
 

MF_DOOM

Active Member
Mar 1, 2023
804
3,749




Sneak Peek 02/19/2024

A little extra treat for you French lovers. Honestly this is such a fun scene to have worked on.
I have a strong suspicion after this update that people are really going to love our sweet Frenchie.
Honestly I've really loved working on her, and really giving her time to shine this update. So excited to see where folks allegiances lie after this.
 
4.60 star(s) 125 Votes