C# Vector3 Opertor Override

  • Obviously i mis-typed the thread name… it’s an “Operator” -.-

Hello,

I’m doing the best i can for using an external “deterministic” math library for computing all floating point operations, the easier way i figured out to do this without extreme work is to override the operators of the different types i will be using, i started from Vector3 but i found a big problem that i can’t find a good way to fix, before spending the whole week i try to ask some advise, this is the current problem:

I cannot override the UnityEngine.Vector3 class since it’s sealed. (or i’m doing it very wrong)

I have figured out an obvious solution… but it does not shine…

Creating a new class like MyVector3 and after implementing all the original Vector3 methods and operators using this in every single piece of code that use Vector3… this solution have the big weakness that any Vector3 computation internal to UnityEngine will use the original one making my work worthless.

How would you proceed in this case?

This is going to be extremely difficult.

Some options that come to mind are to decompile the mscorlib DLL in the unity folder and make your modifications to the System.Single (float) type. This is could be painful.

Also you can spend some design time determining which operations need to be deterministic. It’s possible Camera placement doesn’t have to be deterministic, but Unit movement does. This can reduce the amount of work spent.

You can resort to doing all calculations in a Fixed scale using ints/long/short. This way will do your operations first on a fixed scale and always use those to perform additional calculations, and then have the Transforms approximate those values.

Do you really need it to be fully deterministic? Is there a specific reason that this is a major requirement? Maybe there is a high level solution that avoids you having to rework core data types in a managed language.

Overall if it’s really a major requirement that all float calculations be deterministic, maybe Unity is not a good engine choice. PhysX itself is a non-deterministic physics engine, and it’s using a managed language for scripting limiting your ability to refactor core data types.

Hello,

I try to answer as the best i can:

  1. I need a fully deterministic simulation since i’m working on a MMORTS and having that allow me to share only the user input during a simulation step and all clients can reproduce the deterministic simulation themself without any need of “correction” from the server making the development very easy since i can use a “common” class like “Actions” and use that both for user input and “server” input from other players resulting in a simpler overall work while maintaining a perfectly deterministic approach (the server should run the simulation too just for detecting cheating or such things)

  2. I’m afraid of using fixed scale just for one reason: i’m afraid i could limit myself with that, i should pick a “standard” precision for the conversion and modifying that would be a big problem if i discover it too late and then, even if i optimize it in c# unless i missed something i’ll end up allocating memory for converting the int2float and vice versa, or there is a way to use the engine without any float at all? i’m not aware of that and we speak about a LOT of them.

  3. I know the limit of PhysX, in my game i just have to simulate a sort of “fake” space flight, with very basic phisics (a little of inerthia and back/side/front thruster vectors) it should not be a nightmare to do that, i don’t have collisions, i don’t have “surfaces” is just 3d objects flying around using a very simple physic simulation, you see any fault in this assumption? i can’t see it with my current knowledge.

  4. I would really love to use Unity since being based on Mono i can easily produce a Windows/Mac/Browser version without any problem (the math library i use is cross-platform and pretty efficent in C with a mono .net wrapper) and after all, i’m not a game making genious, the tools provided with Unity and products such as Photon server make this work a LOT easier… and last but not least… C# is the language i use at work, so my knowledge are mostly on that, i’m not able to code in c/c++ or lower level languages and i don’t have the time required to build an experience on that.

Well, this is what i think, i hope you can say all what i said is wrong and i’ll be happy to hear it!

PS: a question, if i avoid to use PhysX at all, if i use c# scripts for all my needs using the appropriate custom floating points classes, can you forecast any situation when unity does “what he want” with the original floats and nullify my work?

  1. I’m gonna assume you got the lock step synchronization in Unity working for RTS networking, but that does make sense as a need for full determinism.

  2. Fixed scales are surprisingly large. For example if you used 1 unit = 1 meter, and using ints for your units, you could have a movable range of 10x the distance from the earth to the moon, or 4 billion meters cubed. Making a fixed scale to millimeters still gives you 4000 km cubed to work with. If that’s still too small using longs, will add approximately 5 billion times more range. You do take a hit doing the conversions, but keep in mind it’s only a quick conversion, once per frame if the object was moved, and doing deterministic floating point calculations without the FPU(which can be the case with deterministic floats) is gonna be a performance hit too.

  3. Makes sense, don’t use PhysX if you require determinism.

  4. I can see that argument, though you can still use Mono without Unity, and it would be easier to override the Single type directly, but you do lose a lot of game making helper that Unity provides.

I still think Fixed scale would be the easiest and most robust, though you are right in that it requires more early design to make sure that your unit scale is well within the acceptable ranges for map sizes, and fluid movement. Although you could still have fluid movement with a larger fixed scale, just have the units interpolate in Update() but move in Fixed scale intervals in FixedUpdate(), similar to how physics keeps it’s motion smooth with slower update cycles.

Easy solve: Don’t use any Unity V3 computation. The second you use it you lose determinism.

Unitys Vector3 is a struct, not a class, so it is implicitly sealed.