Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

Transformation Dungeon

A In development dungeon crawler were you avoid (or actively pursue) transformations into various enemies. · By jakethebeest

You said I could write you some Pseudocode, so, here you are!

A topic by Dukeofbrittany created 46 days ago Views: 135 Replies: 8
Viewing posts 1 to 3
(1 edit)

Ok, since you gave me the go ahead, I started writing up my big pseudocode example on how the transformation system COULD work following it's overdo overhaul. The raw text file I have linked here, (I promise to have not knowingly attached malware),  is by no means complete. After two and a half hours of programming and just relearning how this all actually works myself, this was the result. 

So far, there is no actual TF speed calculation going on here, everything here so far is just me getting a bunch of stuff set up to get my example working in the first place, a mock-up for what causes the TF speed value to update and when, and finally, a proposal for how the TF priority system could be overhauled and how it would apply to to the overhauled TF system. It does not contain any TF speed algorithms, but considering this took about two and a half hours to cook up, hopefully I can get the whole thing written... hopefully about a week at the very longest, but I don't expect it to take that long, assuming nothing gets in my way and there's no significant bugs on my end.

I will say this, this has been, if nothing else, a refresshing change of pace to actually practice my programming skills, even if my training is for colledge level mathmatical operations.

-------

clear;

clc;

% Written by DukeofBrittany, 7-29-2024

% Theoretical plan for Transformation Dungeon mechanics

% First things first, understand that it has been a couple months since I last programed at all, and Octave/matlab format is ...unique, to put it one way.

% For example, the way it uses ';' is very unusual, as I am lead to beleive.

% so, half of this is me just doing it under te excuse of 'practice and review'.

% remember, all of this is intended to be hypothetical, and might not be representative of how it would actually work in gameplay.

% General order of operations:

% 1. Run TF speed timer.

% 2. Calculate priorities

% 3. set up base transformationspeed value

% 4.  compute new base transformation speed value

% 5. store that and also figure out wether or not there are any additional factors that need to be applied.

% 6. determine transformation rank useing priorities and found number.

% 7. apply effects of transformation rank.

% First, how and when should we update our TF speed value?

% I am thinking that it should attempt to update either when when their is ample reason to, such as death or a cursed item being updated, or after enough time has passed with no other stimuli.

% How I am going to model this is to perpose that we use an inturuptable 'for' loop.

% It will either update everything after 50 turns, or imidiately after one of several conditions are met.

% for sake of simplicity, and becuase I only know how to write code that can read one line at once and only do one thing at a time, I will also tie the natureal decay of the TF priority to this for now as well.

% So, I need to get those set up. Octave/matlab is very weird about when exactly it lets you redefine variables, so I am going to have to get a bit creative with things.

% (Hopefully, you are not haveing to jump through hoops like these, i would be suprised if you were.)

% I will just use three enemies for sake of argument and simplicity.

Bunny_priority=[0:0.1:100]; % How much influence one enemy is exerting, from 0 to 100, in increments of 0.1. This is NOT to be confused with a measure of your net transformation level.

Mouse_priority=[0:0.1:100];

Cat_priority=[0:0.1:100];

% and becuase Octave is weird like that, i'm going to predefine the priorities further to have an example to work with.

% basically, it's so I can refrence what I have them set as so I don't get confused later, and so you know where the inital consitions of the model are comeing from.

Cat_priority(331)

Mouse_priority(546)

Bunny_priority(159) %In different words, this code here does nothing except call the value stored at that location of the vector. It's redundant outside of me keeping track of numbers.

for F=1:50  %where F refers to the amount of turns passed since our inital condition.

  % Every turn, I will decay the amount of pririty of all enemies by a tiny bit, then check to see if anything inturupted the wait timer.

  % I will try to make this the last time I mention this, but Octave only saved the vector I establised inialy in lines 29-13. Technically, we are doing nothing here, and having to handle numbers manually. I am sure Unity dosent have these issues, and you are able to redefine variables as you plese.

  % [Enemy's_prioroty((F)]=(Enemy's_priority(Inital_test_value-F));

  [Cat_priority(F)]=(Cat_priority(331-F));

  [Mouse_priority(F)]=(Mouse_priority(546-F));

  [Bunny_priority(F)]=(Bunny_priority(159-F));

  %Cat_priority(F) %(I like to comment out my temporary, bad, and refrence code, instead of deleting it.)

  %Mouse_priority(F)

  %Bunny_priority(F) % I did encounter a weird bug at this step where, unsupriseigly, if you went below the vector range, Octave will call an error.

  %Weirdly, though, if the values got too low, but didin't leave the vector, it would start counting back up. Dunno what's up with that, let's just choose to ignore it.

  % It's stange, as Octave is predominantly for being a calculator, and this is how I was tuaght to use it. Anyway.

  % If (Death>=1 || Cursed_item_update >= 1 || TF_from_damage >= 1 || other_relavant_flag >= 1)

    % In the event that another thing happens that would nessesitate the TF speed value be updated, we would first apply the nessasary ajustment to the prioroty:

    % Example:

      % If we died to a Cat,

      % [Cat_priority(H)]=(Cat_priority(F+300)) && "All_Other_Priorities(H)"="All_Other_Priorities(F-50)"

      % Death I feel will raise the priority of the enemy you died too by a lot, and erode the priorites of the others a small amount.

    % Example:

      % If the Bunny ears entered phase three, I.E. it fully activated,

      % [Bunny_priority(H)]=(Bunny_priority(F+700)) && "All_Other_Priorities(H)"="All_Other_Priorities(F-200)"

    % Example:

       % You took damage from a mouse and rolled to get transformed,

       % [Mouse_priority(H)]=(Mouse_priority(F+30)) % No compensation from the others. This I expect to be going off a lot.

    % And then, we will forceably leave the for loop and move onto the next calculation.

end

% We will assume, for this example, that the for loop was completed without being inturrupted.

display("----")

Cat_priority(F)

Mouse_priority(F) % just to ensure that my numbers and calculation is working correctly.

Bunny_priority(F)

display("----")

% At this time, the priorities of each enemy is as follows, Cat=28, Mouse=49.5, and Bunny=10.8.

% If fully human and "cured", I.E. not experienceing an ongoing transformation, Any one enemy needs a priority of 25 or higher in order to start a transformation,

% The reason the threshold is at 25/100 is becuase the game will choose the transformation with the highest current priority, I want the various transformations to fight over the player, and there will be a minor TF speed penalty for having high priorities.

% and,, this is the only place the transformations have a hierarchy of any kind. Basically, if there is a tie, then the game will favor one over the other.

% Also, this algorythim here will also check the H value instead of the F value, in the event one of the inturrupt conditiond is set off.

%I kept things simple here, but hopefully, you can see that with every new enemy added to the game, you should be able to just build it out backwards, or maybe use a switch?

if (Cat_priority(F) >= 25 || Mouse_priority(F) >= 25 || Bunny_priority(F) >= 25)

  display("A Transformation is occuring!")

  if (Cat_priority(F)>=Mouse_priority(F) && Cat_priority(F)>=Bunny_priority(F) && Cat_priority(F)>=25)

    display("Cat TF active!") % I.E. set Cat as your current transformation.

  elseif (Mouse_priority(F)>=Bunny_priority(F) && Mouse_priority(F)>=25)

    display("Mouse TF active!")

  elseif Bunny_priority(F)>=25

    display("Bunny TF active!")

  else

    display("This condition should not be able to appear, but is included as a failsafe.")

   end

   % move on to TF speed calculation.

else

   display("No TF active...")

   % move onto TF speed calculation.

end

% assumeing that I set everything up correctly, this should recognise that both Cat and Mouse succeeded the check, but that Bunny failed.

% Then, it compares all the priority values against each other, and concluded that Mouse was the highest, which it is. In the event that the highest two prioritys were equal, cat would have been selected over mouse.

% But, at least on this scale test, you should be able to see how this priority system works, and hopefully you can see how it would be pretty easy to add new enemies to the system without much difficulties.

% Additionally, I hope you can see all the little ways you could ajust the present priorities for all the enemies useing these numbers.

% Like, maybe the biome could, depending on the enemy type, could apply passive multipliers to all priority gain and loss, (excludeing time decay), for how much it likes or dislikes the biome.

% For example, bunnies in the plains (or whatever it's refferd to in game) biome would increase all priority gain by 1.5 times, and reduce all priority loss by 0.8 times.

% However, that's beyond the scope of this project. Moveing onto the actual TF speed calculator finally... when I actually get it completed...

ALRIGHTY! I am back as promised with a heafty update! I have gotten the largest segment of the new system completed, that being the actual TF speed function and all of it's component parts, assembled and somehow working with seemingly no major issues on my end? (I still have no idea how I managed to get all this set up with no issues that took forever to work through. Maybe all that programming i did last quarter in college accounted for something after all?)

Anyway, I will also repost the first section that I already submitted as I know that I had added at least three lines of code to it, and I might have changed something in there as well, ( I don't recall).  What you should be able to see pretty clearly is that, even if you decide that you want all different numbers for your game in the end, the function that I have prepared, although undeniably daunting. should actually be pretty easy change and modify at your leisure! I hope you can also now see why I think we can consider replacing the priority system, if we are replacing the TF system.

With this, you should have all the tools you need to reverse engineer it and be able to play around with it in your own engine and programming style. My next goal is to finish all this work up with the section on your Transformation rank, which is way less complicated but will contain some extra fluff for you to consider. Then, I think I might try to reorganize all my code to take up less space, (you know, so it is not an essay written in comments.), and so that I can run some simulations to get a better idea of how it works and behaves over time and in a hypothetical gameplay scenario.

Let me know if you want me to send you a copy with all the comment code removed?

-----

clear;

clc;

% Written by DukeofBrittany, 7-25-2024 to 7-30-2024

% Theoretical plan for Transformation Dungeon mechanics

% First things first, understand that it has been a couple months since I last programed at all, and Octave/matlab format is ...unique, to put it one way.

% For example, the way it uses ';' is very unusual, as I am lead to beleive.

% so, half of this is me just doing it under te excuse of 'practice and review'.

% remember, all of this is intended to be hypothetical, and might not be representative of how it would actually work in gameplay.

% General order of operations:

% 1. Run TF speed timer.

% 2. Calculate priorities

% 3. set up base transformationspeed value

% 4.  compute new base transformation speed value

% 5. store that and also figure out wether or not there are any additional factors that need to be applied.

% 6. determine transformation rank useing priorities and found number.

% 7. apply effects of transformation rank.

% First, how and when should we update our TF speed value?

% I am thinking that it should attempt to update either when when their is ample reason to, such as death or a cursed item being updated, or after enough time has passed with no other stimuli.

% How I am going to model this is to perpose that we use an inturuptable 'for' loop.

% It will either update everything after 50 turns, or imidiately after one of several conditions are met.

% for sake of simplicity, and becuase I only know how to write code that can read one line at once and only do one thing at a time, I will also tie the natureal decay of the TF priority to this for now as well.

% So, I need to get those set up. Octave/matlab is very weird about when exactly it lets you redefine variables, so I am going to have to get a bit creative with things.

% (Hopefully, you are not haveing to jump through hoops like these, i would be suprised if you were.)

% I will just use three enemies for sake of argument and simplicity.

Bunny_priority=[0:0.1:100]; % How much influence one enemy is exerting, from 0 to 100, in increments of 0.1. This is NOT to be confused with a measure of your net transformation level.

Mouse_priority=[0:0.1:100];

Cat_priority=[0:0.1:100];

% and becuase Octave is weird like that, i'm going to predefine the priorities further to have an example to work with.

% basically, it's so I can refrence what I have them set as so I don't get confused later, and so you know where the inital consitions of the model are comeing from.

Cat_priority(331)

Mouse_priority(546)

Bunny_priority(159) %In different words, this code here does nothing except call the value stored at that location of the vector. It's redundant outside of me keeping track of numbers.

for F=1:50  %where F refers to the amount of turns passed since our inital condition.

  % Every turn, I will decay the amount of pririty of all enemies by a tiny bit, then check to see if anything inturupted the wait timer.

  % I will try to make this the last time I mention this, but Octave only saved the vector I establised inialy in lines 29-13. Technically, we are doing nothing here, and having to handle numbers manually. I am sure Unity dosent have these issues, and you are able to redefine variables as you plese.

  % [Enemy's_prioroty((F)]=(Enemy's_priority(Inital_test_value-F));

  [Cat_priority(F)]=(Cat_priority(331-F));

  [Mouse_priority(F)]=(Mouse_priority(546-F));

  [Bunny_priority(F)]=(Bunny_priority(159-F));

  %Cat_priority(F) %(I like to comment out my temporary, bad, and refrence code, instead of deleting it.)

  %Mouse_priority(F)

  %Bunny_priority(F) % I did encounter a weird bug at this step where, unsupriseigly, if you went below the vector range, Octave will call an error.

  %Weirdly, though, if the values got too low, but didin't leave the vector, it would start counting back up. Dunno what's up with that, let's just choose to ignore it.

  % It's stange, as Octave is predominantly for being a calculator, and this is how I was tuaght to use it. Anyway.

  % If (Death>=1 || Cursed_item_update >= 1 || TF_from_damage >= 1 || other_relavant_flag >= 1)

    % In the event that another thing happens that would nessesitate the TF speed value be updated, we would first apply the nessasary ajustment to the prioroty:

    % Example:

      % If we died to a Cat,

      % [Cat_priority(H)]=(Cat_priority(F+300)) && "All_Other_Priorities(H)"="All_Other_Priorities(F-50)"

      % Death I feel will raise the priority of the enemy you died too by a lot, and erode the priorites of the others a small amount.

    % Example:

      % If the Bunny ears entered phase three, I.E. it fully activated,

      % [Bunny_priority(H)]=(Bunny_priority(F+700)) && "All_Other_Priorities(H)"="All_Other_Priorities(F-200)"

    % Example:

       % You took damage from a mouse and rolled to get transformed,

       % [Mouse_priority(H)]=(Mouse_priority(F+30)) % No compensation from the others. This I expect to be going off a lot.

    % And then, we will forceably leave the for loop and move onto the next calculation.

    if (F==50)

      IdleB=0.25; % somethiing for later, don't worry about it.

    endif

end

% We will assume, for this example, that the for loop was completed without being inturrupted.

display("----")

Cat_priority(F)

Mouse_priority(F) % just to ensure that my numbers and calculation is working correctly.

Bunny_priority(F)

display("----")

% At this time, the priorities of each enemy is as follows, Cat=28, Mouse=49.5, and Bunny=10.8.

% If fully human and "cured", I.E. not experienceing an ongoing transformation, Any one enemy needs a priority of 25 or higher in order to start a transformation,

% The reason the threshold is at 25/100 is becuase the game will choose the transformation with the highest current priority, I want the various transformations to fight over the player, and there will be a minor TF speed penalty for having high priorities.

% and,, this is the only place the transformations have a hierarchy of any kind. Basically, if there is a tie, then the game will favor one over the other.

% Also, this algorythim here will also check the H value instead of the F value, in the event one of the inturrupt conditiond is set off.

%I kept things simple here, but hopefully, you can see that with every new enemy added to the game, you should be able to just build it out backwards, or maybe use a switch?

if (Cat_priority(F) >= 25 || Mouse_priority(F) >= 25 || Bunny_priority(F) >= 25)

  display("A Transformation is occuring!")

  if (Cat_priority(F)>=Mouse_priority(F) && Cat_priority(F)>=Bunny_priority(F) && Cat_priority(F)>=25)

    display("Cat TF active!") % I.E. set Cat as your current transformation.

  elseif (Mouse_priority(F)>=Bunny_priority(F) && Mouse_priority(F)>=25)

    display("Mouse TF active!")

  elseif Bunny_priority(F)>=25

    display("Bunny TF active!")

  else

    display("This condition should not be able to appear, but is included as a failsafe.")

   end

   % move on to TF speed calculation.

else

   display("No TF active...")

   % move onto TF speed calculation.

end

% assumeing that I set everything up correctly, this should recognise that both Cat and Mouse succeeded the check, but that Bunny failed.

% Then, it compares all the priority values against each other, and concluded that Mouse was the highest, which it is. In the event that the highest two prioritys were equal, cat would have been selected over mouse.

% But, at least on this scale test, you should be able to see how this priority system works, and hopefully you can see how it would be pretty easy to add new enemies to the system without much difficulties.

% Additionally, I hope you can see all the little ways you could ajust the present priorities for all the enemies useing these numbers.

% Like, maybe the biome could, depending on the enemy type, could apply passive multipliers to all priority gain and loss, (excludeing time decay), for how much it likes or dislikes the biome.

% For example, bunnies in the plains (or whatever it's refferd to in game) biome would increase all priority gain by 1.5 times, and reduce all priority loss by 0.8 times.

% However, that's beyond the scope of this project. Moveing onto the actual TF speed calculator finally...

% WWEW! Overstretched itch.io's character limit again! I'm really good at that!

% So again, Octave is weird and unusual about how it goes about setting independedt functions. You either have to save them as a seperate file and project with a seperate data type,

% or you have to make them an independedt function, which can be pretty hard to read at times.

% so, for this next part, I will be first showing you the whole final function first, as I will be setting it up as an independent function, then break it apart and explain it in chunks as I explain each component.

% I also have you know, that becuasse of how complicated setting these things up can be, I am also breaking things up in my code for ease of reading, and ease of programming.

% I'm sure I could compress all individual steps into one collossal independent function, then set up only its inital conditions, but I think its better for the both of us that I keep it loose for now, and calculate things in steps.

Transformation_speed_value=@(MoPV,SDoPV,HP_Diff,MP_Diff,Pp,Hunger_Diff,Rndm_Drift,RCB,IdleB,FHB,Ss) ((MoPV)+(-(SDoPV./4)+((sqrt(((HP_Diff).^2)+((MP_Diff).^2)+((Pp(1)+Pp(2)+Pp(3)+Pp(4)+Pp(5)).^2)+(Hunger_Diff).^2)+Rndm_Drift(1))./2)-RCB-IdleB-FHB).*Ss);

% So, yeah, theres... a lot going on in that deathstack of an ewuation. I get it. At the time of writeing this comment, I have half a mind to incorperate things a bit further, namely the whole block of "speed penalties", but I will decide as I go along.

% You may also notice that there's a few things absent from the formula all the same.

% The penalties from death and cursed objects, for example, I think are too strong so I think they should NOT get saved to the history of the TF speed value, and additionally will be applied later,

% Biome, I want that to primarilly inpact priority gain, to seperate it from hunger more, and impact the rank effects.

% As for temprature? Yeah, I don't even know how that works in the current build, so i'm disregarding it for now. I'm sure you can ficure out how to cram it in, somewhere. We have a very dynamic system already.

% anyway, we have a lot of component parts to disect as-is, so we should just start plugging away at them one by one. Starting with the two most important:

% the transformation's mean value. I think the baseline value of the transformation speed should be the adverage value of all of it's previous values. I'm thinking the last ten are a good place to start.

% First, to get most of it, we need it's vector of previous results. So, let's set that up and fill it with a bunch of sample data.

TF_value_results=zeros(10,1);

TF_value_results(1)=3.5;

TF_value_results(2)=3.5;

TF_value_results(3)=4.5;

TF_value_results(4)=5.7;

TF_value_results(5)=7.3;

TF_value_results(6)=5.9;

TF_value_results(7)=0.2;

TF_value_results(8)=11.0;

TF_value_results(9)=5.3;

TF_value_results(10)=4.6;

display(TF_value_results); %and now we have a vector of results. The mean of previous values is coulculated quite simply from this.

MoPV=@(TF_value_results) ((TF_value_results(1)+TF_value_results(2)+TF_value_results(3)+TF_value_results(4)+TF_value_results(5)+TF_value_results(6)+TF_value_results(7)+TF_value_results(8)+TF_value_results(9)+TF_value_results(10))./10);

[MoPV_result]=MoPV(TF_value_results);

display(MoPV_result); % In this case, the result was 4.75. so, ideally, with this being the base value, it will be pretty consistant in ignoreing outliars in the data, but trending in the direction of the more recent values.

% We then will add or subtract three more bits of data, subtracting out a reduced form of the standard deviation of these values from the expected defualt value, subtracting out some small and uncommon bonuses, and adding in all the extra active penalties.

% Starting with the Standard deviation, while I could use the in-built function for standard deviation, i'm going to chose to not becuase Unity might not have it, and I am going to be useing a variant form that is not the norm.

% Instead of useing the mean of our current data set, I am going to instead use the 'assumed adverage' version of the equation, i.e. a fixed value for our mean, being our defualt value of 3.5.

D=TF_value_results-3.5;

SDoPV=@(D) (sqrt(((sum(D.^2))./10)-((sum(D)./10).^2)));

[SDoPV_result]=SDoPV(D);

display(SDoPV_result);

% Here, and assumeing that I didin't make a mathmatical error, the result was 2.6534.

% Unless there was an issue in my formula that I and octave failed to catch, this should be giveing pretty reliable and consistant pressure for the TF speed value at all times.

% This is good, as it helps act as a direct compensator for the running adverage values. The higher your TF speed has been on adverage, the more this will try to bring it back down.

% the only issue I can see with it currently is that, if your adverage value is somehow below that of the defualt, it will continue to try to get it even lower as the finsl value has to be negative due to the square root involved. But, as this effect shouldn't be anywhere to the sane strength as with the higher values, this should be ok.

% Next, we have a much more complex yet mosT simple to understand metric which is the leniariesed form of all the little penalties you might be currently experienceing.

% It is comprised of four seperate metrics. Three of which are all pretty similar, and one of which is not. They are the differential of your HP, MP, and Hunger values, compared to your maximums, and a predetermined number.

% In my eyes, I think it should be the case that a lot of factors will affect your transformation speed; some by a lot, some, not very much. And, wherever possible, they should do so in a more interesting way then "yes or no".

% so, all the TF speed penalties, before being added to the function, should be squared and added together before getting the square root treatment.

% (It's a normal thing in colledge level math and physics. It's not worth explaining, just know that it keeps all the data leniar and consistent. Reduces errors and the impact a single outliar has. just roll with it.)

% The net result is that haveing a lot of high penalties will impact far more substantially, relative to the effect from all of them being low save one really high value.

% So, first, HP and MP. I am giveing them the same values in this example, but I think you can aregue that the effect of one could be higher or lower than the other.

% In this example, the impact they give on the final value should be largely neglegeable. I still imagine that the transformation would be more difficult to passively fight as you get weaker.

HP_Diff=@(current_HP,MAX_HP) (2-((2.*current_HP)./MAX_HP));

[HP_Diff_result]=HP_Diff(27,36);

display(HP_Diff_result); % 0.5

MP_Diff=@(current_MP,MAX_MP) (2-((2.*current_MP)./MAX_MP));

[MP_Diff_result]=MP_Diff(0,22);

display(MP_Diff_result); % 2.

% Here, I am just showing what I think often happens. Often, the player will be running around on low MP in the current build allo the time. Hopefully, a small penalty for doing this, plus a cooldown for Reduce Curse should put a stop to that.

% I'm going to run a very similar set up for hunger. It's going to reflect how it opperates in the current build though, and have a higher price than HP and MP.

Hunger_Diff=@(current_hunger,MAX_hunger) (3.0-((3.5.*current_hunger)./MAX_hunger));

[Hunger_Diff_result]=Hunger_Diff(27,100);

display(Hunger_Diff_result); % 2.055

% You may notice that, while the potential for hunger is a lot more than HP and MP, the minimum is actually less then 0. This is intentional. I think there should be a small window for having full or almost full hunger adds a minor bonus to the TF speed value.

% therefore, i'm going to also have an extra bit of code for the hunger, before it gets sent to the value.

if (Hunger_Diff_result<0)

  FHB=Hunger_Diff_result.*(-1);

  Hunger_Diff_result=0;

  display("not Hungry");

else

  FHB=0;

  display("I'm very hungry");

end

% and lastly, we get the weird one. The one that I think should actually be a bigger threat than hunger, relatively speaking. Priority level!

% Unlike the others, this one is generated in logical compariosons only. Unlike the others, this one can be not a problem at all, or... it can singlehandedly kill you.

% Why? becuase were dealing with something that is added to itself before betting squared and added to the other penalties.

% You may also notice that this one is an evil. don't worry about it.

if (Cat_priority(F) >= 95 || Mouse_priority(F) >= 95 || Bunny_priority(F) >= 95)

  display("Very Very High priority!!!!!"); % 16!!!

  Pp(5)=1;

  Pp(4)=1;

  Pp(3)=1.5;

  Pp(2)=1;

  Pp(1)=0.5;

elseif (Cat_priority(F) >= 90 || Mouse_priority(F) >= 90 || Bunny_priority(F) >= 90)

  display("Very High priority!!!") % 9

  Pp(5)=0;

  Pp(4)=1;

  Pp(3)=1.5;

  Pp(2)=1;

  Pp(1)=0.5;

elseif (Cat_priority(F) >= 80 || Mouse_priority(F) >= 80 || Bunny_priority(F) >= 80)

  display("High priority!") % 4

  Pp(5)=0;

  Pp(4)=0;

  Pp(3)=1.5;

  Pp(2)=1;

  Pp(1)=0.5;

elseif (Cat_priority(F) >= 60 || Mouse_priority(F) >= 60 || Bunny_priority(F) >= 60)

  display("Medium priority"); % 2.25

  Pp(5)=0;

  Pp(4)=0;

  Pp(3)=0;

  Pp(2)=1;

  Pp(1)=0.5;

elseif (Cat_priority(F) >= 40 || Mouse_priority(F) >= 40 || Bunny_priority(F) >= 40)

  display("Low priority");

  Pp(5)=0;

  Pp(4)=0;

  Pp(3)=0;

  Pp(2)=0;

  Pp(1)-0.5;

else

  display("Very Low priority");

  Pp(5)=0;

  Pp(4)=0;

  Pp(3)=0;

  Pp(2)=0;

  Pp(1)=0;

end

% and that is it for the penalties being applied. We're almost done, but we have a bouple more misalanious things to bring up first.

% We have a couple situational bonuses to include to the function, things that will lower your TF speed every recalculation in a more linear way, but are rather small.

% Like other factors that you can shove into the feild for the penalties, both thereand here i'm sure there's a whole ton of little things you could shove into both for little slight situations both positive and negative.

% At this point, we have alcually already set up two of them. The bonus for haveing a full belly, and the bonus for not haveing any TF stimuli for a time.

% Currently, for sake of simplicity I am haveing it be tied to the maximum time of the for loop at the top. This you can agrue that it could be split off into it's own seperate system. for now, it's here to act as an exrea reason to evaid battle, and to make the resting mechanic more useful.

% "If you aren't being exposed to anything that would cuase you to transform, then, your transformation will slowdown somewhat."

% The only other ones that I have are a small reduction that is applied for every recalculation when Reduce Curse is active:

Reduce_curse=0; % off

if (Reduce_curse==1)

  RCB=0.5;

  display("Reduce curse active");

else

  RCB=0;

  display("Reduce Curse inactive");

end

% as well as some random drift that is impossible to control. This is to keep the system from getting too stable, or evenunstable. Hopefully, a small amount of random ajustment either up or down will help the whole thing feel more 'alive' and 'dynamic.'

rng("shuffle");

Random_upper_bound=0.5;

Random_lower_bound=-0.5;

Rndm_Drift_result=(Random_upper_bound-Random_lower_bound).*rand(1000,1)+Random_lower_bound;

display(Rndm_Drift_result(1));

display(Rndm_Drift_result(2));

display(Rndm_Drift_result(3));

% and time for the very last thing here before we get to the actual number generation. It's time for the preallocated slot for that item I suggested earlier, the Strange Supressor.

% How it works in here is pretty simple. If it is on, it muliplys the total CHANGE of the formula, excludeing the base adverage of the value, by 0.95.

% if it was on, set Ss to 0.95. I am going to treat it as being off, so

Ss=1;

% and with that, assumeing there are no bugs with my code, I should be able to build the formula again in it's running mode, and it should give us our result!

[New_TF_speed]=Transformation_speed_value(MoPV_result,SDoPV_result,HP_Diff_result,MP_Diff_result,Pp,Hunger_Diff_result,Rndm_Drift_result,RCB,IdleB,FHB,Ss) % depending on how the random number generator was feeling, the results would range from around 5.5 to 5.9 for this exact set up of inital conditions.

% What the fuck, what do you mean all of my code worked correctly and exactly as expacted after only the second try? What do you mean I wrote everything correctly such that it had minimal bugs???

% This is actually such a weird feeling. When I did this for colledge, I would often be banging my head against a wall for a week over one single function for a project.

% A-anyway, uhhhh... yeah! That is the hardest part of the script all written up and functional!!!

% I will let you attempt to reverse engineer and play around with this on your own time. I am going to work on the ranking system and try to build a more robust simulation for this!

% see you in a few days, most likely.

(1 edit)

% Firstly, I forgot something.

% If you died recently, death will add a flat +5 to the New_TF_speed value independent of the main function. This is becuase I think saveing that drastic increase would be a bit unfair. This increase should linger for like 300 turns or so, and probbably decay to zero over that period.

% Similarly, cursed items in phase 3 will add an unsaved +7 to the TF speed the same way death does, and cursed items in phase 2, 3, or 4 that are permenantly equipped will add +0.5^2 to the big square root in the main function that will get saved.

% and now for the ranking system! While the generation of the internal number is ludicrously complicated, the rank itself is much less so, and should be very simple to understand.

display("----");

if (New_TF_speed <= 2) % I will use the terms "rate of transformation" or "TF%" to refer to the actual amount of transformation affcting the player.

  % Reminder for this rank, and all other ranks. The Strange Surpressor, when on, will multiply your per turn TF% by 0.95, even for the recession in this rank.

  % It also affects all priority gain and loss, and all instantanious TF% changes.

  display("Rank A Active");

  % Set per turn TF % for all body parts to -0.1%.

  % Additionally, the most transformed body part recives another -0.1% per turn.

  % Chance for transformation to infect ajacent body parts cured of the ongoing transformation is -1000%.

  % Set all priority gain factor to 1.25 times.

  % Set all priority loss factor to 0.8 times.

  % I think makeing priority more difficult to manage when their transformation is recceding will be useful in stopping the player from ending up in a situation where they become functionally invunerable from transformation.

  % Maybe you could imply the protagonist is feeling overconfidant and full of hubris that they stop paying attention to that?

  % If ( net_TF_level <= 25% and Rank_A == 1)

    % Disable Reduce_curse

    % So the player isin't wasteing MP on it for no reason.

  % end

elseif ((New_TF_speed >2 && New_TF_speed <= 3.5) || (New_TF_speed >2 && New_TF_speed <= 10 && (Cat_priority <= 29.9  && Mouse_priority <= 29.9  && Bunny_priority <= 29.9 )))

  display("Rank B Active");

  % Set per turn TF% to 0.

  % chance for transformation to infect new body parts is -50%.

  % chance for transformation to infect new body parts is -1000% when the overall transformation of a body part is <=80%.

  % Chance for transformation to infect new "special"/"hidden" bodyparts, such as tails and back-mounted wings for example, is -1000%.

  % all priority gain and loss is at normal levels.

  % If reduce curse is active, the player recives the Per turn TF% of rank A instead.

elseif (New_TF_speed >3.5 && New_TF_speed <= 7.5) % && (Cat_priority >= 30 || Mouse_priority >= 30 || Bunny_priority >= 30)

  % The extra priority check is there, at minimum, as extra insureance to make sure the game is not bugging out.

  % I however couldn't get it working?

  % I though to make the minimum priority to actually transform slightly higher than the flag's stand-in, becuase of how dangourous high priority is and becuase I thought, "Maybe you would think of how to use that in a cool way?"

  display("Rank C Active");

  % Set per turn TF% for all currently transforming body parts to +0.05%.

  % Selected at random, a currently transforming body part will recive an aditional +0.1% per turn. (The 'lucky' body part will also change every so often, regardless of if it got full transformed or cured.)

  % chance for transformation to infect new body parts is -50%.

  % chance for transformation to infect new body parts is -1000% when the overall transformation of a body part is <=80%.

  % all priority gain and loss is at normal levels.

  % If reduce curse is active, the player recives the Per turn TF% of rank A instead.

elseif (New_TF_speed >7.5 && New_TF_speed <= 10) % && (Cat_priority >= 30 || Mouse_priority >= 30 || Bunny_priority >= 30)

  display("Rank D Active");

  % Set per turn TF% for all currently transforming body parts to +0.15%.

  % Selected at random, a currently transforming body part will recive an aditional +0.3% per turn. (The 'lucky' body part will also change every so often, regardless of if it got full transformed or cured.)

  % chance for transformation to infect new body parts is -20%.

  % chance for transformation to infect new body parts is -1000% when the overall transformation of a body part is <= 50%.

  % all priority gain and loss is at normal levels.

  % If reduce curse is active, the player recives the Per turn TF% of rank C instead.

elseif (New_TF_speed > 10 && New_TF_speed <= 13)

    display("Rank E Active");

  % Set per turn TF% for all currently transforming body parts to +0.3%.

  % Selected at random, two currently transforming body parts will recive an aditional +0.3% per turn. (The 'lucky' body part will also change every so often, regardless of if it got full transformed or cured.)

  % chance for transformation to infect new body parts is -1000% when the overall transformation of a body part is <= 50%.

  % all priority gain is 1.1 times higher.

  % All priority loss is 1.1 times higher.

  % I like to imagine that, as your body gets more unsatbe and more unable to fight off the transformation, it become more succeptable to all transformative stimuli.

  % What I am concernd about at this point is that the player could easilly end up in a situation where they are perpetually stuck in a rut where, once theings get bad, the player pretty much can't do anything to regain control of the situation.

  % so I thought, maybe there are some small benifits to being at a high TF rate? To give the player a bit of risk and reward? Reward them for doing well in a bad situation?

  % therefore:

  % player hunger drains 10% slower.

  % the player recives an additional per turn HP regen of +0.05. (I like the idea that their body is transforming fast enough to essentially heal wounds by proxy!)

  % the player recives an additional per turn MP regen of +0.02.

  % If reduce curse is active, the player recives the Per turn TF% of rank C instead.

elseif (New_TF_speed > 13)

    display("Rank F Active");

  % Set per turn TF% for all currently transforming body parts to +0.5%.

  % Selected at random, two currently transforming body parts will recive an aditional +0.3% per turn. (The 'lucky' body part will also change every so often, regardless of if it got full transformed or cured.)

  % chance for transformation to infect new body parts is +20%.

  % chance for transformation to infect new body parts is -1000% when the overall transformation of a body part is <= 20%.

  % all priority gain is at 1.5 times.

  % all priority loss is at 1.25 times.

  % player hunger drains 10% slower.

  % the player recives an additional per turn HP regen of +0.05.

  % the player recives an additional per turn MP regen of +0.02.

  % If reduce curse is active, the player recives the Per turn TF% of rank D instead.

else

  display("This failsafe message should not appear");

end

-----------------------------------------

And, that is about everything I have thought out! Obviously, I couldn't go much further without having to reverse engineer your Body parts system which I think is... going a step too far I think, so I think this is a good place to stop! 

Hopefully, this all is good material to hep your game along, and I am curious how much this has done for you already. I might re-build this without all the comments to make a proper simulation to see how the numbers work out in a more realistic setting, but A, I think you are just as capable of doing that, and B, It might be good to let you figure out things and the actual values you want to work with from here. So, unless you ask otherwise, I think I will leave you too it!

Let me know about any other questions you might have, or if there is anything else that you would want me to do for you or your game before the end of September, or if you want to just generally chat. (i'm happy to just talk about things in general, too!) Like, how has the development been going, as well as your life! I hope my work and opinions hasn't been stressing you out at all, or if I was just being annoying, so sorry if I was. I am excited to see where your game goes in the future!

The last thing I will leave you with for now is this: When I first played your game, I was initially confused as to why you had a list of transformed body parts as opposed to a single TF tracker. But, if you had not guessed by now, I have decided that I actually like that system so much that... why don't we go even further with it? Aside from having some 'hidden'/'special' parts like tails and back mounted wings that are invisible until they are needed, why are hands and arms seperateated but legs are not? How about we split them into feet and legs? (Maybe some select animal paws would disable, or destroy, boots?) For the head, maybe ears and muzzle could be separate? For the body, maybe we could split the torso into waist, chest, and internal organs? … Again, maybe that's just going into the realms of the excessive, but the legs especially, when I considered it, I genuinely thought that maybe those should be split if the hands and arms are.

Anyway, I will leave you too it. Tell me what you think, if you want to! I hope this code framework helps, have a good day!

---------- 

Edit from like four hours later...

Welp, I realized, in my rush to get "the easiest part" finished, I completely forgot to include not one but two things, and have also decided that one of the things I put in there could maybe use a bit of clarification.

Clarification first. So, I mentioned that some of the really big TF speed penalties "won't get saved". Ok, what do I mean by that? Well, you know how I put ten possible previous TF speed values into a vector, and called that the previous values? Firstly, at the very beginning of a  run, all these values are filled with 3.5 so that the run can start stable and at the median value. And, after the big main function is all calculated and run, all the values currently in the vector are shuffled down by one, with the oldest one being deleted completely and the new value getting saved to the newest position in that vector. So, the result of the function is instantly saved to the history of your TF speed,  but still can get some extra changes to it after that point. Amd since those extra changes won't be put into the history vector, they are "unsaved".

As for what I forget, first, about Reduce Curse. I showed it secretly dropping your rank by one or two stages here, but That was merely one possible option. We can also have it give the player an independent -0.1% TF per turn for it's duration, or, have your TF value devided by three, (unsaved obviously), for its duration. There's a lot of possible solutions here, and I think they are all good. Regardless, I think reduce curse should also remove a bit of priority from all animals, I'm thinking (10*player_level*how_much_it_was_upcasted)-(10*TF rank.) With lower ranks being more unwilling to remove priority from Reduce Curse.

The other part I forgot is biome effect. Basically, it can operate similar to Reduce curse, just in the opposite way, where it increases or reduces priority gain and lossper animal based on the current biome, and will increase or decrease per turn TF% gain and loss based on animal. It's too complicated to correctly model here.

Developer

HI! Sorry about the late increadibally late reply. i saw the first post of this topic when it came out but i decided to wait until you finished the the tf speed stuff. however i realised that i wasn't subscribed to this topic. so i never noticed the new replies (you see i thought that you are automatically subscribed to any topic created on your own game. but i was wrong). i only noticed them like 2 days ago.

Why am i replying now instead of 2 days ago? because i realised that i didn't have many comments on your code until i properly implemented it on my own. i already had the TF priority code working but i needed to implement the TF speed functions. i still don't have the Rank system done but i feel i should respond first. i'm going to share with you my written code first as i feel it's the easiest way to comment on your code and then respond to everything else in a new reply. This is also my revenge for making me look through octave code for hours, but in seriousness i hope you can understand it.


The main Thing with the first class is that i wanted to generalise any priority stuff for every enemy. so i don't have to hard code in new values every time i want to add a new enemy. keep in mind that even though english is my only language i am bad at it, so some things will probably be misspelled. 

public class Transformation {

    public Enimies enemy;

    //this value will represent the total transformation across all limbs.

    public float overall;

    //get;private set; basically means this value is read only outside of this class.

    public float priority { get; private set; } = 0;

    public List<float[]> decay { get; private set; } = new List<float[]>();

    

    public Limb transforming;

    public List<Limb> transformed = new List<Limb>();

    //you can think of Static values as "global" values that apply to every transformation 

    //this is our beginning setup, setting every value to our medium of 3.5f

    public static List<float> prevtransformations = new List<float>{3.5f,3.5f,3.5f,3.5f,3.5f,3.5f,3.5f,3.5f,3.5f,3.5f};

    public static List<Transformation> alltransformations { get; private set; } = new List<Transformation>();

    public static float allprioritys { get; private set; } = 0f;

    public Transformation(Enimies newenemy) {

        enemy= newenemy;

        alltransformations.Add(this);

    }

    public static void sortpriorities() {

        //This sorts every transformation by their prority. in the case of a tie it will break with the dangerlevel

        //usefull because we can look at the first value to see which has the highest prority. 

        alltransformations.Sort((b,a) => {

            

            return (a.priority*100+a.enemy.dangerlevel).CompareTo(b.priority * 100 + b.enemy.dangerlevel);

        });

    }

    public void changepriority(float amounttoadd,float amounttoreduce=0,bool decayval=true,float decayspeed=1) {

        //We will force a range of 0 to 700. in your code i noitced that the range is set from 0 to 100. but i also see that you added +200 to the value

        //i didn't see a way that you delt with it so im clamping it here. 

        float val= Mathf.Clamp(priority + amounttoadd, 0, 700);

        //if we want prorities to decay based on turn i needed a way to keep track of multiple diffrent sources of decay. so we'll add it to a list

        if(decayval)

            decay.Add(new float[]{val-priority,decayspeed});

        //usefull to keep track of the total prority of every enemy

        allprioritys += val - priority;

        priority = val;

       

        if (amounttoreduce == 0)

            return;

       //if we died we want to reduce every enemy prority so this code deals with that 

        foreach(Transformation transformation in alltransformations) {

            if (transformation == this)

                continue;

        //we'll resursavily call this funciton to change every other enemy prority 

            transformation.changepriority(amounttoreduce*-1, 0,decayval,decayspeed*(amounttoreduce/amounttoadd));

        }

    }

    public static void decayall() {

        //we want to apply all our decay values once per turn. 

        foreach (Transformation transformation in alltransformations) {

            for(int j=0;j<transformation.decay.Count;j++) {

                float[] thisdecay = transformation.decay[j];

                //our decay may be negitive so we want to deal with each case seperatily

                //fun fact: a decay speed that is negitive will never go away. 

                //So if i ever implement that wolfs bane weapon we can give you a constant wolf priority. 

                if (thisdecay[0] > 0) {

                    transformation.changepriority(thisdecay[1] * -1, 0, false);

                    thisdecay[0] -= thisdecay[1];

                    if (thisdecay[0] < 0) {

                        transformation.decay.RemoveAt(j);

                        j--;

                    }

                }

                else {

                    transformation.changepriority(thisdecay[1] * -1, 0, false);

                    thisdecay[0] += thisdecay[1];

                    if (thisdecay[0] > 0) {

                        transformation.decay.RemoveAt(j);

                        j--;

                    }

                }

            }

        }

        }

}

Here is the function that determines the TFspeed without the ranking. 

private float calculatetransformationspeed(Transformation trans) {

        //This is all saved prev transfortation speed values. we are getting the count just incase i want to change how many total values we are saving

        int count = Transformation.prevtransformations.Count;

        

        //Unity to my knowladge doesn't have a equivanlet of the sum function, so we need to make it with a for loop

        //we define all our varables that will use it here so we only have to loop through the prevtransformation array once

        float MoPV = 0;

        float D = 0;

        float d = 0;

        foreach (float number in Transformation.prevtransformations) {

            MoPV += number;

            D += Mathf.Pow(number - 3.5f, 2);

            d += number - 3.5f;

        }

        MoPV /= count;

        float SDoPV = Mathf.Sqrt(D / count) - Mathf.Pow(d / count, 2);

        float HpDiff = 2 - (2 * hp / hpmax);

        float MpDiff = 2 - (2 * mp / mpmax);

        float HungerDiff = 3 - (3.5f * Food_system.instance.hunger / Food_system.instance.maxhunger);

        float FHB = (HungerDiff > 0) ? HungerDiff * -1 : 0;

        HungerDiff*=(HungerDiff > 0) ? 0:1;

        float Pp;

        if (trans.priority / 700 > 0.95f)

            Pp = 5;

        else if (trans.priority / 700 > 0.90f)

            Pp = 4;

        else if (trans.priority / 700 > 0.80f)

            Pp = 3;

        else if (trans.priority / 700 > 0.60f)

            Pp = 1.5f;

        else if (trans.priority / 700 > 0.40f)

            Pp = .5f;

        else

            Pp = 0;

        //I don't have reduce curse stuff set up just yet so we'll skip it Same with Ss.

        //Random.value just gets a random value between 0 and 1

        float rand = Random.value - 0.5f;

        //i think this is the most important change. we wont save the effect of the avrage value to our saved values

        //if we did the value will drift towerds positive or negitive infinity. 

        float Tfspeed = ((Mathf.Sqrt(Mathf.Pow(HpDiff,2)+Mathf.Pow(MpDiff,2)+Mathf.Pow(Pp,2)+Mathf.Pow(HungerDiff,2))+rand)/2)-FHB;

        //we'll remove the first value and add to the end of the array to save it 

        Transformation.prevtransformations.RemoveAt(0);

        Transformation.prevtransformations.Add(Tfspeed);

        Tfspeed += MoPV + (SDoPV * -0.25f);

        print(Tfspeed);

        return Tfspeed;

    }

Developer

As for the other things. The body part system is being reworked as well and was thing i was working on when before i noticed these replies. Alot of the decisions  on it was made because of the old armor system. because armor used to only affect one body part having more of them would make each piece of armor more worthless. with the new coverage system we can experiment a lot more with new body parts. though i will probably keep the human total at 10 body parts. 

Unless you are up for the coding challenge all this is more than enough. This has honestly been a huge help. and yeah i'll probably end up tweaking the values a bunch until the end of time. so a simulation would probably get out of date.  and i have ways of testing these values.  

Again thank you for this! i can easily expand this to incorporate things like the environmental system and anything else i decide will influence transformation speed. something that i kinda been needing. 

No these opinions haven't been stressing me out at all. i think about this game constantly as it and i'm always looking to improve it. also don't worry about annoying me at all i always look forward to feedback on my game, as otherwise i feel like developing to no one. hell i directly asked for this. I'm glad that you like my game enough to tell me how to improve it.

But if you want to just have a conversation either game related or non game related. i have a discord. (I should probably make a server for this game but i haven't yet.). but you can DM me if you want to. Username Pathfinder @path_finder1

Keep in mind that i am not the most social person in the world and probably won't DM you first. but i'll gladly hold a conversation.

But either way Thank you so much for this! and i hope you have a nice day.

Ha! Yeah, I did warn you that, while technically C++, Matlab/Octave format, to my knowledge is pretty cursed and bizarre compared to most programing languages, due to the fact they are meant to be calculators first, and not... you know, things to build games with; and also, if my suspicions are correct, I think their formats have barely changed since THE EARLY 1990's!!! They have just been expanded massively over time. I mean, yeah, I am really glad I had to learn this for college, but, yeah, I dunno how helpful it will be in learning any other sort of programming. Over a week ago, when you said "Oh, sure, I think I will be able to figure out how to read Octave code easy peasy!", I genuinely did a double take. So here we are now, me just having to assume that your programming ability is  more sophisticated than mine, and just taking a blind guess that 'float' must be a data type akin to 'byte' and 'int'. ah well.

Anyway, the thing I am most curious about is what you actually think, on a purely objective level, about my suggestions for radically reworking priority, and using stuff like current HP and MP levels as factors for the TF speed calculations? I felt like the way the priority system worked currently with some enemies always having final say was actually at odds with the game's mechanics and overall spirit, which is why I wanted to make it much more about "What are you being exposed to currently? What is currently the thing you are having the most difficulty dealing with? Do you have a cursed item? If so, then they should have their way with you, even if they are 'weaker' than the other enemies." I think another justification is this: I don't know what your zoo looks like, but I have like three-five mice, bunnies, kobolds, and bats each, and at least five wolves. So far, so ok. And then... I have about twenty cats and it took about three hours of deliberate grinding to get a single snake. I still have a single snake, because wolves are just more omnipresent than snakes at all times. and cats just have zero chill in general and are really good at overwriting bunnies, mice, and kobolds. Cats also have zero chill, and have zero chill. Did I mention that cat's have zero chill and are impossible to deal with if you have no equipment?

I can say that with the priority, what I was trying to do, because this is Octave were talking about that is all about being a calculator first, was actually have it contain 1000 data points evenly distributed across a range from 0 to 100.  In layman's terms, in my code Mouse_priority(555) refers to the data point contained at the 555'th point on the vector... being 55.5. The actual effect of this is that I was originally going to model it as a percent so "+200 to Mouse_priority(555)" would mean that the priority of mice would change from the point (555) or 55.5% to (755), or 75.5%. So I don't think you would be surprised to learn that about three hours in I released, "You know what? That's dumb. Why did I make a number only to divide it by ten invisibly? I should fix that... But i'm already this far and i'm too lazy, so it shall stay." So, all I actually did was remove a comment about the percent and just ignored the fact I did it like that entirely. 

And at the end of the day, I did want to actually apply all my college training onto SOMETHING, which I admit is half the reason I made this so intricate, beyond just thinking it would make for a very dynamic system.

Developer

haha, yeah it just occurred to me that for someone who isn't familiar with C like programming languages my code would look like a foreign language. especially when im messing around with OOP stuff in my implantation.  your right that a float is a data type and basically means a number with a decimal. But yeah reading octave was still weird and not the most intuitive thing. but guessing and hoping that i am right usually works so that's what i went with. but like i said the fundamentals are the same. adding 2 numbers usually adds both values together. except apparently not with the vectors.

For my General opinion on the system i touched on it in my second post (i have a feeling you didn't see it, its posted as a reply to my own post. if you did disregard me entirely). but to reiterate i like the system in concept. i still need to implement the full system so i play around with the values to make sure it feels right but having multiple different factors affecting the transformation speed is neat. i hope that for player communication this system makes sense, hopefully we can just say (your general well being is affecting your transformation speed). but thats my only real concern with the system. again i might tweak the values a bunch but that is kinda my job. I've been wanting a more complicated TF system which is why i constantly say that i'll rework it, but never finding a good way to do it. so this gave me good motivation to change it.

Also i don't think you mentioned it but how did you feel about the cats and their level of chill? yeah fair enough i will see about toning them down. 

About the octave data point thing. that's weird. i suppose that makes sense but i feel that would be strange if you wanted to add 2 data sets together. but either way this mostly speaks to my unfamiliarity to this language.

But yeah, i am very glad that you wrote this. both for the help and seeing someone who seems generally interested in my game is pretty cool. So yeah thank you!  

First, I will try to keep this brief because I do have other things that I need to do today.

second, you probably don't have to respond to this. You are still welcome too if you want, of course.

So, I have gotten a bit more opportunity to play your game since the last patch, where you fixed the whole "You forgot to tell individual body parts to start transforming again." Well, I can confirm, it is fixed! So... now that your game is working as intended, I can confirm that a new problem has arisen, one that I am unsurprised to find. 

Now that your body parts are always transforming again,  the game is now way too difficult. You can spend all of your MP available on using reduce curse, and it will barely buy you any time at all. I am fine with a more difficult experience, even if high difficulty games and roguelikes are not my specialty, but once you start transforming it is pretty much impossible to not lose eventually.

Don't get me wrong.

I understand that this is the point of the game, I get that, I am just finding it really difficult to even stand a chance. 

So on one hand, I think the big Body part, priority, and TF speed system overhaul is coming at the perfect time to help mitigate that. hopefully, the end result of this is that the game is a bit easier, especially on the lower floors.

The minor suggestions that I have are this: You have the logic that has your transformation "infect" adjacent body parts, presumably as the first reaches higher overall values. You also, understandably, tell a body part to stop transforming once it is fully changed. Well, because I am pretty sure this is not the case already; What if similar logic was applied when a body part's level of transformation was dropped to 0? I think how the system currently works is that for a body part that has been infected with the transformation, the transformation will continue to progress for that body part even if it's own transformation has been reduced to zero, as long as your over all transformation has not been "cured". In  other words, while the game will infect you a body part at a time, it will only stop transforming you if you have been completely cured. What about allowing individual body parts to be cured? If you manage to completely cure a body part even if the overall transformation has not, that body part will need to get reinfected in order to progress again? I think cursed equipment in particular could make excellent use of this, to further the idea that they are the source of your current transformation, and that you are trying to contain their influence.

Next, I think you could consider having the game's intended difficulty paced out over a longer period of time. I think what you could do is have size of the next floor increase less than it currently does, and similarly have the enemy spawn odds spread out a bit more as well: like, mice and bunnies spawn on a couple more floors, cats can't spawn on the first floor but have a low chance of spawning even on higher floors, kobolds too, make it so that past floor six you have more to engage with beyond just bats and wolves. And, I think the first couple floors could be just a bit easier to survive in in-general.

As for cat's themselves, I really don't want to nerf them too much, but, they really are the cuase of 95% of game overs. So, I think they could be made like, a lot more rare on the first floor, and have their attack dropped by one or two points. I still think they should be threatening, but for an enemy that is basically the most common cuase of death in this game due to how far away they can see you and the fact they will never leave you alone.