# Trying to find a function to calculate attribute changes in a game

I'm coding a game where after every year depending on results the attributes of characters change. The game is a movie business simulator and here is a example of the ugly code I have in place now:

        if (movie.Reviews.Avg > 8.5f)
{
movie.Producer.Reputation += 6f / movie.Producer.Reputation;
return;
}
else if (movie.Reviews.Avg > 7.5f)
{
movie.Producer.Reputation += 5f / movie.Producer.Reputation;
return;
}
else if (movie.Reviews.Avg > 6.5f)
{
movie.Producer.Reputation += 4f / movie.Producer.Reputation;
return;
}
else if (movie.Reviews.Avg > 5)
{
movie.Producer.Reputation += 1f / movie.Producer.Reputation;
return;
}
else if (movie.Reviews.Avg > 4.5)
{
return;
}
else if (movie.Reviews.Avg > 4)
{
movie.Producer.Reputation -= movie.Producer.Reputation / 6f;
return;
}
else if (movie.Reviews.Avg > 3)
{
movie.Producer.Reputation -= movie.Producer.Reputation / 5f;
return;
}
else if (movie.Reviews.Avg > 2)
{
movie.Producer.Reputation -= movie.Producer.Reputation / 4f;
return;
}
else
{
movie.Producer.Reputation -= movie.Producer.Reputation / 3f;
return;
}


Few problems I have with this code: 1. Reputations balloon. Good AI producers make good choices so their movies get good reviews and their reputation goes even higher. 2. Because reputations keep growing the absolute changes in attributes get smaller and moving up in ranks gets way too slow and hard.

What I am looking from the function: 1. Range is 0-10. 2. At the top of the range growth is slow even with great reviews, but if your movie gets bad reviews the decline is sharp. And the opposite for the bottom of the range.

I'd recommend modelling your "reputation" stat as an "expected review score"

ie. A producer with a reputation of 8.5 is a producer I expect will produce movies that review around 8.5 on average.

That approach keeps your reputation bounded between 0 and 10, solving the ballooning problem, and giving a clear meaning to how good a particular reputation number is.

Then we can update the reputation like this:

newReputation = oldReputation + (movie.Reviews.Avg - oldReputation) * fickleness;


Here fickleness is a parameter that controls how quickly people change their minds about a producer:

• At 0, the producer's previous reputation stays fixed no matter what happens.
• At 1, the reputation changes to match whatever the producer's last movie rated.
• In-between, there's a balance you can control between the producer's past history and the latest info.

(You can even scale this parameter based on the producer's experience, making it high for newcomers quickly establishing their initial reputation, and lower for producers with many films under their belt, whose reputations are more stable)

The further the reviews are from what we expect from this producer's reputation, the more the reputation changes as a result. The closer it is to what we expect, the less the reputation changes.

A review above expectation will raise the producer's reputation, while one below expectation will lower it.

• This seems to work very well for my purposes. Thanks! – petju Nov 8 '18 at 7:39

What you want to use is a sigmoid (logistic function) scaled between 0 and 10. There are a variety of formulas available. I would suggest using one that is parameterized for a midpoint.

Includes a basic logistic function in the explanation

• Can you give a few examples in your answer? – Kromster Nov 7 '18 at 12:44
• This answer would be even better if it showed an example of how to apply one of these functions to the problem of updating a producer's reputation based on the review score. – DMGregory Nov 7 '18 at 15:34
• The plot(for 10/(1+e^-(0.7(x-5)))) looks exactly what I was looking for, but I'm having trouble making a function which produces value for new reputation depending on old reputation and reviews. – petju Nov 8 '18 at 7:38