Skip to content

Conversation

@FloPinguin
Copy link
Contributor

@FloPinguin FloPinguin commented Dec 2, 2025

Description:

I closed my previous PR #2533 which was already reviewed by evan but not yet merged because I noticed some issues.
Which led me to changing the enemy selection entirely.

Nations / Bots previously had a fixed enemy which they kept for 100 ticks (10 seconds). This could make them react too late and feel slow. Now they are a bit more responsive.

But the main benefit: Without a fixed enemy we can do multiple sendAttack() on the same tick, which allowed me to give impossible nations extremely efficient parallel bot attacks:

2025-12-02-19-00-36_g088wvHG.mp4

Previously nations were so slow in taking out bots that you could even encircle them on the Archiran map...
Now they are like 200% faster (but only on the impossible difficulty)

Nuke enemy selection

Previously, the enemy for troop attacks and nukes was identical. Now, as we no longer have a fixed enemy in BotBehaviour, I added findBestNukeTarget() to select better nuke-targets. I will probably open a PR soon which makes nations nuke the crown :)

Betrayal logic

While revamping the attack logic I had to work on the betrayal logic, which was quite confusing, with many negations. And the betrayals were just random.
So I made it easier to understand with maybeBetrayAndAttack().
Now it does betray friends if we have 10 times more troops than them. I will improve that method in a future PR, but already now it should be better than just betraying randomly.

Attack order

Previously, nations attacked in this order:

  • TerraNullius (Untaken land and nuked territory)
  • Bots
  • Retaliate against incoming attacks

Now its in this order:

  • TerraNullius (Untaken land)
  • Retaliate against incoming attacks
  • Bots
  • TerraNullius (Nuked territory)

So the changes are these:

  • After throwing a nuke onto a nation, they will no longer ignore incoming attacks. Previously they attacked the nuked territory first.
  • Nations now retaliate against incoming attacks before attacking bots. Previously you could attack a nation but they did not care because there were still bots left.

I also changed the attack order of bots a bit (retaliate before attacking randoms), but that isn't even noticeable.

Big bug fixed

Additionally, I fixed a big bug: selectEnemy() oftentimes returned null (because of enemySanityCheck) and therefore no attack happened.
This was especially visible in games where nations are surrounded by friends (Team games and nations vs humans).
This was also the reason why Enzo could play nations vs humans in singleplayer and NO NATION of the much bigger nation team would try to attack him.

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
  • I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced

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

FloPinguin

@FloPinguin FloPinguin requested a review from a team as a code owner December 2, 2025 20:53
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 2, 2025

Walkthrough

This pull request centralizes and refactors bot attack decision-making by moving target selection logic from execution classes into BotBehavior. BotExecution delegates to attackRandomTarget(), FakeHumanExecution uses attackBestTarget(), and BotBehavior introduces new targeting methods while removing emoji tracking from execution classes and updating method signatures for null-safety.

Changes

Cohort / File(s) Summary
Attack Delegation
src/core/execution/BotExecution.ts
Replaced inline target selection with single call to BotBehavior.attackRandomTarget(), eliminating per-enemy checks and early returns in the maybeAttack flow.
Execution Refactor & Emoji Removal
src/core/execution/FakeHumanExecution.ts
Removed EmojiExecution imports and EMOJI_HECKLE tracking; refactored border/enemy detection; replaced per-enemy attack sequences with behavior-driven attackBestTarget() call; updated method signatures: sendBoatRandomly (added default parameter), maybeSendNuke (now accepts nullable target), sendNuke (added targetPlayer parameter).
Targeting Pipeline & State Tracking
src/core/execution/utils/BotBehavior.ts
Introduced new state (botAttackTroopsSent, lastEmojiSent); replaced legacy enemy tracking with new targeting methods: findIncomingAttackPlayer, getNeighborTraitorToAttack, attackBestTarget, attackBots, maybeBetrayAndAttack, findBestNukeTarget, findNearestIslandEnemy; refactored attack execution (sendAttack, sendLandAttack, sendBoatAttack); made EMOJI_HECKLE internal; added calculateBotAttackTroops and maybeSendEmoji.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • New targeting pipeline in BotBehavior: Verify logic correctness for attackBestTarget prioritization (retaliation, bot targeting, betrayal, nuked territory, most hated, weakest nearby, island-adjacent).
  • Method signature changes: Confirm all callers updated for nullable parameters in maybeSendNuke(other: Player | null) and new targetPlayer parameter in sendNuke.
  • State tracking migration: Review lastEmojiSent relocation from FakeHumanExecution to BotBehavior and throttling logic in maybeSendEmoji.
  • Boat/ship handling: Validate sendBoatRandomly default parameter usage and TransportShipExecution routing in sendBoatAttack.
  • Null-safety guards: Check all new methods handle null/undefined targets correctly, especially in border detection and emoji emission.

Possibly related PRs

Suggested labels

Feature - AI, Balance Tweak

Suggested reviewers

  • evanpelle
  • scottanderson

Poem

🤖 Targets now speak through one clear voice,
BotBehavior claims the choice—
Retaliate, betray, or strike with might,
Enemies beware the coordinated fight! ⚔️

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Revamp nation/bot enemy selection 🗡️' clearly summarizes the main change: a comprehensive overhaul of how nations and bots select their enemies, which is the central focus of all three modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The pull request description clearly relates to the changeset, detailing removal of fixed-enemy behavior, improvements to enemy selection, and bug fixes in nation/bot attack logic.

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.

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.

1 participant