---
title: 'How to Make a D&D Dice Roller Discord Bot with Initiative'
published date: '2026-10-23'
author: 'Illiana Reed'
title-image: 'https://camelai.com/blog/assets/images/covers/dice-roller-discord-bot.png'
---

A dice roller Discord bot lets your table roll `2d6+3`, `4d6kh3`, or a d20 with advantage in the channel, with every die on show. In this tutorial, I'll walk you through how to make a D&D-style one with camelBot, with private GM rolls and an initiative tracker, without writing code.

We made this exact bot, called dice, tested it privately with pretend players, then added it to our own Discord server. The rolls, screenshots, and one parser lesson below come from that build.

Dungeons & Dragons (D&D, often typed DnD) is a trademark of Wizards of the Coast. camelAI isn't affiliated with Wizards of the Coast, D&D Beyond, or Avrae.

## What tabletop RPG servers make with camelBot

Dice rollers come up more than anything else: custom notation, advantage, hidden rolls, and reroll buttons. Close behind are themed economies with quests and daily rewards, often seasonal, and campaign tools such as character stats, lore that players discover as they explore, and AI game masters that narrate scenes and voice NPCs. These bots lean creative and playful rather than administrative.

## What a good dice roller Discord bot does

A dice bot earns its place when nobody at the table questions a result.

- **Standard notation.** `2d6+3`, `d20+5`, and `1d8+1d6-1`, ignoring spaces and capitals.
- **Keep highest or lowest.** `4d6kh3` keeps the highest three of four d6 for ability scores; `2d20kl1` keeps the lower of two d20.
- **Advantage and disadvantage.** A mode on a single d20 rolls two and keeps one.
- **Every die on show.** Each result, dropped dice struck through, then the total.
- **Clear refusals.** Bad or oversized notation gets a private reply with an example, and nothing is rolled.
- **Private GM rolls.** A separate command answers so only the roller sees it.
- **Initiative per channel.** Add combatants, roll once, then step through turns and rounds. Two tables in two channels don't collide.

The prompt asks for tracker names as plain text, so a name typed as a mention pings nobody. A camelBot bot can't ping a role, `@here`, or `@everyone` either.

**Make one or install one?** If your group plays 5e on D&D Beyond, try Avrae, a ready-made D&D Discord bot. It reads D&D Beyond character sheets, has its own roller and initiative tracker, and [its docs](https://avrae.readthedocs.io/en/latest/ddb.html) describe syncing rolls with a linked D&D Beyond campaign. Make your own for house rules, your own commands and wording, or a game Avrae isn't built around.

## Make a dice roller bot: the steps at a glance

1. **Describe your bot.** Sign in at [bots.camelai.com](https://bots.camelai.com/) with Discord and paste the prompt from Step 1.
2. **Choose Camel's app and a name.** Ours is dice.
3. **Read what camel-builder made.** Check its summary and ask one read-only question.
4. **Roll-test it.** Notation, refusals, caps, advantage, and a GM roll in the test channel.
5. **Run a practice fight.** Ties, a mid-fight add, and a clear, as three people.
6. **Publish and add it to Discord.** Then roll and run one short fight in your server.

## What you need

- A Discord account, to sign in at bots.camelai.com.
- The **Manage Server** permission in your Discord server, and a channel for the game, such as `#game-night`.
- **Manage Messages** in that channel for whoever clears initiative, usually the GM.
- No API, D&D Beyond account, or code. camelBot is free while in beta, with no credit card, and this bot uses no AI.

## Step 1: Describe your dice bot

Once you're signed in, camelBot asks **What should your bot do?** Copy the prompt below, paste it into the box, and select **Continue**. It's the prompt we used, word for word.

```text
Build a dice bot for our D&D-style tabletop group.

/roll dice: takes notation like 2d6+3, d20+5, 1d8+1d6-1, 4d6kh3 (keep highest 3) or 2d20kl1 (keep lowest), ignoring spaces and case. Optional mode: advantage or disadvantage, for one d20 plus modifiers only. Show every die, mark dropped ones, then the total. Refuse bad notation privately with an example; roll nothing. Caps: 10 parts, 100 dice in all, 2 to 1000 sides, numbers up to 1000, keep from 1 up to the dice rolled.

/gmroll rolls the same way, but only the roller sees it.

Initiative, saved per channel: /init add name bonus (-20 to 20), optional total (-20 to 60) for a physical roll. A repeated name (any case) updates it; 30 per channel. /init start rolls d20 + bonus for the rest and starts round 1. Order: highest total, then higher bonus, then who was added first. Refuse a second start until a clear; slot later adds in without moving the current turn.

/init next moves the turn, wrapping into a new round, and shows the order, whose turn it is and the round.

Names: up to 32 characters, shown as plain text so they never ping anyone.

/init clear (Manage Messages only) wipes this channel's initiative.
```

The caps and refusals stop quiet bugs, like `3d6kh4` keeping three dice without a word. `total` lets players who roll real dice enter their own initiative. The command is `/init start`, not `/init roll`, because a bot's command names must be unique, even in different groups.

## Step 2: Choose Camel's app and name your bot

We picked **Camel's app**, so there was nothing to set up on Discord's developer site. camelBot suggested a name; we changed it to **dice**, so commands start with `/dice`, like `/dice roll` and `/dice init next`. We kept the suggested picture and the checked **Use this name and picture in Discord** option, then selected **Create dice**.

Players type roll commands all session, which is a fair reason to choose **Your own app**: commands become `/roll` and `/init next`, under a separate Discord app identity. Follow our [own app guide](https://camelai.com/docs/camelbot/own-app), and paste its bot token only into camelBot's token field, never into the chat. This bot works the same either way.

## Step 3: Read what camel-builder made

camel-builder writes and tries the code while **camel-builder is working…** shows under the message box. Ours finished with **Built dice · checks passed** and said what it hadn't tried: the 30-per-channel cap and fights past round 2.

**The parser lesson.** camel-builder also reported a bug it had caught in its own tries: the parser "ate the first digit of unsigned terms", so `2d6+3` showed one die and a total of 4. It repaired the parser before saving, and every saved-code roll in Step 4 counted its dice correctly. Your build may differ, so count the dice on every roll, not only the total.

Then ask a read-only question, such as "Without changing anything: what random source do the rolls use, is /gmroll private as a whole command, and does the bot save anything besides initiative?" Ours said `/dice gmroll` is private as a whole command and that only initiative is saved, never rolls. It uses no AI, web requests, or schedules.

**How random is it?** camel-builder's read-only report identified JavaScript's `Math.random` as the random source. That's ordinary software randomness: fine for game night, but not cryptographic or audited. Our test rolls stayed in range and added up, which checks the arithmetic, not statistical fairness. Roll physical dice when a result really matters.

## Step 4: Roll-test it in the test channel

Beside the chat is the bot's private [test channel](https://camelai.com/docs/camelbot/test-channel), `#try-dice`. Nothing there reaches Discord, and your commands run the saved code. Under **Talk as**, you can switch between yourself, the server owner, and pretend players **Alex** and **Sam**, who have no permissions. Start with **Reset test data** in the **⋯** menu, and quote values with spaces, like `dice:"1D8 + 1d6 - 1"`. Discord doesn't need the quotes.

1. **Basic rolls.** Run `/dice roll dice:2d6+3`. Ours showed 4 and 5, plus 3, for 12. Roll `10d20` three times; the sets should differ. `d20+5`, `"1D8 + 1d6 - 1"`, and `1d20-1d4` should all roll.
2. **Keeps.** `4d6kh3` and `2d20kl1` each drop exactly one die. Ours rolled 1, 5, 6, and 1 and dropped a 1, for 12, then dropped the 19 and kept 10.

[![Test channel: 4d6kh3 rolls 1, 5, 6 and a dropped 1 for 12, and 2d20kl1 drops 19 and keeps 10](/blog/assets/images/inline/dice-roller-discord-bot/test-channel-dice-keep-highest-lowest.jpg)](/blog/assets/images/inline/dice-roller-discord-bot/test-channel-dice-keep-highest-lowest.jpg "Open full-size screenshot")

The test channel shows the drop marks as `~~` around the dropped die. Discord draws a strikethrough instead, as Step 6 shows.

3. **Bad notation, as Alex.** Try `abc`, `2d`, `1d20++2`, `0d6`, and `3d6kh4`. Each gets a private reply with an example and "Nothing was rolled.", such as "3d6kh4: keep from 1 to 3, the dice it rolls." Ours also refused `d%`, which the prompt didn't mention.
4. **Caps, as yourself.** `100d6` and `1d1000` roll. `101d6` and `60d6+41d4` get "rolls 101 dice: 100 in all at most." `1d1001`, `1d1`, `1d20+1001`, and a roll with 11 parts are refused too, each naming its limit.
5. **Advantage, as Sam.** `/dice roll dice:1d20+5 mode:advantage` dropped a 3 and kept a 20, for 25. `mode:disadvantage` dropped a 9 and kept an 8, for 13. `2d6` with a mode is refused.
6. **A GM roll, as Alex.** `/dice gmroll dice:1d20+2` showed 19, plus 2, for 21, marked **Only you can see this**.

The test channel shows every private reply to you, whoever you talk as, so Alex's GM roll stayed on screen when we switched to Sam. Check privacy from other players in Discord.

It's working when every die is in range, every total adds up, keeps drop the right die, and refusals roll nothing.

## Step 5: Run a practice fight

In Discord, the initiative commands sit in a group: `/dice init add`, `/dice init start`, `/dice init next`, and `/dice init clear`. The test channel's `/` menu lists them without the group, as `/dice add` and so on, and answers `/dice init next` with "dice doesn't have /init." Leave out `init` in the test channel only; the steps below use the Discord names.

1. **Add four combatants.** As yourself, run `/dice init add name:Goblin bonus:2`. As Alex, add `name:Aria bonus:3 total:15`; as Sam, `name:Bram bonus:1 total:15`. Switch **Talk as** back to yourself and add `name:Cato bonus:3 total:15`.
2. **Update one, refuse one.** Add `name:goblin bonus:4`: the reply says "Updated goblin", and the count stays at 4 of 30. `name:Huge bonus:21` gets "The bonus goes from -20 to 20. Nothing was added."
3. **Start the fight.** Run `/dice init start` twice. The first rolled goblin's d20 (ours 9, plus 4, for 13) and posted round 1 with Aria up: Aria 15, Cato 15, Bram 15, goblin 13. Aria and Cato tie on total and bonus, so Aria, added first, goes first. The second start is refused because initiative is already running.
4. **Advance turns, as Alex.** Run `/dice init next` five times: Cato, Bram, goblin, then Aria in round 2, then Cato.
5. **Add someone mid-fight, as Sam.** On Cato's turn, add `name:Dara bonus:0 total:30`. Alex's next `/dice init next` lists Dara first but moves the turn to Bram, still in round 2. Two more go to goblin, then Dara opens round 3.

[![Test channel: round 2 with Cato up, Dara added at 30 by Sam, then next moves the turn to Bram with Dara listed first](/blog/assets/images/inline/dice-roller-discord-bot/test-channel-initiative-mid-fight-add.jpg)](/blog/assets/images/inline/dice-roller-discord-bot/test-channel-initiative-mid-fight-add.jpg "Open full-size screenshot")

6. **Try a second channel.** Switch back to yourself, use the same picker to move to `#general`, and run `/dice init next`: "No initiative is running in this channel." Add a combatant there and start a fight. We also added one named with Sam's mention code; it showed as plain text, with no @Sam pill.
7. **Clear one channel.** Back in `#try-dice`, Alex's `/dice init clear` is refused before the bot's code runs, because Alex lacks Manage Messages. Yours answers privately: "Cleared this channel's initiative (5 removed)." In `#general`, `/dice init next` still moves that fight along.

**Look at test data** in the **⋯** menu showed only initiative tables, with no saved rolls. It's working when ties land in order, a mid-fight add never moves the turn, and a clear wipes one channel only.

## Step 6: Publish it and add it to your game channel

When your tests pass, publish it. camel-builder's card offered to publish dice when it finished; we used the **Publish** button under the chat instead, which published it right away and asked for no extra permissions. camel-builder never publishes on its own.

Camel's app was already in our server, so we opened the bot page's **Channels** tab, selected **Add to a channel**, and chose our server and channel. No Discord permission screen appeared, and the bot page showed **Live in #camel-bots**. For a new installation, **Add to Discord** opens Discord's permission screen; review what it asks for before approving.

Then we tried it in our server, from one account:

- `/dice roll dice:4d6kh3` posted 4, 1, 2, and 4 for everyone, with the 1 struck through, for 10. Our name showed under it as plain text, so nobody was pinged.
- `/dice gmroll dice:1d20+5` showed 5, plus 5, for 10, with Discord's own **Only you can see this** label.

[![Discord: a public 4d6kh3 roll totaling 10 with the 1 struck through, and a private 1d20+5 GM roll totaling 10](/blog/assets/images/inline/dice-roller-discord-bot/discord-dice-roll-and-private-gmroll.jpg)](/blog/assets/images/inline/dice-roller-discord-bot/discord-dice-roll-and-private-gmroll.jpg "Open full-size screenshot")

Use a quiet channel for a test fight. Our `/dice init next` answered privately that no initiative was running, but that alone doesn't rule out saved combatants. Continue only if adding Test says "Added Test" and "1 of 30"; otherwise stop without starting or clearing the fight. Our run was:

- `/dice init add name:Test bonus:1` added Test, 1 of 30 in the channel.
- `/dice init start` rolled 5, plus 1, for 6, and started round 1 with Test up.
- `/dice init next` moved to round 2 without rerolling.
- `/dice init clear` answered privately: "Cleared this channel's initiative (1 removed)."

[![Discord: /dice init start puts Test at 6 in round 1, then /dice init next moves to round 2 without rerolling](/blog/assets/images/inline/dice-roller-discord-bot/discord-initiative-rounds.jpg)](/blog/assets/images/inline/dice-roller-discord-bot/discord-initiative-rounds.jpg "Open full-size screenshot")

So the grouped `/dice init` commands work in Discord. Our replies showed **cases**, another bot on Camel's app in our server: the bot's Settings explain that all Camel bots in a server share the look of the first one added there that has one. Yours can show a different name.

We tested from one account, so ask a player to confirm they can't see your `/dice gmroll`, and run one full fight with your group before game night.

## Permissions a dice roller bot needs

This bot only posts its own replies. It doesn't moderate, give roles, make channels, or read ordinary messages, and its build declared no extra capabilities, so its role position doesn't matter. camelBot doesn't ask for Administrator; don't add it.

Only `/dice init clear` needs a permission, Manage Messages. By default, members can still see `/dice` and all its commands on Camel's app; anyone without Manage Messages who picks clear is refused, as Alex was in the test channel. Any player can add combatants and advance turns.

## Cautions for D&D-style servers

- **Keep the name your own.** Name the bot after your table, not "D&D Bot", and don't use the D&D logo as its picture. "D&D-style" or "5e-compatible" describes it fairly.
- **Don't paste rulebooks.** Keep rulebook text, stat blocks, and adventures out of the bot. Wizards of the Coast publishes the System Reference Document under the CC-BY-4.0 license, which requires attribution.
- **Keep real stakes out.** Dice plus an economy bot's points is a game; dice tied to money or items with cash value is gambling.
- **No roll history in the bot.** This bot's database keeps initiative, not a roll history. Save any result you need later.

## Troubleshooting and limits

| Symptom | Why | Fix |
| --- | --- | --- |
| `/roll` isn't in the menu | On Camel's app, commands start with the bot's name | Type `/dice`, then pick `roll` |
| "dice doesn't have /init" | The test channel lists initiative commands without their group | Type `/dice next` there; use `/dice init next` in Discord |
| "No initiative is running in this channel" | Initiative is saved per channel | Add and start it in the channel you're playing in |
| A second start is refused | A fight is already running | Someone with Manage Messages runs `/dice init clear` |
| `d%` is refused | Percentile shorthand isn't in the notation | Roll `1d100` |

| Limit | Value |
| --- | --- |
| One roll | 10 parts, 100 dice in all, 2 to 1,000 sides, numbers up to 1,000 |
| Initiative | Bonus -20 to 20, total -20 to 60, 30 combatants per channel |
| Combatant names | 32 characters, plain text |

Our prompt set these caps. Our fights reached five combatants, so try a full table before you rely on 30; we also didn't test several players running commands at once. camel-builder tried the 32-character name refusal in its own tests; we didn't repeat it on saved code. This bot uses no AI or web requests, so it doesn't draw on a bot's daily AI allowance. The full list is in [Permissions and limits](https://camelai.com/docs/camelbot/limits).

## Ideas to try (untested)

We haven't built or tested these. Send one to camel-builder, then test it the same way.

**A reroll button:**

```text
Add a Reroll button under each public /roll result. It rolls the same notation again for whoever presses it, as a new message.
```

**Turn pings,** since a role can't be pinged:

```text
Let /init add take an optional player. On /init next, mention that player when it's their combatant's turn. Never mention anyone else.
```

**Crits and a luck tracker:**

```text
Mark a natural 20 or natural 1 on single d20 rolls. /luck shows each player's d20 average and crit count since the last /luck reset.
```

## FAQ

**Can a dice roller Discord bot make secret GM rolls?**
Yes. `/dice gmroll` is private as a whole command, so Discord shows the result only to the person who ran it. We saw its Only you can see this label from one account, so have a player check from theirs.

**Do I need D&D Beyond for a D&D Discord bot?**
No. This one needs no account, character sheets, or API; players type their own bonuses. If your group keeps its characters on D&D Beyond, Avrae reads those sheets directly.

**Is making a dice roller Discord bot free?**
camelBot is free while in beta, with no credit card required. Making and testing use your camel-builder allowance. This bot doesn't use AI, so rolls don't draw on a bot's daily AI allowance.

## Next steps

Ready to make your own dice roller? Start from this example, then describe what you'd like to change.

[Build this bot](https://bots.camelai.com/new?prompt=Build%20a%20dice%20bot%20for%20our%20D%26D-style%20tabletop%20group.%0A%0A%2Froll%20dice%3A%20takes%20notation%20like%202d6%2B3%2C%20d20%2B5%2C%201d8%2B1d6-1%2C%204d6kh3%20(keep%20highest%203)%20or%202d20kl1%20(keep%20lowest)%2C%20ignoring%20spaces%20and%20case.%20Optional%20mode%3A%20advantage%20or%20disadvantage%2C%20for%20one%20d20%20plus%20modifiers%20only.%20Show%20every%20die%2C%20mark%20dropped%20ones%2C%20then%20the%20total.%20Refuse%20bad%20notation%20privately%20with%20an%20example%3B%20roll%20nothing.%20Caps%3A%2010%20parts%2C%20100%20dice%20in%20all%2C%202%20to%201000%20sides%2C%20numbers%20up%20to%201000%2C%20keep%20from%201%20up%20to%20the%20dice%20rolled.%0A%0A%2Fgmroll%20rolls%20the%20same%20way%2C%20but%20only%20the%20roller%20sees%20it.%0A%0AInitiative%2C%20saved%20per%20channel%3A%20%2Finit%20add%20name%20bonus%20(-20%20to%2020)%2C%20optional%20total%20(-20%20to%2060)%20for%20a%20physical%20roll.%20A%20repeated%20name%20(any%20case)%20updates%20it%3B%2030%20per%20channel.%20%2Finit%20start%20rolls%20d20%20%2B%20bonus%20for%20the%20rest%20and%20starts%20round%201.%20Order%3A%20highest%20total%2C%20then%20higher%20bonus%2C%20then%20who%20was%20added%20first.%20Refuse%20a%20second%20start%20until%20a%20clear%3B%20slot%20later%20adds%20in%20without%20moving%20the%20current%20turn.%0A%0A%2Finit%20next%20moves%20the%20turn%2C%20wrapping%20into%20a%20new%20round%2C%20and%20shows%20the%20order%2C%20whose%20turn%20it%20is%20and%20the%20round.%0A%0ANames%3A%20up%20to%2032%20characters%2C%20shown%20as%20plain%20text%20so%20they%20never%20ping%20anyone.%0A%0A%2Finit%20clear%20(Manage%20Messages%20only)%20wipes%20this%20channel's%20initiative.&ref=blog "cta:build-example-end")

Want to start with a different idea?

[Build your own bot](https://bots.camelai.com/new?ref=blog "cta:build-own-bot")

For points and loot your players keep between sessions, see the [economy bot tutorial](https://camelai.com/blog/discord-economy-bot). New to camelBot? Start with [how to make a Discord bot](https://camelai.com/blog/how-to-make-a-discord-bot). For more ideas, visit our [Discord bot maker](https://camelai.com/discord) page.
