Working on Planetary Annihilation I was tracking down a server crash. Long story short, an integer was overflowing which many steps later led to a bad array access and kaboom.
The overflow worked like this. Building a factory has some amount of WorkLeft that is being done at some Rate. WorkLeft / Rate is TimeLeft. This was in floating point seconds and then converted to 32-bit signed integer milliseconds. 2^31 milliseconds is 24.86 days which should be more than enough for a game that only lasts a couple of hours.
But of course it wasn’t. The problem is that if you have a very slow rate (available material is less than a trickle) combined with a very large amount of work left (asteroid propelling engine) then TimeLeft can be a hilarious large number. In our case this happened pretty rarely because rate was typically either zero or a normal number. Because this was in C++ I couldn’t let the int overflow and had to detect it beforehand. I wrote a whole blog post about this.
It’s surprisingly easy to divide a reasonable large number by a reasonable small number to produce an outrageously large number. For example the circumference of the earth (~40 million meters) divided by the speed of a slug (.0028 meters per second) is 14.3 trillion seconds.
Do I think people need u128 bits of millisecond precision? No. But do I think it’s very plausible to encounter extremely large numbers when working with far more normal orders of magnitude.
I’m not experienced enough with Rust yet to have a strong vote as to what should be done. My current vote is a Result. Because I’ve already written overflow detection code and without a Result I’ll probably have to write it again.