Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gather command and the Yo-Yo effect #10827

Open
SomeTroglodyte opened this issue Nov 30, 2024 · 5 comments
Open

Gather command and the Yo-Yo effect #10827

SomeTroglodyte opened this issue Nov 30, 2024 · 5 comments
Labels
mechanics Issues and PRs about changing how the game works

Comments

@SomeTroglodyte
Copy link
Contributor

SomeTroglodyte commented Nov 30, 2024

Problem Description

In a few situations, escort ships told to move to some target will accelerate to the max1 right up to reaching the target, causing them to overshoot and circle back in an almost endless loop . Obviously, you will hardly notice with vanilla freighters, but with fast ships it can get quite funny.

This happens for the "Gather" command, flotsam pickup under the "Harvest" command, and less noticeably for AI ships doing surveillance - as far as I can tell.

Yo-Yo video
Peek.2024-11-29.CircleAround.mp4

Related Issue Links

Found none - I don't do the other three discussion platforms mentioned.
The gather command was recently affected by the introduced then reverted "hold fire" command though, but I see no need to link these.

Desired Solution

Decelerate before reaching destination obviously, just like e.g. for landing and boarding.

Alternate Gather Video
Peek.2024-11-29.MoveTo.mp4
Patch producing the above
Subject: [PATCH] Smarter "Gather" command
---
Index: source/AI.cpp
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/source/AI.cpp b/source/AI.cpp
--- a/source/AI.cpp	(revision 99080039e5fb26cf6397c75947249c97939a944e)
+++ b/source/AI.cpp	(date 1732913467096)
@@ -1784,7 +1784,8 @@
 		if(ship.GetFormationPattern())
 			MoveInFormation(ship, command);
 		else
-			CircleAround(ship, command, *target);
+			MoveTo(ship, command, target->Position(), target->Velocity(), 1., 1.);
 	}
 	else
 		MoveIndependent(ship, command);

It's a nice touch that the method causing the yo-yo effect is actually called CircleAround. This patch is not PR-worthy, however, because:

  • MoveTo won't use afterburners, as can be seen or heard in the demo video.
  • So, boarding and landing won't use afterburners either - but in many situations there's absolutely no reason not to, and the player might be happy to save a few RL seconds.
  • Haven't investigated the possible interactions for ships with zero thrust and only afterburner for forward movement. I suspect but am not even sure those have special code to allow them - at least you can make the outfitter's max speed prediction jump wildly down by installing a thruster...
  • There's some code duplication between these two plus AI::PickUp, likely some more. My gut feeling says it would be best to consolidate them, possibly with some bitmask flag to control specialized behaviour.
  • For harvesting, the "yo-yo" can actually get much worse than for gather - because they change targets and often miss I guess. Yet, "fixing" AI::PickUp isn't as trivial - arriving with zero speed isn't the goal, ideally one would plan a pickup point vector that already factors the next flotsam piece in, and that would need far better skills than mine. Also, the misses seem to be systematic and I haven't been able to formalize any theory on why so far.

Alternative Approaches

🤷

Footnotes

  1. including afterburners if they have them - and the "are we cold/charged/fueled enough to use them" check is good

@TomGoodIdea TomGoodIdea added the mechanics Issues and PRs about changing how the game works label Nov 30, 2024
@tibetiroka
Copy link
Member

Honestly, I'm not a huge fan of 'gather' stacking all of your ships under your flagship. It makes it difficult to select individual ships, and looks extremely crowded.

It would make sense to be more accurate for picking up flotsam, though.

@petervdmeer
Copy link
Member

This Yo-Yo effect for fast ships already exists in the game for many years. I always thought that this was an intentional effect (with a poor mans implementation) to let fast fighters/fast interceptors behave differently. (But that doesn't make much sense now that I think about it.)

Making the gather behavior the same for all ships makes sense; no need to let fast ships behave differently than slow ships for gathering. (I think Gather tries to perform some sort of flocking behavior, where ships are not fully stacked on top of each-other.)

@TheGiraffe3
Copy link
Contributor

isn't this what formations are for?
I agree that it can sometimes be a problem in combat, but you've got to give the enemy a chance...
I guess essentially, gather is "deathball mode" and formations are "trained warriors mode".

I think that yo-yoing is fine; you walk a finer line.

@SomeTroglodyte
Copy link
Contributor Author

Thanks for the input, and reminder: this is a "thinking about options" thing, not production code.

Next video:
Peek.2024-12-01.MoveTo.mp4
Patch that was produced with:
Index: source/AI.cpp
<+>UTF-8
===================================================================
diff --git a/source/AI.cpp b/source/AI.cpp
--- a/source/AI.cpp	(revision 8051714b72846cf98b818cd201d5cd4d7b766350)
+++ b/source/AI.cpp	(revision 6e2798fd769af2aed75d15e9c592955562e3a044)
@@ -1784,7 +1784,7 @@
 		if(ship.GetFormationPattern())
 			MoveInFormation(ship, command);
 		else
-			CircleAround(ship, command, *target);
+			MoveTo(ship, command, target->Position(), target->Velocity(), 60., 15.);
 	}
 	else
 		MoveIndependent(ship, command);
@@ -2447,10 +2447,16 @@
 	// In order for a ship to use their afterburner, they must also have the forward
 	// command active. Therefore, if this ship should use its afterburner, use the
 	// max velocity with afterburner thrust included.
-	double maxVelocity = ship.MaxVelocity(ShouldUseAfterburner(ship)) * .99;
+	const bool shouldBurn = ShouldUseAfterburner(ship);
+	double maxVelocity = ship.MaxVelocity(shouldBurn) * .99;
 	if(isFacing && (velocity.LengthSquared() <= maxVelocity * maxVelocity
 			|| dp.Unit().Dot(velocity.Unit()) < .95))
+	{
 		command |= Command::FORWARD;
+		// If the ship is far away enough the ship should use the afterburner.
+		if(dp.Length() > 750. && shouldBurn)
+			command |= Command::AFTERBURNER;
+	}
 	else if(shouldReverse)
 	{
 		command.SetTurn(TurnToward(ship, velocity));

Save: Desding Desda.txt.zip

... those are no-thrusters ships. They now afterburn with slowdown, and don't bunch up as much (grâce aux derniers paramêtres pour MoveTo) ... I'm pretty sure in vanilla those wouldn't gather at all, and also wouldn't be able to land on a planet, because MoveTo did consider afterburners for determining max speed, but didn't actually command them, probably assuming the frame tick code would do that, but I haven't observed that...

difficult to select

That's pretty universal, I prefer the left escort list for that anyway.

for picking up flotsam

As said, that was the initial trigger but so far I won't try to touch that code.

Formations

I haven't even bothered to teach myself the UI for that... But yes formations bypass the patch here entirely.

thought that this was an intentional

Probably, at least that method name is a strong indicator. But:

  • Suspension of disbelief: There's crew on those escorts or equivalent autopilot, so one would expect a result as if I told a human, sufficiently trained, pilot to "move over there please". Not "fly in ellipses like Niels Bohr's atom model please".
  • Game usecase: Steer battle, transfer cargo, poor man's "Hold fire" (because they no longer turn to aim, only to navigate)... All those are better served my way not the yo-yo way... IMHO.

@SomeTroglodyte
Copy link
Contributor Author

OK, last comment - I've since patched PickUp too, and been playing with this in for weeks now, and it's way better in all respects...

  • Ships now use afterburners to reach a wormhole, ship-to-board or planet quicker, and that's something you really notice with all those fighters ending up 25000 units or more off system center in those few missions where you're required to "destroy" them too (makes you wonder how your flagship knows where they are with tactical scan power way below that)
  • As said, makes No-thrusters, afterburner only ships actually viable
  • The radius and slow parameters of MoveTo serve nicely to "un-bunch" the gathered flock, 60/15 is nice but maybe a little higher numbers would be better. Anybody help testing?
PickUp patch
Subject: [PATCH] Improve harvesting pickup by enabling some slowing down before reaching the target
---
Index: source/AI.cpp
<+>UTF-8
===================================================================
diff --git a/source/AI.cpp b/source/AI.cpp
--- a/source/AI.cpp	(revision 2127556228a10edb6a311a943b4a3209cb4958b6)
+++ b/source/AI.cpp	(revision 565de0e15c0f735813dfb7f089e75acc795a1dc9)
@@ -2859,6 +2859,18 @@
 	time += degreesToTurn / ship.TurnRate();
 	p += v * time;
 
+	// Limit "overshooting": Having a speed of one-third max without afterburners, in the direction of the line from the ship's
+	// current position to the intercept point, at the intercept, might be better to pick up the next flotsam than full throttle.
+	bool shouldReverse = false;
+	Point targetVelocity = p.Unit() * min(300., vMax * 0.333);
+	StoppingPoint(ship, targetVelocity, shouldReverse);
+	if(shouldReverse)
+	{
+		command.SetTurn(TurnToward(ship, ship.Velocity()));
+		command |= Command::BACK;
+		return;
+	}
+
 	// Move toward the target.
 	command.SetTurn(TurnToward(ship, p));
 	double dp = p.Unit().Dot(ship.Facing().Unit());
  • Harvesting with fast ships that have a long flotsam detection range (my "BlindAsABat" branch and lotsa scanners) is - gut estimate - at least 500% more efficient than vanilla, in terms of "pop all minables in Zubeneschamali, Postverta or Patir with an uber weapon then see how much they are able to pick up in the limited time until the flotsam times out"
  • No more "Niels Bohr atom model" where harversting Escorts fly in tightening ellipses around a flotsam, they target properly, no longer accelerate until too late, and chances that they are able to "chain" pickups like a human would are way up - from never to you can see it happen regularly
  • The Fetri'sei in Patir do fine, subjective impression even a little better

Big CON and why I have little drive to prettify this into a PR: Code duplication and how to deal with it in C++. If anyone want to take a shot - any patch I publish here is "public domain" within ES and can be freely reused by any contributor within endless-sky.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mechanics Issues and PRs about changing how the game works
Projects
None yet
Development

No branches or pull requests

5 participants