DEV Community

Cover image for Building a Skribbl.io Clone: From Concept to Completion
DivyanshuLohani
DivyanshuLohani

Posted on

Building a Skribbl.io Clone: From Concept to Completion

Creating a real-time multiplayer game like Skribbl.io is an exciting challenge that combines various aspects of web development. In this article, I'll talk about my implementation and thinking in building a real time clone how you can handle a game which is round based and timer system

If you want to checkout the source code for the project you can find it here Github

Image Showing completed project

Tech Stack

Before diving into the details, let’s briefly look at the tech stack used for this project:

  • Node.js: For the backend server.
  • Socket.IO: For real-time communication.
  • Redis: For efficient data handling.
  • Vite: For fast development with React.
  • TypeScript: For type safety in both frontend and backend.
  • React: For building the user interface.
  • Docker: For containerizing the application.

Setting Up the Backend

The backend is powered by Node.js and Socket.IO, which are perfect for handling real-time interactions. Here’s a quick overview of the main components:

1. WebSockets for Real-Time Communication

Socket.IO allows for seamless communication between the server and clients. We use it to handle events such as players joining rooms, starting games, and sending drawing data.

2. Room System

Each game is hosted in a unique room, identified by a room ID. Players join a room using this ID and interact with others in the same room. The system also handles player connections and disconnections.

But here we have a problem how can we ensute that our server retains the data which was in the game if so the server ever crashes

Here we use a database which is fast and also a separate body from the server

Redis is a great choice for such type of use case. Its an in-memory database which is fast and can be run separately on a different server

We will talk about that more in the post later.

3. Event Handling

The server listens for and emits various events:

  • Client Events: connect, disconnecting, joinRoom, leaveRoom, startGame, draw, guess, changeSettings, wordSelect
  • Server Events: joinedRoom, playerJoined, playerLeft, gameStarted, gameEnded, drawData, guessed, turnEnded, chooseWord, wordChosen, settingsChanged, guessFail

Developing the Frontend

For the frontend, I used React with TypeScript and Vite for a smooth development experience.

1. Building the UI

The user interface includes components for drawing, guessing, and managing game settings. React’s component-based architecture made it easy to create a dynamic and responsive UI.

2. Handling Game State

The frontend manages the game state, including player scores, current turn, and drawing data. TypeScript ensures that the data structures are well-defined and error-free.

3. Real-Time Updates

Using Socket.IO, the frontend updates in real-time based on server events. For example, when a player draws, the drawing data is sent to all clients in the room.

Game State Management

Effective game state management is crucial for ensuring a smooth and enjoyable experience in a real-time multiplayer game like Skribbl.io. Here’s a detailed look at how various aspects of the game state are managed:

Player Joining and Leaving

Managing players joining and leaving a room involves several key steps:

  • Joining:

    1. Event Emission: When a player wants to join a room, they send a joinRoom event with the room ID to the server.
    2. Validation: The server validates the room ID and checks if the room exists.
    3. Player Addition: If valid, the player is added to the room's player list. The server then updates the game state and emits a playerJoined event to all clients in the room, informing them of the new player’s arrival.
    4. UI Update: On the frontend, the new player’s presence is reflected in the room’s player list, ensuring that everyone sees the most current player roster.
  • Leaving:

    1. Event Emission: When a player decides to leave, they send a leaveRoom event to the server.
    2. Player Removal: The server removes the player from the room’s player list and updates the game state accordingly.
    3. Notification: The server emits a playerLeft event to all remaining clients, notifying them that the player has left the room.
    4. UI Update: The frontend reflects this change by removing the player from the player list and adjusting any ongoing game mechanics if necessary.

Image showing joining and leaving

Word Selection

Choosing a word and managing whose turn it is to choose involves several mechanisms:

  • Current Player Turn:
    1. Turn Management: The server maintains a record of whose turn it is to choose a word. This is managed by the game state, which includes a property indicating the current player’s ID.
    2. Word Selection Prompt: When it’s a player’s turn to choose a word, they receive a chooseWord event from the server, prompting them to select a word.

Image Showing slection screen

  • Preventing Word Leakage:

    1. Turn-Restricted Access: The chosen word is not immediately broadcasted to other players. Instead, it is only shared when it is the drawer's turn, to prevent any unfair advantage.
    2. Event Emission: Once the drawer has chosen the word, the server emits a wordChosen event to all players. This event includes a notification that the word has been selected and is ready for guessing.
  • Notification of Word Selection:

    1. Broadcast: The wordChosen event includes a notification that a word has been selected, which is sent to all players in the room.
    2. Frontend Handling: On the client side, players are updated to indicate that the drawing phase has begun, and they can now start guessing.

Image Showing text notification

Handling Timeouts for Word Selection

To handle cases where the current player might delay word selection:

  • Automatic Assignment:
    1. Timeout Mechanism: The server implements a timer that starts when it is the player’s turn to choose a word. If the player does not select a word within the allotted time, a timeout event is triggered.
    2. Word Assignment: The server automatically selects a word from a predefined list and assigns it to the player. This ensures the game continues without unnecessary delays.
    3. Notification: A wordChosen event is then emitted to notify all players that a word has been assigned and that the drawing phase is beginning.

Image Showing timer

Drawing Data Handling

Handling drawing data is essential for maintaining synchronization between players:

  • Real-Time Drawing:
    1. Drawing Events: Players send drawing data to the server using the draw event. This data includes brush color, radius, and coordinates of the drawn points.
    2. Broadcasting: The server receives this data and broadcasts it to all clients in the room using a drawData event. This ensures that every player’s canvas is updated in real time with the latest drawing information.

Image of a drawing written hello in apple style

Handling Player Guess Events

Managing player guesses involves processing and validating each guess:

  • Guess Submission:

    1. Event Handling: When a player makes a guess, they send a guess event to the server with their guess word.
    2. Validation: The server processes the guess, checking it against the correct word. If the guess is correct, the server updates the game state and player scores.
  • Broadcasting Results:

    1. Guess Result: The server emits a guessed event to all players, indicating whether the guess was correct or not.
    2. UI Update: On the frontend, the result is displayed to all players, showing who guessed correctly and updating the game’s progress.

Image showing word guessed

Timeouts for Drawing and Guessing

Managing time constraints is key to keeping the game engaging:

  • Draw Time Over:
    1. Time Management: Each round has a set time limit for drawing. The server tracks this time and triggers a turnEnded event when the time expires.
    2. Transition: This event signals the end of the drawing phase, and the game transitions to the guessing phase or the next round.

Game ended screen

  • All Players Guessed:
    1. Guess Completion: If all players guess the word before the time runs out, the server triggers a turnEnded event early.
    2. Game Flow: This event updates all clients that the guessing phase is complete and transitions the game to the next phase or round.

This approach to managing game state ensures a smooth, interactive, and fair experience for all players, enhancing the overall enjoyment of the game.

Conclusion

Building a Skribbl.io clone involves a complex interplay of real-time communication, game state management, and user interactions. Through this project, we’ve explored various facets of game development, from handling player connections and word selection to managing drawing data and player guesses.

Key Takeaways

  • Real-Time Communication: Leveraging Socket.IO allows for seamless and interactive gameplay, ensuring that all players stay synchronized.
  • State Management: Efficient handling of game state—such as player joining, word selection, and drawing data—is crucial for a smooth user experience. Implementing timeouts and automatic assignments ensures the game flows without interruption.
  • User Experience: Maintaining an engaging and responsive interface enhances player satisfaction. Clear feedback on actions like drawing and guessing, combined with timely updates, keeps players informed and invested in the game.

Next Steps

If you’re inspired to take this project further, consider:

  • Adding New Features: Implement additional game modes, customizations, or enhancements to make the game more dynamic.
  • Optimizing Performance: Explore ways to improve performance, such as optimizing drawing data transmission or reducing latency.
  • Enhancing UI/UX: Refine the user interface and experience based on player feedback to make the game more enjoyable.

This project has been an exciting journey into real-time game development, combining various technologies and techniques to create a fun and engaging multiplayer experience. I hope this article has provided valuable insights into game state management and inspired you to explore more in the world of game development.

Feel free to share your thoughts, questions, or improvements on this project in the comments below. Happy coding!

Top comments (0)