Page MenuHomeWildfire Games

Fix the building construction rate
ClosedPublic

Authored by temple on May 19 2017, 8:00 PM.

Details

Reviewers
fatherbushido
wraitii
Group Reviewers
Restricted Owners Package(Owns No Changed Paths)
Commits
rP19625: Fix the building construction rate for multiple units.
Summary

As described here, units often construct buildings at a slower rate than they should. This should fix that.

Test Plan

Test that buildings are constructed at the correct rate.

Diff Detail

Repository
rP 0 A.D. Public Repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

temple created this revision.May 19 2017, 8:00 PM
leper added reviewers: Restricted Owners Package, fatherbushido.May 19 2017, 8:03 PM
leper added a subscriber: leper.

Add yourself to the credits as described in https://trac.wildfiregames.com/wiki/SubmittingPatches.

temple updated this revision to Diff 2033.May 19 2017, 8:13 PM

added my name to the credits

wraitii accepted this revision.May 21 2017, 10:09 AM
wraitii added a subscriber: wraitii.

As said on the suggestion thread, nice catch with this bug.

I think ultimately we ought to change the "Build" function to run on a timer when at least one unit is building, so that we don't recompute the exact same thing for X different units several times, but that's for later.

This revision is now accepted and ready to land.May 21 2017, 10:09 AM
This revision was automatically updated to reflect the committed changes.
fatherbushido edited edge metadata.EditedMay 21 2017, 3:54 PM

Note that we have mostly the same part of code in Repairable code (which seems a bit more clean and didn't have that floor issue).
It's also funny that we had the test checked the formula without the floor (but don't caught that as we don't get decimals in it).

ps/trunk/binaries/data/mods/public/simulation/components/Foundation.js
272

That formula is itself a bit strange.
Perhaps I miss something.
That kind of function is most often use to set up a low and an high threshold.

Here we have two cases:

  • work (aka the Builder/Rate) is higher than maxHealth. In that case deltaHP = work
  • work is lower than maxHealth (most expected case). In that case deltaHP = work * this.GetBuildRate() * this.buildMultiplier capped from below by work and maxHealth from above.

That means that if we ask to build 5, if maxHealth is 1000, if we this.GetBuildRate() * this.buildMultiplier is 0.5, then we'll build 5?

I am a bit tired so be lenient if I am wrong.

fatherbushido added a comment.EditedMay 21 2017, 4:50 PM

For the story
rP17609 (no real change)
rP13268 (the work min cap)
rP13267

The floor has old meaning when health was integer. It seems that now rP13268 can be reverted?

ping @wraitii

I didn't know if there would be any unintended consequences so I just made the minimal change by removing floor. But yes I agree that the max/min stuff is wrong or unnecessary. (Max health is checked during cmpHealth.Increase(deltaHP).) So I think this will work the same:
var deltaHP = work * this.GetBuildRate() * this.buildMultiplier;

You're asking if we could ever have this.GetBuildRate() * this.buildMultiplier < 1. I think the smallest GetBuildRate() can be is 5000/1000 = 5hp/s for a wonder (or a field), so we would need buildMultiplier < 0.2. To get that, we'd need over 200 units building it since 200**0.7/200 = 0.204. So I don't think we ever see work > work * this.GetBuildRate() * this.buildMultiplier during a game.

In D521#21410, @temple wrote:

I didn't know if there would be any unintended consequences so I just made the minimal change by removing floor. But yes I agree that the max/min stuff is wrong or unnecessary. (Max health is checked during cmpHealth.Increase(deltaHP).) So I think this will work the same:
var deltaHP = work * this.GetBuildRate() * this.buildMultiplier;

You're asking if we could ever have this.GetBuildRate() * this.buildMultiplier < 1. I think the smallest GetBuildRate() can be is 5000/1000 = 5hp/s for a wonder (or a field), so we would need buildMultiplier < 0.2. To get that, we'd need over 200 units building it since 200**0.7/200 = 0.204. So I don't think we ever see work > work * this.GetBuildRate() * this.buildMultiplier during a game.

Sure you did good in taking care of only what you noticed ;-) (It's not a complain)
But yes, we can have that during a 'game', one should not rely on current template values.

Yes, I was only exploring when that could happen. And to be extra clear, in those cases it should still use deltaHP = work * this.GetBuildRate() * this.buildMultiplier, not deltaHP = work. So the current code is bugged, but it's rare/impossible to produce the bug given the current template values.

While I was fixing this I noticed that the build time tooltip was wrong. I tried to patch that with D522, so please take a look at that if you haven't already. I'll add a screenshot and a bit more explanation.

fatherbushido added a comment.EditedMay 23 2017, 4:46 PM
In D521#21431, @temple wrote:

Yes, I was only exploring when that could happen. And to be extra clear, in those cases it should still use deltaHP = work * this.GetBuildRate() * this.buildMultiplier, not deltaHP = work. So the current code is bugged, but it's rare/impossible to produce the bug given the current template values.

As pointed out above, @wraitii had to used this workaround due to a rounding issue he encountered (cf rP13268). In fact, previously health wasn't decimal but integer so there was that floor.
It seems that with your patch we doesn't need that 'work' threshold anymore.