Here is a remodeled version of the game core, relating to the development and use of the serum.
Although it will be mostly useful for those who create add-ons to the game on their own, it also fixes some bugs in the existing version of the game.
The reason for its creation is that the original version of the game from Vren, when saving, memorizes many things that shouldn't be saved because they are constants.
And if we change them in the program code of the game, these changes have no effect after loading the saved game.
For this reason, it was quite difficult to add new serum traits to the game.
In order to be able to add them, the game developers created SerumTraitMod.
This mod is quite workable, but it did not eliminate many problems, and therefore it is impossible to pass the game, each time saving and loading saves without using cheat mods.
The new kernel allows to eliminate this problem, and supports the work of already saved games.
If you play with Pen'Py SDK, you just need to unpack the archive into the folder with the game, replacing the existing files. Base Beta version of the kernel is from 2023.12.11.
The following will outline information for those who make additions to the game on their own.
To create a new serum trait you need to either in a new file or in an existing file, write the following lines:
<name_trait> = <"Displayed Serum Name">: my_new_serum_trait = "My New Trait"
Naturally, the variable name must be unique, just like the serum name. If you use an already existing name, it may cause errors in the game, and to give an identical already existing displayed name, you will not allow the parser, giving an error message and stopping the execution of the program.
Next, you should describe the functions on_apply, on_remove, on_turn, on_day, if you intend to use them. You should not give them unique names, because they are usually not used and only clutter the namespace.
It is enough to describe a function once, before calling the class constructor, and then create a function with the same name (but with a different code), because the reference to the previously written function will be saved in the object attribute.
def on_apply(person, design, effect, add_to_log):
____<function code>
I chose not to create copies of the SerumDesign object each time I gave the drug to the girls, because that takes up a lot of memory.
Instead, a new instance of the SerumPreparate class is added to the girls with only a few attributes: a reference to the original SerumDesign object, the number of remaining moves of the serum's action, and a list of several lists, originally and usually consisting of a reference to the SerumTrait object.
The run_on_#### functions take as arguments a reference to the source SerumDesign object (design), and a list containing a reference to the source SerumTrait object (effect), since the game already has serums that have parameters that change as a result of their use.
If a function needs to save any data for later transfer to another function, the "effect" parameter is used as a stack, for example with effect.append() in on_apply and effect[-1] effect[-2] e.t.c. in on_remove.
Now instead of the SerumTrait class, the STBDDS class is used when adding a serum trait to the game. # (Serum Trait Base Default Data Store).
Giving a name to the created object is pointless.
The names passed in when the object is created are the same as those used when the SerumTrait objects were created.
STBDDS(name = my_new_serum_trait, desc = "This is a new serum trait", e.t.c
The variable we set at the beginning of the creation of a new serum trait should be passed as the name, because it allows us to avoid misprints and, of course, to use it later, if necessary.
Among the parameters that are passed when creating a whey trait we include "triggers" - a string, a list, or a logical True value.
This is to make certain traits in the scenario available or unavailable for research or use at a certain point in the game. Previously, this was done with:
list_of_traits.append(some_trait)
some_trait.tier = n
then the command is given here
enable_trait(some_trait)
or
disable_trait(some_trait)
respectively, instead of
if some_trait in list_of_traits:
is used
if trait_enabled(some_trait):
or
if trait_disabled(some_trait):
If we pass True as "triggers", triggers accepts as a value a list consisting of the trait name.
However, it is possible to set another value common to multiple traits to "enable" them with a single command:
traits_triggers_list.append(some_common_value)
Or we can set a list of several values, if several conditions are required to activate a trait.
We also introduced the "Reserchable" parameter - it determines whether a trait is explorable, and whether a SerumTrait object corresponding to it should be created.
The SerumTraitBlueprint and side effects traits are not explorable.
In fact, no other actions are necessary to make the serum trait in the game.
Parameters equal to default parameters are ignored when creating an object of STBDDS class and class variables are used instead.
STBDDS objects are created each time the game is launched and cannot be changed.
They are stored in the STBDDS.traits class dictionary.
When loading a saved game, the dict_of_traits dictionary is checked for SerumTrait objects corresponding to STBDDS objects - both are found by the key <name_trait>, which is specified in the description of the serum (as described earlier).
This variable can be used to get a SerumTrait object or an STBDDS object at any time, if the existence of a SerumTrait object is not assumed:
get_trait(some_trait:string|SerumTrait|STBDDS)->SerumTrait|STBDDS|None
The SerumTrait object contains only a couple variables: "base"&"progress" are actually the key name and the state in the study of this trait.
All other values are obtained by methods from the base object STBDDS and mathematical calculation.
However, it is possible to set values for the attributes of the SerumTrait object during the game that differ from the constants obtained from STBDDS.
When loading a saved game of the previous version, the program processes the objects contained in list_of_traits and mc.business.blueprinted_traits, and changes the state of research for the created new set of traits.
SerumDesign objects are also processed, both in mc.business.serum_design and in segum_effects of each girl, and references to the previous SerumTraits objects in them are replaced with new ones.
However, 100% guarantee in the absence of any errors cannot be given yet, and I would like you to test this kernel.
P. S. I just found two error. Tomorrow I will send two corrected files.