Revolutionary-Games / Thrive

The main repository for the development of the evolution game Thrive.
https://revolutionarygamesstudio.com/
Other
2.79k stars 496 forks source link

Rigidity slider breaks when trying to move it at exactly 0 MP #4150

Open hhyyrylainen opened 1 year ago

hhyyrylainen commented 1 year ago

It looks like rigidity slider does a divide by zero to end up with ridiculously wrong numbers when it tries to move when there's exactly 0 MP left. This can be triggered with a very specific MP cost multiplier to be able to place parts to reach 0 MP and then trying to move the rigidity slider.

https://community.revolutionarygamesstudio.com/t/membrane-rigidity-visual-bug/6059

Video: https://youtu.be/9c4ekW5QNI8

84634E1A607A commented 1 year ago

https://github.com/Revolutionary-Games/Thrive/blob/master/src/microbe_stage/editor/CellEditorComponent.cs#L961

This can be 0. I remember we discussed before that MP should be a float instead of int. When that is done this bug should go away.

hhyyrylainen commented 1 year ago

I guess that is kind of unavoidable anyway with MP discounts etc. Though, we absolutely don't want to show really long decimal values to the user in the MP bar or tooltips.

ItsStolas commented 4 months ago

https://github.com/Revolutionary-Games/Thrive/assets/18731181/7a8d1e3a-b86a-49c9-bb69-12a42798aa87

Can't seem to reproduce this, the membrane slider doesn't move with 0 MP.

ItsStolas commented 4 months ago

A possible(?) division by zero, I guess, would be this costPerStep:

if (cost > Editor.MutationPoints)
  {
      int stepsToCutOff = (int)Math.Ceiling((float)(cost - Editor.MutationPoints) / costPerStep);
      data.NewRigidity -= (desiredRigidity - previousRigidity > 0 ? 1 : -1) * stepsToCutOff /
          Constants.MEMBRANE_RIGIDITY_SLIDER_TO_VALUE_RATIO;

      // Action is enqueued or canceled here, so we don't need to go on.
      UpdateRigiditySlider((int)Math.Round(data.NewRigidity * Constants.MEMBRANE_RIGIDITY_SLIDER_TO_VALUE_RATIO));
      return;
  }

But if we want, we could just do,

if (cost > Editor.MutationPoints && costPerStep > 0)
  {
      int stepsToCutOff = (int)Math.Ceiling((float)(cost - Editor.MutationPoints) / costPerStep);
      data.NewRigidity -= (desiredRigidity - previousRigidity > 0 ? 1 : -1) * stepsToCutOff /
          Constants.MEMBRANE_RIGIDITY_SLIDER_TO_VALUE_RATIO;

      // Action is enqueued or canceled here, so we don't need to go on.
      UpdateRigiditySlider((int)Math.Round(data.NewRigidity * Constants.MEMBRANE_RIGIDITY_SLIDER_TO_VALUE_RATIO));
      return;
  }

Because the cost no longer matters, if the step cost is 0.

hhyyrylainen commented 4 months ago

The slider is disabled when at 0 MP, but I think you can still trigger this bug by moving the slider while you still have MP but running out at exactly the mid point. Or a more reproducible way to trigger this is probably to modify new game settings to reduce the mutation costs so that steps are sometimes free and sometimes cost MP.

Also there exists a full fix for this problem here, but this PR was never finished: https://github.com/Revolutionary-Games/Thrive/pull/4154