Skip to content

Make TileDirection.INVALID safe to use (#397) - #998

Open
Billytifft wants to merge 1 commit into
C7-Game:Developmentfrom
Billytifft:billy/tiledirection-invalid
Open

Billytifft wants to merge 1 commit into
C7-Game:Developmentfrom
Billytifft:billy/tiledirection-invalid

Conversation

@Billytifft

Copy link
Copy Markdown
Contributor

Closes #397

Summary

Adding a TileDirection.INVALID value used to crash the game (e.g. System.ArgumentOutOfRangeException in Tile.HasRiverCrossing) because several places iterated the enum with Enum.GetValues(typeof(TileDirection)), leaking the new member into the map's tile.neighbors dictionary and from there into movement/pathing.

This PR:

  1. Adds TileDirection.INVALID — appended at the end of the enum, so the existing % 8 arithmetic in MapGenerator and the serialized facingDirection values in SaveUnit are unaffected.
  2. Adds TileDirectionExtensions.All (an explicit array of the 8 real directions) and switches GameMap.computeNeighbors and ImportCiv3 to iterate it instead of Enum.GetValues(...), so INVALID can never be injected into the neighbors dictionary or tile knowledge.
  3. Makes the switch-style helpers INVALID-safe instead of throwing: HasRiverCrossing returns false, Reversed / RotatedCounterClockwise90Degrees return INVALID, and ToCoordDiff returns (0, 0).

Verified locally: dotnet build (0 errors), dotnet test (56 passed, 13 skipped), dotnet format C7/C7.sln whitespace --verify-no-changes (clean).

Question for reviewers

C7/Animations/AnimationManager.cs:143-144 carries a TODO left over from this exact issue — the author wanted to add TileDirection.INVALID as the fallback for flicRowToAnimationDirection but couldn't because adding the value crashed the game (the very bug #397 tracks). That fallback currently silently returns TileDirection.SOUTHEAST.

With this PR, INVALID is safe to use, so that TODO can finally be implemented (the fallback could return TileDirection.INVALID instead of guessing SOUTHEAST). I left AnimationManager.cs untouched to keep this PR small — would you prefer that TODO be implemented in this PR or in a separate one?

@ajhalme

ajhalme commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Seems reasonable. Not sure if an explicit Invalid enum is that much better than just raising an error, which we currently have, but I suppose this can reduce crashing in some unexpected situations.

The AnimationManager change should go in this PR as well, as that's the driver for the change, the comment, and the GH issue. Returning INVALID instead of SOUTHEAST for the animation "row" seems reasonable: if there's an unexpected animation that we don't handle, it shouldn't interfere with the others.

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.

Adding a new TileDirection.INVALID value causes existing code to crash

2 participants