Numbers.... o_o

Previous topic - Next topic

Darmakwolf

ok so... weird thing. With my platformer engine, I noticed an inconsistency. In iOS, all the objects snap snugly together and stay right where they're supposed to be. In Win32, it's basically the same except when there are a lot of smaller objects and the scroller moves veritcally, a line of empty space appears between the objects horizontally. I noticed that the ONLY difference is how it stores the vertical speed variable, vspeed. In debug mode, I can see that it cuts off the number to be not-so-precise in Windows. It's always like 0, 1.1, 1.2, 1.3. In iOS, it's 0, 1.100000, 1.138263, etc. I've tried declaring vspeed# with the # sign, no luck. What is causing this strangeness? The only thing different for ios is the fact that it was compiled for iOS. No game mechanics are altered!

Slydog

Hmm, strange.
They should be the same, unless they handle some math commands differently.
Anybody know if floating point numbers use the same precision between the two systems (4 bytes vs 8 bytes).

And floats are the default type, so omitting the '#' would still result in a float.

One possibility is the math you perform on the vspeed variable, and each system may behave differently.  If you have any commands with hard coded integers, that may force your vspeed to an integer value, and cut off the decimals, which it looks like later it's divided by 10.0 or something.  Try adding a '.0' to all your hard coded numbers in any vspeed calculation to see if it helps.

And/or if possible, post the code where you calculate the vspeed.
But it is strange for sure!
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Kitty Hello

post a bit of code. Working with floats requires taking a bit of care.
Rules:

Never compare floats with = operator. They might look the same but are not (1.000001 and 0.999999)
Compare with IF ABS(one - two) < 0.000001 ...

Division by zero is not crashing - but gives great headache.
Always do this:
LOCAL div = ...
IF ABS(div) > 0.0000001
    division = number / div
ELSE
    END // or proper error handling
ENDIF


Darmakwolf

#3
I'll post some code but I'm still perplexed why it'll work fine in iOS but be less precise in Windows.
This function handles Y changing in-game. It needs its own function because many things have to change along with just the Y position of the scroller.


Code (glbasic) Select
FUNCTION changey: amnt
IF ood <> 0
IF ST = 1
vspeed = 0.0
ongnd = 1
ENDIF
IF ST = 0
yv = yv - amnt
b1y = b1y - amnt
ENDIF
IF t1 = 1 AND ST = 1
ST = 0
yv = yv - amnt
b1y = b1y - amnt
act = 4
ENDIF
ENDIF
ENDFUNCTION


At another point in the code, vspeed increments to cause falling:
I've tried using just 0, 0.0 does the same thing.

Code (glbasic) Select
IF vspeed < 8 THEN vspeed = vspeed + 0.10

Now, another part of the code which checks vspeed:

Code (glbasic) Select
IF vspeed <> 0 AND ood <> 0 THEN changey(vspeed)

(Basically this checks to see that we're standing still and doing nothing special while the ground is right below us (ood = 0))

I'm really at a loss here. In fact, in debug mode, at the VERY HEIGHT of a jump.... vspeed becomes a long number with many digits after the decimal - but only for one frame. In win32. I am really at a loss  :blink:

<that one frame in time is attached>


Update: Attached game demo - it's small. Compiled this evening with the latest stable GLB. (One horizontal-moving platform in the demo for lol's - they're incomplete xD)  To see the problem, go to any wall and jump. You will notice the lines that appear between objects. This cannot be observed in iOS because the numbers are more precise for some reason. I'm sorry I cannot provide the full source at this point because I've put too much work into getting this to work that I don't want to have it stolen and used in a commercial product.

Controls: This is a keyboard controlled game
Arrow keys = directions
Z = attack/cancel ( Can't attack yet ;) )
X = accept/jump
I = inventory
F1 = DEBUG
F2 = Experimental frameskip while in debug. Don't do this - it's scary.
F3 = hold to show a simple FPS counter in the corner. Useful for getting a real FPS reading.
Press A while in debug mode to add items to the inventory (testing purposes only.)

That aside: collision detection for normal objects is flawless now, and there's an awesome perfectly looping scrolling background system in place now, still running at a full 60 FPS on iOS - I am happy :)
If I can just squash this one bug...


Note: the blob character has no hands - i'm aware :P they're going to be separate entities. This is a work in progress snapshot demo of my platform engine at work - it's going to be at least somewhat buggy. When it's done, it's going to be very similar to Symphony of the Night in play style!




[attachment deleted by admin]

Slydog

You could try rounding vspeed after each change: (eg: round to 2 decimal places)
Code (glbasic) Select
vspeed = INTEGER(vspeed * 100.0) / 100.0

Or create a rounding function (untested!):
Code (glbasic) Select
FUNCTION Round: value#, decimals%
    LOCAL factor#
    factor = POW(10.0, decimals)
    value = INTEGER(value * factor) / factor
    RETURN value
ENDFUNCTION

vspeed = Round(vspeed, 2)


But it still doesn't explain why it differs on the different platforms!
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Darmakwolf

Why would I want to round it? I want the long precise digits like on iOS to be in windows, so the weird problem will disappear o_o

Slydog

#6
Not knowing your other code, I just thought vspeed was only incremented by 0.1:
Code (glbasic) Select
IF vspeed < 8 THEN vspeed = vspeed + 0.10
But I guess your other code may alter vspeed by other amounts, so ignore my rounding advice!  :)

I wonder if this line:
Code (glbasic) Select
IF vspeed <> 0 AND ood <> 0 THEN changey(vspeed)
is being triggered because of that one weird frame where vspeed <> 0 but it's a small fraction.

Applying Kitty's suggestion:
Code (glbasic) Select
IF ABS(vspeed) > 0.0000001 AND ABS(ood) > 0.0000001 THEN changey(vspeed)

Again, it's only happening on one platform, which I have no answer for that.

[Edit] Oops, fixed a bug in the line with Kitty's suggestion!
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Kitty Hello

also, iOS has 32 bit floats, where win/lin/mac has 64 bit precission. That's because of the processor optimized architecture. You don't want 64 bit floats on a mobile device.


Darmakwolf

So I woke up, barely awake, opened the source. Something possessed me to change this line:

Code (glbasic) Select
IF vspeed < 8 THEN vspeed = vspeed + 0.10

to:

Code (glbasic) Select
IF vspeed < 8 THEN vspeed = vspeed + 0.11

... and the lines disappeared. No need for huge floats. Right when that happened and I realized I fixed it, my phone rang which plays the Final Fantasy 7 Victory theme (for real!) ... it's going to be a good day =)

Crivens

I remember all the old tutorials from languages gone by (eg. STOS) saying to use large integer numbers and then divide the numbers to locate on screen. Main advantage is speed as integers are processed faster, but also should sort out problems between devices with only fractions of a pixel difference when it comes to drawing it on the screen.

Cheers
Current fave quote: Cause you like musicians and I like people with boobs.