I come back to MMF once a year or so, hit a wall where the solution involves yet another workaround that leads me to put it down, swear it off forever, and promise myself that I'll learn C# and move on to greener pastures. This time, I sat down to code a new platform engine from scratch. I wanted to use a model where the player's velocity increments by fractions, for example "while right arrow is down, add 0.2 to xSpeed" or something similar. I realize MMF stores the actual X and Y positions as whole numbers, so I woukd have to store a separate value like "newXposition" and set the player's X position to that variable, so I do not lose a fraction of a "pixel" of distance.
In just a few lines of code, I came across an engine-breaking problem. If the player's xSpeed variable, which increments/decrements by 0.2, reaches 1 or -1, and then goes back to 0, the value of xSpeed will be something like "52487e11."
I slowed down the game speed, loaded up the debugger, and sure enough, 0.6, 0.4, 0.2, 54287e11. (That's not the exact number, I'm posting this from my phone at work.)
I tried a couple other tests. I used a counter. Got the same results. I tried a workaround, by using a counter whose value is *10 what it should be (so it would increment/decrement by 2 instead of 0.2), then set a separate counter to that counter's value /10. The second counter would not show the fraction. So if the first counter read 22, the secon counter, set to 22/10, would show 2 instead of 2.2.
TL;DR---Why does MMF hate fractions? Why does 0.2 - 0.2 != 0 ? And finally, what can I do to work around this before giving up forevernand switching to C# and XML?
:/ was hoping there would be a better answer than that. Not that I don't appreciate the response, I do. Just disappoints to use workarounds.
I've never worked with one of the scripting plugins like Lua. Do you think it would be worth it to start using Lua for all of the simple calulations to avoid weird BS like this? Or is that overkill, and I should just use workarounds everytime something makes no logical sense?
About the counter showing 2 instead of 2.2; are you forcing it to use decimals? I don't know if you even have to do that with counters, but make sure you end the "set counter" action with a decimal, like "22/10.0". If it works like values that will force the counter to floats instead of integers.
This is not technically a bug in MMF2, and you may experience the exact same issue with other programming/scripting languages:
Binary floating-point numbers are inept at handling decimal fractions, so 0.1 + 0.2 is not equal to 0.3. This is the most frequently reported bug in JavaScript, and it is an intentional consequence of having adopted the IEEE Standard for Binary Floating-Point Arithmetic (IEEE 754). This standard is well-suited for many applications, but it violates most of the things you learned about numbers in middle school. Fortunately, integer arithmetic in floating point is exact, so decimal representation errors can be avoided by scaling.
For example, dollar values can be converted to whole cents values by multiplying them by 100. The cents then can be accurately added. The sum can be divided by 100 to convert back into dollars. People have a reasonable expectation when they count money that the results will be exact.
Sketchy, I think I remember you chiming in last question I brought to these forums, probably around a year ago! That's good to know. Couldn't I easily solve the problem with other languages by using a different data type, like a short? It' been a long time since I've programmed in anything other than
VB, forgive me if I sound ignorant. If I could specify data types in MMF, I'd be a happier person.
Like sketchy said, its because of how IEEE floating point numbers are represented. The binary code for them is not like integers that gives only absolute values- it will happen in pretty much any programming language that lets you do floats. Yeah in other languages there is direct control over data types, and more options. In MMF2, one of the ideas behind streamlining development is that data types are automatically handled, and in 99.999% of cases it works just fine. In MMF2 there are really only 2 data types, "number" and "string"- no worrying about char * [], unsigned char * [], int, unsigned int, double, short, long, string, float, etc.
But you'd have to study up on floats to understand how they are really represented- theres no exact values for something like "0.2" in IEEE to begin with.