⚔️ Multiplayer
Discord Activities are a great way to create multiplayer games and experiences. Even if you're not building a game, you can still use multiplayer features to create collaborative activities or experiences.
Multiplayer often involve websockets for real-time communication between clients. There are different ways to implement such features. Depending on what you're building, we recommend @robojs/sync for simplicity or a more powerful solution like Colyseus.
Need a tutorial? We've got you covered!
@robojs/sync
If you're building a React app, you can use the @robojs/sync plugin to sync state across clients in real-time. This is the easiest way to add multiplayer functionality to your Discord Activity.
Websocket features can be complex to set up, but @robojs/sync handles all of that for you. Robo.js plugins are designed to work out of the box, no matter how powerful, so you can focus on features!
Setup
To install, run the following command:
npx robo add @robojs/sync
You will need to wrap your app with the <SyncProvider>
component. This will handle state synchronization for you.
import { SyncProvider } from '@robojs/sync'
export function App() {
return (
<SyncProvider>
<Activity />
</SyncProvider>
)
}
Usage
If you're already familiar with React's useState
hook, then you'll feel right at home with useSyncState
. You can use it just like React's useState
hook, but the state will be synced across all clients in real-time. The only difference is that you need to provide a dependency array as the second argument.
import { useSyncState } from '@robojs/sync'
export function Player() {
const [position, setPosition] = useSyncState({ x: 0, y: 0 }, ['position'])
const handleMouseMove = (event) => {
setPosition({ x: event.clientX, y: event.clientY })
}
return (
<div onMouseMove={handleMouseMove}>
Position: {position.x}, {position.y}
</div>
)
}
Updating the state will cause all clients to receive the new state in real-time. When doing so, we recommend using an updater function to ensure you're always working with the latest state.
const handleMouseMove = (event) => {
setPosition((prev) => ({ x: event.clientX, y: event.clientY }))
}
Dependency Array
The dependency array (['position']
) is used to determine which clients should share the same state. In this case, all clients with the same dependency array will share the same position
state. You can use any value in the dependency array, such as the user's ID or a room ID.
const { session } = useDiscordSdk()
const [position, setPosition] = useSyncState({ x: 0, y: 0 }, [session.user.id, 'position'])
Learn More
Colyseus
If you're building a more complex multiplayer game, we recommend using Colyseus.
Colyseus is a powerful multiplayer game server that handles real-time communication between clients. It's mature, scalable, and designed for live multiplayer games. It works great with most game engines, UI libraries, and frameworks - including Robo.js!
Setup
Unlike Robo plugins, Colyseus requires a bit more setup. Let's start by installing dependencies:
npm install @colyseus/core @colyseus/schema @colyseus/ws-transport colyseus.js
From here on, you'll need to:
- Create a Server: We recommend extending
NodeEngine
in @robojs/server to work with Colyseus. - Define Schemas: Use @colyseus/schema to define your state schemas.
- Define Rooms: Create rooms that handle game logic and state synchronization.
- Connect Clients: Use Colyseus.js to connect clients to your server.
If the above sounds complicated, don't worry! We've created a template to help you get started!
npx create-robo <project-name> --template discord-activities/react-colyseus-ts
Read more about the template:
Usage
Once you've set up your server and rooms, you can start using Colyseus to handle real-time communication between clients. You can use Colyseus to handle game logic, state synchronization, and more.
import { Client } from 'colyseus.js'
const client = new Client('ws://localhost:2567')
const room = client.join('my_room')
room.onStateChange((state) => {
console.log('New state:', state)
})
We recommend creating a Context Provider to manage the Colyseus client and room. This will allow you to access the client and room from anywhere in your Discord Activity.