Page MenuHomeWildfire Games

Use correct distance for determining nearest dropsite
ClosedPublic

Authored by temple on Dec 20 2017, 5:00 PM.

Details

Summary

The nearest dropsite is calculated using the center of the dropsite (in red).

With the patch it will instead use the nearest point on the dropsite (in green).

(Strictly speaking, units have obstructions and ranges, so the new calculation isn't completely correct, but it's close enough.)

Test Plan

We can quit the loop if we know that the distance to later dropsites will never be better than the current best. Since the range manager sorts dropsites by the distance to their centers, all we need to do is figure out how far away the nearest point on an obstruction can be from the center of the obstruction. Civic centers are at most 40m on a side, so a corner can't be farther than 40/sqrt(2) = 28m away from the center, but in the patch I use 40m to be safe.

I don't think performance will be an issue, but I should probably test that.

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.Dec 20 2017, 5:00 PM
Owners added a subscriber: Restricted Owners Package.Dec 20 2017, 5:00 PM
Vulcan added a subscriber: Vulcan.Dec 20 2017, 5:53 PM

Successful build - Chance fights ever on the side of the prudent.

Updating workspaces...
Build (release)...
Build (debug)...
Running release tests...
Running cxxtest tests (308 tests)....................................................................................................................................................................................................................................................................................................................OK!
Running debug tests...
Running cxxtest tests (308 tests)....................................................................................................................................................................................................................................................................................................................OK!
Checking XML files...

Tested performance a bit, didn't seem to have a noticeable effect.

mimo added a subscriber: mimo.Dec 20 2017, 6:45 PM

A bit out of context, but as you did quite some patches with resourceDropsites lately, and are familiar with the hierarchicalPathfinder, some checks on dropsite accessibility for a next patch would be nice :)
On naval maps, units sometimes try to deposit their resources in a dropsite from another island if it is nearer (in straight line) than those on their own island.

Seems like a good idea, agree with mimo that accessibility ought to be checked (perhaps another diff though indeed).

I'll give this a look over the WE, thanks for the patch

elexis added a subscriber: elexis.Dec 21 2017, 12:42 PM
elexis added inline comments.
binaries/data/mods/public/simulation/components/UnitAI.js
4159 ↗(On Diff #4828)

let bestEnt; (our ESLint linter used by Vulcan points that out)

4162 ↗(On Diff #4828)

Should the constant be removed or moved to the UnitAI, ResourceGatherer, ResourceDropsite template? (Dunno, might be stupid, but always my first thought when seeing magic numbers)

4175 ↗(On Diff #4828)

(was wondering if it should become isShip = foo... and a continue statement too, doesn't matter though)

In D1160#46504, @mimo wrote:

A bit out of context, but as you did quite some patches with resourceDropsites lately, and are familiar with the hierarchicalPathfinder, some checks on dropsite accessibility for a next patch would be nice :)

I did think about how the walking distance to a dropsite might be different than the straight line distance, for example if a wall was in the way. But that seems too complicated to deal with.

Looking at global regions in the hierarchical pathfinder (once D53 is done) might be possible, although it's not trivial since buildings themselves aren't in a region (see FindGoalRegions). Oh, I guess you might be able to use the terrain-only passability classes (which might be what you're more familiar with, with the AI), but then "islands" created by trees or walls wouldn't count.

On naval maps, units sometimes try to deposit their resources in a dropsite from another island if it is nearer (in straight line) than those on their own island.

That seems pretty crazy to me, that units could be gathering resources so far away from a dropsite that there's a nearer one on another island. Why not just build a new dropsite closer to the resource?

binaries/data/mods/public/simulation/components/UnitAI.js
4162 ↗(On Diff #4828)

There's magic range constants in the other FindNearby functions, but in this one we search the whole map for dropsites. (I wondered if we should have a max range here too, but fish and hunts can be really far away.) We want this constant so we can quit the loop early rather than calculate the nearest point on every dropsite. We could move it to a template, but I don't expect the value to ever be different.

4175 ↗(On Diff #4828)

I thought about it, but didn't do it.

In D1160#46585, @temple wrote:

walking distance

Indeed the idea by players and the design of the pathfinder is that units always chose the shortest path if they need a path.
Computing the walking distance would mean computing a path right? So can't be done anyway until the the pathfinder is lightning fast.

On naval maps, units sometimes try to deposit their resources in a dropsite from another island if it is nearer (in straight line) than those on their own island.

That seems pretty crazy to me, that units could be gathering resources so far away from a dropsite that there's a nearer one on another island.

Unlikely, but surely possible and if it happens, the player would certainly consider it a bug if the units clinch at the shoreline.

Why not just build a new dropsite closer to the resource?

That means that the bug is recoverable, but it's still considered a bug IMO
So wouldn't be wrong to create a ticket IMO

mimo added a comment.Dec 21 2017, 7:13 PM
In D1160#46585, @temple wrote:
In D1160#46504, @mimo wrote:

Looking at global regions in the hierarchical pathfinder (once D53 is done) might be possible, although it's not trivial since buildings themselves aren't in a region (see FindGoalRegions). Oh, I guess you might be able to use the terrain-only passability classes (which might be what you're more familiar with, with the AI), but then "islands" created by trees or walls wouldn't count.

yes, i was thinking to the the terrain-only passability classes (as used by the AI). I agree that would not cover wall cases, but still is worth to have (but it was just a proposition of course if you were looking for new patches).

On naval maps, units sometimes try to deposit their resources in a dropsite from another island if it is nearer (in straight line) than those on their own island.

That seems pretty crazy to me, that units could be gathering resources so far away from a dropsite that there's a nearer one on another island. Why not just build a new dropsite closer to the resource?

I had seen it several times in petra (and added a protection for it in the ai) when islands were very nearby. That's still a bug: the player should be allowed to gather far from its dropsite (even if not the best strategy) without having its units idling on the shoreline. There are cases where UnitAI make gatherers drift far away from the dropsite, or you may miss wood to build a new dropsite, or whatever could happen.

In D1160#46605, @mimo wrote:

without having its units idling on the shoreline.

(Although they don't actually go idle. If they did then it'd be easier spot them and take corrective action by building a new dropsite. I played a game last night where a similar thing happened, units getting stuck trying to gather from trees on a hill.

It would be nice if for a23 we could get a split of D13 to detect when this happens and tell units to abort the order. I've looked at this before, maybe I'll try to spend some more time on it.)

(but it was just a proposition of course if you were looking for new patches).

Sure. (I count.. 42 patches at the moment, plus others I've worked on but haven't submitted. We need more reviewers. :) )

Patch reads correct and ideal (and is deseparately needed).

binaries/data/mods/public/simulation/components/UnitAI.js
4162 ↗(On Diff #4828)

(Sorry for the non-actionable argument, maybe it helps in some other patch.)

(In general:

I don't expect the value to ever be different.

True, but not the deciding argument. The argument to not move the magic constant now should be that the cost/benefit ratio of having it moved is too low. Hardcoding and magic constatns still are anti-patterns.
For this constant, if one ever needs to reconsider all numbers in this coordinate system (for instance when changing the coordinate system) and all numbers are in one place then only one place has to be changed. Also the crazy mod argument.)

Correctness of having this constant:
A worse location can only be found if the greatest footprint (or half of the diagonal or something) of all dropsite templates is larger than maxDifference.
A worse than optimal performance can only be found if maxDifference is greater than the greatest footprint of all templates.

(So perhaps the constant should be computed in a universe that doesn't collapse after a finite amount of time)

4169 ↗(On Diff #4828)

(I saw an anti-pattern but I exceeded my pedantery limit already)

4175 ↗(On Diff #4828)

(Probably still worth the performance optimization when committing)

4194 ↗(On Diff #4828)

(could be a line and few characters shorter with a ternary)
(correct to test for cmpObstruction since ResourceDropsite doesn't imply it by design or code)

4202 ↗(On Diff #4828)

(correct, since dist starts with infinity, it will also return a dropsite if the first dropsite > maxDifference)

source/simulation2/components/CCmpObstruction.cpp
501 ↗(On Diff #4828)

(possibly warn before the caller processes an invalid number)

In D1160#46613, @temple wrote:

I played a game last night where a similar thing happened, units getting stuck trying to gather from trees on a hill.

and you didn't post a one-sentence ticket with a replayfile </3 refs #4902

Sure. (I count.. 42 patches at the moment, plus others I've worked on but haven't submitted. We need more reviewers. :) )

(or chose ways to become more economical with the existing reviewers).

bb added a subscriber: bb.Dec 22 2017, 9:34 PM
bb added inline comments.
source/simulation2/components/CCmpObstruction.cpp
497 ↗(On Diff #4828)

Instead of calculating the nearest point, you could calculate the distance directly with Geometry:: DistanceToSquare,

if you want to allow non square obstructions too, or even any type of obstruction, it might be good to add this in obstructionManager like we have in D981. Looking at this, it might be worth to split those functions in the comparing ranges and calculating the distances.

temple marked 6 inline comments as done.Dec 23 2017, 7:42 PM
temple added inline comments.
source/simulation2/components/CCmpObstruction.cpp
497 ↗(On Diff #4828)

Right. Initially I was trying to avoid explicitly calculating the distance, instead using comparisons.

temple updated this revision to Diff 4914.Dec 23 2017, 7:44 PM
temple marked an inline comment as done.

Use distance rather than point, move to obstruction manager.

(Can I have that ungatherable tree replay?)

(thx linting)

binaries/data/mods/public/simulation/components/UnitAI.js
4169 ↗(On Diff #4828)

(thanks, you got it :-) )

Successful build - Chance fights ever on the side of the prudent.

Updating workspaces...
Build (release)...
Build (debug)...
Running release tests...
Running cxxtest tests (308 tests)....................................................................................................................................................................................................................................................................................................................OK!
Running debug tests...
Running cxxtest tests (308 tests)....................................................................................................................................................................................................................................................................................................................OK!
Checking XML files...
wraitii accepted this revision.Jan 21 2018, 3:58 PM

Some naming refinements as inline comments, otherwise looks good. Thanks for the patch!

binaries/data/mods/public/simulation/components/UnitAI.js
4166 ↗(On Diff #4914)

nearby => nearbyDropsites

4170 ↗(On Diff #4914)

ent => dropsite

source/simulation2/components/CCmpObstructionManager.cpp
659 ↗(On Diff #4914)

To avoid any confusion I'd name those pointX and pointZ

source/simulation2/components/ICmpObstructionManager.h
162 ↗(On Diff #4914)

+ Returns -1 if the entity is out of this world

This revision is now accepted and ready to land.Jan 21 2018, 3:58 PM
temple updated this revision to Diff 5400.Jan 21 2018, 10:12 PM
This revision was automatically updated to reflect the committed changes.
temple added inline comments.Jan 21 2018, 10:23 PM
source/simulation2/components/CCmpObstructionManager.cpp
659 ↗(On Diff #4914)

I'll do px, pz to be consistent with D981.