private unsafe AtkComponentButton *GetTileButton(AddonWeeklyPuzzle *addon, int index) => addon->GameBoard[index / 6][index % 6].Button;
        private unsafe bool UpdateGameState(AddonWeeklyPuzzle *addon)
        {
            var stateChanged = false;

            for (int i = 0; i < 36; i++)
            {
                var tileButton          = GetTileButton(addon, i);
                var tileBackgroundImage = GetBackgroundImageNode(tileButton);
                var tileBackgroundTex   = (WeeklyPuzzleTexture)tileBackgroundImage->PartId;

                var newState = Tile.Unknown;
                if (tileBackgroundTex == WeeklyPuzzleTexture.Hidden)
                {
                    newState = Tile.Hidden;
                }
                else if (tileBackgroundTex == WeeklyPuzzleTexture.Blocked)
                {
                    newState = Tile.Blocked;
                }
                else if (tileBackgroundTex == WeeklyPuzzleTexture.Blank)
                {
                    var tileIconImage = GetIconImageNode(tileButton);
                    var tileIconTex   = (WeeklyPuzzlePrizeTexture)tileIconImage->PartId;

                    if (!tileIconImage->AtkResNode.IsVisible)
                    {
                        newState = Tile.Empty;
                    }
                    else
                    {
                        newState = tileIconTex switch
                        {
                            WeeklyPuzzlePrizeTexture.BoxUpperLeft => Tile.BoxUpperLeft,
                            WeeklyPuzzlePrizeTexture.BoxUpperRight => Tile.BoxUpperRight,
                            WeeklyPuzzlePrizeTexture.BoxLowerLeft => Tile.BoxLowerLeft,
                            WeeklyPuzzlePrizeTexture.BoxLowerRight => Tile.BoxLowerRight,
                            WeeklyPuzzlePrizeTexture.ChestUpperLeft => Tile.ChestUpperLeft,
                            WeeklyPuzzlePrizeTexture.ChestUpperRight => Tile.ChestUpperRight,
                            WeeklyPuzzlePrizeTexture.ChestLowerLeft => Tile.ChestLowerLeft,
                            WeeklyPuzzlePrizeTexture.ChestLowerRight => Tile.ChestLowerRight,
                            WeeklyPuzzlePrizeTexture.SwordsUpperLeft => Tile.SwordsUpperLeft,
                            WeeklyPuzzlePrizeTexture.SwordsUpperRight => Tile.SwordsUpperRight,
                            WeeklyPuzzlePrizeTexture.SwordsMiddleLeft => Tile.SwordsMiddleLeft,
                            WeeklyPuzzlePrizeTexture.SwordsMiddleRight => Tile.SwordsMiddleRight,
                            WeeklyPuzzlePrizeTexture.SwordsLowerLeft => Tile.SwordsLowerLeft,
                            WeeklyPuzzlePrizeTexture.SwordsLowerRight => Tile.SwordsLowerRight,
                            WeeklyPuzzlePrizeTexture.Commander => Tile.Commander,
                            _ => throw new Exception($"Unknown tile icon state: {tileIconTex} at index {i}")
                        };

                        var rotation = tileIconImage->AtkResNode.Rotation;
                        if (rotation < 0)
                        {
                            newState |= Tile.RotatedLeft;
                        }
                        else if (rotation > 0)
                        {
                            newState |= Tile.RotatedRight;
                        }
                    }
                }
                else
                {
                    throw new Exception($"Unknown tile bg state: {tileBackgroundTex} at index {i}");
                }

                stateChanged |= GameState[i] != newState;
                GameState[i]  = newState;
            }
            return(stateChanged);
        }