LibBlockAttributes
LibBlockAttributes copied to clipboard
Deprecate (and eventually remove) fractions, and move to fixed-integer for fluid amounts
First of all, fractions have some distinct advantages: they can handle any denominator (although not every combination at once) and I'm somewhat sad to see them go. All advantages / disadvantages being compared here should only affect developers though (and potentially pack developers or recipe writers, since fluid amounts can be parsed from json files).
However they have some pretty big drawbacks that make them much, much worse than fixed-integer denominators:
- They require devs to think about the unlikely situation where adding two fractions might overflow.
- Since Java doesn't have operator overloading devs need to use methods to perform basic arithmetic, which is painful.
- Any operation that isn't directly provided by the
FluidAmount
class needs to be written manually, which can be fairly complicated since it's mixed fractions (whole + numerator / denominator
).
LBA will most likely move to 81000
as the new fixed denominator, in line with fabric's transfer API. (This isn't a certainty though). LBA will also use long
as it's base type rather than int
, since 81000
(or 81k
) only permits a maximum fluid tank size of 26,000 buckets - less than normal amount of oil in a single buildcraft oil well! Some of the maths below assume using 81k though, so they'd need to be reconsidered if LBA doesn't end up with 81k. The main consideration for a denominator is that it needs to be divisible by 81 (as there's 81 nuggets of gold per block), and it shouldn't be too big (since players will actually have to think about 1/<unit>
buckets of fluid).
To make the transition a bit easier I'll be sticking to my usual "keep backwards compatibility for long periods of time" ideal, to give lots of time for mods to move away from fractions. However, some parts will be kept around forever:
- Parsing fractions as fluid amounts. Fractions that don't use the same base (or a divisor of the real base) will result in rounding (likely up). Fluid amount parsing utilities in LBA will continue to parse fluid amounts in buckets, so
"amount": "1"
would result in an amount of 1 bucket (81000
base units), not 1 base unit (or1/81000
, or~0.0000123 buckets
- Reading fractions as amounts from NBT. (Like how LBA still supports reading 1620-based fluid amounts), since there's no reason to ever remove this. (
FluidVolume
currently saves 1620-based values asAmount
, fraction based amounts asAmountF
, and 81k will probably be saved asAmount81k
)
As for display:
- LBA will continue to display fluid amounts as decimal, at least by default. This will use exactly 0, 3, or 6 digits of precision depending on whether the amount of fluid divides evenly by
81000
,81
, or1
. For example1.670 Buckets
for135270
or1.670099
for135278
- LBA will gain a config option (set by the user) to instead display with 3 digits of precision and display the fraction at the end, similar to fabric's transfer API. (For example
1.670 + ⁸/₈₁ Buckets
for135278
). I might add a config option to not use super/subscripts though, and instead just display8/81
instead. Note that display only matters where devs use LBA's classes and methods for tooltips - likeFluidUnit
orFluidUnitSet
, or methods that call it likeFluidVolume.addTooltipNameAmount
.