# Percentage reduction

1. Jan 7, 2012

### Nanako

hello everyone. I need a little help with something probably simple, for a game engine i'm writing.

I want to reduce a number n by a certain percentage each second, p.
But i want to do this with higher granularity, depending on the framerate my game is running at.

So for example, if i want to reduce a 100 by 5% per second, and i'm running at 30 frames per second, How do i calculate what to multiply the number by each frame, to achieve that.

To make it clear, i'm looking for a compound reduction here. ie the sequence after 0, 1, 2, 3 seconds etc, would be 100, 95, 90.25, 85.735, 81.45, etcetera.

2. Jan 7, 2012

### chiro

Hey Nanako and welcome to the forums.

The way you would do this is to use a simple event system that produces an event every so often (every second).

With your example, all you are doing is setting some variable x and if you follow your example you are setting x = 0.95 * x.

Now from what you have said you want to adjust this based on the framerate, but I can't see how it should be scaled.

You said you want to do this based on higher granularity. Does this mean that if the framerate is lower then you want a more regular transform? In other words, if you have a lower frame-rate, you want to reduce your 'x' variable more frequently?

If the above is the case then, with your event system, you just post a new event that is based on the current framerate. You would probably base it on the inverse of the framerate (f(currentframerate)), for an appropriate function f. You might even have to bound the value to 1 per second max.

The key thing is to figure out f(currentframerate). I might suggest that you start off with f(x) = (x+1) / c where x is the last known framerate. The value of c is up to you depending on the behaviour.

3. Jan 7, 2012

### Nanako

hii!
i'd consider this more of a workaround than a solution. It's not right for me here though. I'm dealing with events on a scale of higher resolution than per second, with objects that may not even last one second before i need to utilise the scaled value.

Also, with your example. even if i was going to do it that way, it would have to be 0.95 to the power of x, not multiplied by it. maybe you missed that i meant compound reduction.

no, the opposite. Higher framerate equals more often. With a framerate of 30, i want to be updating the value 30 times every second. But no matter what the framerate is, the result at the end of each whole second should always be the same.

4. Jan 7, 2012

### chiro

This means you need to check every 1/framerate times per second if you update the framerate variable every second.

What will help me clarify what you want to do, is to tell me what the value should be at point a, what it will be at point a + t (t could be 1 second, or it could be based on some formula) and what you want in-between.

My example did compound the result because after each event x was modified. This means if 30 events were processed in the space of a second, then after a second x = x_int x (0.95)^30 where x_int is the initial value since the process gets called 30 times (1 time each event for 30 events).

The reason why events are good is because this kind of thing is easy. Also you should realize most modern engines have a very comprehensive event system (just so you know I used to be a games programmer) so it would be worth your while to think about this.

5. Jan 7, 2012

### Staff: Mentor

So you are looking for x such that

x30 = 0.95

Take logs of both sides.

Are you sure your framerate will be constant?

6. Jan 7, 2012

### Nanako

yes i know that. i already have an event that triggers once per frame, that i do a lot of work in. i'm not updating the framerate every second though. it'll be just an occasional thing. but i have a global variable for the framerate which is incorporated into most calculations in the engine (the variable is actually 1/framerate). if i modify the framerate, i'll change that too.

i think i mentioned that:
that assumes a starting value of 100 and a reduction of 5%

ah i misread, my bad. But no, that's not what i want to do. With a reduction value of 5%, i want to end up at 95 after one second. I want to knopw how to figure out what value to multiply it by each frame so that it will end up decreasing by 5% each second

yes i know, i;m using events. I think we misunderstood each other. my issue with your approach was simply that it was updating the value once per second. I want to update it f times per second.

just so there's no misunderstanding here, let me clarify the variables involved:

n: a value i want to reduce. in this example, n = 100
p: The percentage i want to reduce it by. in this case p = 0.95 to represent a 5% reduction
f: the framerate of the program - how many times we're going to be updating the value each second. in this example, f = 30

What value should i multiply n by in frame 1? can i work out a value to repeatedly multiply n by, so that it will be 95 by the time we've done the multiplication 30 times?

let me also make it clear that i'm aware that i can do this to calculate n for any arbitrary frame x:
=n * p^(x*(1/f))

but that is not what i want to do, because i don't want to have to track x. this may well be more efficient or simpler, but it's NOT what i want to do.
do we understand each other now ?

Last edited: Jan 7, 2012
7. Jan 7, 2012

### Nanako

yes exactly. this is what i'm looking for. except that p (0.95) could well be any value, so i need a good formula to calculate it.

No the framerate (f) will not be constant. It won't change *much* but i want to support it changing as and when i wish it to, so i'll incorporate it into the calculation. that's the easy part really, let me worry about the framerate. But for now, assume it's 30 :p

i'm not sure what you mean by take logs. i'm gonna go read logarithm on wikipedia now (i assume that's it, right?)

8. Jan 7, 2012

### chiro

Borek has what you want, but it assumes that the effect is constant for each application of the formula in the period of a second.

Basically ln(p) = ln(x^a) = aln(x)
ln(p)/a = ln(x) => x = e^(ln(p)/a)

ln(p) will exist as long as p > 0 (which should always be the case) and a will be a positive integer so no problem there.

9. Jan 7, 2012

### Nanako

i've done a little reading on logarithms. i quickly got lost in stuff i didn't understand, but the general gist i got is that logarithm is the reverse of exponential. i understand that much.

i couldn't see any information on how to calculate it. is it one of those things you generally use a calculator for?

The language i'm using (AS3) has a math library containing a log function. It takes an input value and produces the natural logarithm of it. I looked up natural logarithms too, and the value of e seems to be some long decimal number that I have no idea what to do with. So i don't see how log(0.95) is going to yield a meaningful result for me. The function has no way to specify the base of the operation, so what am i supposed to do with that output?

I guess what i really WANT to do is logn(p) and that would give me my value, but i can't seem to do that directly

you've lost me. what is ln ? and what is a ?
also i'm not sure about => is that "greater than or equal to" or is it something else ?

10. Jan 7, 2012

### Staff: Mentor

ln is a natural log (base e).

Assuming

$$x^{30} = 0.95$$

taking logs (base 10, not that it matters much - you just need to use the same base all the time) of both sides and knowing log properties:

$$30 log x = log 0.95$$

$$log x = \frac {log 0.95} {30}$$

and finally

$$x = 10^{\frac {log 0.95} {30}}$$

(here it is important that we used log base 10).

You can put any numbers you want in the place of 30 (framerate) and 0.95 (which represent your percentage change).

Calculating log is best done using math library or calculator.

To be honest with you - if you have no idea what the log is and what its properties are, you really should work on your math, if you want to work on game engines. Serious game engines are about math and data structures. And you won't understand properties of data structures not knowing math.

11. Jan 7, 2012

### chiro

Logs are ways to study systems where powers are involved. Logs are basically the inverse of exponentials (exponentials raise something to a power and that power can be a fraction or a real number in general and it can also be negative).

There are other uses, but think of it as the inverse of raising something to something else in the same way that division is the inverse of multiplication and subtraction is the inverse of addition.

Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook