Internal deterministic math.#626
Conversation
|
I was trying to solve a similar problem 2 days ago where floats and double precision causes an issue when counting their decimals due to how they are stored in memory, i just saw you're storing decimal precision as two Strings, so i was wondering how much memory a single class would need to be stored? and how many memory allocations can occur for precise math operations? I know it was made to solve some specific issues so it won't be used heavily, but it really makes me interested about seeing it in action and the optimizations that it can have to make it more efficient ie. creating a TinyString class to get rid of all the String overhead that is not needed for the newly added Classes. |
I don't store 2 strings, i store a long number (it is 8 bytes, see the header for fint) the code to convert the number to a string is the one that produces a string. EDIT: sorry for not answering the second thing; there is no allocation per operation, unless you num(String) it. |
|
As a random guy who is making online games for 2 years full-time, and I even tried making my own netcoding back-end, my question is how does this work?
99999+99999 will return the same result on all computers. The main problem with non-deterministic (random) values is that players are on a different state and cannot even hash-sync. So is this for floats only? If yes, which use-cases does it cover? |
This is to replace float in a game as a conscious choice, yes. But there is some context missing and, yes, there are other uses other than determinism, let me explain everything. WARNING, HIGH AUTISM About determinismWhile summing up numbers will return the same result in most platforms and architectures most of the time, that is not the case for square root, sine, cosine and division. There are some reasons for that, maybe one operation gets switched around at compile time because it's easy in one architecture but it's too intensive on the next, maybe it uses a instruction that behaves slightly different across architectures, or maybe the architecture uses more or less bits per operation to handle overflow, etc. However, this number does have its use cases beyond determinism. Beyond determinismBroad use cases:
And so on. Niche/rare/stretch use cases:
|
|
Reminder to self: rebase when told to, squash then push. |
Adds an internal number (still not available in the editor) called FInt, it does deterministic math, AKA math that produces the exact same results in any computer given the same input.
"Why?" -> All netcode has been suffering for decades with lack of determinism, I hope somebody uses this while I'm gone, please. Without determinism many things are impossible or difficult, such as: letting the server validate the client's game state with a hash - skips many expensive operations, rollback netcode syncing - the float operations are different from machine to machine, lockstep syncing - same problem as rollback netcode, edge case reduction - float precision causes many edge cases, especially in physics, resulting in many permanent ifs and elses.
"How?" -> I used a Q12 number (1Q12 = 4096i), and made a number (FInt) and a vector (Vector2FI), and the operations they need to function. I also made hyper-optimized math for it in MathFI (math_funcs_deterministic .h and .cpp)
"What is the use case?" -> In any numeric operation where you want all computers to come up with the same result given the same input AND a precision of 1/4096 is tolerable, you use this number.
Cheers.