Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redo instability: per-tree and static with mutatedness #72402

Merged

Conversation

anoobindisguise
Copy link
Contributor

@anoobindisguise anoobindisguise commented Mar 15, 2024

Summary

Balance "Instability no longer accumulates or decreases; it depends on how many mutations you have, and how many are outside of your current tree"

Purpose of change

Instability was a broken mechanic. It encouraged waiting around doing nothing for long periods of time so that it can decrease, and meant you effectively had a 0% chance of ever getting bad mutations because you always could stay within the safe bounds of instability. Further, it led to "feels-bad moments" such as getting punished for getting a negative mutation (which gives you more instability on top of already being bad) or getting punished for your tree swapping its mutations around (for example, Chimera would repeatedly swap its type of tail, effectively durdling around and doing nothing but accumulating instability). All these things combined, it was in need of overhaul.

Describe the solution

  • Instability, the vitamin, no longer exists. Your "instability" is a fixed number that depends on how many mutations you have, and also depends on your tree. Mutagenic Slurry no longer decays into Instability and the Instability vitamin decreases at a rate of 1/s for obsoletion purposes.
  • Instability is calculated for a given tree. For each mutation you have that can be found in that tree, instability is increased by 1. For each mutation you have that isn't in that tree, it is increased by 2. For example if you had STR_UP and were mutating into Alpha, you would have +1 instability. If you have Feline Ears and were mutating into Alpha, you'd have +2 instability. But if you had Feline Ears and were mutating into Cat, that would also just be +1 instability. This means you can make cross tree mutants, but will have an easier time doing so if the trees are very similar (for example, mixing Mouse and Rabbit is easier than mixing Mouse and Plant, resulting in fewer overall negative mutations)
  • Instability does NOT count any negative mutations, and does NOT count any starting traits, even if those are theoretically mutable. Thus you are advantaged for going into a tree that matches your arrangement of starting traits, and will not be "punished" for accumulating bad mutations. Bad mutations are the risk you take, but don't compound that risk any more.
  • Your instability number is compared against the total number of non-bad mutations in a given tree. For example Alpha has 21, and Trog has 28. So if you had for example STR_UP and STR_UP_2, which are both in Alpha and Trog, your next mutation in Alpha is slightly more likely to be bad than your next mutation in Trog.
  • The exact chance of getting a bad mutation instead of a good one is (your instability number multiplied by 0.5) / (the total non bad in a given tree) - so with an instability score of 2, you have a 1/21 chance of bad mutation in Alpha and a 1/28 chance of bad in Trog. This means that while bigger trees will give you more total chances to get a bad mutation (since you have to roll more times to get all the good ones) the odds of getting a bad mutation increase slower. At the final good mutation in the tree, you have about a 50/50 chance of getting a bad mutation instead of that final good one.
  • The absolute worst chances you can get, which will only be possible by mixing trees heavily, is 0.67; you'll never have worse than 2/3 odds of your mutation being bad.
  • Robust Genetics lets you ignore the out-of-tree penalty. Instead any given mutation is worth 1 point of instability, instead of possibly double.
  • This does nothing to change the way "good" mutations can choose a "bad" mutation as a prerequisite. Your actual odds of the mutation being good/bad are a little more skewed in favor of them being bad than the raw numbers above.
  • You cannot naturally decrease your instability with time. Once you have a mutation, its instability is locked in. The only way to reduce your instability is to use purifier, which reduces your mutation count and thus your instability.
  • True random mutations are still true random, but will influence your instability score for targeted mutations. Likewise although raw mutagen (the slurry kind) no longer gives instability vitamin, it still effectively makes you an unstable mutant because it's giving you muts from every category which means you're likely getting out-of-tree penalties constantly.
  • Your instability is no longer "player-visible". You get no feedback about how unstable you are; I think this is probably acceptable given the information presented was already useless unless you code-dove, and the mnemonic of "more mutations = riskier mutations" is a simple enough way to understand the system without a status effect telling you that you're in danger of bad muts.

Describe alternatives you've considered

I made an edit to mutation_height() making it a const in order to be able to call it in my function. This doesn't appear to do any harm anywhere but it's worth mentioning.
I also made roll_bad_mutation() take the mutation tree in question as an argument, since there's no way to make the instability depend on the tree otherwise. I haven't seen any areas where this causes a problem and there aren't any compiler errors so I think it's probably fine, but again I figure it's worth mentioning that I'm fucking with already written stuff a bit.

Testing

I cloned and compiled my repo locally.

  • I created a tester character with some starting traits. I added debug traits for testing purposes. Their starting instability was 0.
  • I used mutagen and watched my instability tick up as I mutated. I have the debug menu reporting the exact chance of getting a bad mutation so I got to see that creep up too.
  • I then swapped categories and saw that it had a different number of non-bad mutations and also that my raw instability score was higher in that category, because many of my mutations were outside of it.
  • Then I used purifier and watched my instability decrease back to zero as I purified all of my mutations.

Debug screenies of a char with 9 trog mutations:
test1b
test1a

The old instability test was no longer valid, so I wrote a new one that should go through some steps and confirm that things are working the way I wanted them to. The test is possibly a little less robust since it's no longer using the game's natural mutation process, only checking the odds that process would use; if that's a problem I can try to take another look at it. I'm a little unfamiliar with the test-writing process.

Additional context

@github-actions github-actions bot added [JSON] Changes (can be) made in JSON Mutations / Traits / Professions/ Hobbies Mutations / Traits / Professions/ Hobbies Code: Tests Measurement, self-control, statistics, balancing. [C++] Changes (can be) made in C++. Previously named `Code` <Bugfix> This is a fix for a bug (or closes open issue) <Enhancement / Feature> New features, or enhancements on existing Code: Infrastructure / Style / Static Analysis Code internal infrastructure and style Game: Balance Balancing of (existing) in-game features. Info / User Interface Game - player communication, menus, etc. astyled astyled PR, label is assigned by github actions json-styled JSON lint passed, label assigned by github actions labels Mar 15, 2024
@Vaskritaya
Copy link
Contributor

Having read the PR description, this is very intuitive to understand in my opinion. The more you fuck up your genes, the more your genes are fucked up. Enormous step up from the awkward vitamin mechanic that needs much more explanation for a considerably worse gameplay experience.

@Venera3
Copy link
Member

Venera3 commented Mar 15, 2024

Pretty good way of handling it, though I'd differentiate between traits depending on invasivity for the calculations - either vitamin cost or base points, where obviously the former is underutilized outside of limb stuff and the latter is inconsistent.

Also, do we need Robust Genetics in the first place? It has been flipping between "basically worthless" and "indispensible" depending on personal taste (and savescumming rate), and it just serves as a soft opt-out on a system we want to have.

@Standing-Storm
Copy link
Contributor

Standing-Storm commented Mar 15, 2024

Is there any method that in-repo mods can hook into for changing the effective instability?

@RedMisao
Copy link
Contributor

This is much more intuitive than how mutations work atm.

@anoobindisguise
Copy link
Contributor Author

Is there any method that in-repo mods can hook into for changing the effective instability?

right now there's basically no interaction with the JSON. that's one weakness of my implementation. I'm not sure how best to do that though.

@lapis413
Copy link

Perhaps Robust Genetics could be tweaked somehow so it's more effective at very high instability rather than low? This system seems excellent for single tree mutation characters, but I worry a little about how it plays out when you're doing heavy tree mixing.

Robust genetics could be the tool you take if you intend to do some real immersion blending on your genome, rather than just making early mutations a little more consistent. Though I'm unsure how that would play with it being in several mutation trees; maybe it deserves to be a starting trait only.

@carlarctg
Copy link
Contributor

Robust Genetics is too wishy-washy to be a starting trait methinks. We want our characters to be RP-focused now, yeah? I always enjoy mutating, so what, do I always take it? If I don't take it it feels like I'm arbitrarily handicapping myself. If I do take it it feels like I'm arbitrarily giving myself a positive handicap.

With Vitamin Bullshit I always took it because that system isn't fun, but now that dilemma will happen again. I think it should be made a Medical mutation- that's the mutagen addicts, after all. Makes sense the DNA is more robust there.

@CleverRaven CleverRaven deleted a comment from Alm999 Mar 15, 2024
@I-am-Erk
Copy link
Member

I love how you're taking this and I think this is definitely the right way to work it.

  • I think it might be a good idea to somewhat reduce the randomness, ie. at some point we might want it to be inevitable that you get a negative mutation. By capping the rate at 2/3, there's an incentive to keep trying again and again, but if the rate caps at 1.0, eventually you just have to suck up and accept a negative mutation.
  • I'm not sure we need to keep robust genetics at all in this system but if we do, it might be a trait that allows you to mix mutation lines more readily instead of something that reduces instability at a flat rate. Basically, it becomes the mutation "multiclass" option.

@anoobindisguise
Copy link
Contributor Author

  • I think it might be a good idea to somewhat reduce the randomness, ie. at some point we might want it to be inevitable that you get a negative mutation. By capping the rate at 2/3, there's an incentive to keep trying again and again, but if the rate caps at 1.0, eventually you just have to suck up and accept a negative mutation.

If I'm understanding this correctly, you mean you get a "bad luck pool" that fills up as you mutate, and fills more quickly the more mutated you are, and then periodically empties and gives you a bad mutation? How do you go about making that non-deterministic, or is deterministic the goal? Like do we want it do be such that you'll always get your first bad mutation after 5 good ones, and then the next one after 4, then the next one after 3 (to use fudged magic numbers as an example). Personally for me the "rng" element makes it a little more exciting but I'd like to think I have decent save-scum discipline so I'm not just cheating the consequences until I roll perfectly.

@lapis413
Copy link

Another thought: one factor that makes getting negative mutations more painful is the fact that it's consuming some of your vitamin and thus your resources; is it too much for a negative mutation to develop alongside your positive one, when you fail an instability check? Not counting negative traits that are prerequisites for positive ones.

@github-actions github-actions bot added the BasicBuildPassed This PR builds correctly, label assigned by github actions label Mar 16, 2024
@I-am-Erk
Copy link
Member

  • I think it might be a good idea to somewhat reduce the randomness, ie. at some point we might want it to be inevitable that you get a negative mutation. By capping the rate at 2/3, there's an incentive to keep trying again and again, but if the rate caps at 1.0, eventually you just have to suck up and accept a negative mutation.

If I'm understanding this correctly, you mean you get a "bad luck pool" that fills up as you mutate, and fills more quickly the more mutated you are, and then periodically empties and gives you a bad mutation? How do you go about making that non-deterministic, or is deterministic the goal? Like do we want it do be such that you'll always get your first bad mutation after 5 good ones, and then the next one after 4, then the next one after 3 (to use fudged magic numbers as an example). Personally for me the "rng" element makes it a little more exciting but I'd like to think I have decent save-scum discipline so I'm not just cheating the consequences until I roll perfectly.

It'd still be nondeterministic, but after a while you'd be guaranteed to have a bad mutation. If your chance is 60% by your third mutation, you might get it then; by your fifth, if you've rolled incredibly lucky (or more likely, savescummed a lot), you're at a point where you can't avoid a consequence anymore.

Copy link
Contributor

@Kamayana Kamayana left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestions for giving the added comments consistent capitalization and punctuation.

src/character.h Outdated Show resolved Hide resolved
src/mutation.cpp Outdated Show resolved Hide resolved
src/mutation.cpp Outdated Show resolved Hide resolved
src/mutation.cpp Outdated Show resolved Hide resolved
src/mutation.cpp Outdated Show resolved Hide resolved
src/mutation.cpp Outdated Show resolved Hide resolved
src/mutation.cpp Outdated Show resolved Hide resolved
tests/mutation_test.cpp Outdated Show resolved Hide resolved
tests/mutation_test.cpp Outdated Show resolved Hide resolved
@github-actions github-actions bot removed the BasicBuildPassed This PR builds correctly, label assigned by github actions label Mar 24, 2024
@github-actions github-actions bot added the BasicBuildPassed This PR builds correctly, label assigned by github actions label Apr 1, 2024
@I-am-Erk I-am-Erk merged commit 174d33b into CleverRaven:master Apr 4, 2024
26 of 27 checks passed
@I-am-Erk
Copy link
Member

I-am-Erk commented Apr 4, 2024

I do think this still needs some refinement but it is a steady improvement as is. The refinement can follow up.

@Maleclypse
Copy link
Member

OK as I said i was going to test this after compiling last night and I've done so now. I tested with first one mutagen and then consumed a different type of mutagen after my set was complete and had awarded one negative mutation after around 5 positive/neutral mutations. The new mutagen resulted in negative mutations faster around the third mutation. Then I added back more original mutagen and began mutating quickly not quite alternating between the two trees as I had both transformation effects running. This is good to merge now.

@Maleclypse
Copy link
Member

Oh erk already merged 18 minutes ago.

@I-am-Erk
Copy link
Member

I-am-Erk commented Apr 4, 2024

I'm glad you checked though

@anoobindisguise anoobindisguise deleted the anoobindisguise-instability-redux branch July 31, 2024 04:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
astyled astyled PR, label is assigned by github actions BasicBuildPassed This PR builds correctly, label assigned by github actions <Bugfix> This is a fix for a bug (or closes open issue) [C++] Changes (can be) made in C++. Previously named `Code` Code: Infrastructure / Style / Static Analysis Code internal infrastructure and style Code: Tests Measurement, self-control, statistics, balancing. <Enhancement / Feature> New features, or enhancements on existing Game: Balance Balancing of (existing) in-game features. Info / User Interface Game - player communication, menus, etc. [JSON] Changes (can be) made in JSON json-styled JSON lint passed, label assigned by github actions Mutations / Traits / Professions/ Hobbies Mutations / Traits / Professions/ Hobbies
Projects
None yet
Development

Successfully merging this pull request may close these issues.