AI turn stuck after naval combat

Leoreth

Bofurin
Retired Moderator
Joined
Aug 23, 2009
Messages
38,058
Location
風鈴高等学校
I need some help with a hard to debug issue. What happens is the following:
- Player ends the turn letting the AIs take their turn
- The AI decides to attack one of the player's naval units with one of theirs
- "Waiting for other players to finish their turns" never goes away and the game remains stuck

I investigated what is happening with logging some more and here is some additional information that may be relevant:
- I think where the code is stuck is CvGame::updateMoves() where a player is checked for busy units. If a player has no busy (and no ready) units "setAutomoves(true)" is called, ostensibly triggering the move of the next unit. However, the stuck AI player has a busy unit, being the one which attacked the player's unit.
- The unit is considered busy because both its attacked unit and attacked plot are not NULL. These are set to NULL when combat ends
- My understanding is that it's quite normal that they are not NULL for a while until combat is resolved and animated. It seems that CvGame::updateTimers() is responsible for resolving additional steps in the combat evaluation. It seems this function is not called at all. I compared this with normal combat evaluations where updateTimers() is called multiple times until the combat was done.
- I have no idea what the reason of updateTimers() not being called is. Maybe the code is stuck somewhere else but I have no clue where to start.
- Something else that may be relevant: both the attacking and the defending unit have a retreat chance. However it does not matter if the attacking unit retreats or not (forced the latter by disabling the retreat check), the combat will not properly end.

This occurred in my mod so I cannot easily share the save but if someone has any idea what might be going on here or what I could do to further debug this it would help a lot.
 
I ran into an issue kind of like that with WTP. The issue turned out to be that complete kill requires all units. The timing of combat is as follows:
  1. combat starts
  2. combat is resolved. Dead unit gets the dying flag
  3. game logic moves on
  4. combat animation is displayed
  5. combat is done. The dying unit is removed from memory
This seems simple enough and it works most of the time. The AI can kill a unit and move on doing AI stuff without having to wait for you to watch the combat.

The problem is step 3. If the game logic detects that the player has no units or cities left, it can remove the player from the game. The dying unit is then removed. Once the game reaches the combat, the game asks the now gone (NULL) unit to perform combat animation and since it never informs back that it's done, the game is stuck.

I fixed this by not allowing removal of players until all units returned false for isCombat().

Diff for a fix: https://github.com/We-the-People-civ4col-mod/Mod/commit/07dd8430f3c962d3d7301ad60240b278645a14e9

I'm not sure if this is related, but it's the only thing I can think of.


Another note. If I get a completely frozen game, I profile it. Whatever loop is stuck will use 100% of the CPU time. It will not tell you what went wrong, but knowing where to look for the issue is a great start.
 
It's not that any of the involved players dies while combat is resolved, so that doesn't seem to be the issue.

But using the profiler is a great idea, I will try that.
 
Back
Top Bottom