• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
GradualGames

Does anyone use fixed point math anymore?

29 posts in this topic

Fixed Point data  still might have its uses to minimize memory storage space.

As long as the conversions are not done constantly  (and obviously one or two bytes are enough of a range for the values needed.)

 

Example - for bone animations angles being applied with individual bones getting target angles and rates/time periods to Tween individually.  With complex choreographed movements with upto 30+ bones in play --  that can be alot of data for just a few seconds of animation .  And you may want to have many such animations kept in memory for the figures.

 

Each  fixed point data value  is generally converted once when its its applied  as a delta to the floating point state variables.

 

 

Another use can be for packing data for attributes of sub-objects (like inventory items of an NPC - when you have hundreds of them - both NPCs and items).  The inventory is infrequently used  and a great deal of attribute data can be  compressed down   (....reminded me that packed data sent thru network likewise can be more efficient if data size is minimized)

 

 

There is a benefit of fewer cache misses when you have more data in less memory (the simulation I did before had huge data sets that no way could fit in caches even now).  Possibly the smaller disk size of the data may speed up some of those operations.

 

 

Note these are specialized uses and much of the calculations they are associated with use floats if they are constantly used in calculations.

 

 

 

 

0

Share this post


Link to post
Share on other sites



In addition to the uses for fixed point already stated (e.g. large worlds,) it is also used to make code deterministic across machines/platforms/etc.

It is possible to do this with floating point code but your milleage may vary (in my experience it is challenging.)

One example of this is RTS games where inputs are broadcast to all clients and each client must update their state and stay in sync.

 
 
 I actually experienced floating-point determinism being varied across machines in an engine which 'planted' trees around terrain at game load time using a procedural method of creating potential points all over the terrain and checking the slope of the ground at those points one at a time before generating a new point to test, and in some cases it would throw off the scene generation algorithm so wildly that the two machines in the same game would be in two geometrically different worlds due to the PRN code becoming out of sync when some trees would get planted and others wouldn't based on floating point precision nuances in the slope check.


 
If both were running the same executable, then this really can't happen. The result of a floating point instruction is defined exactly (the rule is that it should return the nearest floating point number to the exact result, and round to even on ties). Also, if you don't have options like fast math enabled, then the same thing is true for C/C++ code (at least if it's IEEE 754 compliant), so it's likely that this difference was caused by something else.


Ah, I wish things were this simple. The result of a floating-point operation is not defined exactly. For instance, the FPU might use a more precise type internally (say, 80 bits) and only round the results when they have to be put in memory. The x87 FPU does this, and I have seen programs where adding a debugging print statement changed the results of a computation, because now an intermediate result had to be written to memory.

You can set the FPU to only use 53 bits of mantissa internally (I primarily use double precision), and that takes care of that particular nasty behavior. Using SSE for floating-point computations also gets rid of the problem. But that's not the end of the horrors: For instance, computations on x86 and on Sparc still don't match to the last bit for operations like sin(), log() and exp(). The IEEE standard doesn't specify their behavior at all, so this is not surprising.

Someone in my company had to spend a lot of effort to ensure that we get reproducible behaviors in all our machines, and the solution involves using software implementations for some functions because the hardware implementations can't be trusted.

EDIT: I found this relevant link. Edited by Álvaro
0

Share this post


Link to post
Share on other sites

No, that will not solve the issue. The reason why using floating point is "wrong" and fixed point is "correct" is not that vertices within a model are in world space, but that entire objects are (necessarily) in world space. Though floating point will still "work" in many situations.

An object (person, car, box, whatever) near the origin might have a position accurate to 5 nanometers, which seems "cool" but is not really necessary -- nobody can tell. On the other hand, an object on the far end of the world might only have a position accurate to 15 meters.

Bang. It is now entirely impossible for a person to walk, as you can only move in steps of 15 meters, or not at all (and people just don't leap 15 meters). It is also impossible to distinguish 10 people standing in a group, since they all have the exact same position. It is further impossible to properly distinguish between objects moving at different speeds. A bicycle moving at 25km/h stands still. A car moving at 53.9 km/h stands still, but a car moving at 54km/h moves at 54km/h.

This is inherent to how floating point math works (it is a "feature", not so much a "bug"). Fixed point does not have that feature. A person can walk the same speed and be positioned the same at the origin or at the far end of the world.

It doesn't matter that the vertices you render are in their own coordinate system if the entire object cannot be simulated properly or if the entire object is culled away.

Actually, when used right it does solve the issue. The error you are making is assuming that everything will be rendered using a fixed origin. That is dumb and will cause the problems you described. But there is no point to do that.
You pick an origin based on your camera position and then render the scene. Everything close to the camera is then rendered in very high precision. Everything very far from the camera is rendered in decreasing precision, but you never notice because the error you are making will be much less than a pixel in image space.

For example my professional work is on a terrain renderer that can render the whole earth. The render space places (0, 0, 0) in the earth's center, so anything rendered on the surface is more than 6000km away from that. Doing that the dumb way or just with 32 bit floats would never work in sub-meter precision. You never notice though because everything rendering itself has a local origin with 64 bit precision while all geometry is actually stored and rendered using 32 bit floats.
Assuming six decimal digits for float accuracy (not a bad rule of thumb), you can of course only represent things 10km away the camera with an accuracy of around 1m. But with any reasonable camera, being off by 1m in a 10km distance will have exactly zero visible effect.
0

Share this post


Link to post
Share on other sites

You pick an origin based on your camera position and then render the scene.

Samoth wasn't talking about rendering, but physics / gameplay movement.
i.e. If you're placing/moving objects in absolute world coordinates, then those coordinates break down at some distance from the world-space origin, in the gameplay update code.

Ah, I wish things were this simple. The result of a floating-point operation is not defined exactly. For instance, the FPU might use a more precise type internally (say, 80 bits) and only round the results when they have to be put in memory. The x87 FPU does this, and I have seen programs where adding a debugging print statement changed the results of a computation, because now an intermediate result had to be written to memory.

Yeah, but as he said, this doesn't matter if everyone is running the same program. Everyone will perform the same rounding operations as each other.

If you support cross-platform play, or cross-version play (e.g. playing back old replay files), then yes, you've got a big problem, as any little change in the code may cause a huge change in FP behaviour. In MSVC, the "precise" floating point compilation option helps with this, by rounding to 32-bits after every single damn FP operation, which is really slow, but makes the code obey the IEEE spec. Edited by Hodgman
0

Share this post


Link to post
Share on other sites

For example my professional work is on a terrain renderer that can render the whole earth. The render space places (0, 0, 0) in the earth's center, so anything rendered on the surface is more than 6000km away from that. Doing that the dumb way or just with 32 bit floats would never work in sub-meter precision. You never notice though because everything rendering itself has a local origin with 64 bit precision while all geometry is actually stored and rendered using 32 bit floats.
Assuming six decimal digits for float accuracy (not a bad rule of thumb), you can of course only represent things 10km away the camera with an accuracy of around 1m. But with any reasonable camera, being off by 1m in a 10km distance will have exactly zero visible effect.

 

That's a perfectly reasonable solution, but an argument could be made that fixed point is a better solution than floating point for your object positions. This is evident from the fact a 32-bit float gives you sub-metre accuracy while a 32-bit fixed gives you sub cm accuracy. I'm sure your doubles give you more than adequate precision, but 64-bit fixed point will give you more accuracy, and perhaps more importantly, more consistency. For rendering, consistency might not matter too much, but for physics simulations it occasionally can.

 

Tom Forsyth has a nice article on it http://home.comcast.net/~tom_forsyth/blog.wiki.html#[[A%20matter%20of%20precision]]

0

Share this post


Link to post
Share on other sites

...

Assuming you're working in metres and need 1mm of accuracy, this isn't much of a problem unless your game world is a few thousand kilometers across. Fixed point grants you a few more orders of magnitude, but at those scales you'd soon have to switch to a hierarchy of coordinate systems anyway.

Assuming 1mm of accuracy, and taking into account rounding and such, the slightly-over-6 digits of precision in a float, this allows for a 1km range. If that's enough for all times -- fine, no issue. If you might ever want 10km or 20km, or maybe 100km at some time in the future, you have a problem.

 

Using a 32bit fixed point number with 1/1024m (0,97mm) resolution, you can go for a range of 4194km, which is enough for pretty much everyone who doesn't want to simulate planetary systems. In other words, it just works and you (probably) never need to think about it.

 

Of course one could just use [tt]double[/tt], and that'll work fine for anything reasonably sized (though Tom Forsynth's OffedOMatic might classify you as "idiot"). Unless of course, you want to simulate a single contiguous thing that is bigger than 100 million kilometers, but that isn't very likely.

 

I'm generally OK with "doing the wrong thing" as long as it works reliably. However, doubles are twice the size necessary, which somewhat puts me off. But I guess it's just a matter of taste.

1

Share this post


Link to post
Share on other sites

Of course one could just use double, and that'll work fine for anything reasonably sized (though Tom Forsynth's OffedOMatic might classify you as "idiot")

Yeah I mostly agree with Tom. The only use that I automatically condone doubles for is storing absolute time values that have sub-millisecond precision (such as you need in any decent game loop). 32-bit integer or float isn't accurate enough if you want to allow for more than a day of up-time, so 64-bit tick-counters are required, and at that point, just converting ticks to seconds and storing them in a double is more convenient (because it avoids keeping around a separate ticksPerSecond integer that the gameplay code has to use when performing absolute-time based calculations).

 

On that note -- all our high precision timers are basically fixed point, counting in arbitrary "ticks", and providing this "ticks per second" that can be used to convert to floating point if required (as above, double-precision for absolute-time and single-precision for delta-times).

this allows for a 1km range

Oh, apparently I dropped a few zeros in my napkin math! I figured about 1000km unsure.png

Edited by Hodgman
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0