Skip to content

Improve "Better troop management for nations 🤖"#4278

Open
FloPinguin wants to merge 5 commits into
mainfrom
allow-retaliation-bypass-troop-cap
Open

Improve "Better troop management for nations 🤖"#4278
FloPinguin wants to merge 5 commits into
mainfrom
allow-retaliation-bypass-troop-cap

Conversation

@FloPinguin

@FloPinguin FloPinguin commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Description:

Allow Hard/Impossible nations to retaliate and expand freely

Previously, nations on Hard/Impossible difficulty could be stuck unable to fight back if their troopSendCap or isAttackTooWeak checks blocked them from sending enough troops. @legan320 on the main discord noticed it. Now:

  • troopSendCap raises the cap to at least the total incoming attack troops, so nations can match the force being used against them
  • isAttackTooWeak bypasses the 20% minimum check entirely when under attack
  • troopSendCap no longer applies when attacking Terra Nullius, so nations can always expand into unowned land with full troops

All checks still apply normally for unprovoked attacks against other players.

Please complete the following:

  • I have added screenshots for all UI updates
  • I process any text displayed to the user through translateText() and I've added it to the en.json file
  • I have added relevant tests to the test directory

Please put your Discord username so you can be contacted if a bug or regression is found:

FloPinguin

@FloPinguin FloPinguin added this to the v32 milestone Jun 14, 2026
@FloPinguin FloPinguin requested a review from a team as a code owner June 14, 2026 16:14
@FloPinguin FloPinguin added the Gameplay Features that affect gameplay label Jun 14, 2026
@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

AiAttackBehavior allows Hard/Impossible FFA nations under incoming attack to ignore the isAttackTooWeak check and receive a raised troopSendCap equal to max(neighbor-cap, totalIncoming). Simultaneously, troop caps are applied conditionally based on target ownership: player-owned destinations receive the cap, while TerraNullius targets do not. A new test confirms the retaliation bypass end-to-end.

Changes

Retaliation Logic and Destination-Aware Troop Limiting

Layer / File(s) Summary
isAttackTooWeak bypass and troopSendCap retaliation raise
src/core/execution/utils/AiAttackBehavior.ts
isAttackTooWeak early-exits with false when the player has any incoming attacks. troopSendCap preserves the neighbor-based cap calculation, sums all incoming attack troops, and returns max(neighbor-cap, totalIncoming). JSDoc updated to describe the retaliation exception.
Destination-aware troop cap application
src/core/execution/utils/AiAttackBehavior.ts
attackWithRandomBoat applies troopSendCap only for player-owned destinations (otherwise unlimited). sendBoatAttackToNearbyTerraNullius removes troopSendCap clamping entirely. sendLandAttack applies the neighbor cap only for player targets, not for TerraNullius.
Test: under-attack nation bypasses cap
tests/AiAttackBehavior.test.ts
Imports AttackExecution, adds a test that computes the neighbor-based hard cap, schedules a simulated incoming AttackExecution, then asserts the retaliation attack is created with startTroops greater than the previously computed cap.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • openfrontio/OpenFrontIO#4265: Modifies the same isAttackTooWeak and troopSendCap functions in AiAttackBehavior.ts to bypass troop restrictions under a different special case (GameMode.Team).
  • openfrontio/OpenFrontIO#4239: Changes Hard/Impossible logic in the same troopSendCap and isAttackTooWeak code paths in AiAttackBehavior.ts.

Suggested reviewers

  • evanpelle

Poem

A nation besieged gains strength to reply,
isAttackTooWeak falls when enemies fly!
The cap rises high: max(neighbor, incoming) true,
Strike back with the power of armies who flew. ⚔️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is vague and uses non-descriptive phrasing with an emoji. It references 'better troop management' but doesn't clearly convey the specific change: allowing retaliation when under attack. Replace with a more specific title that captures the main change, such as 'Allow Hard/Impossible nations to retaliate when under attack' or 'Enable retaliation for nations under attack regardless of troop caps'.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description clearly relates to the changeset, describing the relaxed gating for retaliation attacks, expanded troop limits, and separate adjustments for different target types.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/AiAttackBehavior.test.ts`:
- Around line 572-601: The test named "Hard: nation under attack bypasses
troopSendCap and isAttackTooWeak" does not properly verify the bypass logic
because the cap naturally increases after the neighbor loses troops to the
initial attack. To actually test the bypass, modify the test setup so that the
incoming attack amount (the 10_000 troops from the neighbor) exceeds the
neighbor-based cap calculation, ensuring the bypass logic max(neighborCap,
totalIncoming) is what allows the retaliation to exceed the normal cap, not just
natural cap fluctuations from troop losses.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 884635a1-3cdb-4b4c-b4a7-ac895ed793e5

📥 Commits

Reviewing files that changed from the base of the PR and between bb5e7dc and 0b5b395.

📒 Files selected for processing (2)
  • src/core/execution/utils/AiAttackBehavior.ts
  • tests/AiAttackBehavior.test.ts

Comment thread tests/AiAttackBehavior.test.ts
@github-project-automation github-project-automation Bot moved this from Triage to Development in OpenFront Release Management Jun 14, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 14, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/core/execution/utils/AiAttackBehavior.ts`:
- Around line 140-142: The retaliation-only cap relaxation logic in
troopSendCap() and isAttackTooWeak() is being applied to all attacks when there
are incoming attacks, not just retaliations. To fix this, modify the call paths
to these methods to explicitly pass the retaliation context or attacker
identity. Update troopSendCap() to accept a parameter indicating whether the
current attack is a retaliation and who the incoming attacker is, then apply the
relaxed cap limits only when the destination owner is the actual incoming
attacker. Apply this same retaliation context passing logic to all call sites of
these methods throughout the attack behavior code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9f848ce9-1d01-4edd-8c42-d455603017e7

📥 Commits

Reviewing files that changed from the base of the PR and between 9161557 and 5a27a51.

📒 Files selected for processing (1)
  • src/core/execution/utils/AiAttackBehavior.ts

Comment thread src/core/execution/utils/AiAttackBehavior.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Gameplay Features that affect gameplay

Projects

Status: Development

Development

Successfully merging this pull request may close these issues.

1 participant