SamuKata
vrengames
vrengames

patreon


Lab Rats 2 v0.51.1 Release!

Lab Rats 2 v0.51.1 is Live! Get it Here!

PC: Lab Rats 2 v0.51.1-PC
Mac: Lab Rats 2 v0.51.1-Mac
Android: Lab Rats 2 v0.51.1-Android 

LR2 v0.51.1 is finished it's week of patron bug testing and is ready for it's public release! This month's update cycle was focused on adding new storyline content for Jennifer and cleaning up the code base. Jennifer now has a new section of storyline focused on her starting an InstaPic account, followed by an OnlyFanatics account when she realises how limiting the former could be. Lily's storyline has been updated as well, adding a few minor interactions and a new event to have her start her only OnlyFanatics page as well.

Squashing bugs and tidying up the code base was an important part of this update. Multiple game classes have been refactored to make them easier to maintain and easier to mod. Height values have been updated to be more internally consistent and to match up with logical values in feet and inches. Dozens of minor bugs have been fixed, ranging from crashes triggered by random events to incorrect duty and policy requirements. A cheat menu has been added for patrons to allow them to speed through the game to newer content.

Let me know if you run into any problems!

Changelog (v0.50.1 to v0.51.1):

*CHANGES AND ADDITIONS*

- Refactored random_lists.rpy file to more accurately break up contents.

- Lists of names (first, last, male) are now class variables of the Person class.

- Key characters are now defined inside world_setup_characters.rpy

- Storyline character setup code refactored to be more clear.

- Character height refactored to be more internally consistent.

- Character height now described in feet/inches inside of the character details screen.

- Possible character opinion lists (normal and sexy) are stored as class variables inside of Person.

- Updated "Classical", "Punk", and "Pop" opinions to include "music" so they read more clearly inside of lists.

- Functions to check/compare breast sizes are now class functions of Person.

- Added several breast comparison functions (including checks for huge/tiny breasts, getting breasts by weight, etc.)

- Updated all existing calls to those breast comparisons to comply with the new interface.

- Hair colour functions are now class functions of Person.

- Eye colour functions are now class functions of Person.

- Refactored how random characters are generated. Should result in much more logically generated applicants when stacking recruitment requirements.

- Added new InstaPic/OnlyFanatics content for Jennifer.

- Jennifer's InstaPic content begins after she has helped you twice. Results in her making an InstaPic account.

- Second phase of Jennifer's new story content begins a few days after you have convinced her and Lily to take topless shots twice. Results in her making an OnlyFanatics account.

- Added event for helping Jennifer with her OnlyFanatics account; includes multiple branches.

- Added new event for Lily after you have helped Jennifer with her OnlyFanatics account. Results in her making an OnlyFanatics account.

- Added alternative triggers for all of the new events for situations where either character already has an InstaPic/OnlyFanatics account from other events/special training options.

- Levels of sex skill reduce energy cost from sex by 5% per level (truncated to integer value).

- Position class now responsible for calculating effective energy costs for both parties.

- Breast milk based serums now stack properly for identical designs.

Comments

I discovered that strippers aren't being replaced when you hire them, so made some changes to fix it. First, I had to create "store.strip_club_no_of_strippers", as that variable wasn't accessible in the Gabrielle blackmail route, and I'm not sure exactly why. I did this much earlier because the game otherwise breaks when you try to pursue the Gabrielle blackmail events. So that's the variable I'm using here, which I set to 4 elsewhere (I usually add code to smalltalk_person to do such things). In "world_setup_characters.rpy", I modified "create_random_stripper()" to this: def create_random_stripper(): a_stripper = create_random_person(sluttiness = renpy.random.randint(15,30), job = stripper_job) a_stripper.generate_home() if time_of_day == 3 or time_of_day == 4: strip_club.add_person(a_stripper) elif time_of_day == 0: a_stripper.home.add_person(a_stripper) else: downtown.add_person(a_stripper) return a_stripper This just prevents adding a stripper to the club in the middle of the day, instead placing them either in their home (early morning), or downtown. In "hiring_events.rpy", I modified "stripper_replace()" to this: def stripper_replace(the_person): # on_quit function called for strippers to make sure there's always somewone working at the club. Also removes them from the list of dancers #Note: Gabrielle is a special case and is manually added back into the list after she quits. if the_person in stripclub_strippers: stripclub_strippers.remove(the_person) min_strippers = store.strip_club_no_of_strippers if cousin in stripclub_strippers: min_strippers += 1 if len(stripclub_strippers) < min_strippers: create_random_stripper() I'm incrementing the minimum count if Gabrielle is working there, so there are always four strippers besides her. Finally, in "role_stripper.rpy" I changed "stripper_hire_accept()" to this: label stripper_hire_accept(the_person): if the_person.has_role(cousin_role): $special_stripper_leave(the_person) call stranger_hire_result(the_person) $ stripper_replace(the_person) if _return: mc.name "It's settled then. I'll see you at work." the_person "And I'll go call my boss and let him know I'm finished." the_person "I don't think he's going to be very happy to hear it..." else: if the_person.has_role(cousin_role): $special_stripper_hire(the_person) mc.name "On second thought... I think I'm going to have to wait a little before I can take you on." the_person "I can't just wait around doing nothing. Tell me when you actually have a position for me, then I'll quit." return This adds a call to "stripper_replace()", which is what was entirely missing, and prevented strippers from being replaced. Hopefully Patreon's horrible comment entry mechanism doesn't too badly mangle this.

Thanny

Anyone else having problems using the research traits cheat?

sb2017

The code makes it so it's more likely that she hates it (it's one of her common dislikes), but the Person generator makes it that only some set opinions are randomly chosen along with other completely random opinions. Long story short: Yes it's intentional, cause weighted RNG is still RNG.

Something that I've had to manually fix for many versions now are several serum selection screens, which don't scroll so become unusable when there are a lot of different serum types. serum_production_ui,rpy and serum_selection_ui.rpy come to mind as the ones which simply aren't working for large serum counts.

Thanny

I've returned to the game after not playing for a few months, and noticed that Gabrielle now loves small talk; is that intentional? She used to hate it.

MayoiSnail

You just need to make sure you put a girl in Marketing or work it yourself until you have a reach over 1000 (I like to go to 5k-10k to be extra future-proof) instead of the 100 you begin with. Then you should be good until you hire Alexia, assuming you get her when she's available. Try to fill every contract you can for extra boosts in income, since they're not affected by aspect demand and don't rush higher research tiers until you have a solid product at your current tier. Don't auto-sell unless your product is attention 0 or you've purchased enough attention reducing business policies to stay safe

Baarogue

it's also accessible in your Main Office at work

Baarogue

Access to cheats should be a new button in your characters bedroom

Dreamdayer

Just started playing this version, and it's way, way too hard to make money in the early game.

Thanny

The new position energy calculations are not used for picking a new position, so there are a lot of times when it says someone is too tired, but there actually is enough energy. Position.rpy line 156 elif mc.energy &lt; self.guy_energy or the_person.energy &lt; self.girl_energy: possible = False # One of them is too tired. should be: elif mc.energy &lt; self.calculate_energy_cost(mc) or the_person.energy &lt; self.calculate_energy_cost(the_person): possible = False # One of them is too tired. Also lines 221 - 229: elif mc.energy &lt; self.guy_energy and the_person.energy &lt; self.girl_energy: disable = True willingness_string += "\nYou're both too tired" elif mc.energy &lt; self.guy_energy: disable = True willingness_string += "\nYou're too tired" elif the_person.energy &lt; self.girl_energy: disable = True willingness_string += "\nShe's too tired" should be: elif mc.energy &lt; self.calculate_energy_cost(mc) and the_person.energy &lt; self.calculate_energy_cost(the_person): disable = True willingness_string += "\nYou're both too tired" elif mc.energy &lt; self.calculate_energy_cost(mc): disable = True willingness_string += "\nYou're too tired" elif the_person.energy &lt; self.calculate_energy_cost(the_person): disable = True willingness_string += "\nShe's too tired"

What level patron do you need to be to have access to the cheats and where would they be located?

Winged_Paragon

This is an issue for me as well as I've gotten to it and get this error every time. After a few updates I'm now in the habit of beginning a new game every update to accommodate code changes, so that's not the issue here, just not sure why it's not working, unless the assignment operator is incorrect? but it doesn't seem like that's the case, maybe as Mattias thought, it's an issue of scope and that variable should be instantiated later in the label or in a different label altogether, along with everything else at the club?

The issue with the special_stripper_hire() call is something I noted above, but I think the issue you caught Mattias is maybe if you haven't started a new game this update (or whenever the changes to how strippers are handled, I forget if it was this major revision or the last)? strip_club_no_of_strippers is instantiated in initialize_game_state() for the global data store in script.rpy and should be able to be manipulated wherever. I've actually not gotten to the Gabrielle stripper blackmail in recent games (been really slow), so haven't tested if this is an issue everyone might hit.

EDIT: I tried to simply set the variable value to 4 before it is incremented, gonna' try if it works. However, that unveiled another error, which I believe I have a proper fix for. In the file "role_cousin.rpy", line 792, the function special_stripper_hire() is incorrectly called with the job rather than the person as argument, i.e. "stripper_job" should be changed to "the_person". I'll hop in with another bug report: When talking to Gabrielle about seeing her at the club, the varialbe "strip_club_no_of_strippers" is not defined. It is defined in scripts.rpy, but maybe in the wrong scope? Full trace: I'm sorry, but an uncaught exception occurred. While running game code: File "game/script.rpy", line 261, in script call call talk_person(picked_option) from _call_talk_person File "game/script.rpy", line 382, in script call $ _return.call_action(the_person) File "game/game_roles/role_cousin.rpy", line 791, in script $ special_stripper_hire(stripper_job) File "game/game_roles/role_cousin.rpy", line 791, in $ special_stripper_hire(stripper_job) File "game/game_roles/role_cousin.rpy", line 124, in special_stripper_hire strip_club_no_of_strippers += 1 #Increase the list target to account for Gabrielle UnboundLocalError: local variable 'strip_club_no_of_strippers' referenced before assignment -- Full Traceback ------------------------------------------------------------ Full traceback: File "game/script.rpy", line 261, in script call call talk_person(picked_option) from _call_talk_person File "game/script.rpy", line 382, in script call $ _return.call_action(the_person) File "game/game_roles/role_cousin.rpy", line 791, in script $ special_stripper_hire(stripper_job) File "renpy/ast.py", line 923, in execute renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store) File "renpy/python.py", line 2235, in py_exec_bytecode exec(bytecode, globals, locals) File "game/game_roles/role_cousin.rpy", line 791, in $ special_stripper_hire(stripper_job) File "game/game_roles/role_cousin.rpy", line 124, in special_stripper_hire strip_club_no_of_strippers += 1 #Increase the list target to account for Gabrielle UnboundLocalError: local variable 'strip_club_no_of_strippers' referenced before assignment Windows-10-10.0.19041 Ren'Py 7.4.8.1895 Lab Rats 2 - Down to Business v0.51.1 Thu Apr 14 19:14:35 2022

Mattias Nordahl

Not really a reasonable situation, but thought I might bring it up. For REALLY high happiness values (like greater than 100 K, obviously I did some cheats and mods, and exxcessive numbers of serum applications), the get_red_heart for situational_sluttiness can hit the recursion cap for Python. I added a hard upper limit check (like 400 or so) for add_situational_slut amount to get around this. Not really a change needed, but just something I found. def add_situational_slut(self, source, amount, description = ""): ### CUSTOM ADDITION ### # Added to avoid issue with recursive add of hearts by capping situational slut if amount &gt; 400: amount = 400 ### END CUSTOM ADDITION ### self.situational_sluttiness[source] = (amount,description)

This is an opinion rather than a bug report. It may be better to not personalize the milky serums/breast milk. Right now if you have a dozen employee's you end up with a huge list of serums from only 2-3 lacation serum designs. It might be interesting to have that personalization, but my feeling is it's not worth the annoyance of huge lists when trying to mass produce via lactating serums and auto-milking. Instead, just have the milky trait/breast milk be a general "Breast Milk" rather than (the_person.title + "'s Breast Milk"). If there is a technical reason to have them separate, like this avoids some issue with merging the different sources, then fine it's not that much of an annoyance, but otherwise I'd rather have smaller lists.

Negative Love doesn't affect if the Flirt option is available for the phone menu (Mainly an issue for Gabrielle). Maybe copy the love condition from flirt_requirement to text_flirt_requirement.

Not so much a bug but maybe not right behavior. When changing duties, it does not dynamically update the number of active duties. So when you select to remove a duty you cannot add a duty to replace it. This means you cannot swap duties without taking 2 days. Right now, active duties behave differently from inactive duties that were just added when hitting the remove duty button. I don't know if this is intentionally to avoid problems with trying to update active duties within the screen, but I tried at least a quick and dirty method to get around this. I changed the calculation of used duty slots to subtract the duties being removed from the active duties and added duties: set_duties_screen.rpy lines 76, 135: len(the_person.duties)+len(add_duties) changed to len(the_person.duties)+len(add_duties)-len(remove_duties) It ends up looking a bit wonky as the removed duties stay visually in the active duties list, but it at least allows swapping duties and seems to update correctly after finishing changing duties. You just won't be able to add back the removed duties in one duty change session, which is pretty much fine for my purposes, but maybe not as robust as could be.

The random_infraction_generation for the infractions duties may have the out of uniform criteria wrong. is_wearing_uniform is True when they are in uniform correct? Maybe include should_wear_uniform like the logic in the LTE generator? Or use should_wear_uniform instead if we are generating infractions as long as there is a uniform assigned? _duty_definitions.rpy lines 365-366 if the_person.is_wearing_uniform(): potential_infractions.append(Infraction.out_of_uniform_factory()) should be?: if not ( person.should_wear_uniform() and person.is_wearing_uniform() ): potential_infractions.append(Infraction.out_of_uniform_factory())

Currently no scroll bars are available for the Serum Selection screen (like for giving a serum to someone, or assigning a serum for auto dosing). I think in serum_selection_ui.rpy the order of frame and viewport are out of order (just looking in comparison to serum_inventory_ui.rpy, that does have scrollbars). After swapping them the scroll bars are there. Also, the sizing for the frame and viewport might be out of order in serum_inventory_ui.rpy, xsize is smaller for the outer frame than the inner viewport (600 &gt; 610).

For the Supply duty "Alternate Payment Methods", it's actually possible to have sex skills high enough (with Greymarket as well, an 8 in both foreplay and oral will do it) to gain money from buying supplies. Might want to add a check to limit the cost factor to a 0 minimum or something. Maybe like this: _duty_definitions.rpy lines 15-26 def get_duty_supply_cost_modifier(the_person): cost_modifier = 1.0 if the_person.has_duty(greymarket_deals_duty): cost_modifier = 0.75 if the_person.has_duty(alternative_payment_duty): if the_person.effective_sluttiness() &gt;= 25: cost_modifier += -0.05*the_person.sex_skills["Foreplay"] if the_person.effective_sluttiness() &gt;= 50: cost_modifier += -0.05*the_person.sex_skills["Oral"] return cost_modifier changed to: def get_duty_supply_cost_modifier(the_person): cost_modifier = 1.0 if the_person.has_duty(greymarket_deals_duty): cost_modifier = 0.75 if the_person.has_duty(alternative_payment_duty): if the_person.effective_sluttiness() &gt;= 25: cost_modifier += -0.05*the_person.sex_skills["Foreplay"] if the_person.effective_sluttiness() &gt;= 50: cost_modifier += -0.05*the_person.sex_skills["Oral"] if cost_modifier &lt; 0: cost_modifier = 0 return cost_modifier

Issue with paying the mom nothing when hiring. role_mother_work.rpy line 1389 mom_convince_quit_label $ the_person.salary = calculate_base_salary() should be: $ the_person.salary = the_person.calculate_base_salary()

role_cousin.rpy line 791 cousin_blackmail_level_2_confront_label $ special_stripper_hire(stripper_job) should be $ special_stripper_hire(the_person)

Got to this version a bit late for bug fixing in the initial week. Here is an initial post for a list of things I found in the current version. The bug fixes are replies.

when i wait in the office I'm sorry, but an uncaught exception occurred. While running game code: File "game/script.rpy", line 264, in script call $ picked_option.call_action() File "game/general_actions/location_actions/business_actions.rpy", line 157, in script call call advance_time from _call_advance_time_3 File "game/script.rpy", line 406, in script python: File "game/script.rpy", line 408, in people.run_turn() #T File "game/major_game_classes/character_related/Person.rpy", line 1574, in run_turn a_role.run_turn(self) File "game/major_game_classes/game_logic/Role.rpy", line 83, in run_turn self.on_turn(the_person) File "game/game_roles/role_employee/role_employee.rpy", line 23, in employee_on_turn warning_message = the_person.title + " (" +mc.business.get_employee_title(the_person) + ") " + " is unhappy with her job and is considering quitting." TypeError: unsupported operand type(s) for +: 'NoneType' and 'unicode'

retchedegg

Could some lesbian stuff be added for the next version?

SuperSaiyaMan12


More Creators