Help! Trouble with Modulo

0 favourites
  • 10 posts
From the Asset Store
Game with complete Source-Code (Construct 3 / .c3p) + HTML5 Exported.
  • 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.

  • 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?

  • Dang. I was hoping it was my fault.

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

    Would it not better to do something every x seconds rather than based on tickcount?

  • 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.

  • 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

  • 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:

    <img src="https://dl.dropboxusercontent.com/u/5426011/examples19/a.gif" border="0" />

    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.

    <img src="https://dl.dropboxusercontent.com/u/5426011/examples19/b.gif" border="0" />

    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.

    <img src="https://dl.dropboxusercontent.com/u/5426011/examples19/c.gif" border="0" />

    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.

  • 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.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • 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.

    docs.google.com/file/d/0B1keSNvq9c4JZHFKTnhEQ1gxQ28/edit

  • 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

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)