Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

% 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.