You can use either doubles to get close but the only real solution is using int64 then converting it to float, unit32/ fixed pt / fractional, when its appropriate for measurement or scaling to “real world” coordinates for and display and or some functions and caches. Problems is simply using doubles everywhere is slow for SIMD lanes, calcs, memory , caches, and such. but for hightly constrained dynamics, reversibility, machine agreement, and the persistent ground truth data model , this uint and fixed point concept mentioned earlier is key: In most practical cases for games, Floats using epsilons and other equality operators are usually ideal and rarely catastrophic, given some care. But see the bottom link comments and the catastrophic effects that can happen, missle crashes and such.
right to your point on RTS this might help:
https://forum.unity.com/threads/fixed-point-number-library-for-c.649609/
This library might help GitHub - stormmuller/fixed-point-types: A C# library for fixed point numbers
or looking in the dotnet vault proposals… Vector128 and exisitng generalized maths if you want simd, burt you can get only vector2,3 4 in floats in .net But you can make your own vectors and arrrays 2d and such.
on a more general note
This problem of nondeterminism affects physics engines, neural networks and reversibilty as well as multiplayer games.
even with constraint solvers and simple Verlet Integration a 5-node pendulum can explode due to floating point errors. you have to damp energy artifiicially by doing 0.00000001 each integration step and carefully choose time steps and coordinate frames. real numbers and infinitesimals are not “real” , argueably, they are a construct and machines cannot agree on them nor can mathematicians. But there is a practical way and its not doubles everywhere, its a hybrid: see here an example a new paper from legendary jos stam , who put the smoke in the first games in the 90s
see this https://www.josstam.com/reversible
[2207.07695v1] An Exact Bitwise Reversible Integrator
So if you watch his demos and see this paper it’s very simple, and you can see how profoundly nondeterministic floats are. i used similar method in a CAD company long ago. So whille he representation and integration steps are are done usng the longs, its a hybrid method.
It doesn’t need any changes in monogame. because then when the determistic part is finished,
you simply divide the target int by a fixed point to get the float. that you can pass to monogame to draw. But would be nice if dotnet made it a bit easier and on par with other languages, theres lot of proposals and discussions in net8 and net 7 already has Vector128 w SIMD you can make stuff 27 x faster…
As far as libaries and such, its hard to find in c#, but Julia and even Swift all come with these homogenous vectors types , with Simd Intrinsics already , Vector2 3, 4 and the Matrix operators used of graphics and physics maths. but generalized Math is possible, and now I think Vector256 has some implemenation in the develop branch . in dotnet. But thats for batch calculation and conversion from uint to float and back.
this is a bit too far out, but Julia already has has Vector2 and in machine learning they use variable bit units now, burn chips with it from IL. For the sake of determinism, performance and reversibility. other radical paradigm changes are
Unum (number format) - Wikipedia(Unum (number format) - Wikipedia
If you want SIMD and this stuff:
if you look at netcore proposals, in the internals, Numerics, generalized math, , and Slik.Maths you might find something helpful. The proposals include some implementation but its looks like a big deal to decide on for the whole netcore, and or numberics or the comminty extensions. They do have a kind of generalized math interface but you have to implement the operators yourself.
In for monogame The compute branch has int32 surfaces now, that might be useful, if you want to do deterministic compute stuff on gpu.
. I can add that Autocads visionary John Walker decided to use doubles floats for its main data storage in .dwg files, since 1982, otherwise CAD drawings would mutate after many edits to where things dont fit , as do those of some of its competitors. Thats one reason why the 40-year old codebase still dominates. doubles or big ints are not high performance, so for display where determinism did not matter, we cached display lists as floats for drawing performance but kept the data model stored as doubles… if zooming too far we could rescale an make a new display list with a differnet scale. His famous solar system zoom was a bit much, but even in a large buildings, significant errors add up, after tons of edits on different machines.
now some of the other Media and game design products sufffer, even 3ds max suffers from drift since its using floats for data storage, from one early bad executive decision.