# Thread: set X to X -0.3 moves by -1.0 : bug or feature?

1. The video posted above from zentaco explains it perfectly fine.

He says, fusion floors by default, that means if you put a float number into the editor or the expression editor it will be rounded down.
You can overcome this issue by storing the float number on runtime via events into an alterable value.

Just watch the video

2. Originally Posted by Manuel
I think the last comment on that thread by Jacob explains it very clear, what happens is "flooring" as said already above.

"Flooring the values is logical, actually. The coordinates on the field are not the pixels, but actually the vertices on the top left of each pixel. Single points, rather than 2D areas. If you are at ordinate 24.7, you still fall within the pixel that corresponds to 24, not 25. For this reason, I never use Round() when I pass my float values to MMF's integral positions."
Firstly, no, it's not logical.

This is logical: -34.001 = -34.001
This is logical: -34 = -34
Neither this -34.001 = -34 nor this -34.001 = -35 is logical. These are approximations, which are illogical by their very nature. So if Fusion is performing an approximation like this, it has sacrificed logic for some other purpose (performance, simplicity, etc.). So if Fusion is automatically making approximations, then at least it should be a helpful approximation.

But anyway, logical ≠ sensible. It is illogical to divide by zero, yet Fusion (thankfully) lets you do it instead of returning annoying errors. It is illogical to parallax objects and pretend that one is on a "background layer" and one a "foreground layer" when in fact this is an utter fiction and both are precisely as far away from your eyes as your monitor is. Yet Fusion allows to parallax with coefficients because it's useful. Because we're humans, not computers, and we can make sense of things in ways that a computer cannot.

So what if the precise mathematical vertice of a pixel is at the top left? We are not theoretical physicists or NASA computer engineers. We are game developers using a game engine that's intended to be intuitive and user friendly. 9 out of 10 game developers, if shown an x coordinate of x = 34.001 will expect and want it to translate to x = 34 when converted to real pixels. Likewise, 9 out of 10 game developers, if shown an x coordinate of x = -34.001 will surely expect and want it to translate to x = -34 when converted to real pixels.

I mean, think of the real-world scenarios. If you have a bomb that sends your player moving by a procedurally-generated floating point number (say, depending on how close to the bomb the player is), you may now have to code it twice to make sure it works exactly the same way if your player is being moved left or right. Or else add some other workaround to nullify the 'logic' of 0.001 = 0 & -0.001 = -1.

@elvisish : it depends on what you're doing. But it generally it will probably boil down to you truncating a float before you finally pass it to Fusion to move something. One way to do that is to perform int() on it (this is different from flooring - it just removes the bits after the decimal, so -1.3 becomes -1 and 1.3 becomes 1). If you like, you can save the remainder (0.3) in an alterable value and add it to the movement the next round so that it doesn't get wasted.

Another way is to perform movement by a fastloop. So if your variable Xmovement happens to be -4.3, you can run a fastloop abs(Xmovement) times (and in the fast loop you move something 1 pixel exactly). This will of course run the loop 4 times, not 4.3 or 5 times, which means that your object will move 4.0 pixels. You can then do subtract int(Xmovement) from Xmovement to leave the 0.3 remainder in your Xmovement variable, so that it can stack with subsequent loops. Eventually, these remainders will add up to more than 1.0 and will be used...this will ultimately provide smoother and more graceful movement.

3. @Volnaiskra , well i cannot give you a better answer to this, i can only search and look for the best solution that explains the behavior you experience, and flooring (rounding down) just explains it.
Why it's now used in fusion, i don't know i'm no expert on that low level rendering things, but i think thats one more example why the documentation in fusion just has to be more professional, this kind of things have to be detailed explained/documented to the enduser from official side, so everybody knows exactly how to deal with it.

4. That almightyzentaco video was Published on Dec 5, 2016.
So Fusion must of been doing it this way for a very long time.
I followed it as a total noob about a year ago and was able to make sense of it.
He talks through making a whole sub pixel movement engine with alt values, floats and fast loops. End result is really good.
I generally find the almightyzentaco videos much easier to follow than long text posts. No offense to Vol, i learn a lot from his posts . This one though scratches chin a lot.
Plus one for the comment. on the video . Make a special effect when ever you slurp ! lol

5. I have a subpixel movement in my game too. It also uses fastloops, so is probably similar to what zentaco suggests. And because it uses fastloops it is immune from the -0.3 = - 1 problem, since the fastloop method effectively converts the movement to an integer before moving anything. That's why I was never exposed to this problem before even though I've been using subpixel movement for 5 years.

But now I'm using subpixel movement for particles, and the fastloop method is no longer suitable. If there are 50 particles and each particle has to move 4.3 pixels, it would be way too expensive to perform 4 fast loops for each one. That would be 200 fastloops. Much better to just tell fusion to move the particles by 4.3.

But now this annoying problem raised its head. If a particle was left with a tiny number like 0.3, the fastloop method would have ignored it. But now, it is ignored for particles travelling east or south but turned into perpetual movement for particles travelling west or north.

It's easy to fix by forcing the integer with (int) before moving. But as Manuel says, it's a pity things like this have to be hidden surprises

6. But when i think about it now, i had the same issue recently when needed to put a decimal number into "apply impulse" from the physics engine, no matter what you do it will always round down, not even setting on runtime works. I ended up with a full number and adjusted the display factor of the physics engine to get the desired result.

7. This has been a thing for quite a long time iirc. Fusion can't handle anything but integers in the expression editor, i.e 0.3 turns into 0. This is why it's common practice to use values to handle floats. You can add 0.3 to a value constantly and set X of Active to X( "Active" ) + value and it will move correctly. Or in my opinion the "better" way is to set two values (xpos and ypos) to x and y of object at start, and treat these as the "real" position of the object that you modify, then always position the object at X = Round( xpos ) and Y= Round( ypos).

8. Originally Posted by casleziro
This has been a thing for quite a long time iirc. Fusion can't handle anything but integers in the expression editor, i.e 0.3 turns into 0.
That's not the issue. The issue is that 0.3 turns to 0, but -0.3 turns to -1, because Fusion floors numbers instead of truncating them. It's the assymetry between negative and positive numbers that's the annoyance.

9. Oh, I didn't know that. Interesting.

10. A quick google and I’m guessing fusion uses typecasting for speed. Instead of precise math.

The other function available is round(), which takes two parameters - the number to round, and the number of decimal places to round to. If a number is exactly half way between two integers, round() will always round up.

Author's Note: The floor() function converts a floating-point number to an integer in roughly the same way as typecasting, except typecasting is faster. The only difference is with negative numbers, where floor() will round -4.5 down to -5 whereas typecasting would return -4.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•