public static int dot(int2 a, int2 b)
 {
     return(a.x * b.x + a.y * b.y);
 }
 public int dot(int2 b)
 {
     return(x * b.x + y * b.y);
 }
        private bool ParseGollyString(Texture2D texture, string golly, int stringIndex, int worldStartX, ref int2 cellPos, ref int prevInt)
        {
            var nextChar = golly[stringIndex];

            if (char.IsDigit(nextChar))
            {
                prevInt = 10 * prevInt + nextChar - 48;
                return(true);
            }
            else if (nextChar == 'o')
            {
                var cellsCount = math.max(1, prevInt);
                var areas      = texture.GetRawTextureData <int>();
                while (cellsCount > 0)
                {
                    cellsCount--;
                    var areaPos   = cellPos / new int2(4, 3);
                    var areaIndex = areaPos.y * texture.width + areaPos.x;
                    var bitMask   = ConwaysWorldUtils.CellBitMask[2 - (cellPos.y % 3)][cellPos.x % 4];
                    areas[areaIndex] |= bitMask;
                    cellPos.x++;
                }
            }
            else if (nextChar == 'b')
            {
                cellPos.x += math.max(1, prevInt);
            }
            else if (nextChar == '$')
            {
                cellPos = new int2(worldStartX, cellPos.y - math.max(1, prevInt));
            }
            else if (nextChar == 10 || nextChar == 13)
            {
                return(true);
            }
            else if (nextChar == '!')
            {
                return(false);
            }
            else
            {
                throw new NotImplementedException($"Unknown char={nextChar}({(int)nextChar}) index={stringIndex}");
            }
            prevInt = 0;
            return(true);
        }