Opened 7 years ago

Last modified 3 years ago

#4340 new enhancement

[PATCH] Allow units to react when their path is obstructed / Change attack orders to not be forced

Reported by: wraitii Owned by: wraitii
Priority: Should Have Milestone: Backlog
Component: Simulation Keywords: pathfinding patch design
Cc: scythetwirler Patch: Phab:D15

Description (last modified by Silier)

One of the long-standing issues with the pathfinder is that units cannot tell when their path was obstructed, they can only react if the path fails entirely. Having specific behavior for an obstructed path, however, may be desirable (see below).

I implemented a git branch for those changes with 2 commits: https://github.com/wraitii/0ad/commits/MoveObstructedOptim

The first commit is just the back-end ability: send a MessageObstructed message the first time you're obstructed. The second commit is a behavior change in UnitAI.

Currently, when units are ordered to attack an entity, this order is "forced". Units will, unless their stance is violent, always try to attack that entity specifically. If their stance is violent, they will respond to being attacked by counter-attacking. My second commit changes the Attack order to not be forced (and then changes ShouldAbandonChange to use player LOS instead of unit vision, otherwise it reacts weirdly). This helps a little.

More importantly, I also leverage the "MoveObstructed" message. Now if units are going to attack neater entity, and they run in an enemy unit, they will try and attack it even before that enemy unit attacks them.

Those two changes mean that when you order a group of units to attack another, the unit's behavior is now much more natural: they will attack the first entity they run into (kind of like an attack-move). This creates "fronts" of combat, just try it on combat demo huge and you'll see what I mean. Please note: this does not mean you can't order units to attack another specifically. They still do that. Just if they run into an issue along the way, they will change their mind more often.

I also implemented an optimization to FindNewTargets: units will first try the 8 closest units, then if none were acceptable retry with all units. This makes that function generally much faster with a large number of units, and does not change behavior much (if anything, it improves it since units will be biased towards units close to them).

NB: patch has one problem: we should still allow the player to force an attack (for example if you want to destroy rams). One possible behavior I can think of would be double clicking, and/or a shortcut.

Attachments (1)

Capture d’écran 2016-11-12 à 09.52.27.png (151.4 KB ) - added by wraitii 7 years ago.
Graphs of activity, above is SVN, below is patched.

Download all attachments as: .zip

Change History (17)

by wraitii, 7 years ago

Graphs of activity, above is SVN, below is patched.

comment:1 by Stan, 7 years ago

Can't you just return something like playerChoseTarget ? return : findTheNearest8Units ?

comment:2 by fatherbushido, 7 years ago

What is described in the graph ?

comment:3 by wraitii, 7 years ago

Stan: I do not understand the question

Fatherbushido: that's the smoothed time per frame for, in black, the update Components function, and in red, the "FindNewTargets" function ins UnitAI. Note that they should be added to get the total frame time.

As you can see, this patch makes FindNewTargets much quicker, and overall smoothes the update because units stop earlier and create a "front" of combat.

Edit: obviously the top one is the original one. Note also that this has no graphical elements at all.

Last edited 7 years ago by wraitii (previous) (diff)

comment:4 by Stan, 7 years ago

I'm not sure having units being too smart is a good thing, since it will allow more micro in battle where strategy is key, ie for rams, So I'd rather have my units forced to attack what I click, instead of having them pick the nearest target.

comment:5 by elexis, 7 years ago

Cc: scythetwirler added

scythetwirler your input on game design is required here, as I had a similar impression that this might be confusing to the player.

comment:6 by elexis, 7 years ago

Milestone: Alpha 22Work In Progress

Moving to the new WIP milestone.

comment:7 by bb, 7 years ago

The problem of not being able to give a force attack can easily be solved by setting UnitAI L5147 back to true (not sure why you changed this in the first place). This will lead to the following behaviour: the selection will first target the forced attacked unit until that dies, after that the will start using the obstruction messages (as they get an unforced order via FindNewTargets) when there path is obstructed, so we still win the performance and fronts will still appear.

Shouldn't the MoveObstructed function be also used for chasing units?

Ranged units use will now have the same behaviour, I think this is ok, but we need to keep non-melee units in mind to (before we break them).

Maybe healers/gatherers could use same sort of behaviour? (And maybe there are more cases, but it shouldn't break performance ofc).

The changes in AttackEntitiesByPreference only change the outcome when preferred classes are set in the attack template, but as the are hardly used, (and are deprecated a bit IMO, I would better use an DPS/range anyway) the changes are ok IMO.


Some style issues: UnitAI L1869 Split check over several lines + useless parenthesis L1870-72 useless parenthesis L4035, L5147 Don't forget spaces in objects L6067 use ++valid >= 8

The source code looks good, but as I am no pathfinding expert, I cannot judge wheter the code is 100% ok.

comment:8 by wraitii, 7 years ago

The reason for the change from true to false is that the behavior you described is undesirable in the first place. It's what i'm trying to avoid with this patch.

comment:9 by elexis, 7 years ago

Still believe if the player clicks on a unit, that the units should go and attack that enemy, even if they are being attacked and blocked by other units.

The analysis is correct that units trying to reach blocked targets can cause a performance impact (as they walk instead of stand and fight) and also expose the units to the enemies units. It should still be the players decision which unit behavior is desired (focusing siege or a hero, or buildings with rams) and the default should be attacking the selected IMO.

Perhaps it is more a question of educating players and could be improved with a better GUI. Players who set their units to violent or repeatedly send stop commands to their units will also attack their closest enemy units and thus address these 2 problems. These fact are not known enough. Having attack-move instead of attack by default would also alleviate this problem.

comment:10 by wraitii, 7 years ago

attack-move instead of attack by default would be fine by me but it'd lead to exactly the same behavior as removing "force": unit won't attack the target always.

I remain convinced that attacking necessarily the target enemy first is the wrong decision. Now, the problem is that in both cases we are trying to guess what the plane wants, which is difficult. We may experiment with some specifics: -I a unit was not attacking, and gets an order attack, force is "false", i.e. equivalent to attack-move (sorta) -if a unit already has an attacking order, assume that this one is meant to be "noon specifically target this unit" and force is true.

This also should have the effect that a "double click" attack will force, and single click won't.

What do you think?

comment:11 by bb, 7 years ago

Why would we create such a mess? Orders depending on previous order is not a clean approach IMO. And this way we cannot use the double click as some sort of "hotkey" for all order types, as it is already used for one (and it won't be clear to the player if one order has another function). So we unnecessary block a key combination.

Also what is your wanted behaviour? As mine is "undesirable" (which I don't see why), it should conflict with yours. IMO when a player orders a selection to attack a target, they should simply attack that target and not be distracted by blocking units.

comment:12 by elexis, 7 years ago

Single click = attack-walk and doubleclick = attack as defaults might work, but if players are able to chose (and they should be), then they might disagree with the performance-optimized defaults. Double-click implementation should be detected in the gui engine, not with simulation orders depending on previous orders (refs #4414).

comment:13 by wraitii, 7 years ago

Ok for allowing the player to choose and single click/double click split. Will change the patch to reflect that.

comment:14 by elexis, 7 years ago

Keywords: rfc removed

comment:15 by Imarok, 5 years ago

Component: UI & SimulationSimulation

Move tickets to Simulation as UI & Simulation got some sub components.

comment:16 by Silier, 3 years ago

Description: modified (diff)
Milestone: Work In ProgressBacklog
Owner: set to wraitii
Patch: Phab:D15
Note: See TracTickets for help on using tickets.