Skip to content

Add stranded soldier return-search addon#1929

Open
DevOpsOfChaos wants to merge 4 commits intoReturn-To-The-Roots:masterfrom
DevOpsOfChaos:sidequest/stranded-soldier-return-search
Open

Add stranded soldier return-search addon#1929
DevOpsOfChaos wants to merge 4 commits intoReturn-To-The-Roots:masterfrom
DevOpsOfChaos:sidequest/stranded-soldier-return-search

Conversation

@DevOpsOfChaos
Copy link
Copy Markdown

@DevOpsOfChaos DevOpsOfChaos commented May 1, 2026

Summary

This adds an optional STRANDED_SOLDIER_RETURN_SEARCH addon.

The addon controls the fallback search behavior used by stranded soldiers when they are wandering and looking for a reachable own flag with a warehouse connection.

Default behavior is unchanged.

Motivation

When soldiers lose their target or warehouse route, they may start wandering and eventually die if they do not find a reachable own flag with a warehouse connection.

This addon provides optional control over that fallback search behavior:

  • stricter games can reduce the search range
  • default games keep the original behavior
  • easier games can allow staged search escalation for rare stranded-soldier situations

The change is limited to stranded soldiers. Workers and normal routing behavior are not affected.

Options

The addon keeps four explicit options:

  • Default search range (1x): keep the existing soldier search radius and normal soldier try count
  • Reduced search range (0.5x): use a smaller fixed search radius for a stricter/harder setting
  • Extended search range (2x): first search with the default range, then escalate up to 2x before dying
  • Very large search range (4x): first search with the default range, then 2x, then escalate up to 4x before dying

The default option remains the first option, so existing gameplay behavior is preserved unless another option is selected.

Implementation details

This PR adds a new addon:

  • AddonStrandedSoldierReturnSearch
  • AddonId::STRANDED_SOLDIER_RETURN_SEARCH = 0x01100001
  • addon namespace entry: 011 DevOpsOfChaos

The selected option is treated as the maximum stranded-soldier return-search escalation stage:

  • selection 0: 6 tries, fixed radius WANDER_RADIUS_SOLDIERS
  • selection 1: 6 tries, fixed radius WANDER_RADIUS_SOLDIERS / 2
  • selection 2: 12 tries total
    • first 6 tries use WANDER_RADIUS_SOLDIERS
    • final 6 tries use 2 * WANDER_RADIUS_SOLDIERS
  • selection 3: 18 tries total
    • first 6 tries use WANDER_RADIUS_SOLDIERS
    • next 6 tries use 2 * WANDER_RADIUS_SOLDIERS
    • final 6 tries use 4 * WANDER_RADIUS_SOLDIERS

The radius is only used when soldiers are already in the wandering fallback state and are searching for an own flag that can lead back to a warehouse.

The staged behavior uses the existing wander_tryings state. No new serialized fields are added.

Scope / safety notes

This PR intentionally keeps the behavior limited:

  • default behavior is unchanged
  • reduced 0.5x remains a separate fixed-radius hardcore mode and does not use staged escalation
  • only soldiers are affected
  • workers still use the existing worker wandering radius
  • normal soldier routing is unchanged
  • attack routing is unchanged
  • warehouse acceptance rules are unchanged
  • no teleporting
  • no map-wide search
  • no pathfinding shortcut
  • no new serialized state

A stranded soldier still has to find:

  • an own reachable flag
  • a valid route to that flag
  • a warehouse that can accept the soldier

The addon only changes the local search radius and number of wandering search attempts used for this fallback situation.

Validation

Built locally with Visual Studio 2022 / Debug:

  • cmake --build .\build-vs-x64-debug-local --config Debug --target Test_integration

Ran targeted validation:

  • Test_integration.exe --run_test=FigureTests/StrandedSoldierReturnSearch* --report_level=short
    • 4 test cases passed
    • 19 assertions passed
  • Test_integration.exe --run_test=AttackSuite --report_level=short
    • 21 test cases passed
    • 1189 assertions passed
  • Test_integration.exe --run_test=BuildingSuite --report_level=short
    • 7 test cases passed
    • 1727 assertions passed

Ran full integration ctest:

  • ctest --test-dir .\build-vs-x64-debug-local -C Debug -R "^Test_integration$" --output-on-failure
    • passed

Style / whitespace validation:

  • ran clang-format 10.0.0
  • ran git diff --check

Comment thread libs/s25main/addons/AddonStrandedSoldierReturnSearch.h Outdated
@Spikeone
Copy link
Copy Markdown
Member

Spikeone commented May 2, 2026

Thinking about this, would it make sense to make the time also dependent on the range? So they first search in the default range (until they would die) then they search in the 2x range (until they would die again) and then in the 4x range (but this time they die).

@DevOpsOfChaos
Copy link
Copy Markdown
Author

DevOpsOfChaos commented May 2, 2026

Good point. I made the option names explicit and added a reduced 0.5x (range 7) setting.

Default remains the first option, so the current behavior is unchanged unless a different option is selected.

Validation passed locally with clang-format 10.0.0, AttackSuite, and BuildingSuite.

I also agree with the staged search idea.

The current update only makes the fixed options clearer and adds the 0.5x setting. I’ll take another look at changing the larger-range behavior into a progressive search instead: start with the default range first, then escalate to 2x and 4x before the soldier finally dies.

That seems like the better gameplay behavior than applying the larger radius immediately.

@DevOpsOfChaos
Copy link
Copy Markdown
Author

Thinking about this, would it make sense to make the time also dependent on the range? So they first search in the default range (until they would die) then they search in the 2x range (until they would die again) and then in the 4x range (but this time they die).

Done. I changed the larger options to staged escalation instead of applying the larger radius immediately.

2x now searches with the default range first, then escalates to 2x. 4x searches with 1x, then 2x, then 4x.

The reduced 0.5x option stays a separate fixed hardcore setting. No new serialized fields were added.

Comment thread libs/s25main/figures/noFigure.cpp Outdated
@DevOpsOfChaos DevOpsOfChaos force-pushed the sidequest/stranded-soldier-return-search branch from 25cf29a to 1810a42 Compare May 3, 2026 17:15
switch(ggs.getSelection(AddonId::STRANDED_SOLDIER_RETURN_SEARCH))
{
case 1: return STRANDED_SOLDIER_RETURN_SEARCH_RADIUS_REDUCED;
case 2: return wanderTriesLeft > WANDER_TRYINGS_SOLDIERS ? WANDER_RADIUS_SOLDIERS : 2 * WANDER_RADIUS_SOLDIERS;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add short comments for each case? The reason here is not clear.
Maybe add a (file-local) enum for the values instead of using 1,2,3

Logic is correct though: 2==double the attempts --> tries left = (1x, 2x] then normal radius, [0,1x] then double radius

Or I guess named values (e.g. enum) for the cases and a short description would help here. I.e. what was discussed: first default number of attempts use default radius, then doubles with each full attempt/try cycle.

}

/// Radius used only for stranded soldiers looking for a return path to an own warehouse.
/// Normal worker wandering and non-soldier fallback behavior keep using WANDER_RADIUS.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the docstrings to the header please. Also what is "non-soldier fallback behavior" (opposed to "Normal worker wandering")?

@Flamefire
Copy link
Copy Markdown
Member

@Spikeone fine with the current solution?
@DevOpsOfChaos did you test how this actually looks in a real game?

@Spikeone
Copy link
Copy Markdown
Member

Spikeone commented May 3, 2026

fine with the current solution?

Sounds good to me - sadly no 0x option, but that idea may have been a bit over the top, so 👍

@Flamefire
Copy link
Copy Markdown
Member

Sounds good to me - sadly no 0x option, but that idea may have been a bit over the top, so 👍

Like "die immediately"? Yeah, too much for me too ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants