Host a Discord Activity

A multiplayer game that runs inside a Discord voice channel, on the free plan.

The discord-activity-starter template is a game of Trails, a realtime light-cycle arena. Up to eight riders steer glowing trails around the board, the last one riding wins, and everyone else in the call watches live. A scoreboard counts wins and a list shows who is here. One app serves the game page, the Discord sign-in and the live connection. Deploy it as it is, or use it as the starting point for your own Activity. This template is not affiliated with Discord.

Who can launch it

Discord decides who can open an Activity, and deploying does not change that. Until Discord has verified your application, the Activity launches only for you, the members of the application's developer team, and up to 50 App Testers you invite in the developer portal. Discord also limits an unverified Activity to servers with fewer than 25 members.

To let anyone open it, take your application through Discord's verification and Discovery process. Discord's help article How Can Users Discover and Play My Activity explains teams, App Testers and verification.

1. Create the Discord application

  1. In the Discord developer portal, choose New Application. If other people will test it, choose your developer team as the owner, because team members can launch it.
  2. On the OAuth2 page, copy the Client ID. Choose Reset Secret and copy the Client Secret. Discord shows it once.
  3. Still on OAuth2, under Redirects, add https://127.0.0.1 and save. Discord requires one redirect. The Activity never uses it.
  4. Open Activities, then Settings, and turn on Enable Activities.

2. Deploy the app

Open the deploy link and sign in if asked. Leave App size as it is. The free plan is enough.

  1. Under Environment, click + Add Variable and add DISCORD_CLIENT_ID with the Client ID as its value.
  2. In the Secrets list, click + New secret. Give the entry a name that belongs to this app, for example discord-activity-client-secret, because secrets are shared across your apps by name. Paste the Client Secret as its value, tick it, and set its Env var name to DISCORD_CLIENT_SECRET.
  3. Click Deploy and wait until the app shows as running.
Env varKindValue
DISCORD_CLIENT_IDVariable (the app's Variables tab)The Client ID
DISCORD_CLIENT_SECRETSecret (Secrets in the dashboard sidebar)The Client Secret

If a value is missing, the app still starts. Its address then shows a setup page that names the missing value, and the app's log says the same in one line. Add the value on the app's Variables tab or under Secrets in the dashboard sidebar. Restart the app if it does not restart on its own.

3. Map the URL in Discord

In the developer portal, open Activities, then URL Mappings. Set the root mapping: prefix /, and as the target your app's address without https://, for example discord-activity-starter-a1b2c3.dockhold.app. The app's setup page shows the exact value to paste. Save.

4. Add testers and launch it

In the developer portal, invite the people who should try it as App Testers, up to 50. Members of your developer team need no invite.

Join a voice channel, open the Activities menu (the rocket icon) and pick your application. The first time, Discord asks you to authorize it. Click Ride and a round starts after a three-second countdown. Riding alone is a practice round. A second account on your developer team, or one of your App Testers, joins the same voice channel, opens the Activity and clicks Ride too: from the next round you ride against each other. Everyone else in the voice channel watches, and can switch with the Ride and Watch toggle. Steer with the arrow keys or WASD, or on a phone with a swipe on the board or the four on-screen buttons.

Run one copy only

Keep this app at one copy. The game rooms live in the app's memory, so a second copy would split the players of one game between two servers.

A restart or a deploy ends the round in progress. Every open page signs in to Discord again without a dialog, reconnects by itself and lands in a fresh room: an empty board, no wins on the scoreboard, and nobody riding until they click Ride again.

A room ends about a minute after everyone has left it. Rounds restart by themselves after a three-second results screen.

How the sign-in works

The page asks Discord to authorize the identify scope. The app exchanges the result with your client secret and hands the page a short-lived session of its own, good for 15 minutes, that names the Discord user.

The game connection opens only with that session. No Discord token reaches the game socket, and the player's identity comes from the session, never from a message.

Make your own copy

Click Use this template on GitHub to make your own copy, connect that repository in Dockhold, and deploy it. From then on every push redeploys the app. The game is in server/src/game.js and client/src/main.ts. The server's limits (message size, message rate, rooms and sockets) are in server/src/limits.js. Change them there as your Activity grows.

Troubleshooting

  • The app's address shows a setup page: it names the missing value. Add DISCORD_CLIENT_ID on the app's Variables tab or DISCORD_CLIENT_SECRET under Secrets in the dashboard sidebar, then restart.
  • The page says to open it from a voice channel: the Activity only runs inside Discord. Launch it from the Activities menu in a voice channel.
  • The Activity does not appear, or will not launch for someone: that person is not you, on your developer team or an App Tester, or the server has 25 members or more. See Who can launch it above.
  • Everyone is signed out after you reset the secret: update the secret in the dashboard and restart. Sessions end and players sign in again when they reconnect.
  • A cycle keeps riding after its player closed the Activity: it rides on in a straight line until it crashes. If the player comes back during the round they steer it again. After 30 seconds away they lose their place.

Next

Suggested guides
↑↓ to move ↵ to open Esc to close From the Dockhold docs