C7-Game / Prototype

An early-stage, open-source 4X strategy game
https://c7-game.github.io/
MIT License
34 stars 9 forks source link

Crash due to failing to remove zombie unit from tile #323

Closed QuintillusCFC closed 1 year ago

QuintillusCFC commented 2 years ago

This part of MapUnitExtensions.cs can cause a crash:

            if (!unit.location.unitsOnTile.Remove(unit))
                throw new System.Exception("Failed to remove unit from tile it's supposed to be on");

It seems to happen semi-randomly when barbarians move, although the fact that it's barbarians moving may be coincidental as they move a lot and engage in combat a lot. I might also be seeing it more because I've been using the Shift key to skip animations, and there might be a timing issue involved in it.

Now that we have good logging, we should probably avoid unhandled exceptions like this, and prefer logging errors. But it's also curious that this is happening at all.

Adding to Carthage so someone can pick it up if they please, it's never good to leave crashes around.

QuintillusCFC commented 2 years ago

Just had it happen again after two galleys fought. Not sure if that's always the case? Have also seen a bunch of times where it doesn't crash after galleys fight. And then it did happen when I pressed Shift during the fight.

QuintillusCFC commented 2 years ago

Investigating at a breakpoint, it seems that both units wound up on the same tile and it tries to remove units from what presumably is the other tile in the combat. Although it claims both of those units have 3 hitpoints (when it should be 0 and 1), and there's another tile right next to the combat that has two healthy galleys.

I think this would be easier to investigate with a fixed seed, and with the error converted to an error first rather than a crash, so the map could be queried for Tile IDs afterwards. As it is, it's just tough to evaluate having new circumstances every time it happens.

QuintillusCFC commented 1 year ago

Reproducing info: With commit 7976165cc24556993e279a7ea7ccc6622bc1cf71

And seed: 1626442457 (or 1453020662? It prints the seed twice with different values for some reason)

On turn 19, this happens via BarbarianAI.cs, line 37

Fortify the Carthage units, enter Observer Mode. On turn 11 Carthage should destroy a barb camp. Play till turn 18, add a breakpoint.

QuintillusCFC commented 1 year ago

Unit location = 10, 66

It's a galley moving northwest.

QuintillusCFC commented 1 year ago

The barb camp west of Rome spawns a galley for turn 13.

Rome sends a galley out on turn 16.

Starting turn 18, Rome's galley is at 9, 69; the barbarian one is at 10, 66.

Rome's galley moves north to 9, 67.

The barbarian galley moves to 9, 67 (which is southwest, not northwest).

They fight; the attacker (barbarian) is defeated.

Oh, but the BarbarianAI keeps going. It doesn't know that the unit is dead, it just sees that it has move movement points left. So we have a zombie galley rising from the deep to challenge Rome again.

The zombie galley now moves to 9, 65 (it sunk at 9, 67).

The crash is because the game can't remove it from 9, 65.

Not sure where I got "northwest" from 9 minutes ago, but this sequence makes sense at least.