Nodes/ComfyUI-Games/Tic Tac Toe Game
ComfyUI Node

Tic Tac Toe Game

Tic Tac Toe inside ComfyUI, with a CPU that plays medium by default

By GraftingRayman·Created 8 months ago·Updated 2 months ago· 0
Tic Tac Toe Game
  • image
  • IMAGE

The TicTacToeNode is the smallest and most honest game in ComfyUI-Games: a full tic-tac-toe board living inside a ComfyUI node, playable against the CPU or a human on the same machine. It's not going to eat your afternoon the way the pack's Pac-Man will, but that's fine - it's the node you drop in when you want a 30-second distraction between generations, not a forty-minute arcade session. It also proves the pack's trick better than any of its siblings, because the gap between "node" and "game" has never been wider.

How it works: pure frontend, zero backend drama

Read the node's Python and you'll swear you're looking at a placeholder:

def play_tictactoe(self, image):
    return (image,)

One image tensor in, the identical tensor out. All of the actual game - the 3×3 grid, X and O turn logic, the win detection, the draw handling - runs in web/js/tictactoe.js, which extends ComfyUI so a canvas widget renders inside the node when you add it to a graph. The AI is a proper difficulty ladder (getRandomMove for easy, getMediumMove, getHardMove), there's a PvP mode if you'd rather lose to a human, and the backend contributes nothing but the pass-through plus a /tictactoe/highscores route that stores your win/loss record in tictactoe_highscores.json in the pack folder.

And the usual two truths apply. First, the game only runs in the browser UI - execute the workflow headless or via API and the node is a silent no-op. Second, your input image is not the board. No matter what you wire in, the game draws its own grid and never looks at the tensor. The image input is there to give the node a port to hang on in a workflow; treat it as a bus stop, not a destination.

Inputs and outputs

From the info_schema, the surface is minimal:

  • Input: image (IMAGE, required) - passed through unchanged.
  • Output: IMAGE - same tensor out.

Everything you can actually change - difficulty, CPU-vs-PvP mode, starting a new round - lives inside the canvas widget, so there are no node parameters to fiddle with. The only persistence is the win/loss scoreboard written to tictactoe_highscores.json.

Installing ComfyUI-Games

This is one of six games in the pack, so one install gets you the whole collection. Use ComfyUI Manager and search for ComfyUI-Games, or:

cd ComfyUI/custom_nodes
git clone https://github.com/GraftingRayman/ComfyUI-Games

Restart ComfyUI. No requirements.txt, no model files, no VRAM cost - the only server-side dependency is aiohttp, which ships with ComfyUI already. For a pack that embeds six games, the install footprint is nearly invisible.

Common issues

  • "My image came out the other side unchanged." Working as designed. It's a passthrough; the game is in the widget.
  • High scores reset after updating the pack. They're a plain JSON file inside custom_nodes/ComfyUI-Games/; overwriting the folder clears them.
  • The CPU seems to let you win on easy. That's getRandomMove - literally random moves. Medium is the real game.
  • Red "Node Loaded" lines at startup. The pack prints one per game. Cosmetic noise.

It's the pack's smallest toy and it knows it. But it's also the cheapest way to spend thirty seconds of render time you'll find in the entire node graph - and beating the CPU on hard never gets old.

Categorygames

Inputs (1)

NameTypeDefaultDescription
imageIMAGE

Outputs (1)

NameTypeDescription
IMAGEIMAGE