Create an issue if you would like this to be deployed online and developed further!
Skribbl clone where you live-code p5.js sketches instead of drawing by hand. Built with TypeScript, React, and Socket.IO.
- Real-time multiplayer with Socket.IO
- Turn-based gameplay, 5 rounds per game
- p5.js drawing canvas
- Live chat and guessing
- Choose from 3 words per turn
- 25-second rounds with countdown
- Progressive hints
- Time-based scoring
- shadcn/ui + Tailwind CSS
- React 19 + TypeScript
- Vite
- Zustand (state)
- p5.js (canvas)
- Socket.IO Client
- shadcn/ui + Radix UI
- Tailwind CSS
- date-fns
- Bun runtime
- Socket.IO
- TypeScript
- date-fns
- Bun v1.0+
Clone and install:
git clone <repository-url>
cd turtlegame
bun installMonorepo with separate frontend and backend packages.
# Start frontend (http://localhost:5173)
just fe
# Start backend (separate terminal)
just beOr run directly:
bun --filter=frontend vite --host
bun --filter=backend devturtlegame/
├── packages/
│ ├── backend/ # Game server
│ │ └── src/
│ │ ├── index.ts # Server entry point
│ │ ├── game.ts # Core game logic
│ │ ├── player.ts # Player management
│ │ ├── room.ts # Room management
│ │ ├── socket.ts # Socket.IO setup
│ │ ├── view.ts # View generation
│ │ ├── protocol.ts # Communication protocol
│ │ └── words.json # Word database
│ └── frontend/ # React application
│ └── src/
│ ├── components/ # Reusable UI components
│ ├── features/ # Feature-specific components
│ ├── pages/ # Page components
│ ├── stores/ # Zustand stores
│ ├── services/ # External services (socket)
│ └── hooks/ # Custom React hooks
└── justfile # Task runner commands
- Join or create a room
- Wait for players to ready up
- Drawer picks from 3 words, writes p5.js sketch (25s)
- Guessers type in chat (faster = more points)
- Play 5 rounds
- 5 rounds per game
- Everyone draws once per round
- 5s to pick word, 25s to draw
- Points scale with guess speed
- Drawer earns points when others guess
# Format all code with Prettier
just fmt
# Run PR workflow
just pr-workflow <branch-name> <commit-message># Run linter
bun --filter=frontend lint
# Fix linting issues
bun --filter=frontend lint:fix- State Management: Use Zustand for global state, useState for local state
- UI Components: Prefer shadcn/ui components when available
- Formatting: Prettier with Tailwind CSS plugin
- Linting: ESLint for code quality
- Event-driven Socket.IO
- Room-based isolation
- Server generates view state per player
- State updates broadcast to room
- Modular React components
- Socket.IO maintains connection
- Zustand for reactive state
- Custom hooks:
use-clock,use-diff
Backend: port 3000 (see index.ts)
Frontend: port 5173 (see vite.config.ts)
- Create a feature branch
- Make your changes
- Run linting and formatting:
just fmt - Test your changes locally
- Submit a pull request
- Custom word lists
- Private rooms with passwords
- Drawing tools expansion (colors, brush sizes, eraser)
- Replay system
- Player profiles and statistics
- Multiple language support
- Mobile-responsive design improvements
Connection issues: Check both services running, ports 3000/5173 free, Socket.IO connected in console.
Build issues: Clear node_modules and reinstall, update Bun.
rm -rf node_modules packages/*/node_modules
bun install
bun upgradeThis project is open source and available for personal and educational use.
