I made a realtime 1v1 game with Next.js & Tailwind CSS, learn how
Tags: javascript, react, nextjs, tailwindcss
Published: 2022-02-10 22:13:53

Everyone knows about Wordle the game where you have to guess a 5 letter word and you only have 6 attempts.

So I thought that will be a good idea to make a version where you can play against another player to see who can guess the word first.
And that you can see in realtime the guesses from your opponent.

I called it [WarWordly](https://warwordly.com) and it was product of the day in [Product Hunt](https://www.producthunt.com/posts/warwordly)

## Rules of the game

The rules of the game are simple enough, you start with a valid word and each letter receives a color acording to this rules:

- ⬜️ Gray: the letter is incorrect
- 🟧 Orange: the letter is correct but in the wrong position
- 🟩 Green: the letter is correct and is in the correct position

![Guessing the word](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3qdtghldd59ik6xuj3cf.png)

## Make Wordle a 1v1 game

The idea for this game is that we can compete with another player, and for that we have to see how our opponent is doing, like this:

![Playing against opponent](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7y4lkinmro6xvf1a5dh6.png)

So on the left is our guesses and on the right is our opponent.

## Making it realtime
The main technology used was:

- ▲ [Next.js](https://nextjs.org/) as a React app
- 🔋 [Supabase](https://supabase.com/) for DB, Auth & Realtime
- 🎨 [Tailwind CSS](https://tailwindcss.com/) for styling
- 💾 [SWR](https://swr.vercel.app/) for data fetching

These tools make it so easy right know to start with an idea and make it real so anyone can use it, and why not, make your little game Product of the Day on Product Hunt.

The entire game is Open Source and you can see the [project on GitHub](https://github.com/nicoandrade/warwordly).

We are going to focus on the realtime feature in this post.

## Let's code

On Supabase you can create any kind of PostgreSQL database, but they have a really cool feature where you can create subscription to any table with their [javascript client](https://github.com/supabase/supabase-js).

Just install their client on your project
```
npm install @supabase/supabase-js
```
Then import the client into your page
```javascript
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY)
```
You can grab your `SUPABASE_URL` and `SUPABASE_ANON_KEY` from your Supabase account.

Now we are going to create a [React Hook](https://reactjs.org/docs/hooks-effect.html) to subscribe to our table from our database.

```javascript
import { useEffect } from "react";

useEffect(() => {
    if (!battleId) return;

    // Subscribe to the Battle
    const battleSubscription = supabase
        .from(`battles:id=eq.${battleId}`)
        .on("UPDATE", (payload) => {
            // Updates all the data from the Battle to SWR
            battleMutate(payload.new);
        })
        .subscribe();

    // Cleanup on unmount
    return () => {
        battleSubscription.unsubscribe();
    };
}, [battleId]);
```

This code is where the magic happens, so let's take a closer look 👇.

First we import `useEffect` from React.
Then we create our hook, which is this one:
```javascript
useEffect(() => {
   // code...
}, [battleId]);
```
We use `battleId` as a dependency for the Hook, this is a variable with our Battle ID, since we need the ID to find the battle on our database.

After that all we have to do is use the Supabase JS client to [create a new subscription](https://supabase.com/docs/reference/javascript/subscribe) to our database:
```javascript
// Subscribe to the Battle
const battleSubscription = supabase
    .from(`battles:id=eq.${battleId}`)
    .on("UPDATE", (payload) => {
        // Updates all the data from the Battle to SWR
        battleMutate(payload.new);
    })
    .subscribe();
```
This code sends us a JS object everytime someone makes an `UPDATE` on our database.

This is how we keep track of the guesses from our opponent.

Then we can update the state of the battle using the awesome [SWR](https://swr.vercel.app/) and its mutate function
```javascript
// Updates all the data from the Battle to SWR
battleMutate(payload.new);
```
And that's it.

This is the code that lets the game be in realtime and see who player guess the word first.

You can see this code on [the repo on GitHub](https://github.com/nicoandrade/warwordly/blob/9688dd49cee19e92c52746aaf6034866e759ca19/pages/battles/%5BbattleId%5D/index.js#L242).

## Ending
I hope that this short post helps you learn how to make an easy realtime feature on your app with just a few lines of code.

🎮 You can [play the game here](https://warwordly.com/)
🛠 View the [entire project on GitHub](https://github.com/nicoandrade/warwordly)
🙋‍♂️ Say hi [on Twitter](https://twitter.com/NicoAndrade)