Version: 6.20
Language: English
Modified: No
Game Start: Budgeted Custom (or Any)
Problem:
Due to the relevant script accidentally leaves the repair rate value as an integer, the repair rate for repair drones only increases by 50MJs at a time.
A ship with a single repair drone should repair exactly 10x faster than the same ship with 0 - However for specific drone amounts and crew skill values, this isn't the case.
For a ship with any number of drones, the repair amount is rounded down to the nearest 50 MJ.
How to Reproduce:
Start a new game using one of the custom start options.
Add a ship with a 0 star pilot and no crew and no repair drones.
Add an identical ship with a 0 star pilot and no crew, but with 1 repair drone.
Damage each ship somewhere below 64% hull so that it can repair, noting the current hull value in MJ.
Note the increase after each repair tick.
The ship with 0 drones will repair at a rate of 7MJ/tick.
The ship with 1 drones will repair at a rate of 50MJ/tick.
The ship with 1 drone should be repairing at 70MJ/tick. It is repairing 29% slower than it should be.
Notes:
This bug can lose up to 49% of the expected repair rate given specific conditions.
Save:
The following save is from a custom creative game, the player is positioned in front of a damaged ship with 1 repair drone, a 0 star pilot, and no crew. You can note the repair amounts as it's health ticks up.
https://drive.google.com/file/d/167FLLm ... sp=sharing
There are also other ships in the save scattered around that I used to test.
The ships with 1 drone and 5 star pilots should repair at 210MJ/tick (compared to 21 of their 0 drone counterparts), but they only repair at a rate of 200MJ/tick.
Unfortunately only the ones with 1 drone will exhibit the bug, as those with increments of 5 (every other ship) end up with expected values ending in 50.
Research:
The offending lines of code is in the engineer.ai script.
I'll give an example of 2 drones, and a crew with 0 skill.
Code: Select all
<set_value name="$repairratefactor" exact="0" />
Code: Select all
<set_value name="$repairratefactor" operation="add" exact="$unitamounts.{$i} * $i" />
repairratefactor = 0 + number of drones
repairratefactor = 2
Code: Select all
<set_value name="$repairratefactor" operation="add" exact="$repairratefactor * $repairmodifier / 25" comment="crew speeds up repair by up to 400% (meaning a fifth of the normal repair time)" />
repairmodifier is defined elsewhere in the script as: "crewskill + 10" with a cap of 100.
So for a 0 star crew, repairmodifier equals 10.
Also rembering that repairratefactor is currenty 2, we have:
repairratefactor = 2 + 2 * 10 / 25
If we simplify it one step we get:
repairratefactor = 2 + (20 / 25)
This seems like it should equal to "2 + 0.8" or "2.8", the problem here is that everything we have dealt with up until now has been an integer (whole number).
When (most) programming languages do math with integers, they throw away anything after the decimal place when dividing one integer by another.
So what happens here is that the "0.8" becomes just a "0", so we get "2 + 0" = "2"
Our crew have effectively contributed nothing! - Admittedly they sucked, but they should still count.
The final repair value in MJ is calculated as the repairratefactor at this step * 50.
So what we get is "2 * 50" or 100MJ repair rate.
When we should have had "50 * 2.8" or 140MJ repair rate.
We have lost a whole 40MJ of repair rate per tick!
Solution 1:
Simply replace the line:
Code: Select all
<set_value name="$repairratefactor" exact="0" />
Code: Select all
<set_value name="$repairratefactor" exact="0f" />
Solution 2:
Simply replace the line:
Code: Select all
<set_value name="$repairratefactor" operation="add" exact="$repairratefactor * $repairmodifier / 25" comment="crew speeds up repair by up to 400% (meaning a fifth of the normal repair time)" />
Code: Select all
<set_value name="$repairratefactor" operation="add" exact="$repairratefactor * $repairmodifier / 25f" comment="crew speeds up repair by up to 400% (meaning a fifth of the normal repair time)" />
Why doesn't this happen when you have 0 repair drones?
Because of these lines:
Code: Select all
<do_else>
<!-- if no builds are underway, repair 10 times more slowly than with just one mk1 drone -->
<set_value name="$repairratefactor" exact="0.1"/>
The reason that this fixes the problem is that instead of setting the the value of repairrate as either "0" or the number of drones - which are both whole numbers (and therefore integers) - it is given as "0.1" which is implicitly a float.
Because it is implicit it doesn't need the "f" afterwards for the programming language to know that decimal places are important.