But then relevant branch will need to check each relationship both ways, which tends to result in inconsistencies unless you actively code against it. I'm not saying it necessarily creates inconsistencies here as I haven't played through every single scene, but it does make it more complex than just modeling each relationship instead of each character
What? What are you talking about? I'm saying that for this
post, he just has to keep fostering friendship between the 2 characters. Because anything below 0 is marked as "rival". Whether that number is -1 or -999 so it might take a while. There's no inconsistency check both ways or duplicate/redundant values or anything that's causing the rival status.
Like here's the code (version 0.53b):
./scripts/interface/Player_menu.rpy:1919
Code:
viewport id "relationships_friendship_viewport" anchor (0.0, 0.5) pos (0.515, 0.595) xysize (0.385, int(195*game_resolution)):
<snip viewport properties>
hbox:
spacing 20
for C in eval(f"{current_relationships_Entry.tag}_friendship_thresholds.keys()"):
if C != current_relationships_Entry.tag and eval(C) in active_Companions:
$ friendship = eval(f"current_relationships_Entry.get_friendship({C})")
fixed xysize (int(135*game_resolution), int(195*game_resolution)):
add f"images/interface/photos/{C}.webp" align (0.5, 0.5) zoom 0.13
add f"images/interface/Player_menu/relationships_{friendship}.webp" align (0.5, 0.5) zoom interface_adjustment
Where current_relationships_Entry is set to a single character via a button here:
./scripts/interface/Player_menu.rpy:1758
Code:
button xysize (int(911*game_resolution), int(191*game_resolution)):
<snip button properties>
action SetVariable("current_relationships_Entry", C)
As you can see, it's a simple for-loop that iterates through the keys of a single character's friendship object. There's no reverse checks for friendship counts in the rival calculation. In fact, the rival status isn't even a straight evaluation, but rather a threshold check to return a string that just gets concatenated into what color it shows on the game's GUI.
Or, to put it simply:
current_relationships_Entry ==> current character whose info is being viewed
friendship ==> variable to hold string of a number, ranging from -2 to 3 (depending on characters and thresholds)
which means that this line:
add f"images/interface/Player_menu/relationships_{friendship}.webp"
Will display one of the following images:
images/interface/Player_menu/relationships_3.webp
images/interface/Player_menu/relationships_2.webp
images/interface/Player_menu/relationships_1.webp
images/interface/Player_menu/relationships_0.webp
images/interface/Player_menu/relationships_-1.webp
images/interface/Player_menu/relationships_-2.webp
Which you will find are borders with colors that correspond to a characters relationship status/threshold to another character. A. Single. Linear. Evaluation. No inconsistencies, no duplicate states. Just a single instance for one character and how they feel about another.
That's part of what makes this code so much better to mod/maintain. The evaluations are straightforward and simple. As Jamie Hynemann of Mythbusters said:
"Whenever you run into an overly complicated design, that's a sign of an inferior engineer. Simpler is always better."
Like, I had to understand this code to know how to inject my cheats and my cheat allows you to turn off rival status. I know how it works.