Basic math in sdk is offsetting result by a fraction of a ten-thousandth

,

This is on Mac SDK.

I am making a game involving moving a sprite between two places of variable length over a set period of time. For some reason, when my formula gives a movement of 2.1 multiple times, after 9-16 frames, my sprite is offset an additional .0001 is added. Meaning that I cannot reliably tell my sprite to spot when it reaches the desired spot. The offset then swings around to .0001 under 2.1 at a higher rate after about 100 frames (not relevant based on the scale of my game but still weird when it comes to solving the issue).

Here is the relevant code where the issue exists:

boardSquaresTotal = 5
vertSpacing = 210 / boardSquaresTotal
horizSpacing = 210 / boardSquaresTotal

timing = 20
trueSpeed = 1
gameSpeedVert = vertSpacing / timing
gameSpeedHoriz = horizSpacing / timing

-- sprite command (example)
characterTarget = character.sprite.y + vertSpacing

function moveCharacter()
     if character.move == down then
          character.sprite:moveBy(0, gameSpeedVert)
          if character.sprite.y == characterTarget then
               character.move = nil
          end
     end
end


As you can see from the math in the code, there are 5 squares and each are 42 pixels apart (210/5). My character gets a speed of 2.1 pixels per frame for what should be 20 frames (42/2.1). Instead, after 20 frames, my character ends up moving 42.0001 pixels according to the SDK.

The problem also does not exist for total squares of 2-9, excluding 5.

I will attempt to provide a video either here or in a comment below if not possible.

YT link to video of issue

In fact, in the video provided, it doesn't appear that the differences are exactly as I explained it (may be different for vertical and horizontal, despite the math being the same).

Tips on how to write a bug report:

  1. Have a clear title.
  2. If relevant, tell us what platform you're using the SDK on (Mac, Windows, Linux)
  3. Explain what the expected result was and what happened instead.
  4. Provide details on when and where this bug happens. Videos and images of the issue can be helpful.
  5. Instructions on how to reproduce the issue.

Welcome to floating point math! This isn't a bug with the SDK but just a general behavior of floating point numbers. Generally, you never want to compare exact decimal numbers but instead check if it's close within some threshold.
You can read more about this:

something like:

function approximately(x,y)
    if math.abs(x-y) < 0.001 then
        return true
    end
    return false
end

if approximately(character.sprite.y, characterTarget) then
    -- do something
end
2 Likes

Thank you!! Glad to see it was a simple issue like that. I was able to fix it with:

local function approx(x, y)
        if math.abs(x - y) < .001 then
            return true
        else
            return false
        end
    end

    character.sprite:moveBy(character.horizSpeed, character.vertSpeed)
    if approx(character.sprite.x, character.targetLocX) then
        character.sprite:moveTo(character.targetLocX, character.sprite.y)
    end
    if approx(character.sprite.y, character.targetLocY) then
        character.sprite:moveTo(character.sprite.x, character.targetLocY)
    end

You can simplify the approx function to just this:

local function approx(x, y)
    return math.abs(x - y) < .001
end

There's no need to use an if statement for just returning true/false

1 Like