Help! Trouble with Modulo

Get help using Construct 2

Post » Wed Oct 23, 2013 5:18 pm

Hi everyone! I have a weird behavior which I don't understand and I'm hoping someone can help.

Hopefully I'm just doing something stupid.

I have an expression which doesn't seem to be evaluating correctly, which leads me to think I've written the expression wrong or something, but I can't see how.

The expression:
TickCount % (32/speed)

Or in words, the remainder of TickCount divided by (the result of 32 divided by the speed).

Where TickCount is the variable representing the current tick number, and speed is a variable used in a game I am making.

When that equals 0, I want to do a thing.

I have a specific case where that expression should be evaluating to zero, but is not.

Example:
TickCount = 416
speed = 5

so:
416 % (32/5) = 0

Unless I'm crazy, that is true, it evaluates to zero, but my program isn't doing it's thing.

So, I had it also output the result of that expression to a global variable every tick I can monitor in debug, and it claims to be evaluating to 5.399999999999977 at tick 416 with speed 5.

I am baffled by this. Any help would be appreciated! It's a bit of a pain for me to post the actual project for people to poke around in, so I'm hoping the answer is obvious from the above, but if not, let me know and I can try to find a way to share the project.
B
4
Posts: 13
Reputation: 226

Post » Wed Oct 23, 2013 5:40 pm

That is strange, I just straight up had it print out 416%6.4 and its output is 6.4 instead of 0. Maybe there's a bug when using modulo with decimal numbers?
B
11
S
2
Posts: 87
Reputation: 1,112

Post » Wed Oct 23, 2013 6:15 pm

Dang. I was hoping it was my fault.
B
4
Posts: 13
Reputation: 226

Post » Wed Oct 23, 2013 7:22 pm

http://floating-point-gui.de/

Would it not better to do something every x seconds rather than based on tickcount?
B
55
S
29
G
19
Posts: 1,520
Reputation: 25,630

Post » Wed Oct 23, 2013 7:40 pm

I don't think I can use timing for what I am trying to do. I am following this guide to create an endless runner:
http://
gamedev.tutsplus.com/tutorials/from-scratch/build-a-canabalt-style-infinite-runner-from-scratch/

In this case, we are using this expression to know exactly when we need to create a new platform object, which are 32 pixels wide each, and taking into consideration a speed variable which increments as the game progresses.

If this can be done using timing in seconds, rather than ticks, it is a little beyond me, but I would be thrilled if someone knew of a way to do that, and could explain it.
B
4
Posts: 13
Reputation: 226

Post » Wed Oct 23, 2013 7:41 pm

Yep. I get the same.

And it is a decimal issue. if you try to multiply the decimal away it works.

4160%64 = 0 in C2.
but
416%6.4 = 6.4
B
20
S
6
G
4
Posts: 347
Reputation: 4,451

Post » Wed Oct 23, 2013 10:21 pm

Modulo with integers will always be exact. Hence 4160%64 = 0. Modulo with decimals will be as accurate as the computer can represent it. (tivia: 6.4 cannot be exactly represented with floating point numbers)

416/6.4 is not acctually 6.4 it's 5.399999999999977, but Construct does some rounding so numbers look prettier. For example if you set some text to 416/6.4 you'll get 6.4 and if you set the text to str(416/6.4) you'll get 5.399999999999977.

Back to the issue, it's bad practice to check to see if a floating point value is equal to an exact value.
So instead of this:
number=value
The usual method is to do something like this:
abs(number-value)<epsilon
Where epsilon is a small number such as 0.00000001. The idea is you don't check if it's exact but rather it's close enough.

When using modulo for example a%b the result will be in the range of 0 to b so to check if the result is close enough to 0 or b you can do an expression like:
abs(a%b - b/2)>b/2-epsilon

Of course I don't think such a formula is needed, but I'm too lazy at the moment to watch the tutorial video to see exactly what they do.

You could re-write your formula for time. I assume speed is in pixels/tick and you're events are something like this:

You could rewrite it to be time based so it would run the same speed no mater how many ticks per count, and you'd avoid the cpu math precision issue.

The issue now is the platforms aren't always butted up against each other, sometimes there's a gap. So instead you could check the last platform's distance from the edge of the screen to see when to create another platform.

No gaps, but with constant 60fps you may run into the need to create more than one platform if the speed exceeds 32*60 or 1920pixels/second. Not sure if the player will die long before that speed. If the issue comes up you could just duplicate the last event for a quick fix.
B
91
S
31
G
103
Posts: 5,241
Reputation: 67,768

Post » Thu Oct 24, 2013 5:57 pm

Awesome response R0J0hound, thanks for taking the time.

I'm actually glad to find out that it was me after all, because that means I can learn something!

I guess I'm so used to thinking of calculators as computers, that I expected expressions in Construct to evaluate as they do on my calculator.

I'll play around with your suggestions and let you know how it turns out in case any one else is interested in doing a project like this.ravelin2013-10-24 17:58:12
B
4
Posts: 13
Reputation: 226

Post » Thu Oct 24, 2013 7:32 pm

Great! So, I've eliminated the old modulo, and implemented something similar to what R0J0hound suggested instead, but I am having the problem of little gaps between each platform block.

I have constant 60fps, and the speed definitely does not exceed 1920 pixels per second.

Also, I noticed the gap varies a little with a bit of a display stutter, so I imagine it wouldn't scale well with older machines?

I'm posting the project file in case anyone wants to have a look. I'm doing this for fun and education, so I welcome any comments, thoughts, (constructive) criticisms, or alternative approaches.

https://docs.google.com/file/d/0B1keSNvq9c4JZHFKTnhEQ1gxQ28/editravelin2013-10-24 19:32:32
B
4
Posts: 13
Reputation: 226

Post » Wed Sep 14, 2016 8:10 pm

Well maybe i can bump this one. I'm doing the same tutorial, and i have managed to get everything to work by doing some tweaks in the events, but now when i try to make the level go faster, it stop spawning platforms. it spawns again when the speed goes to 8. so everything works on 4, 8, 16, 32 and so on. why does it stop in between?

""https://www.dropbox.com/s/7yacvlm3llkhdvx/Endless%20Runner.capx?dl=0""

if you answer try to make it easy to understand this is my first :)
B
5
Posts: 3
Reputation: 233

Next

Return to How do I....?

Who is online

Users browsing this forum: bluesun66 and 2 guests