diff --git a/tuxbot/cogs/Dev/dev.py b/tuxbot/cogs/Dev/dev.py
index ba698d1..59080b7 100644
--- a/tuxbot/cogs/Dev/dev.py
+++ b/tuxbot/cogs/Dev/dev.py
@@ -1,6 +1,13 @@
 import logging
+import random
+import string
+
+import discord
+from discord.enums import ButtonStyle
+from discord import ui, SelectOption
 from discord.ext import commands
 
+from tuxbot.cogs.Dev.functions.utils import TicTacToe
 from tuxbot.core.bot import Tux
 from tuxbot.core.i18n import (
     Translator,
@@ -12,6 +19,57 @@ log = logging.getLogger("tuxbot.cogs.Dev")
 _ = Translator("Dev", __file__)
 
 
+class Test(ui.View):
+    @ui.button(label="label1", disabled=True, style=ButtonStyle.grey)
+    async def label1(self, button, interaction):
+        print("label1")
+
+        print(type(button), button)
+        print(type(interaction), interaction)
+
+    @ui.button(label="label2", style=ButtonStyle.danger)
+    async def label2(self, button, interaction):
+        print("label2")
+
+        print(type(button), button)
+        print(type(interaction), interaction)
+
+
+class Test2(ui.View):
+    @ui.select(
+        placeholder="placeholder",
+        min_values=1,
+        max_values=3,
+        options=[
+            SelectOption(
+                label="label1",
+                value="value1",
+                description="description1",
+            ),
+            SelectOption(
+                label="label2",
+                value="value2",
+                description="description2",
+            ),
+            SelectOption(
+                label="label3",
+                value="value3",
+                description="description3",
+            ),
+            SelectOption(
+                label="label4",
+                value="value4",
+                description="description4",
+            ),
+        ],
+    )
+    async def select1(self, *args, **kwargs):
+        print("select1")
+
+        print(args)
+        print(kwargs)
+
+
 class Dev(commands.Cog):
     def __init__(self, bot: Tux):
         self.bot = bot
@@ -29,3 +87,56 @@ class Dev(commands.Cog):
             await ctx.send(str(int([])))  # type: ignore
         elif crash_type == "IndexError":
             await ctx.send(str([0][5]))
+
+    # =========================================================================
+
+    @command_extra(name="test", deletable=True)
+    @checks.is_owner()
+    async def _test(self, ctx: ContextPlus):
+        button = ui.Button(
+            style=ButtonStyle.primary,
+            label="test",
+        )
+        button2 = ui.Button(
+            style=ButtonStyle.secondary,
+            label="test2",
+        )
+        button3 = ui.Button(
+            style=ButtonStyle.green,
+            label="test3",
+        )
+        button4 = ui.Button(
+            style=ButtonStyle.blurple,
+            label="test4",
+        )
+        button5 = ui.Button(
+            style=ButtonStyle.danger,
+            label="test5",
+        )
+
+        view = ui.View()
+        view.add_item(button)
+        view.add_item(button2)
+        view.add_item(button3)
+        view.add_item(button4)
+        view.add_item(button5)
+
+        await ctx.send("test", view=view)
+
+    # =========================================================================
+
+    @command_extra(name="test2", deletable=True)
+    @checks.is_owner()
+    async def _test2(self, ctx: ContextPlus):
+        await ctx.send(view=Test2())
+
+    # =========================================================================
+
+    @command_extra(name="test3", deletable=False)
+    async def _test3(self, ctx: ContextPlus, opponent: discord.Member):
+        game = await ctx.send(f"Turn: {ctx.author}")
+        game_id = "".join(random.choices(string.ascii_letters, k=10))
+
+        view = TicTacToe(ctx.message.author, opponent, game, game_id=game_id)
+
+        await game.edit(content=f"Turn: {ctx.author}", view=view)
diff --git a/tuxbot/cogs/Dev/functions/utils.py b/tuxbot/cogs/Dev/functions/utils.py
new file mode 100644
index 0000000..1cbec1b
--- /dev/null
+++ b/tuxbot/cogs/Dev/functions/utils.py
@@ -0,0 +1,161 @@
+from typing import List, Optional, Dict
+
+import discord
+from discord import ui
+from discord.enums import ButtonStyle
+
+
+class TicTacToe(ui.View):
+    turn: int = 0
+    grid: Dict[str, List[List[Optional[int]]]] = {}
+    win: bool = False
+
+    def __init__(self, player: discord.Member, opponent: discord.Member,
+                 game: discord.Message, game_id: str):
+        super().__init__()
+
+        self.player = player
+        self.opponent = opponent
+        self.game = game
+
+        self.game_id = game_id
+
+        self.init_grid()
+
+    def init_grid(self):
+        self.grid[self.game_id]: List[List[Optional[int]]] = [
+            [None for _ in range(3)]
+            for _ in range(3)
+        ]
+
+    def get_grid(self):
+        return self.grid[self.game_id]
+
+    def get_turn(self):
+        return self.player if self.turn == 0 else self.opponent
+
+    def get_emoji(self):
+        return "❌" if self.turn == 0 else "⭕"
+
+    def check_win(self):
+        wins = [
+            [self.get_grid()[0][0], self.get_grid()[0][1], self.get_grid()[0][2]],
+            [self.get_grid()[1][0], self.get_grid()[1][1], self.get_grid()[1][2]],
+            [self.get_grid()[2][0], self.get_grid()[2][1], self.get_grid()[2][2]],
+            [self.get_grid()[0][0], self.get_grid()[1][0], self.get_grid()[2][0]],
+            [self.get_grid()[0][1], self.get_grid()[1][1], self.get_grid()[2][1]],
+            [self.get_grid()[0][2], self.get_grid()[1][2], self.get_grid()[2][2]],
+            [self.get_grid()[0][0], self.get_grid()[1][1], self.get_grid()[2][2]],
+            [self.get_grid()[2][0], self.get_grid()[1][1], self.get_grid()[0][2]],
+        ]
+
+        return [self.turn, self.turn, self.turn] in wins
+
+    async def congrats(self):
+        self.win = True
+        del self.grid[self.game_id]
+
+        await self.game.edit(
+            content=f"{self.get_turn()} wins!",
+            view=self
+        )
+
+    def set_pos(self, i, j):
+        self.get_grid()[i][j] = self.turn
+
+    async def next_turn(self, i, j):
+        if self.win:
+            return
+
+        self.set_pos(i, j)
+
+        if self.check_win():
+            return await self.congrats()
+
+        self.turn = 1 if self.turn == 0 else 0
+
+        await self.game.edit(
+            content=f"Turn {self.get_turn()}",
+            view=self
+        )
+
+    # =========================================================================
+    # =========================================================================
+
+    @ui.button(label="•", style=ButtonStyle.grey, group=1)
+    async def button_1(self, button: ui.Button,
+                       interaction: discord.Interaction):
+        if button.label == "•" and interaction.user == self.get_turn():
+            button.label = ""
+            button.emoji = self.get_emoji()
+            await self.next_turn(0, 0)
+
+    @ui.button(label="•", style=ButtonStyle.grey, group=1)
+    async def button_2(self, button: ui.Button,
+                       interaction: discord.Interaction):
+        if button.label == "•" and interaction.user == self.get_turn():
+            button.label = ""
+            button.emoji = self.get_emoji()
+            await self.next_turn(0, 1)
+
+    @ui.button(label="•", style=ButtonStyle.grey, group=1)
+    async def button_3(self, button: ui.Button,
+                       interaction: discord.Interaction):
+        if button.label == "•" and interaction.user == self.get_turn():
+            button.label = ""
+            button.emoji = self.get_emoji()
+            await self.next_turn(0, 2)
+
+    # =========================================================================
+    # =========================================================================
+
+    @ui.button(label="•", style=ButtonStyle.grey, group=2)
+    async def button_4(self, button: ui.Button,
+                       interaction: discord.Interaction):
+        if button.label == "•" and interaction.user == self.get_turn():
+            button.label = ""
+            button.emoji = self.get_emoji()
+            await self.next_turn(1, 0)
+
+    @ui.button(label="•", style=ButtonStyle.grey, group=2)
+    async def button_5(self, button: ui.Button,
+                       interaction: discord.Interaction):
+        if button.label == "•" and interaction.user == self.get_turn():
+            button.label = ""
+            button.emoji = self.get_emoji()
+            await self.next_turn(1, 1)
+
+    @ui.button(label="•", style=ButtonStyle.grey, group=2)
+    async def button_6(self, button: ui.Button,
+                       interaction: discord.Interaction):
+        if button.label == "•" and interaction.user == self.get_turn():
+            button.label = ""
+            button.emoji = self.get_emoji()
+            await self.next_turn(1, 2)
+
+    # =========================================================================
+    # =========================================================================
+
+    @ui.button(label="•", style=ButtonStyle.grey, group=3)
+    async def button_7(self, button: ui.Button,
+                       interaction: discord.Interaction):
+        if button.label == "•" and interaction.user == self.get_turn():
+            button.label = ""
+            button.emoji = self.get_emoji()
+            await self.next_turn(2, 0)
+
+    @ui.button(label="•", style=ButtonStyle.grey, group=3)
+    async def button_8(self, button: ui.Button,
+                       interaction: discord.Interaction):
+        if button.label == "•" and interaction.user == self.get_turn():
+            button.label = ""
+            button.emoji = self.get_emoji()
+            await self.next_turn(2, 1)
+
+    @ui.button(label="•", style=ButtonStyle.grey, group=3)
+    async def button_9(self, button: ui.Button,
+                       interaction: discord.Interaction):
+        if button.label == "•" and interaction.user == self.get_turn():
+            button.label = ""
+            button.emoji = self.get_emoji()
+            await self.next_turn(2, 2)